summaryrefslogtreecommitdiff
path: root/source3/smbd/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd/dir.c')
-rw-r--r--source3/smbd/dir.c73
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) {