The branch, v4-12-test has been updated
       via  121fbf80523 vfs_fruit: fix close for fake_fd
       via  8a77dcd6935 vfs_fruit: check fake_fd in fruit_pread_meta_stream()
       via  00b37ef3cdf vfs_fruit: use "fake_fd" instead of "created"
       via  1bd5ffc109b vfs_streams_xattr: make use of vfs_fake_fd_close()
       via  cbdd15c13aa vfs_fruit: make use of vfs_fake_fd_close()
       via  83bd07f3806 s3:smbd: add vfs_fake_fd_close() helper
       via  6da2e77cf81 s3:lib: Create the cache path of user gencache 
recursively
       via  83e0a8cdd13 lib:util: Add directory_create_or_exists_recursive()
       via  6adf3619069 vfs_virusfilter: Allocate separate memory for config 
char*
      from  578c5805ac7 Do not create an empty DB when accessing a sam.ldb

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-12-test


- Log -----------------------------------------------------------------
commit 121fbf80523e4456a0fc068e08b0e6379d39200d
Author: Ralph Boehme <[email protected]>
Date:   Fri Dec 11 12:59:28 2020 +0100

    vfs_fruit: fix close for fake_fd
    
    If the next backend doesn't use kernel fd's should not
    pass a fake_fd to the next backend.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14596
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>
    
    Autobuild-User(master): Jeremy Allison <[email protected]>
    Autobuild-Date(master): Fri Jan  8 21:38:18 UTC 2021 on sn-devel-184
    
    (back-ported from commit 564b62a6f7c0a9b9712946d723118122b9c3785f)
    
    Autobuild-User(v4-12-test): Karolin Seeger <[email protected]>
    Autobuild-Date(v4-12-test): Wed Jan 13 13:45:00 UTC 2021 on sn-devel-184

commit 8a77dcd69358a3f16ae7a93f9e7f606967ab2951
Author: Ralph Boehme <[email protected]>
Date:   Fri Dec 11 13:00:56 2020 +0100

    vfs_fruit: check fake_fd in fruit_pread_meta_stream()
    
    Don't call into the next VFS backend if we know we still have a fake-fd. 
Just
    return -1 and the caller has the logic to handle this, which results in
    returning a AFP_AfpInfo blob initialized with some defaults.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14596
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>
    (back-ported from commit c5da08422990dfc1e082bc01aa10d6e415eebe3f)

commit 00b37ef3cdf78236dbd2289e702a3fca89dba1a6
Author: Ralph Boehme <[email protected]>
Date:   Fri Dec 11 13:00:09 2020 +0100

    vfs_fruit: use "fake_fd" instead of "created"
    
    Both have basically the same semantics.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14596
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>
    (back-ported from commit 36eb30fd7d4b82bffd0e1ab471c088f678d700a4)

commit 1bd5ffc109b426903aca8bb913dc504e3e8dbb0d
Author: Stefan Metzmacher <[email protected]>
Date:   Fri Dec 18 14:36:00 2020 +0100

    vfs_streams_xattr: make use of vfs_fake_fd_close()
    
    When we used vfs_fake_fd() we should use vfs_fake_fd_close()
    in order to have things symetric.
    
    That may allows us to change vfs_fake_fd() internally if required.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14596
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>
    (back-ported from commit 40e70cbd3c3a1df9205a7b18d07784c1754cc340)

commit cbdd15c13aa89834b11dc5ec9c6f23cdab692aeb
Author: Stefan Metzmacher <[email protected]>
Date:   Fri Dec 18 14:36:00 2020 +0100

    vfs_fruit: make use of vfs_fake_fd_close()
    
    When we used vfs_fake_fd() we should use vfs_fake_fd_close()
    in order to have things symetric.
    
    That may allows us to change vfs_fake_fd() internally if required.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14596
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>
    (back-ported from commit 719c83b4dc4cef16429ec2803621039545f6885e)

