const char *mask,
uint32_t attr);
-static void DirCacheAdd(struct smb_Dir *dirp, const char *name, long offset);
+static void DirCacheAdd(struct smb_Dir *dir_hnd, const char *name, long offset);
+
+static int smb_Dir_destructor(struct smb_Dir *dir_hnd);
#define INVALID_DPTR_KEY (-3)
return(0);
}
-/****************************************************************************
- Close a dptr (internal func).
-****************************************************************************/
-
-static void dptr_close_internal(struct dptr_struct *dptr)
-{
- struct smbd_server_connection *sconn = dptr->conn->sconn;
-
- DEBUG(4,("closing dptr key %d\n",dptr->dnum));
-
- if (sconn == NULL) {
- goto done;
- }
-
- if (sconn->using_smb2) {
- goto done;
- }
-
- DLIST_REMOVE(sconn->searches.dirptrs, dptr);
-
- /*
- * Free the dnum in the bitmap. Remember the dnum value is always
- * biased by one with respect to the bitmap.
- */
-
- if (!bitmap_query(sconn->searches.dptr_bmap, dptr->dnum - 1)) {
- DEBUG(0,("dptr_close_internal : Error - closing dnum = %d and bitmap not set !\n",
- dptr->dnum ));
- }
-
- bitmap_clear(sconn->searches.dptr_bmap, dptr->dnum - 1);
-
-done:
- TALLOC_FREE(dptr->dir_hnd);
- TALLOC_FREE(dptr);
-}
-
-/****************************************************************************
- Close a dptr given a key.
-****************************************************************************/
-
-void dptr_close(struct smbd_server_connection *sconn, int *key)
-{
- struct dptr_struct *dptr;
-
- if(*key == INVALID_DPTR_KEY)
- return;
-
- /* OS/2 seems to use -1 to indicate "close all directories" */
- if (*key == -1) {
- struct dptr_struct *next;
- for(dptr = sconn->searches.dirptrs; dptr; dptr = next) {
- next = dptr->next;
- dptr_close_internal(dptr);
- }
- *key = INVALID_DPTR_KEY;
- return;
- }
-
- dptr = dptr_get(sconn, *key);
-
- if (!dptr) {
- DEBUG(0,("Invalid key %d given to dptr_close\n", *key));
- return;
- }
-
- dptr_close_internal(dptr);
-
- *key = INVALID_DPTR_KEY;
-}
-
/****************************************************************************
Close all dptrs for a cnum.
****************************************************************************/
for(dptr = sconn->searches.dirptrs; dptr; dptr = next) {
next = dptr->next;
if (dptr->conn == conn) {
- dptr_close_internal(dptr);
+ files_struct *fsp = dptr->dir_hnd->fsp;
+ close_file(NULL, fsp, NORMAL_CLOSE);
+ fsp = NULL;
}
}
}
-/****************************************************************************
- Are there any SMB1 searches active on this connection struct ?
-****************************************************************************/
-
-bool dptr_activecnum(const struct smbd_server_connection *sconn,
- const struct connection_struct *conn)
-{
- const struct dptr_struct *dptr;
-
- for(dptr = sconn->searches.dirptrs; dptr; dptr = dptr->next) {
- if (dptr->conn == conn) {
- return true;
- }
- }
- return false;
-}
-
-/****************************************************************************
- Close a dptr that matches a given path, only if it matches the spid also.
-****************************************************************************/
-
-void dptr_closepath(struct smbd_server_connection *sconn,
- char *path,uint16_t spid)
-{
- struct dptr_struct *dptr, *next;
- for(dptr = sconn->searches.dirptrs; dptr; dptr = next) {
- next = dptr->next;
- if (spid == dptr->spid &&
- strequal(dptr->smb_dname->base_name,path)) {
- dptr_close_internal(dptr);
- }
- }
-}
-
-/****************************************************************************
- Try and close the oldest handle not marked for
- expect close in the hope that the client has
- finished with that one.
-****************************************************************************/
-
-static void dptr_close_oldest(struct smbd_server_connection *sconn,
- bool old)
-{
- struct dptr_struct *dptr;
-
- /*
- * Go to the end of the list.
- */
- for(dptr = sconn->searches.dirptrs; dptr && dptr->next; dptr = dptr->next)
- ;
-
- if(!dptr) {
- DEBUG(0,("No old dptrs available to close oldest ?\n"));
- return;
- }
-
- /*
- * If 'old' is true, close the oldest oldhandle dnum (ie. 1 < dnum < 256) that
- * does not have expect_close set. If 'old' is false, close
- * one of the new dnum handles.
- */
-
- for(; dptr; dptr = DLIST_PREV(dptr)) {
- if ((old && (dptr->dnum < 256) && !dptr->expect_close) ||
- (!old && (dptr->dnum > 255))) {
- dptr_close_internal(dptr);
- return;
- }
- }
-}
-
-/****************************************************************************
- Safely do an OpenDir as root, ensuring we're in the right place.
-****************************************************************************/
-
-static struct smb_Dir *open_dir_with_privilege(connection_struct *conn,
- struct smb_request *req,
- const struct smb_filename *smb_dname,
- const char *wcard,
- uint32_t attr)
-{
- struct smb_Dir *dir_hnd = NULL;
- struct smb_filename *smb_fname_cwd = NULL;
- struct smb_filename *saved_dir_fname = vfs_GetWd(talloc_tos(), conn);
- struct privilege_paths *priv_paths = req->priv_paths;
- int ret;
-
- if (saved_dir_fname == NULL) {
- return NULL;
- }
-
- if (vfs_ChDir(conn, smb_dname) == -1) {
- return NULL;
- }
-
- /* Now check the stat value is the same. */
- smb_fname_cwd = synthetic_smb_fname(talloc_tos(),
- ".",
- NULL,
- NULL,
- smb_dname->flags);
- if (smb_fname_cwd == NULL) {
- goto out;
- }
- ret = SMB_VFS_STAT(conn, smb_fname_cwd);
- if (ret != 0) {
- goto out;
- }
-
- if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
- DEBUG(0,("open_dir_with_privilege: stat mismatch between %s "
- "and %s\n",
- smb_dname->base_name,
- smb_fname_str_dbg(&priv_paths->parent_name)));
- goto out;
- }
-
- dir_hnd = OpenDir(NULL, conn, smb_fname_cwd, wcard, attr);
-
- out:
-
- vfs_ChDir(conn, saved_dir_fname);
- TALLOC_FREE(saved_dir_fname);
- return dir_hnd;
-}
-
/****************************************************************************
Create a new dir ptr. If the flag old_handle is true then we must allocate
from the bitmap range 0 - 255 as old SMBsearch directory handles are only
NTSTATUS dptr_create(connection_struct *conn,
struct smb_request *req,
files_struct *fsp,
- const struct smb_filename *smb_dname,
bool old_handle,
bool expect_close,
uint16_t spid,
struct dptr_struct *dptr = NULL;
struct smb_Dir *dir_hnd;
- if (fsp && fsp->is_directory && fsp->fh->fd != -1) {
- smb_dname = fsp->fsp_name;
- }
-
- DEBUG(5,("dptr_create dir=%s\n", smb_dname->base_name));
+ DBG_INFO("dir=%s\n", fsp_str_dbg(fsp));
if (sconn == NULL) {
DEBUG(0,("dptr_create: called with fake connection_struct\n"));
return NT_STATUS_INVALID_PARAMETER;
}
- if (fsp) {
- if (!(fsp->access_mask & SEC_DIR_LIST)) {
- DEBUG(5,("dptr_create: directory %s "
- "not open for LIST access\n",
- smb_dname->base_name));
- return NT_STATUS_ACCESS_DENIED;
- }
- dir_hnd = OpenDir_fsp(NULL, conn, fsp, wcard, attr);
- } else {
- int ret;
- bool backup_intent = (req && req->priv_paths);
- NTSTATUS status;
- struct smb_filename *smb_dname_cp =
- cp_smb_filename(talloc_tos(), smb_dname);
-
- if (smb_dname_cp == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
-
- if (req != NULL && req->posix_pathnames) {
- ret = SMB_VFS_LSTAT(conn, smb_dname_cp);
- } else {
- ret = SMB_VFS_STAT(conn, smb_dname_cp);
- }
- if (ret == -1) {
- status = map_nt_error_from_unix(errno);
- TALLOC_FREE(smb_dname_cp);
- return status;
- }
- if (!S_ISDIR(smb_dname_cp->st.st_ex_mode)) {
- TALLOC_FREE(smb_dname_cp);
- return NT_STATUS_NOT_A_DIRECTORY;
- }
- status = smbd_check_access_rights(conn,
- smb_dname_cp,
- backup_intent,
- SEC_DIR_LIST);
- if (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(smb_dname_cp);
- return status;
- }
- if (backup_intent) {
- dir_hnd = open_dir_with_privilege(conn,
- req,
- smb_dname_cp,
- wcard,
- attr);
- } else {
- dir_hnd = OpenDir(NULL,
- conn,
- smb_dname_cp,
- wcard,
- attr);
- }
- TALLOC_FREE(smb_dname_cp);
+ if (!(fsp->access_mask & SEC_DIR_LIST)) {
+ DBG_INFO("dptr_create: directory %s "
+ "not open for LIST access\n",
+ fsp_str_dbg(fsp));
+ return NT_STATUS_ACCESS_DENIED;
}
-
+ dir_hnd = OpenDir_fsp(NULL, conn, fsp, wcard, attr);
if (!dir_hnd) {
return map_nt_error_from_unix(errno);
}
return NT_STATUS_NO_MEMORY;
}
- dptr->smb_dname = cp_smb_filename(dptr, smb_dname);
- if (!dptr->smb_dname) {
+ dptr->smb_dname = cp_smb_filename(dptr, fsp->fsp_name);
+ if (dptr->smb_dname == NULL) {
TALLOC_FREE(dptr);
TALLOC_FREE(dir_hnd);
return NT_STATUS_NO_MEMORY;
dptr->dnum = bitmap_find(sconn->searches.dptr_bmap, 255);
if(dptr->dnum == -1 || dptr->dnum < 255) {
-
- /*
- * Try and close the oldest handle close in the hope that
- * the client has finished with that one. This will only
- * happen in the case of the Win98 client bug where it leaks
- * directory handles.
- */
-
- dptr_close_oldest(sconn, false);
-
- /* Now try again... */
- dptr->dnum = bitmap_find(sconn->searches.dptr_bmap, 255);
-
- if(dptr->dnum == -1 || dptr->dnum < 255) {
- DEBUG(0,("dptr_create: returned %d: Error - all new dirptrs in use ?\n", dptr->dnum));
- TALLOC_FREE(dptr);
- TALLOC_FREE(dir_hnd);
- return NT_STATUS_TOO_MANY_OPENED_FILES;
- }
+ DBG_ERR("returned %d: Error - all new "
+ "dirptrs in use ?\n",
+ dptr->dnum);
+ TALLOC_FREE(dptr);
+ TALLOC_FREE(dir_hnd);
+ return NT_STATUS_TOO_MANY_OPENED_FILES;
}
}
DLIST_ADD(sconn->searches.dirptrs, dptr);
done:
- DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n",
- dptr->dnum,
- dptr->smb_dname->base_name,
- expect_close));
+ DBG_INFO("creating new dirptr [%d] for path [%s], expect_close = %d\n",
+ dptr->dnum, fsp_str_dbg(fsp), expect_close);
*dptr_ret = dptr;
void dptr_CloseDir(files_struct *fsp)
{
- if (fsp->dptr) {
+ struct smbd_server_connection *sconn = NULL;
+
+ if (fsp->dptr == NULL) {
+ return;
+ }
+ sconn = fsp->dptr->conn->sconn;
+
+ /*
+ * The destructor for the struct smb_Dir (fsp->dptr->dir_hnd)
+ * now handles all resource deallocation.
+ */
+
+ DBG_INFO("closing dptr key %d\n", fsp->dptr->dnum);
+
+ if (sconn != NULL && !sconn->using_smb2) {
+ DLIST_REMOVE(sconn->searches.dirptrs, fsp->dptr);
+
/*
- * The destructor for the struct smb_Dir
- * (fsp->dptr->dir_hnd) now handles
- * all resource deallocation.
+ * Free the dnum in the bitmap. Remember the dnum value is
+ * always biased by one with respect to the bitmap.
*/
- dptr_close_internal(fsp->dptr);
- fsp->dptr = NULL;
+
+ if (!bitmap_query(sconn->searches.dptr_bmap,
+ fsp->dptr->dnum - 1))
+ {
+ DBG_ERR("closing dnum = %d and bitmap not set !\n",
+ fsp->dptr->dnum);
+ }
+
+ bitmap_clear(sconn->searches.dptr_bmap, fsp->dptr->dnum - 1);
}
+
+ TALLOC_FREE(fsp->dptr->dir_hnd);
+ TALLOC_FREE(fsp->dptr);
}
void dptr_SeekDir(struct dptr_struct *dptr, long offset)
while ((name = ReadDirName(dptr->dir_hnd, poffset, pst, &talloced))
!= NULL) {
if (is_visible_file(dptr->conn,
- dptr->smb_dname->base_name,
+ dptr->dir_hnd,
name,
pst,
true)) {
/* First check if it should be visible. */
if (!is_visible_file(dptr->conn,
- dptr->smb_dname->base_name,
+ dptr->dir_hnd,
dptr->wcard,
pst,
true)) {
}
/****************************************************************************
- Fetch the dir ptr and seek it given the 5 byte server field.
+ Return the associated fsp and seek the dir_hnd on it it given the 5 byte
+ server field.
****************************************************************************/
-struct dptr_struct *dptr_fetch(struct smbd_server_connection *sconn,
+files_struct *dptr_fetch_fsp(struct smbd_server_connection *sconn,
char *buf, int *num)
{
unsigned int key = *(unsigned char *)buf;
uint32_t wire_offset;
long seekoff;
- if (!dptr) {
+ if (dptr == NULL) {
DEBUG(3,("fetched null dirptr %d\n",key));
return(NULL);
}
SeekDir(dptr->dir_hnd,seekoff);
DEBUG(3,("fetching dirptr %d for path %s at offset %d\n",
key, dptr->smb_dname->base_name, (int)seekoff));
- return(dptr);
+ return dptr->dir_hnd->fsp;
}
/****************************************************************************
- Fetch the dir ptr.
+ Fetch the fsp associated with the dptr_num.
****************************************************************************/
-struct dptr_struct *dptr_fetch_lanman2(struct smbd_server_connection *sconn,
+files_struct *dptr_fetch_lanman2_fsp(struct smbd_server_connection *sconn,
int dptr_num)
{
struct dptr_struct *dptr = dptr_get(sconn, dptr_num);
-
- if (!dptr) {
- DEBUG(3,("fetched null dirptr %d\n",dptr_num));
- return(NULL);
+ if (dptr == NULL) {
+ return NULL;
}
- DEBUG(3,("fetching dirptr %d for path %s\n",
+ DBG_NOTICE("fetching dirptr %d for path %s\n",
dptr_num,
- dptr->smb_dname->base_name));
- return(dptr);
+ dptr->smb_dname->base_name);
+ return dptr->dir_hnd->fsp;
}
static bool mangle_mask_match(connection_struct *conn,
continue;
}
- if (ask_sharemode) {
+ if (ask_sharemode && !S_ISDIR(smb_fname.st.st_ex_mode)) {
struct timespec write_time_ts;
struct file_id fileid;
fileid = vfs_file_id_from_sbuf(conn,
&smb_fname.st);
get_file_infos(fileid, 0, NULL, &write_time_ts);
- if (!null_timespec(write_time_ts)) {
+ if (!is_omit_timespec(&write_time_ts)) {
update_stat_ex_mtime(&smb_fname.st,
write_time_ts);
}
NOTE: A successful return is no guarantee of the file's existence.
********************************************************************/
-bool is_visible_file(connection_struct *conn, const char *dir_path,
- const char *name, SMB_STRUCT_STAT *pst, bool use_veto)
+bool is_visible_file(connection_struct *conn,
+ struct smb_Dir *dir_hnd,
+ const char *name,
+ SMB_STRUCT_STAT *pst,
+ bool use_veto)
{
bool hide_unreadable = lp_hide_unreadable(SNUM(conn));
bool hide_unwriteable = lp_hide_unwriteable_files(SNUM(conn));
bool hide_special = lp_hide_special_files(SNUM(conn));
int hide_new_files_timeout = lp_hide_new_files_timeout(SNUM(conn));
char *entry = NULL;
+ struct smb_filename *dir_path = dir_hnd->fsp->fsp_name;
struct smb_filename *smb_fname_base = NULL;
bool ret = false;
hide_special ||
(hide_new_files_timeout != 0))
{
- entry = talloc_asprintf(talloc_tos(), "%s/%s", dir_path, name);
+ entry = talloc_asprintf(talloc_tos(),
+ "%s/%s",
+ dir_path->base_name,
+ name);
if (!entry) {
ret = false;
goto out;
goto out;
}
/* Honour _hide unwriteable_ option */
- if (hide_unwriteable && !user_can_write_file(conn,
- smb_fname_base)) {
+ if (hide_unwriteable &&
+ !user_can_write_file(conn,
+ smb_fname_base))
+ {
DEBUG(10,("is_visible_file: file %s is unwritable.\n",
entry ));
ret = false;
return ret;
}
-static int smb_Dir_destructor(struct smb_Dir *dirp)
+static int smb_Dir_destructor(struct smb_Dir *dir_hnd)
{
- if (dirp->dir != NULL) {
- SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir);
- if (dirp->fsp != NULL) {
- /*
- * The SMB_VFS_CLOSEDIR above
- * closes the underlying fd inside
- * dirp->fsp.
- */
- dirp->fsp->fh->fd = -1;
- if (dirp->fsp->dptr != NULL) {
- SMB_ASSERT(dirp->fsp->dptr->dir_hnd == dirp);
- dirp->fsp->dptr->dir_hnd = NULL;
- }
- dirp->fsp = NULL;
- }
+ files_struct *fsp = dir_hnd->fsp;
+
+ SMB_VFS_CLOSEDIR(dir_hnd->conn, dir_hnd->dir);
+ fsp->fh->fd = -1;
+ if (fsp->dptr != NULL) {
+ SMB_ASSERT(fsp->dptr->dir_hnd == dir_hnd);
+ fsp->dptr->dir_hnd = NULL;
}
+ dir_hnd->fsp = NULL;
return 0;
}
Open a directory.
********************************************************************/
-static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx,
- connection_struct *conn,
- const struct smb_filename *smb_dname,
- const char *mask,
- uint32_t attr)
+static int smb_Dir_OpenDir_destructor(struct smb_Dir *dir_hnd)
{
- struct smb_Dir *dirp = talloc_zero(mem_ctx, struct smb_Dir);
-
- if (!dirp) {
- return NULL;
- }
-
- dirp->dir = SMB_VFS_OPENDIR(conn, smb_dname, mask, attr);
-
- if (!dirp->dir) {
- DEBUG(5,("OpenDir: Can't open %s. %s\n",
- smb_dname->base_name,
- strerror(errno) ));
- goto fail;
- }
-
- dirp->conn = conn;
-
- if (!conn->sconn->using_smb2) {
- /*
- * The dircache is only needed for SMB1 because SMB1 uses a name
- * for the resume wheras SMB2 always continues from the next
- * position (unless it's told to restart or close-and-reopen the
- * listing).
- */
- dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn));
- }
-
- talloc_set_destructor(dirp, smb_Dir_destructor);
+ files_struct *fsp = dir_hnd->fsp;
- return dirp;
-
- fail:
- TALLOC_FREE(dirp);
- return NULL;
+ smb_Dir_destructor(dir_hnd);
+ file_free(NULL, fsp);
+ return 0;
}
-/****************************************************************************
- Open a directory handle by pathname, ensuring it's under the share path.
-****************************************************************************/
-
-static struct smb_Dir *open_dir_safely(TALLOC_CTX *ctx,
- connection_struct *conn,
- const struct smb_filename *smb_dname,
- const char *wcard,
- uint32_t attr)
+struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx,
+ connection_struct *conn,
+ const struct smb_filename *smb_dname,
+ const char *mask,
+ uint32_t attr)
{
+ struct files_struct *fsp = NULL;
struct smb_Dir *dir_hnd = NULL;
- struct smb_filename *smb_fname_cwd = NULL;
- struct smb_filename *saved_dir_fname = vfs_GetWd(ctx, conn);
NTSTATUS status;
- if (saved_dir_fname == NULL) {
- return NULL;
- }
-
- if (vfs_ChDir(conn, smb_dname) == -1) {
- goto out;
- }
-
- smb_fname_cwd = synthetic_smb_fname(talloc_tos(),
- ".",
- NULL,
- NULL,
- smb_dname->flags);
- if (smb_fname_cwd == NULL) {
- goto out;
- }
-
- /*
- * Now the directory is pinned, use
- * REALPATH to ensure we can access it.
- */
- status = check_name(conn, smb_fname_cwd);
+ status = open_internal_dirfsp_at(conn, conn->cwd_fsp, smb_dname, &fsp);
if (!NT_STATUS_IS_OK(status)) {
- goto out;
+ return NULL;
}
- dir_hnd = OpenDir_internal(ctx,
- conn,
- smb_fname_cwd,
- wcard,
- attr);
-
+ dir_hnd = OpenDir_fsp(mem_ctx, conn, fsp, mask, attr);
if (dir_hnd == NULL) {
- goto out;
+ return NULL;
}
/*
- * OpenDir_internal only gets "." as the dir name.
- * Store the real dir name here.
+ * This overwrites the destructor set by smb_Dir_OpenDir_destructor(),
+ * but smb_Dir_OpenDir_destructor() calls the OpenDir_fsp() destructor.
*/
-
- dir_hnd->dir_smb_fname = cp_smb_filename(dir_hnd, smb_dname);
- if (!dir_hnd->dir_smb_fname) {
- TALLOC_FREE(dir_hnd);
- errno = ENOMEM;
- }
-
- out:
-
- vfs_ChDir(conn, saved_dir_fname);
- TALLOC_FREE(saved_dir_fname);
+ talloc_set_destructor(dir_hnd, smb_Dir_OpenDir_destructor);
return dir_hnd;
}
-struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn,
- const struct smb_filename *smb_dname,
- const char *mask,
- uint32_t attr)
-{
- return open_dir_safely(mem_ctx,
- conn,
- smb_dname,
- mask,
- attr);
-}
-
/*******************************************************************
Open a directory from an fsp.
********************************************************************/
const char *mask,
uint32_t attr)
{
- struct smb_Dir *dirp = talloc_zero(mem_ctx, struct smb_Dir);
+ struct smb_Dir *dir_hnd = talloc_zero(mem_ctx, struct smb_Dir);
- if (!dirp) {
+ if (!dir_hnd) {
goto fail;
}
- if (!fsp->is_directory) {
+ if (!fsp->fsp_flags.is_directory) {
errno = EBADF;
goto fail;
}
goto fail;
}
- dirp->conn = conn;
+ dir_hnd->conn = conn;
if (!conn->sconn->using_smb2) {
/*
* position (unless it's told to restart or close-and-reopen the
* listing).
*/
- dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn));
+ dir_hnd->name_cache_size =
+ lp_directory_name_cache_size(SNUM(conn));
}
- dirp->dir_smb_fname = cp_smb_filename(dirp, fsp->fsp_name);
- if (!dirp->dir_smb_fname) {
+ dir_hnd->dir_smb_fname = cp_smb_filename(dir_hnd, fsp->fsp_name);
+ if (!dir_hnd->dir_smb_fname) {
errno = ENOMEM;
goto fail;
}
- dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr);
- if (dirp->dir != NULL) {
- dirp->fsp = fsp;
- } else {
- DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned "
- "NULL (%s)\n",
- dirp->dir_smb_fname->base_name,
- strerror(errno)));
- if (errno != ENOSYS) {
- goto fail;
- }
- }
-
- if (dirp->dir == NULL) {
- /* FDOPENDIR is not supported. Use OPENDIR instead. */
- TALLOC_FREE(dirp);
- return open_dir_safely(mem_ctx,
- conn,
- fsp->fsp_name,
- mask,
- attr);
+ dir_hnd->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr);
+ if (dir_hnd->dir == NULL) {
+ goto fail;
}
+ dir_hnd->fsp = fsp;
- talloc_set_destructor(dirp, smb_Dir_destructor);
+ talloc_set_destructor(dir_hnd, smb_Dir_destructor);
- return dirp;
+ return dir_hnd;
fail:
- TALLOC_FREE(dirp);
+ TALLOC_FREE(dir_hnd);
return NULL;
}
Don't check for veto or invisible files.
********************************************************************/
-const char *ReadDirName(struct smb_Dir *dirp, long *poffset,
+const char *ReadDirName(struct smb_Dir *dir_hnd, long *poffset,
SMB_STRUCT_STAT *sbuf, char **ptalloced)
{
const char *n;
char *talloced = NULL;
- connection_struct *conn = dirp->conn;
+ connection_struct *conn = dir_hnd->conn;
/* Cheat to allow . and .. to be the first entries returned. */
if (((*poffset == START_OF_DIRECTORY_OFFSET) ||
- (*poffset == DOT_DOT_DIRECTORY_OFFSET)) && (dirp->file_number < 2))
+ (*poffset == DOT_DOT_DIRECTORY_OFFSET)) && (dir_hnd->file_number < 2))
{
- if (dirp->file_number == 0) {
+ if (dir_hnd->file_number == 0) {
n = ".";
- *poffset = dirp->offset = START_OF_DIRECTORY_OFFSET;
+ *poffset = dir_hnd->offset = START_OF_DIRECTORY_OFFSET;
} else {
n = "..";
- *poffset = dirp->offset = DOT_DOT_DIRECTORY_OFFSET;
+ *poffset = dir_hnd->offset = DOT_DOT_DIRECTORY_OFFSET;
}
- dirp->file_number++;
+ dir_hnd->file_number++;
*ptalloced = NULL;
return n;
}
if (*poffset == END_OF_DIRECTORY_OFFSET) {
- *poffset = dirp->offset = END_OF_DIRECTORY_OFFSET;
+ *poffset = dir_hnd->offset = END_OF_DIRECTORY_OFFSET;
return NULL;
}
/* A real offset, seek to it. */
- SeekDir(dirp, *poffset);
+ SeekDir(dir_hnd, *poffset);
- while ((n = vfs_readdirname(conn, dirp->dir, sbuf, &talloced))) {
+ while ((n = vfs_readdirname(conn, dir_hnd->dir, sbuf, &talloced))) {
/* Ignore . and .. - we've already returned them. */
if (*n == '.') {
if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
continue;
}
}
- *poffset = dirp->offset = SMB_VFS_TELLDIR(conn, dirp->dir);
+ *poffset = dir_hnd->offset = SMB_VFS_TELLDIR(conn, dir_hnd->dir);
*ptalloced = talloced;
- dirp->file_number++;
+ dir_hnd->file_number++;
return n;
}
- *poffset = dirp->offset = END_OF_DIRECTORY_OFFSET;
+ *poffset = dir_hnd->offset = END_OF_DIRECTORY_OFFSET;
*ptalloced = NULL;
return NULL;
}
Rewind to the start.
********************************************************************/
-void RewindDir(struct smb_Dir *dirp, long *poffset)
+void RewindDir(struct smb_Dir *dir_hnd, long *poffset)
{
- SMB_VFS_REWINDDIR(dirp->conn, dirp->dir);
- dirp->file_number = 0;
- dirp->offset = START_OF_DIRECTORY_OFFSET;
+ SMB_VFS_REWINDDIR(dir_hnd->conn, dir_hnd->dir);
+ dir_hnd->file_number = 0;
+ dir_hnd->offset = START_OF_DIRECTORY_OFFSET;
*poffset = START_OF_DIRECTORY_OFFSET;
}
Tell a dir position.
********************************************************************/
-long TellDir(struct smb_Dir *dirp)
+long TellDir(struct smb_Dir *dir_hnd)
{
- return(dirp->offset);
+ return(dir_hnd->offset);
}
/*******************************************************************
Add an entry into the dcache.
********************************************************************/
-static void DirCacheAdd(struct smb_Dir *dirp, const char *name, long offset)
+static void DirCacheAdd(struct smb_Dir *dir_hnd, const char *name, long offset)
{
struct name_cache_entry *e;
- if (dirp->name_cache_size == 0) {
+ if (dir_hnd->name_cache_size == 0) {
return;
}
- if (dirp->name_cache == NULL) {
- dirp->name_cache = talloc_zero_array(
- dirp, struct name_cache_entry, dirp->name_cache_size);
+ if (dir_hnd->name_cache == NULL) {
+ dir_hnd->name_cache = talloc_zero_array(dir_hnd,
+ struct name_cache_entry,
+ dir_hnd->name_cache_size);
- if (dirp->name_cache == NULL) {
+ if (dir_hnd->name_cache == NULL) {
return;
}
}
- dirp->name_cache_index = (dirp->name_cache_index+1) %
- dirp->name_cache_size;
- e = &dirp->name_cache[dirp->name_cache_index];
+ dir_hnd->name_cache_index = (dir_hnd->name_cache_index+1) %
+ dir_hnd->name_cache_size;
+ e = &dir_hnd->name_cache[dir_hnd->name_cache_index];
TALLOC_FREE(e->name);
- e->name = talloc_strdup(dirp, name);
+ e->name = talloc_strdup(dir_hnd, name);
e->offset = offset;
}
Don't check for veto or invisible files.
********************************************************************/
-bool SearchDir(struct smb_Dir *dirp, const char *name, long *poffset)
+bool SearchDir(struct smb_Dir *dir_hnd, const char *name, long *poffset)
{
int i;
const char *entry = NULL;
char *talloced = NULL;
- connection_struct *conn = dirp->conn;
+ connection_struct *conn = dir_hnd->conn;
/* Search back in the name cache. */
- if (dirp->name_cache_size && dirp->name_cache) {
- for (i = dirp->name_cache_index; i >= 0; i--) {
- struct name_cache_entry *e = &dirp->name_cache[i];
+ if (dir_hnd->name_cache_size && dir_hnd->name_cache) {
+ for (i = dir_hnd->name_cache_index; i >= 0; i--) {
+ struct name_cache_entry *e = &dir_hnd->name_cache[i];
if (e->name && (conn->case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) {
*poffset = e->offset;
- SeekDir(dirp, e->offset);
+ SeekDir(dir_hnd, e->offset);
return True;
}
}
- for (i = dirp->name_cache_size - 1; i > dirp->name_cache_index; i--) {
- struct name_cache_entry *e = &dirp->name_cache[i];
+ for (i = dir_hnd->name_cache_size - 1;
+ i > dir_hnd->name_cache_index; i--) {
+ struct name_cache_entry *e = &dir_hnd->name_cache[i];
if (e->name && (conn->case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) {
*poffset = e->offset;
- SeekDir(dirp, e->offset);
+ SeekDir(dir_hnd, e->offset);
return True;
}
}
}
/* Not found in the name cache. Rewind directory and start from scratch. */
- SMB_VFS_REWINDDIR(conn, dirp->dir);
- dirp->file_number = 0;
+ SMB_VFS_REWINDDIR(conn, dir_hnd->dir);
+ dir_hnd->file_number = 0;
*poffset = START_OF_DIRECTORY_OFFSET;
- while ((entry = ReadDirName(dirp, poffset, NULL, &talloced))) {
+ while ((entry = ReadDirName(dir_hnd, poffset, NULL, &talloced))) {
if (conn->case_sensitive ? (strcmp(entry, name) == 0) : strequal(entry, name)) {
TALLOC_FREE(talloced);
return True;
NTSTATUS status = NT_STATUS_OK;
long dirpos = 0;
const char *dname = NULL;
- const char *dirname = fsp->fsp_name->base_name;
char *talloced = NULL;
SMB_STRUCT_STAT st;
struct connection_struct *conn = fsp->conn;
}
}
- if (!is_visible_file(conn, dirname, dname, &st, True)) {
+ if (!is_visible_file(conn,
+ dir_hnd,
+ dname,
+ &st,
+ True)) {
TALLOC_FREE(talloced);
continue;
}