diff options
-rw-r--r-- | source3/include/proto.h | 1 | ||||
-rw-r--r-- | source3/smbd/close.c | 3 | ||||
-rw-r--r-- | source3/smbd/dir.c | 73 | ||||
-rw-r--r-- | source3/smbd/filename.c | 2 | ||||
-rw-r--r-- | source3/smbd/reply.c | 6 |
5 files changed, 64 insertions, 21 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 969d12fb52..58585a1bfc 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -4581,7 +4581,6 @@ bool get_dir_entry(TALLOC_CTX *ctx, bool ask_sharemode); bool is_visible_file(connection_struct *conn, const char *dir_path, const char *name, SMB_STRUCT_STAT *pst, bool use_veto); struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, - files_struct *fsp, const char *name, const char *mask, uint32 attr); const char *ReadDirName(struct smb_Dir *dirp, long *poffset, SMB_STRUCT_STAT *sbuf, char **talloced); diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 60cf8ed945..d5a824f868 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -699,7 +699,7 @@ static bool recursive_rmdir(TALLOC_CTX *ctx, SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname)); - dir_hnd = OpenDir(talloc_tos(), conn, NULL, smb_dname->base_name, NULL, 0); + dir_hnd = OpenDir(talloc_tos(), conn, smb_dname->base_name, NULL, 0); if(dir_hnd == NULL) return False; @@ -817,7 +817,6 @@ static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp) char *talloced = NULL; long dirpos = 0; struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, - NULL, smb_dname->base_name, NULL, 0); diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index edc1ffe65f..5c502f7706 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -63,6 +63,10 @@ struct dptr_struct { bool did_stat; /* Optimisation for non-wcard searches. */ }; +static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, + files_struct *fsp, + const char *mask, + uint32 attr); #define INVALID_DPTR_KEY (-3) @@ -190,7 +194,7 @@ static struct dptr_struct *dptr_get(struct smbd_server_connection *sconn, dptr_idleoldest(sconn); DEBUG(4,("dptr_get: Reopening dptr key %d\n",key)); if (!(dptr->dir_hnd = OpenDir( - NULL, dptr->conn, NULL, dptr->path, + NULL, dptr->conn, dptr->path, dptr->wcard, dptr->attr))) { DEBUG(4,("dptr_get: Failed to open %s (%s)\n",dptr->path, strerror(errno))); @@ -437,14 +441,16 @@ NTSTATUS dptr_create(connection_struct *conn, files_struct *fsp, return NT_STATUS_INVALID_PARAMETER; } - if (!fsp) { + if (fsp) { + dir_hnd = OpenDir_fsp(NULL, conn, fsp, wcard, attr); + } else { status = check_name(conn,path); if (!NT_STATUS_IS_OK(status)) { return status; } + dir_hnd = OpenDir(NULL, conn, path, wcard, attr); } - dir_hnd = OpenDir(NULL, conn, fsp, path, wcard, attr); if (!dir_hnd) { return map_nt_error_from_unix(errno); } @@ -1312,7 +1318,6 @@ static int smb_Dir_destructor(struct smb_Dir *dirp) ********************************************************************/ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, - files_struct *fsp, const char *name, const char *mask, uint32 attr) @@ -1327,11 +1332,51 @@ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, dirp->conn = conn; dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); - if (fsp) { - dirp->dir_path = talloc_strdup(dirp, fsp->fsp_name->base_name); - } else { - dirp->dir_path = talloc_strdup(dirp, name); + dirp->dir_path = talloc_strdup(dirp, name); + if (!dirp->dir_path) { + errno = ENOMEM; + goto fail; } + + if (sconn) { + sconn->smb1.searches.dirhandles_open++; + } + talloc_set_destructor(dirp, smb_Dir_destructor); + + dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); + if (!dirp->dir) { + DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, + strerror(errno) )); + goto fail; + } + + return dirp; + + fail: + TALLOC_FREE(dirp); + return NULL; +} + +/******************************************************************* + Open a directory from an fsp. +********************************************************************/ + +static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, + files_struct *fsp, + const char *mask, + uint32 attr) +{ + struct smb_Dir *dirp = TALLOC_ZERO_P(mem_ctx, struct smb_Dir); + struct smbd_server_connection *sconn = conn->sconn; + + if (!dirp) { + return NULL; + } + + dirp->conn = conn; + dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); + + dirp->dir_path = talloc_strdup(dirp, fsp->fsp_name->base_name); if (!dirp->dir_path) { errno = ENOMEM; goto fail; @@ -1342,10 +1387,10 @@ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, } talloc_set_destructor(dirp, smb_Dir_destructor); - if (fsp && fsp->is_directory && fsp->fh->fd != -1) { + if (fsp->is_directory && fsp->fh->fd != -1) { dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); if (dirp->dir == NULL) { - DEBUG(10,("OpenDir: SMB_VFS_FDOPENDIR on %s returned " + DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned " "NULL (%s)\n", dirp->dir_path, strerror(errno))); @@ -1356,13 +1401,12 @@ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, } if (dirp->dir == NULL) { - /* FDOPENDIR didn't work - or fsp == NULL. Use - OPENDIR instead. */ + /* FDOPENDIR didn't work. Use OPENDIR instead. */ dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); } if (!dirp->dir) { - DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, + DEBUG(5,("OpenDir_fsp: Can't open %s. %s\n", dirp->dir_path, strerror(errno) )); goto fail; } @@ -1374,6 +1418,7 @@ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, return NULL; } + /******************************************************************* Read from a directory. Return directory entry, current offset, and optional stat information. @@ -1568,7 +1613,7 @@ NTSTATUS can_delete_directory(struct connection_struct *conn, const char *dname = NULL; char *talloced = NULL; SMB_STRUCT_STAT st; - struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, NULL, + struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, dirname, NULL, 0); if (!dir_hnd) { diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 8e6de84424..03877218de 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -1074,7 +1074,7 @@ static int get_real_filename_full_scan(connection_struct *conn, } /* open the directory */ - if (!(cur_dir = OpenDir(talloc_tos(), conn, NULL, path, NULL, 0))) { + if (!(cur_dir = OpenDir(talloc_tos(), conn, path, NULL, 0))) { DEBUG(3,("scan dir didn't open dir [%s]\n",path)); TALLOC_FREE(unmangled_name); return -1; diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 120b8bc69f..dea265f679 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -2647,7 +2647,7 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req, goto out; } - dir_hnd = OpenDir(talloc_tos(), conn, NULL, fname_dir, fname_mask, + dir_hnd = OpenDir(talloc_tos(), conn, fname_dir, fname_mask, dirtype); if (dir_hnd == NULL) { status = map_nt_error_from_unix(errno); @@ -6380,7 +6380,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, goto out; } - dir_hnd = OpenDir(talloc_tos(), conn, NULL, fname_src_dir, fname_src_mask, + dir_hnd = OpenDir(talloc_tos(), conn, fname_src_dir, fname_src_mask, attrs); if (dir_hnd == NULL) { status = map_nt_error_from_unix(errno); @@ -7067,7 +7067,7 @@ void reply_copy(struct smb_request *req) goto out; } - dir_hnd = OpenDir(ctx, conn, NULL, fname_src_dir, fname_src_mask, 0); + dir_hnd = OpenDir(ctx, conn, fname_src_dir, fname_src_mask, 0); if (dir_hnd == NULL) { status = map_nt_error_from_unix(errno); reply_nterror(req, status); |