diff options
Diffstat (limited to 'source3/smbd/dir.c')
-rw-r--r-- | source3/smbd/dir.c | 73 |
1 files changed, 59 insertions, 14 deletions
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) { |