commit 83bd07f3806d212a3051e02897fdceb36557d78b
Author: Stefan Metzmacher <[email protected]>
Date:   Fri Dec 18 14:03:09 2020 +0100

    s3:smbd: add vfs_fake_fd_close() helper
    
    When we used vfs_fake_fd() we should use vfs_fake_fd_close()
    in order to have things symetric.
    
    This makes code easier to understand and may allow us to change
    vfs_fake_fd() internally if required.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14596
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>
    (back-ported from commit 8f057333466b2d9845cd8bc2b794d98252ade2a4)

commit 6da2e77cf81f13ca23bbad0454e068c6b74a181e
Author: Andreas Schneider <[email protected]>
Date:   Mon Dec 21 10:36:46 2020 +0100

    s3:lib: Create the cache path of user gencache recursively
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14601
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>
    
    Autobuild-User(master): Jeremy Allison <[email protected]>
    Autobuild-Date(master): Wed Jan  6 23:59:58 UTC 2021 on sn-devel-184
    
    (cherry picked from commit 38c989fab78c3baade3e441829b7becf6b25ef3f)

commit 83e0a8cdd133d91aec959dc750896beb61158cd8
Author: Andreas Schneider <[email protected]>
Date:   Mon Dec 21 10:35:51 2020 +0100

    lib:util: Add directory_create_or_exists_recursive()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14601
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>
    
    from commit bf7b165877bdfd07eb84ecafdc87bd7a6d945f09)

commit 6adf36190693d3183437fdc07bd77fc8b708bace
Author: Arne Kreddig <[email protected]>
Date:   Fri Jan 1 22:54:22 2021 +0100

    vfs_virusfilter: Allocate separate memory for config char*
    
    Instead of using only the pointer to the configuration char* from the
    global configuration, vfs_virusfilter now allocates its own memory and
    copies the char* from the global configuration.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14606
    Signed-off-by: Arne Kreddig <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>
    
    Autobuild-User(master): Jeremy Allison <[email protected]>
    Autobuild-Date(master): Thu Jan  7 19:25:38 UTC 2021 on sn-devel-184
    
    (cherry picked from commit 2f21d1b0ac8526508161de73290f67858b2fe668)

-----------------------------------------------------------------------

Summary of changes:
 lib/util/samba_util.h               |  14 +++++
 lib/util/tests/test_util.c          | 118 +++++++++++++++++++++++++++++++++---
 lib/util/util.c                     |  40 ++++++++++++
 source3/lib/gencache.c              |   2 +-
 source3/modules/vfs_fruit.c         |  34 ++++++-----
 source3/modules/vfs_streams_xattr.c |   4 +-
 source3/modules/vfs_virusfilter.c   |  66 +++++++++++++++++---
 source3/smbd/proto.h                |   2 +
 source3/smbd/vfs.c                  |   9 +++
 9 files changed, 254 insertions(+), 35 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h
