From aef2e6858831083d95fc4ba24991fa7bdacbd183 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 25 Mar 2013 11:33:28 -0700 Subject: [PATCH 01/11] Remove malloc use - change to talloc off connection context. Signed-off-by: Jeremy Allison --- source3/modules/vfs_scannedonly.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/source3/modules/vfs_scannedonly.c b/source3/modules/vfs_scannedonly.c index c48c21a..d995b9e 100644 --- a/source3/modules/vfs_scannedonly.c +++ b/source3/modules/vfs_scannedonly.c @@ -933,24 +933,19 @@ static int scannedonly_rmdir(vfs_handle_struct * handle, const char *path) return SMB_VFS_NEXT_RMDIR(handle, path); } -static void free_scannedonly_data(void **data) -{ - SAFE_FREE(*data); -} - static int scannedonly_connect(struct vfs_handle_struct *handle, const char *service, const char *user) { struct Tscannedonly *so; - so = SMB_MALLOC_P(struct Tscannedonly); + so = talloc_zero(handle->conn, struct Tscannedonly); if (so == NULL) { errno = ENOMEM; return -1; } - handle->data = (void *)so; - handle->free_data = free_scannedonly_data; + SMB_VFS_HANDLE_SET_DATA(handle, so, NULL, struct Tscannedonly, return -1); + so->gsendbuffer[0]='\0'; so->domain_socket = lp_parm_bool(SNUM(handle->conn), "scannedonly", -- 1.8.1.3 From 35470192dba5399a613a63caf5a364df14d74f28 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 25 Mar 2013 11:34:12 -0700 Subject: [PATCH 02/11] Remove custom macro STRUCTSCANO. Change to SMB_VFS_HANDLE_GET_DATA. Signed-off-by: Jeremy Allison --- source3/modules/vfs_scannedonly.c | 95 ++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 32 deletions(-) diff --git a/source3/modules/vfs_scannedonly.c b/source3/modules/vfs_scannedonly.c index d995b9e..1a13a62 100644 --- a/source3/modules/vfs_scannedonly.c +++ b/source3/modules/vfs_scannedonly.c @@ -84,8 +84,6 @@ struct Tscannedonly { char gsendbuffer[SENDBUFFERSIZE + 1]; }; -#define STRUCTSCANO(var) ((struct Tscannedonly *)var) - struct scannedonly_DIR { char *base; int recheck_tries_done; /* if 0 the directory listing has not yet @@ -192,7 +190,9 @@ static char *construct_full_path(TALLOC_CTX *ctx, vfs_handle_struct * handle, static int connect_to_scanner(vfs_handle_struct * handle) { - struct Tscannedonly *so = (struct Tscannedonly *)handle->data; + struct Tscannedonly *so; + + SMB_VFS_HANDLE_GET_DATA(handle, so, struct Tscannedonly, return -1); if (so->domain_socket) { struct sockaddr_un saun; @@ -247,8 +247,11 @@ static int connect_to_scanner(vfs_handle_struct * handle) static void flush_sendbuffer(vfs_handle_struct * handle) { - struct Tscannedonly *so = (struct Tscannedonly *)handle->data; int ret, len, loop = 10; + struct Tscannedonly *so; + + SMB_VFS_HANDLE_GET_DATA(handle, so, struct Tscannedonly, return); + if (so->gsendbuffer[0] == '\0') { return; } @@ -312,8 +315,11 @@ static void notify_scanner(vfs_handle_struct * handle, const char *scanfile) { const char *tmp; int tmplen, gsendlen; - struct Tscannedonly *so = (struct Tscannedonly *)handle->data; TALLOC_CTX *ctx=talloc_tos(); + struct Tscannedonly *so; + + SMB_VFS_HANDLE_GET_DATA(handle, so, struct Tscannedonly, return); + if (scanfile[0] != '/') { tmp = construct_full_path(ctx,handle, scanfile, false); } else { @@ -383,6 +389,10 @@ static bool scannedonly_allow_access(vfs_handle_struct * handle, TALLOC_CTX *ctx=talloc_tos(); char *cachefile; int retval = -1; + struct Tscannedonly *so; + + SMB_VFS_HANDLE_GET_DATA(handle, so, struct Tscannedonly, return false); + DEBUG(SCANNEDONLY_DEBUG, ("smb_fname->base_name=%s, shortname=%s, base_name=%s\n" ,smb_fname->base_name,shortname,base_name)); @@ -390,7 +400,7 @@ static bool scannedonly_allow_access(vfs_handle_struct * handle, if (ISDOT(shortname) || ISDOTDOT(shortname)) { return true; } - if (is_scannedonly_file(STRUCTSCANO(handle->data), shortname)) { + if (is_scannedonly_file(so, shortname)) { DEBUG(SCANNEDONLY_DEBUG, ("scannedonly_allow_access, %s is a scannedonly file, " "return 0\n", shortname)); @@ -413,8 +423,7 @@ static bool scannedonly_allow_access(vfs_handle_struct * handle, ("%s is not a regular file, ISDIR=%d\n", smb_fname->base_name, S_ISDIR(smb_fname->st.st_ex_mode))); - return (STRUCTSCANO(handle->data)-> - show_special_files || + return (so->show_special_files || S_ISDIR(smb_fname->st.st_ex_mode)); } if (smb_fname->st.st_ex_size == 0) { @@ -424,7 +433,7 @@ static bool scannedonly_allow_access(vfs_handle_struct * handle, cachefile = cachefile_name(ctx, shortname, base_name, - STRUCTSCANO(handle->data)->p_scanned); + so->p_scanned); create_synthetic_smb_fname(ctx, cachefile,NULL,NULL,&cache_smb_fname); if (!VALID_STAT(cache_smb_fname->st)) { retval = SMB_VFS_NEXT_STAT(handle, cache_smb_fname); @@ -572,8 +581,11 @@ static struct dirent *scannedonly_readdir(vfs_handle_struct *handle, int namelen; struct dirent *newdirent; TALLOC_CTX *ctx=talloc_tos(); - struct scannedonly_DIR *sDIR = (struct scannedonly_DIR *)dirp; + struct Tscannedonly *so; + + SMB_VFS_HANDLE_GET_DATA(handle, so, struct Tscannedonly, return NULL); + if (!dirp) { return NULL; } @@ -583,7 +595,7 @@ static struct dirent *scannedonly_readdir(vfs_handle_struct *handle, if (!result) return NULL; - if (is_scannedonly_file(STRUCTSCANO(handle->data), result->d_name)) { + if (is_scannedonly_file(so, result->d_name)) { DEBUG(SCANNEDONLY_DEBUG, ("scannedonly_readdir, %s is a scannedonly file, " "skip to next entry\n", result->d_name)); @@ -604,10 +616,8 @@ static struct dirent *scannedonly_readdir(vfs_handle_struct *handle, handle, sDIR, smb_fname, result->d_name, sDIR->base, 0, - STRUCTSCANO(handle->data)->hide_nonscanned_files - ? STRUCTSCANO(handle->data)->recheck_time_readdir - : 0, - STRUCTSCANO(handle->data)->recheck_tries_readdir, + so->hide_nonscanned_files ? so->recheck_time_readdir : 0, + so->recheck_tries_readdir, -1, 1); DEBUG(SCANNEDONLY_DEBUG, @@ -618,12 +628,12 @@ static struct dirent *scannedonly_readdir(vfs_handle_struct *handle, } DEBUG(SCANNEDONLY_DEBUG, ("hide_nonscanned_files=%d, allow_nonscanned_files=%d\n", - STRUCTSCANO(handle->data)->hide_nonscanned_files, - STRUCTSCANO(handle->data)->allow_nonscanned_files + so->hide_nonscanned_files, + so->allow_nonscanned_files )); - if (!STRUCTSCANO(handle->data)->hide_nonscanned_files - || STRUCTSCANO(handle->data)->allow_nonscanned_files) { + if (!so->hide_nonscanned_files + || so->allow_nonscanned_files) { return result; } @@ -632,7 +642,7 @@ static struct dirent *scannedonly_readdir(vfs_handle_struct *handle, "allowed, notify user\n", result->d_name)); notify_name = talloc_asprintf( ctx,"%s %s",result->d_name, - STRUCTSCANO(handle->data)->scanning_message); + so->scanning_message); namelen = strlen(notify_name); newdirent = (struct dirent *)talloc_array( ctx, char, sizeof(struct dirent) + namelen + 1); @@ -682,8 +692,12 @@ static int scannedonly_closedir(vfs_handle_struct * handle, static int scannedonly_stat(vfs_handle_struct * handle, struct smb_filename *smb_fname) { + struct Tscannedonly *so; int ret; ret = SMB_VFS_NEXT_STAT(handle, smb_fname); + + SMB_VFS_HANDLE_GET_DATA(handle, so, struct Tscannedonly, return -1); + DEBUG(SCANNEDONLY_DEBUG, ("scannedonly_stat: %s returned %d\n", smb_fname->base_name, ret)); if (ret != 0 && errno == ENOENT) { @@ -694,7 +708,7 @@ static int scannedonly_stat(vfs_handle_struct * handle, stat the real name */ test_base_name = real_path_from_notify_path( ctx, - STRUCTSCANO(handle->data), + so, smb_fname->base_name); if (test_base_name) { smb_fname->base_name = test_base_name; @@ -710,8 +724,12 @@ static int scannedonly_stat(vfs_handle_struct * handle, static int scannedonly_lstat(vfs_handle_struct * handle, struct smb_filename *smb_fname) { + struct Tscannedonly *so; int ret; ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname); + + SMB_VFS_HANDLE_GET_DATA(handle, so, struct Tscannedonly, return -1); + DEBUG(SCANNEDONLY_DEBUG, ("scannedonly_lstat: %s returned %d\n", smb_fname->base_name, ret)); if (ret != 0 && errno == ENOENT) { @@ -721,7 +739,7 @@ static int scannedonly_lstat(vfs_handle_struct * handle, viruses.txt): check for that and create the real name and stat the real name */ test_base_name = real_path_from_notify_path( - ctx, STRUCTSCANO(handle->data), smb_fname->base_name); + ctx, so, smb_fname->base_name); if (test_base_name) { smb_fname->base_name = test_base_name; ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname); @@ -741,6 +759,10 @@ static int scannedonly_open(vfs_handle_struct * handle, char *tmp, *shortname; int allowed, write_access = 0; TALLOC_CTX *ctx=talloc_tos(); + struct Tscannedonly *so; + + SMB_VFS_HANDLE_GET_DATA(handle, so, struct Tscannedonly, return -1); + /* if open for writing ignore it */ if ((flags & O_ACCMODE) == O_WRONLY) { return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode); @@ -762,15 +784,15 @@ static int scannedonly_open(vfs_handle_struct * handle, handle, NULL, smb_fname, shortname, base, write_access, - STRUCTSCANO(handle->data)->recheck_time_open, - STRUCTSCANO(handle->data)->recheck_tries_open, - STRUCTSCANO(handle->data)->recheck_size_open, + so->recheck_time_open, + so->recheck_tries_open, + so->recheck_size_open, 0); flush_sendbuffer(handle); DEBUG(SCANNEDONLY_DEBUG, ("scannedonly_open: allow=%d for %s\n", allowed, smb_fname->base_name)); if (allowed - || STRUCTSCANO(handle->data)->allow_nonscanned_files) { + || so->allow_nonscanned_files) { return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode); } errno = EACCES; @@ -802,16 +824,19 @@ static int scannedonly_rename(vfs_handle_struct * handle, bool needscandst=false; int ret; TALLOC_CTX *ctx = talloc_tos(); + struct Tscannedonly *so; + + SMB_VFS_HANDLE_GET_DATA(handle, so, struct Tscannedonly, return -1); /* Setup temporary smb_filename structs. */ cachefile_src = cachefile_name_f_fullpath( ctx, smb_fname_src->base_name, - STRUCTSCANO(handle->data)->p_scanned); + so->p_scanned); cachefile_dst = cachefile_name_f_fullpath( ctx, smb_fname_dst->base_name, - STRUCTSCANO(handle->data)->p_scanned); + so->p_scanned); create_synthetic_smb_fname(ctx, cachefile_src,NULL,NULL, &smb_fname_src_tmp); create_synthetic_smb_fname(ctx, cachefile_dst,NULL,NULL, @@ -841,11 +866,14 @@ static int scannedonly_unlink(vfs_handle_struct * handle, struct smb_filename *smb_fname_cache = NULL; char * cachefile; TALLOC_CTX *ctx = talloc_tos(); + struct Tscannedonly *so; + + SMB_VFS_HANDLE_GET_DATA(handle, so, struct Tscannedonly, return -1); cachefile = cachefile_name_f_fullpath( ctx, smb_fname->base_name, - STRUCTSCANO(handle->data)->p_scanned); + so->p_scanned); create_synthetic_smb_fname(ctx, cachefile,NULL,NULL, &smb_fname_cache); if (SMB_VFS_NEXT_UNLINK(handle, smb_fname_cache) != 0) { @@ -864,8 +892,11 @@ static int scannedonly_rmdir(vfs_handle_struct * handle, const char *path) TALLOC_CTX *ctx = talloc_tos(); bool only_deletable_files = true, have_files = false; char *path_w_slash; + struct Tscannedonly *so; + + SMB_VFS_HANDLE_GET_DATA(handle, so, struct Tscannedonly, return -1); - if (!STRUCTSCANO(handle->data)->rm_hidden_files_on_rmdir) + if (!so->rm_hidden_files_on_rmdir) return SMB_VFS_NEXT_RMDIR(handle, path); path_w_slash = name_w_ending_slash(ctx,path); @@ -878,13 +909,13 @@ static int scannedonly_rmdir(vfs_handle_struct * handle, const char *path) continue; } have_files = true; - if (!is_scannedonly_file(STRUCTSCANO(handle->data), + if (!is_scannedonly_file(so, dire->d_name)) { struct smb_filename *smb_fname = NULL; char *fullpath; int retval; - if (STRUCTSCANO(handle->data)->show_special_files) { + if (so->show_special_files) { only_deletable_files = false; break; } -- 1.8.1.3 From 974ae3f0d7ec5e7dedd9770a020f9320d054283d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 25 Mar 2013 11:39:43 -0700 Subject: [PATCH 03/11] Change struct scannedonly_DIR to make it usable as a DLINK list. Signed-off-by: Jeremy Allison --- source3/modules/vfs_scannedonly.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source3/modules/vfs_scannedonly.c b/source3/modules/vfs_scannedonly.c index 1a13a62..65c2e43 100644 --- a/source3/modules/vfs_scannedonly.c +++ b/source3/modules/vfs_scannedonly.c @@ -60,6 +60,13 @@ + strlen((sunp)->sun_path)) #endif +struct scannedonly_DIR { + struct scannedonly_DIR *prev, *next; + char *base; + int recheck_tries_done; /* if 0 the directory listing has not yet + been checked for files that need to be scanned. */ + DIR *DIR; +}; struct Tscannedonly { int socket; @@ -84,12 +91,6 @@ struct Tscannedonly { char gsendbuffer[SENDBUFFERSIZE + 1]; }; -struct scannedonly_DIR { - char *base; - int recheck_tries_done; /* if 0 the directory listing has not yet - been checked for files that need to be scanned. */ - DIR *DIR; -}; #define SCANNEDONLY_DEBUG 9 /*********************/ /* utility functions */ -- 1.8.1.3 From 90ec953ef2525d644283333c2cc97255c63a2e4c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 25 Mar 2013 11:50:32 -0700 Subject: [PATCH 04/11] Rename struct member DIR to DIRp to avoid macro conflicts. Signed-off-by: Jeremy Allison --- source3/modules/vfs_scannedonly.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/source3/modules/vfs_scannedonly.c b/source3/modules/vfs_scannedonly.c index 65c2e43..d489b5b 100644 --- a/source3/modules/vfs_scannedonly.c +++ b/source3/modules/vfs_scannedonly.c @@ -65,7 +65,7 @@ struct scannedonly_DIR { char *base; int recheck_tries_done; /* if 0 the directory listing has not yet been checked for files that need to be scanned. */ - DIR *DIR; + DIR *DIRp; }; struct Tscannedonly { @@ -458,8 +458,8 @@ static bool scannedonly_allow_access(vfs_handle_struct * handle, long offset; struct dirent *dire; - offset = SMB_VFS_NEXT_TELLDIR(handle, sDIR->DIR); - dire = SMB_VFS_NEXT_READDIR(handle, sDIR->DIR, NULL); + offset = SMB_VFS_NEXT_TELLDIR(handle, sDIR->DIRp); + dire = SMB_VFS_NEXT_READDIR(handle, sDIR->DIRp, NULL); while (dire) { char *fpath2; struct smb_filename *smb_fname2; @@ -475,10 +475,10 @@ static bool scannedonly_allow_access(vfs_handle_struct * handle, base_name, 0, 0, 0, 0, 0); talloc_free(fpath2); talloc_free(smb_fname2); - dire = SMB_VFS_NEXT_READDIR(handle, sDIR->DIR,NULL); + dire = SMB_VFS_NEXT_READDIR(handle, sDIR->DIRp,NULL); } sDIR->recheck_tries_done = 1; - SMB_VFS_NEXT_SEEKDIR(handle, sDIR->DIR, offset); + SMB_VFS_NEXT_SEEKDIR(handle, sDIR->DIRp, offset); } if (recheck_time > 0 && ((recheck_size > 0 @@ -536,7 +536,7 @@ static DIR *scannedonly_opendir(vfs_handle_struct * handle, } DEBUG(SCANNEDONLY_DEBUG, ("scannedonly_opendir, fname=%s, base=%s\n",fname,sDIR->base)); - sDIR->DIR = DIRp; + sDIR->DIRp = DIRp; sDIR->recheck_tries_done = 0; return (DIR *) sDIR; } @@ -564,7 +564,7 @@ static DIR *scannedonly_fdopendir(vfs_handle_struct * handle, } DEBUG(SCANNEDONLY_DEBUG, ("scannedonly_fdopendir, fname=%s, base=%s\n",fname,sDIR->base)); - sDIR->DIR = DIRp; + sDIR->DIRp = DIRp; sDIR->recheck_tries_done = 0; return (DIR *) sDIR; } @@ -591,7 +591,7 @@ static struct dirent *scannedonly_readdir(vfs_handle_struct *handle, return NULL; } - result = SMB_VFS_NEXT_READDIR(handle, sDIR->DIR, sbuf); + result = SMB_VFS_NEXT_READDIR(handle, sDIR->DIRp, sbuf); if (!result) return NULL; @@ -662,21 +662,21 @@ static void scannedonly_seekdir(struct vfs_handle_struct *handle, DIR * dirp, long offset) { struct scannedonly_DIR *sDIR = (struct scannedonly_DIR *)dirp; - SMB_VFS_NEXT_SEEKDIR(handle, sDIR->DIR, offset); + SMB_VFS_NEXT_SEEKDIR(handle, sDIR->DIRp, offset); } static long scannedonly_telldir(struct vfs_handle_struct *handle, DIR * dirp) { struct scannedonly_DIR *sDIR = (struct scannedonly_DIR *)dirp; - return SMB_VFS_NEXT_TELLDIR(handle, sDIR->DIR); + return SMB_VFS_NEXT_TELLDIR(handle, sDIR->DIRp); } static void scannedonly_rewinddir(struct vfs_handle_struct *handle, DIR * dirp) { struct scannedonly_DIR *sDIR = (struct scannedonly_DIR *)dirp; - SMB_VFS_NEXT_REWINDDIR(handle, sDIR->DIR); + SMB_VFS_NEXT_REWINDDIR(handle, sDIR->DIRp); } static int scannedonly_closedir(vfs_handle_struct * handle, @@ -685,7 +685,7 @@ static int scannedonly_closedir(vfs_handle_struct * handle, int retval; struct scannedonly_DIR *sDIR = (struct scannedonly_DIR *)dirp; flush_sendbuffer(handle); - retval = SMB_VFS_NEXT_CLOSEDIR(handle, sDIR->DIR); + retval = SMB_VFS_NEXT_CLOSEDIR(handle, sDIR->DIRp); TALLOC_FREE(sDIR); return retval; } -- 1.8.1.3 From 07dcb79c503488ed002f3471afdb8d804036e5b4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 25 Mar 2013 11:53:55 -0700 Subject: [PATCH 05/11] Change scannedonly_opendir to store open directory on a list. Return the opened directory pointer. Note - module logic is broken from here until final commit for bug #9534. Signed-off-by: Jeremy Allison --- source3/modules/vfs_scannedonly.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/source3/modules/vfs_scannedonly.c b/source3/modules/vfs_scannedonly.c index d489b5b..d3cde8a 100644 --- a/source3/modules/vfs_scannedonly.c +++ b/source3/modules/vfs_scannedonly.c @@ -88,6 +88,7 @@ struct Tscannedonly { const char *p_scanned; /* prefix for scanned files */ const char *p_virus; /* prefix for virus containing files */ const char *p_failed; /* prefix for failed to scan files */ + struct scannedonly_DIR *dir_list; char gsendbuffer[SENDBUFFERSIZE + 1]; }; @@ -520,25 +521,36 @@ static DIR *scannedonly_opendir(vfs_handle_struct * handle, const char *fname, const char *mask, uint32 attr) { - DIR *DIRp; struct scannedonly_DIR *sDIR; + struct Tscannedonly *so; - DIRp = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr); - if (!DIRp) { + SMB_VFS_HANDLE_GET_DATA(handle, so, struct Tscannedonly, return NULL); + + sDIR = talloc_zero(so, struct scannedonly_DIR); + if (sDIR == NULL) { return NULL; } - - sDIR = talloc(NULL, struct scannedonly_DIR); if (fname[0] != '/') { sDIR->base = construct_full_path(sDIR,handle, fname, true); } else { sDIR->base = name_w_ending_slash(sDIR, fname); } + if (sDIR->base == NULL) { + TALLOC_FREE(sDIR); + return NULL; + } DEBUG(SCANNEDONLY_DEBUG, ("scannedonly_opendir, fname=%s, base=%s\n",fname,sDIR->base)); - sDIR->DIRp = DIRp; sDIR->recheck_tries_done = 0; - return (DIR *) sDIR; + sDIR->DIRp = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr); + if (!sDIR->DIRp) { + TALLOC_FREE(sDIR); + return NULL; + } + + DLIST_ADD(so->dir_list, sDIR); + + return sDIR->DIRp; } static DIR *scannedonly_fdopendir(vfs_handle_struct * handle, -- 1.8.1.3 From 883b624595a5d3a743bce5d45d842c422d471403 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 25 Mar 2013 12:51:41 -0700 Subject: [PATCH 06/11] Change scannedonly_fdopendir to store open directory on a list. Return the opened directory pointer. Note - module logic is broken from here until final commit for bug #9534. Signed-off-by: Jeremy Allison --- source3/modules/vfs_scannedonly.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/source3/modules/vfs_scannedonly.c b/source3/modules/vfs_scannedonly.c index d3cde8a..a7764e1 100644 --- a/source3/modules/vfs_scannedonly.c +++ b/source3/modules/vfs_scannedonly.c @@ -557,28 +557,36 @@ static DIR *scannedonly_fdopendir(vfs_handle_struct * handle, files_struct *fsp, const char *mask, uint32 attr) { - DIR *DIRp; struct scannedonly_DIR *sDIR; const char *fname; + struct Tscannedonly *so; - DIRp = SMB_VFS_NEXT_FDOPENDIR(handle, fsp, mask, attr); - if (!DIRp) { - return NULL; - } + SMB_VFS_HANDLE_GET_DATA(handle, so, struct Tscannedonly, return NULL); fname = (const char *)fsp->fsp_name->base_name; - sDIR = talloc(NULL, struct scannedonly_DIR); + sDIR = talloc_zero(so, struct scannedonly_DIR); if (fname[0] != '/') { sDIR->base = construct_full_path(sDIR,handle, fname, true); } else { sDIR->base = name_w_ending_slash(sDIR, fname); } + if (sDIR->base == NULL) { + TALLOC_FREE(sDIR); + return NULL; + } DEBUG(SCANNEDONLY_DEBUG, ("scannedonly_fdopendir, fname=%s, base=%s\n",fname,sDIR->base)); - sDIR->DIRp = DIRp; sDIR->recheck_tries_done = 0; - return (DIR *) sDIR; + sDIR->DIRp = SMB_VFS_NEXT_FDOPENDIR(handle, fsp, mask, attr); + if (!sDIR->DIRp) { + TALLOC_FREE(sDIR); + return NULL; + } + + DLIST_ADD(so->dir_list, sDIR); + + return sDIR->DIRp; } -- 1.8.1.3 From 2cd057a14836b6f3f232eb543d81324ea85207fa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 25 Mar 2013 13:08:12 -0700 Subject: [PATCH 07/11] Remove seekdir/telldir/rewinddir functions. Not now needed. Signed-off-by: Jeremy Allison --- source3/modules/vfs_scannedonly.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/source3/modules/vfs_scannedonly.c b/source3/modules/vfs_scannedonly.c index a7764e1..8e55311 100644 --- a/source3/modules/vfs_scannedonly.c +++ b/source3/modules/vfs_scannedonly.c @@ -678,27 +678,6 @@ static struct dirent *scannedonly_readdir(vfs_handle_struct *handle, return newdirent; } -static void scannedonly_seekdir(struct vfs_handle_struct *handle, - DIR * dirp, long offset) -{ - struct scannedonly_DIR *sDIR = (struct scannedonly_DIR *)dirp; - SMB_VFS_NEXT_SEEKDIR(handle, sDIR->DIRp, offset); -} - -static long scannedonly_telldir(struct vfs_handle_struct *handle, - DIR * dirp) -{ - struct scannedonly_DIR *sDIR = (struct scannedonly_DIR *)dirp; - return SMB_VFS_NEXT_TELLDIR(handle, sDIR->DIRp); -} - -static void scannedonly_rewinddir(struct vfs_handle_struct *handle, - DIR * dirp) -{ - struct scannedonly_DIR *sDIR = (struct scannedonly_DIR *)dirp; - SMB_VFS_NEXT_REWINDDIR(handle, sDIR->DIRp); -} - static int scannedonly_closedir(vfs_handle_struct * handle, DIR * dirp) { @@ -1071,9 +1050,6 @@ static struct vfs_fn_pointers vfs_scannedonly_fns = { .opendir_fn = scannedonly_opendir, .fdopendir_fn = scannedonly_fdopendir, .readdir_fn = scannedonly_readdir, - .seekdir_fn = scannedonly_seekdir, - .telldir_fn = scannedonly_telldir, - .rewind_dir_fn = scannedonly_rewinddir, .closedir_fn = scannedonly_closedir, .rmdir_fn = scannedonly_rmdir, .stat_fn = scannedonly_stat, -- 1.8.1.3 From 7f3d7fcbc6d82a93f5e928b29900e701d4fbfc41 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 25 Mar 2013 13:11:34 -0700 Subject: [PATCH 08/11] Add utility function find_so_dir() to convert from a DIR * pointer to the internal struct. Signed-off-by: Jeremy Allison --- source3/modules/vfs_scannedonly.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/source3/modules/vfs_scannedonly.c b/source3/modules/vfs_scannedonly.c index 8e55311..303a055 100644 --- a/source3/modules/vfs_scannedonly.c +++ b/source3/modules/vfs_scannedonly.c @@ -589,6 +589,19 @@ static DIR *scannedonly_fdopendir(vfs_handle_struct * handle, return sDIR->DIRp; } +static struct scannedonly_DIR *find_so_dir(struct Tscannedonly *so, DIR * dirp) +{ + struct scannedonly_DIR *sDIR; + + for (sDIR = so->dir_list; sDIR; sDIR = sDIR->next) { + if (sDIR->DIRp == dirp) { + return sDIR; + } + } + + return NULL; +} + static struct dirent *scannedonly_readdir(vfs_handle_struct *handle, DIR * dirp, -- 1.8.1.3 From 13be43f1158dcc1666afe68c6129644f6481d9c2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 25 Mar 2013 13:13:48 -0700 Subject: [PATCH 09/11] Fix scannedonly_readdir() to convert from DIR * to struct scannedonly_DIR *. Signed-off-by: Jeremy Allison --- source3/modules/vfs_scannedonly.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source3/modules/vfs_scannedonly.c b/source3/modules/vfs_scannedonly.c index 303a055..0c21b7b 100644 --- a/source3/modules/vfs_scannedonly.c +++ b/source3/modules/vfs_scannedonly.c @@ -615,12 +615,13 @@ static struct dirent *scannedonly_readdir(vfs_handle_struct *handle, int namelen; struct dirent *newdirent; TALLOC_CTX *ctx=talloc_tos(); - struct scannedonly_DIR *sDIR = (struct scannedonly_DIR *)dirp; + struct scannedonly_DIR *sDIR; struct Tscannedonly *so; SMB_VFS_HANDLE_GET_DATA(handle, so, struct Tscannedonly, return NULL); - if (!dirp) { + sDIR = find_so_dir(so, dirp); + if (!sDIR) { return NULL; } -- 1.8.1.3 From c6288437e2b587fa1d9402aee3a95b2482f2bf9d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 25 Mar 2013 13:19:16 -0700 Subject: [PATCH 10/11] Fix scannedonly_closedir() to map from DIR * to struct scannedonly_DIR *. Signed-off-by: Jeremy Allison --- source3/modules/vfs_scannedonly.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/source3/modules/vfs_scannedonly.c b/source3/modules/vfs_scannedonly.c index 0c21b7b..28aa2f9 100644 --- a/source3/modules/vfs_scannedonly.c +++ b/source3/modules/vfs_scannedonly.c @@ -696,9 +696,19 @@ static int scannedonly_closedir(vfs_handle_struct * handle, DIR * dirp) { int retval; - struct scannedonly_DIR *sDIR = (struct scannedonly_DIR *)dirp; + struct scannedonly_DIR *sDIR; + struct Tscannedonly *so; + + SMB_VFS_HANDLE_GET_DATA(handle, so, struct Tscannedonly, return -1); + + sDIR = find_so_dir(so, dirp); + if (!sDIR) { + return -1; + } + flush_sendbuffer(handle); retval = SMB_VFS_NEXT_CLOSEDIR(handle, sDIR->DIRp); + DLIST_REMOVE(so->dir_list, sDIR); TALLOC_FREE(sDIR); return retval; } -- 1.8.1.3 From ce63bb11cf3f36dd99a8d39bbe6da427c2aea291 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 25 Mar 2013 13:40:17 -0700 Subject: [PATCH 11/11] Fix scannedonly_unlink() and scannedonly_rmdir() to delete the auxiliary files. This completes the bug fixes for bug #9534 - NT_STATUS_INVALID_HANDLE when deleting a directory on a "scannedonly" covered share Signed-off-by: Jeremy Allison --- source3/modules/vfs_scannedonly.c | 58 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/source3/modules/vfs_scannedonly.c b/source3/modules/vfs_scannedonly.c index 28aa2f9..045a331 100644 --- a/source3/modules/vfs_scannedonly.c +++ b/source3/modules/vfs_scannedonly.c @@ -886,6 +886,7 @@ static int scannedonly_rename(vfs_handle_struct * handle, static int scannedonly_unlink(vfs_handle_struct * handle, const struct smb_filename *smb_fname) { + int ret; /* unlink the 'scanned' file too */ struct smb_filename *smb_fname_cache = NULL; char * cachefile; @@ -900,9 +901,28 @@ static int scannedonly_unlink(vfs_handle_struct * handle, so->p_scanned); create_synthetic_smb_fname(ctx, cachefile,NULL,NULL, &smb_fname_cache); - if (SMB_VFS_NEXT_UNLINK(handle, smb_fname_cache) != 0) { - DEBUG(SCANNEDONLY_DEBUG, ("_unlink: failed to unlink %s\n", - smb_fname_cache->base_name)); + + ret = SMB_VFS_NEXT_STAT(handle, smb_fname_cache); + if (ret == 0) { + if (SMB_VFS_NEXT_UNLINK(handle, smb_fname_cache) != 0) { + DEBUG(SCANNEDONLY_DEBUG, ("_unlink: failed to unlink %s\n", + smb_fname_cache->base_name)); + } + } + + /* unlink the 'failed' file too */ + cachefile = cachefile_name_f_fullpath( + ctx, + smb_fname->base_name, + so->p_failed); + create_synthetic_smb_fname(ctx, cachefile,NULL,NULL, + &smb_fname_cache); + ret = SMB_VFS_NEXT_STAT(handle, smb_fname_cache); + if (ret == 0) { + if (SMB_VFS_NEXT_UNLINK(handle, smb_fname_cache) != 0) { + DEBUG(0, ("_unlink: failed to unlink %s\n", + smb_fname_cache->base_name)); + } } return SMB_VFS_NEXT_UNLINK(handle, smb_fname); } @@ -911,11 +931,14 @@ static int scannedonly_rmdir(vfs_handle_struct * handle, const char *path) { /* if there are only .scanned: .virus: or .failed: files, we delete those, because the client cannot see them */ + int ret; DIR *dirp; struct dirent *dire; TALLOC_CTX *ctx = talloc_tos(); bool only_deletable_files = true, have_files = false; char *path_w_slash; + struct smb_filename *smb_fname_cache = NULL; + char * cachefile; struct Tscannedonly *so; SMB_VFS_HANDLE_GET_DATA(handle, so, struct Tscannedonly, return -1); @@ -985,6 +1008,35 @@ static int scannedonly_rmdir(vfs_handle_struct * handle, const char *path) } } SMB_VFS_NEXT_CLOSEDIR(handle, dirp); + + /* unlink the 'scanned' file too */ + cachefile = cachefile_name_f_fullpath( + ctx, + path, + so->p_scanned); + create_synthetic_smb_fname(ctx, cachefile,NULL,NULL, + &smb_fname_cache); + ret = SMB_VFS_NEXT_STAT(handle, smb_fname_cache); + if (ret == 0) { + if (SMB_VFS_NEXT_UNLINK(handle, smb_fname_cache) != 0) { + DEBUG(0, ("_unlink: failed to unlink %s\n", + smb_fname_cache->base_name)); + } + } + /* unlink the 'failed' file too */ + cachefile = cachefile_name_f_fullpath( + ctx, + path, + so->p_failed); + create_synthetic_smb_fname(ctx, cachefile,NULL,NULL, + &smb_fname_cache); + ret = SMB_VFS_NEXT_STAT(handle, smb_fname_cache); + if (ret == 0) { + if (SMB_VFS_NEXT_UNLINK(handle, smb_fname_cache) != 0) { + DEBUG(0, ("_unlink: failed to unlink %s\n", + smb_fname_cache->base_name)); + } + } return SMB_VFS_NEXT_RMDIR(handle, path); } -- 1.8.1.3