index f0aa42e7271..d32765bf6d1 100644
--- a/lib/util/samba_util.h
+++ b/lib/util/samba_util.h
@@ -451,6 +451,20 @@ _PUBLIC_ bool file_check_permissions(const char *fname,
  */
 _PUBLIC_ bool directory_create_or_exist(const char *dname, mode_t dir_perms);
 
+/**
+ * @brief Try to create a specified directory and the parent directory if they
+ *        don't exist.
+ *
+ * @param[in]  dname     The directory path to create.
+ *
+ * @param[in]  dir_perms The permission of the directories.
+ *
+ * @return true on success, false otherwise.
+ */
+_PUBLIC_ bool directory_create_or_exists_recursive(
+               const char *dname,
+               mode_t dir_perms);
+
 _PUBLIC_ bool directory_create_or_exist_strict(const char *dname,
                                               uid_t uid,
                                               mode_t dir_perms);
diff --git a/lib/util/tests/test_util.c b/lib/util/tests/test_util.c
index eebba39e70c..a893e6175c2 100644
--- a/lib/util/tests/test_util.c
+++ b/lib/util/tests/test_util.c
@@ -4,6 +4,7 @@
  *  Unit test for util.c
  *
  *  Copyright (C) Christof Schmitt 2020
+ *  Copyright (C) Andreas Schneider 2020
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -19,13 +20,22 @@
  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "lib/util/util.c"
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <setjmp.h>
 #include <cmocka.h>
 
+#include "lib/replace/replace.h"
+#include "system/dir.h"
+
+#include "lib/util/util.c"
+
 struct test_paths {
        char testdir[PATH_MAX];
        char none[PATH_MAX];
        char dir[PATH_MAX];
+       char dir_recursive[PATH_MAX];
        mode_t dir_mode;
        char file[PATH_MAX];
        mode_t file_mode;
@@ -59,6 +69,12 @@ static int group_setup(void **state)
        ret = mkdir(paths->dir, paths->dir_mode);
        assert_return_code(ret, errno);
 
+       strlcpy(paths->dir_recursive, testdir, sizeof(paths->dir));
+       strlcat(paths->dir_recursive, "/dir_recursive", sizeof(paths->dir));
+       paths->dir_mode = 0750;
+       ret = mkdir(paths->dir_recursive, paths->dir_mode);
+       assert_return_code(ret, errno);
+
        strlcpy(paths->file, testdir, sizeof(paths->file));
        strlcat(paths->file, "/file", sizeof(paths->file));
        paths->file_mode = 0640;
@@ -89,16 +105,79 @@ static int group_setup(void **state)
        return 0;
 }
 
+static int torture_rmdirs(const char *path)
+{
+       DIR *d;
+       struct dirent *dp;
+       struct stat sb;
+       char *fname;
+
+       if ((d = opendir(path)) != NULL) {
+               while(stat(path, &sb) == 0) {
+                       /* if we can remove the directory we're done */
+                       if (rmdir(path) == 0) {
+                               break;
+                       }
+                       switch (errno) {
+                               case ENOTEMPTY:
+                               case EEXIST:
+                               case EBADF:
+                                       break; /* continue */
+                               default:
+                                       closedir(d);
+                                       return 0;
+                       }
+
+                       while ((dp = readdir(d)) != NULL) {
+                               size_t len;
+                               /* skip '.' and '..' */
+                               if (dp->d_name[0] == '.' &&
+                                               (dp->d_name[1] == '\0' ||
+                                                (dp->d_name[1] == '.' && 
dp->d_name[2] == '\0'))) {
+                                       continue;
+                               }
+
+                               len = strlen(path) + strlen(dp->d_name) + 2;
+                               fname = malloc(len);
+                               if (fname == NULL) {
+                                       closedir(d);
+                                       return -1;
+                               }
+                               snprintf(fname, len, "%s/%s", path, dp->d_name);
+
+                               /* stat the file */
+                               if (lstat(fname, &sb) != -1) {
+                                       if (S_ISDIR(sb.st_mode) && 
!S_ISLNK(sb.st_mode)) {
+                                               if (rmdir(fname) < 0) { /* 
can't be deleted */
+                                                       if (errno == EACCES) {
+                                                               closedir(d);
+                                                               
SAFE_FREE(fname);
+                                                               return -1;
+                                                       }
+                                                       torture_rmdirs(fname);
+                                               }
+                                       } else {
+                                               unlink(fname);
+                                       }
+                               } /* lstat */
+                               SAFE_FREE(fname);
+                       } /* readdir */
+
+                       rewinddir(d);
+               }
+       } else {
+               return -1;
+       }
+
+       closedir(d);
+       return 0;
+}
+
 static int group_teardown(void **state)
 {
        struct test_paths *paths = *state;
        int ret;
 
-       return 0;
-
-       ret = rmdir(paths->dir);
-       assert_return_code(ret, errno);
-
        ret = unlink(paths->file);
        assert_return_code(ret, errno);
 
@@ -111,7 +190,7 @@ static int group_teardown(void **state)
        ret = unlink(paths->symlink_file);
        assert_return_code(ret, errno);
 
-       ret = unlink(paths->testdir);
+       ret = torture_rmdirs(paths->testdir);
        assert_return_code(ret, errno);
 
        free(paths);
@@ -217,6 +296,30 @@ static void 
test_directory_create_or_exists_symlink_file(void **state)
        assert_true(S_ISLNK(sbuf.st_mode));
 }
 
+static void test_directory_create_or_exists_recursive(void **state)
+{
+       struct test_paths *paths = *state;
+       char recursive_testdir[PATH_MAX] = {0};
+       struct stat sbuf = {0};
+       bool ok;
+       int ret;
+
+       ret = snprintf(recursive_testdir,
+                      sizeof(recursive_testdir),
+                      "%s/wurst/brot",
+                      paths->dir_recursive);
+       assert_int_not_equal(ret, -1);
+
+       ok = directory_create_or_exists_recursive(recursive_testdir,
+                                                 0700);
+       assert_true(ok);
+
+       ret = lstat(recursive_testdir, &sbuf);
+       assert_return_code(ret, errno);
+       assert_int_equal(sbuf.st_mode & 0777, 0700);
+       assert_true(S_ISDIR(sbuf.st_mode));
+}
+
 int main(int argc, char **argv)
 {
        const struct CMUnitTest tests[] = {
@@ -226,6 +329,7 @@ int main(int argc, char **argv)
                cmocka_unit_test(test_directory_create_or_exists_symlink_none),
                cmocka_unit_test(test_directory_create_or_exists_symlink_dir),
                cmocka_unit_test(test_directory_create_or_exists_symlink_file),
+               cmocka_unit_test(test_directory_create_or_exists_recursive),
        };
 
        cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
diff --git a/lib/util/util.c b/lib/util/util.c
index 52fc61a3e81..0c6a06e4ff2 100644
--- a/lib/util/util.c
+++ b/lib/util/util.c
@@ -35,6 +35,7 @@
 #include "debug.h"
 #include "samba_util.h"
 #include "lib/util/select.h"
+#include <libgen.h>
 
 #undef malloc
 #undef strcasecmp
@@ -394,6 +395,45 @@ _PUBLIC_ bool directory_create_or_exist(const char *dname,
        return true;
 }
 
+_PUBLIC_ bool directory_create_or_exists_recursive(
+               const char *dname,
+               mode_t dir_perms)
+{
+       bool ok;
+
+       ok = directory_create_or_exist(dname, dir_perms);
+       if (!ok) {
+               if (!directory_exist(dname)) {
+                       char tmp[PATH_MAX] = {0};
+                       char *parent = NULL;
+                       size_t n;
+
+                       /* Use the null context */
+                       n = strlcpy(tmp, dname, sizeof(tmp));
+                       if (n < strlen(dname)) {
+                               DBG_ERR("Path too long!\n");
+                               return false;
+                       }
+
+                       parent = dirname(tmp);
+                       if (parent == NULL) {
+                               DBG_ERR("Failed to create dirname!\n");
+                               return false;
+                       }
+
+                       ok = directory_create_or_exists_recursive(parent,
+                                                                 dir_perms);
+                       if (!ok) {
+                               return false;
+                       }
+
+                       ok = directory_create_or_exist(dname, dir_perms);
+               }
+       }
+
+       return ok;
+}
+
 /**
  * @brief Try to create a specified directory if it doesn't exist.
  *
diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c
index 896bf50cbd7..07a08fa8268 100644
--- a/source3/lib/gencache.c
+++ b/source3/lib/gencache.c
@@ -124,7 +124,7 @@ static bool gencache_init(void)
                        return false;
                }
 
-               ok = directory_create_or_exist(cache_dname, 0700);
+               ok = directory_create_or_exists_recursive(cache_dname, 0700);
                if (!ok) {
                        DBG_ERR("Failed to create directory: %s - %s\n",
                                cache_dname, strerror(errno));
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index b2d0901a800..a3b823fc6af 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -178,9 +178,6 @@ struct fio {
        /* Denote stream type, meta or rsrc */
        adouble_type_t type;
 
-       /* Whether the create created the stream */
-       bool created;
-
        /*
         * AFP_AfpInfo stream created, but not written yet, thus still a fake
         * pipe fd. This is set to true in fruit_open_meta if there was no
@@ -1635,6 +1632,7 @@ static int fruit_open(vfs_handle_struct *handle,
 static int fruit_close_meta(vfs_handle_struct *handle,
                            files_struct *fsp)
 {
+       struct fio *fio = (struct fio *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
        int ret;
        struct fruit_config_data *config = NULL;
 
@@ -1643,11 +1641,16 @@ static int fruit_close_meta(vfs_handle_struct *handle,
 
        switch (config->meta) {
        case FRUIT_META_STREAM:
-               ret = SMB_VFS_NEXT_CLOSE(handle, fsp);
+               if (fio->fake_fd) {
+                       ret = vfs_fake_fd_close(fsp->fh->fd);
+                       fsp->fh->fd = -1;
+               } else {
+                       ret = SMB_VFS_NEXT_CLOSE(handle, fsp);
+               }
                break;
 
        case FRUIT_META_NETATALK:
-               ret = close(fsp->fh->fd);
+               ret = vfs_fake_fd_close(fsp->fh->fd);
                fsp->fh->fd = -1;
                break;
 
@@ -1676,7 +1679,7 @@ static int fruit_close_rsrc(vfs_handle_struct *handle,
                break;
 
        case FRUIT_RSRC_XATTR:
-               ret = close(fsp->fh->fd);
+               ret = vfs_fake_fd_close(fsp->fh->fd);
                fsp->fh->fd = -1;
                break;
 
@@ -2189,9 +2192,14 @@ static ssize_t fruit_pread_meta_stream(vfs_handle_struct 
*handle,
                                       files_struct *fsp, void *data,
                                       size_t n, off_t offset)
 {
+       struct fio *fio = (struct fio *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
        ssize_t nread;
        int ret;
 
+       if (fio->fake_fd) {
+               return -1;
+       }
+
        nread = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
        if (nread == -1 || nread == n) {
                return nread;
@@ -2300,7 +2308,7 @@ static ssize_t fruit_pread_meta(vfs_handle_struct *handle,
                return -1;
        }
 
-       if (nread == -1 && fio->created) {
+       if (nread == -1 && fio->fake_fd) {
                AfpInfo *ai = NULL;
                char afpinfo_buf[AFP_INFO_SIZE];
 
@@ -2527,13 +2535,13 @@ static ssize_t 
fruit_pwrite_meta_stream(vfs_handle_struct *handle,
        }
 
        if (fio->fake_fd) {
-               int fd;
+               int fd = fsp->fh->fd;
 
-               ret = SMB_VFS_NEXT_CLOSE(handle, fsp);
+               ret = vfs_fake_fd_close(fd);
+               fsp->fh->fd = -1;
                if (ret != 0) {
                        DBG_ERR("Close [%s] failed: %s\n",
                                fsp_str_dbg(fsp), strerror(errno));
-                       fsp->fh->fd = -1;
                        return -1;
                }
 
@@ -3999,7 +4007,6 @@ static NTSTATUS fruit_create_file(vfs_handle_struct 
*handle,
        NTSTATUS status;
        struct fruit_config_data *config = NULL;
        files_struct *fsp = NULL;
-       struct fio *fio = NULL;
        bool internal_open = (oplock_request & INTERNAL_OPEN_ONLY);
        int ret;
 
@@ -4072,11 +4079,6 @@ static NTSTATUS fruit_create_file(vfs_handle_struct 
*handle,
                goto fail;
        }
 
-       fio = (struct fio *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
-       if (fio != NULL && pinfo != NULL && *pinfo == FILE_WAS_CREATED) {
-               fio->created = true;
-       }
-
        if (is_named_stream(smb_fname)
            || fsp->is_directory) {
                return status;
diff --git a/source3/modules/vfs_streams_xattr.c 
b/source3/modules/vfs_streams_xattr.c
index 85efe2bcc37..7d0617507e3 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -490,7 +490,7 @@ static int streams_xattr_open(vfs_handle_struct *handle,
 
  fail:
        if (fakefd >= 0) {
-               close(fakefd);
+               vfs_fake_fd_close(fakefd);
                fakefd = -1;
        }
 
@@ -512,7 +512,7 @@ static int streams_xattr_close(vfs_handle_struct *handle,
                return SMB_VFS_NEXT_CLOSE(handle, fsp);
        }
 
-       ret = close(fd);
+       ret = vfs_fake_fd_close(fd);
        fsp->fh->fd = -1;
 
        return ret;
diff --git a/source3/modules/vfs_virusfilter.c 
b/source3/modules/vfs_virusfilter.c
index 12f0364d2a7..6344afc1945 100644
--- a/source3/modules/vfs_virusfilter.c
+++ b/source3/modules/vfs_virusfilter.c
@@ -196,6 +196,14 @@ static int virusfilter_vfs_connect(
        struct virusfilter_config *config = NULL;
        const char *exclude_files = NULL;
        const char *temp_quarantine_dir_mode = NULL;
+       const char *infected_file_command = NULL;
+       const char *scan_error_command = NULL;
+       const char *quarantine_dir = NULL;
+       const char *quarantine_prefix = NULL;
+       const char *quarantine_suffix = NULL;
+       const char *rename_prefix = NULL;
+       const char *rename_suffix = NULL;
+       const char *socket_path = NULL;
        char *sret = NULL;
        char *tmp = NULL;
        enum virusfilter_scanner_enum backend;
@@ -253,11 +261,21 @@ static int virusfilter_vfs_connect(
                snum, "virusfilter", "infected file action",
                virusfilter_actions, VIRUSFILTER_ACTION_DO_NOTHING);
 
-       config->infected_file_command = lp_parm_const_string(
+       infected_file_command = lp_parm_const_string(
                snum, "virusfilter", "infected file command", NULL);
+       config->infected_file_command = talloc_strdup(config, 
infected_file_command);
+       if (config->infected_file_command == NULL) {
+               DBG_ERR("virusfilter-vfs: out of memory!\n");
+               return -1;
+       }
 
-       config->scan_error_command = lp_parm_const_string(
+       scan_error_command = lp_parm_const_string(
                snum, "virusfilter", "scan error command", NULL);
+       config->scan_error_command = talloc_strdup(config, scan_error_command);
+       if (config->scan_error_command == NULL) {
+               DBG_ERR("virusfilter-vfs: out of memory!\n");
+               return -1;
+       }
 
        config->block_access_on_error = lp_parm_bool(
                snum, "virusfilter", "block access on error", false);
@@ -265,9 +283,14 @@ static int virusfilter_vfs_connect(
        tmp = talloc_asprintf(config, "%s/.quarantine",
                handle->conn->connectpath);
 
-       config->quarantine_dir = lp_parm_const_string(
+       quarantine_dir = lp_parm_const_string(
                snum, "virusfilter", "quarantine directory",
                tmp ? tmp : "/tmp/.quarantine");
+       config->quarantine_dir = talloc_strdup(config, quarantine_dir);
+       if (config->quarantine_dir == NULL) {
+               DBG_ERR("virusfilter-vfs: out of memory!\n");
+               return -1;
+       }
 
        if (tmp != config->quarantine_dir) {
                TALLOC_FREE(tmp);
@@ -281,13 +304,23 @@ static int virusfilter_vfs_connect(
                config->quarantine_dir_mode = mode;
        }
 
-       config->quarantine_prefix = lp_parm_const_string(
+       quarantine_prefix = lp_parm_const_string(
                snum, "virusfilter", "quarantine prefix",
                VIRUSFILTER_DEFAULT_QUARANTINE_PREFIX);
+       config->quarantine_prefix = talloc_strdup(config, quarantine_prefix);
+       if (config->quarantine_prefix == NULL) {
+               DBG_ERR("virusfilter-vfs: out of memory!\n");
+               return -1;
+       }
 
-       config->quarantine_suffix = lp_parm_const_string(
+       quarantine_suffix = lp_parm_const_string(
                snum, "virusfilter", "quarantine suffix",
                VIRUSFILTER_DEFAULT_QUARANTINE_SUFFIX);
+       config->quarantine_suffix = talloc_strdup(config, quarantine_suffix);
+       if (config->quarantine_suffix == NULL) {
+               DBG_ERR("virusfilter-vfs: out of memory!\n");
+               return -1;
+       }
 
        /*
         * Make sure prefixes and suffixes do not contain directory
@@ -318,13 +351,23 @@ static int virusfilter_vfs_connect(
        config->quarantine_keep_name = lp_parm_bool(
                snum, "virusfilter", "quarantine keep name", true);
 


-- 
Samba Shared Repository

Reply via email to