#include "includes.h"
#include "smbd/globals.h"
+#include "libcli/security/security.h"
/*
This module implements directory related functions for Samba.
return true;
}
- sconn->smb1.searches.dptr_bmap = bitmap_allocate(MAX_DIRECTORY_HANDLES);
+ sconn->smb1.searches.dptr_bmap = bitmap_talloc(
+ sconn, MAX_DIRECTORY_HANDLES);
if (sconn->smb1.searches.dptr_bmap == NULL) {
return false;
/*
* Go to the end of the list.
*/
- for(dptr = sconn->smb1.searches.dirptrs; dptr && dptr->next; dptr = dptr->next)
- ;
+ dptr = DLIST_TAIL(sconn->smb1.searches.dirptrs);
if(!dptr) {
DEBUG(0,("No dptrs available to idle ?\n"));
* Idle the oldest pointer.
*/
- for(; dptr; dptr = dptr->prev) {
+ for(; dptr; dptr = DLIST_PREV(dptr)) {
if (dptr->dir_hnd) {
dptr_idle(dptr);
return;
* biased by one with respect to the bitmap.
*/
- if(bitmap_query(sconn->smb1.searches.dptr_bmap, dptr->dnum - 1) != true) {
+ if (!bitmap_query(sconn->smb1.searches.dptr_bmap, dptr->dnum - 1)) {
DEBUG(0,("dptr_close_internal : Error - closing dnum = %d and bitmap not set !\n",
dptr->dnum ));
}
* one of the new dnum handles.
*/
- for(; dptr; dptr = dptr->prev) {
+ for(; dptr; dptr = DLIST_PREV(dptr)) {
if ((old && (dptr->dnum < 256) && !dptr->expect_close) ||
(!old && (dptr->dnum > 255))) {
dptr_close_internal(dptr);
Wrapper functions to access the lower level directory handles.
****************************************************************************/
-int dptr_CloseDir(struct dptr_struct *dptr)
+void dptr_CloseDir(files_struct *fsp)
{
- struct smbd_server_connection *sconn = dptr->conn->sconn;
- DLIST_REMOVE(sconn->smb1.searches.dirptrs, dptr);
- TALLOC_FREE(dptr->dir_hnd);
- return 0;
+ if (fsp->dptr) {
+ if (fsp->fh->fd == dirfd(fsp->dptr->dir_hnd->dir)) {
+ /* The call below closes the underlying fd. */
+ fsp->fh->fd = -1;
+ }
+ dptr_close_internal(fsp->dptr);
+ fsp->dptr = NULL;
+ }
}
void dptr_SeekDir(struct dptr_struct *dptr, long offset)
Return the next visible file name, skipping veto'd and invisible files.
****************************************************************************/
-static char *dptr_normal_ReadDirName(struct dptr_struct *dptr,
- long *poffset, SMB_STRUCT_STAT *pst)
+static const char *dptr_normal_ReadDirName(struct dptr_struct *dptr,
+ long *poffset, SMB_STRUCT_STAT *pst,
+ char **ptalloced)
{
/* Normal search for the next file. */
- char *name;
- while ((name = ReadDirName(dptr->dir_hnd, poffset, pst)) != NULL) {
+ const char *name;
+ char *talloced = NULL;
+
+ while ((name = ReadDirName(dptr->dir_hnd, poffset, pst, &talloced))
+ != NULL) {
if (is_visible_file(dptr->conn, dptr->path, name, pst, True)) {
+ *ptalloced = talloced;
return name;
}
- TALLOC_FREE(name);
+ TALLOC_FREE(talloced);
}
return NULL;
}
long *poffset,
SMB_STRUCT_STAT *pst)
{
- struct smb_filename *smb_fname_base = NULL;
+ struct smb_filename smb_fname_base;
char *name = NULL;
+ const char *name_temp = NULL;
+ char *talloced = NULL;
char *pathreal = NULL;
char *found_name = NULL;
int ret;
- NTSTATUS status;
SET_STAT_INVALID(*pst);
if (dptr->has_wild || dptr->did_stat) {
- name = dptr_normal_ReadDirName(dptr, poffset, pst);
- return name;
+ name_temp = dptr_normal_ReadDirName(dptr, poffset, pst,
+ &talloced);
+ if (name_temp == NULL) {
+ return NULL;
+ }
+ if (talloced != NULL) {
+ return talloc_move(ctx, &talloced);
+ }
+ return talloc_strdup(ctx, name_temp);
}
/* If poffset is -1 then we know we returned this name before and we
return NULL;
/* Create an smb_filename with stream_name == NULL. */
- status = create_synthetic_smb_fname(ctx, pathreal, NULL, NULL,
- &smb_fname_base);
- if (!NT_STATUS_IS_OK(status)) {
- return NULL;
- }
+ ZERO_STRUCT(smb_fname_base);
+ smb_fname_base.base_name = pathreal;
- if (SMB_VFS_STAT(dptr->conn, smb_fname_base) == 0) {
- *pst = smb_fname_base->st;
- TALLOC_FREE(smb_fname_base);
+ if (SMB_VFS_STAT(dptr->conn, &smb_fname_base) == 0) {
+ *pst = smb_fname_base.st;
name = talloc_strdup(ctx, dptr->wcard);
goto clean;
} else {
- TALLOC_FREE(smb_fname_base);
/* If we get any other error than ENOENT or ENOTDIR
then the file exists we just can't stat it. */
if (errno != ENOENT && errno != ENOTDIR) {
TALLOC_FREE(pathreal);
- name = dptr_normal_ReadDirName(dptr, poffset, pst);
-
- return name;
+ name_temp = dptr_normal_ReadDirName(dptr, poffset, pst, &talloced);
+ if (name_temp == NULL) {
+ return NULL;
+ }
+ if (talloced != NULL) {
+ return talloc_move(ctx, &talloced);
+ }
+ return talloc_strdup(ctx, name_temp);
clean:
TALLOC_FREE(pathreal);
bool isdots;
char *fname = NULL;
char *pathreal = NULL;
- struct smb_filename *smb_fname = NULL;
+ struct smb_filename smb_fname;
uint32_t mode = 0;
bool ok;
NTSTATUS status;
}
/* Create smb_fname with NULL stream_name. */
- status = create_synthetic_smb_fname(ctx, pathreal,
- NULL, &sbuf,
- &smb_fname);
- TALLOC_FREE(pathreal);
- if (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(dname);
- TALLOC_FREE(fname);
- return false;
- }
+ ZERO_STRUCT(smb_fname);
+ smb_fname.base_name = pathreal;
+ smb_fname.st = sbuf;
- ok = mode_fn(ctx, private_data, smb_fname, &mode);
+ ok = mode_fn(ctx, private_data, &smb_fname, &mode);
if (!ok) {
TALLOC_FREE(dname);
TALLOC_FREE(fname);
- TALLOC_FREE(smb_fname);
+ TALLOC_FREE(pathreal);
continue;
}
fname, (unsigned int)mode, (unsigned int)dirtype));
TALLOC_FREE(dname);
TALLOC_FREE(fname);
- TALLOC_FREE(smb_fname);
+ TALLOC_FREE(pathreal);
continue;
}
struct file_id fileid;
fileid = vfs_file_id_from_sbuf(conn,
- &smb_fname->st);
- get_file_infos(fileid, NULL, &write_time_ts);
+ &smb_fname.st);
+ get_file_infos(fileid, 0, NULL, &write_time_ts);
if (!null_timespec(write_time_ts)) {
- update_stat_ex_mtime(&smb_fname->st,
+ update_stat_ex_mtime(&smb_fname.st,
write_time_ts);
}
}
DEBUG(3,("smbd_dirptr_get_entry mask=[%s] found %s "
"fname=%s (%s)\n",
- mask, smb_fname_str_dbg(smb_fname),
+ mask, smb_fname_str_dbg(&smb_fname),
dname, fname));
DirCacheAdd(dirptr->dir_hnd, dname, cur_offset);
TALLOC_FREE(dname);
+ status = copy_smb_filename(ctx, &smb_fname, _smb_fname);
+ TALLOC_FREE(pathreal);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
*_fname = fname;
- *_smb_fname = smb_fname;
*_mode = mode;
*_prev_offset = prev_offset;
struct smb_filename *smb_fname)
{
/*
- * If user is a member of the Admin group
- * we never hide files from them.
+ * Never hide files from the root user.
+ * We use (uid_t)0 here not sec_initial_uid()
+ * as make test uses a single user context.
*/
- if (conn->admin_user) {
+ if (get_current_uid(conn) == (uid_t)0) {
return True;
}
const struct smb_filename *smb_fname)
{
/*
- * If user is a member of the Admin group
- * we never hide files from them.
+ * Never hide files from the root user.
+ * We use (uid_t)0 here not sec_initial_uid()
+ * as make test uses a single user context.
*/
- if (conn->admin_user) {
+ if (get_current_uid(conn) == (uid_t)0) {
return True;
}
const struct smb_filename *smb_fname)
{
/*
- * If user is a member of the Admin group
- * we never hide files from them.
+ * Never hide files from the root user.
+ * We use (uid_t)0 here not sec_initial_uid()
+ * as make test uses a single user context.
*/
- if (conn->admin_user)
+ if (get_current_uid(conn) == (uid_t)0) {
return False;
+ }
SMB_ASSERT(VALID_STAT(smb_fname->st));
goto out;
}
- /* If it's a dfs symlink, ignore _hide xxxx_ options */
- if (lp_host_msdfs() &&
- lp_msdfs_root(SNUM(conn)) &&
- is_msdfs_link(conn, entry, NULL)) {
- ret = true;
- goto out;
- }
-
/* Create an smb_filename with stream_name == NULL. */
status = create_synthetic_smb_fname(talloc_tos(), entry, NULL,
pst, &smb_fname_base);
Don't check for veto or invisible files.
********************************************************************/
-char *ReadDirName(struct smb_Dir *dirp, long *poffset,
- SMB_STRUCT_STAT *sbuf)
+const char *ReadDirName(struct smb_Dir *dirp, long *poffset,
+ SMB_STRUCT_STAT *sbuf, char **ptalloced)
{
- char *n;
+ const char *n;
+ char *talloced = NULL;
connection_struct *conn = dirp->conn;
/* Cheat to allow . and .. to be the first entries returned. */
(*poffset == DOT_DOT_DIRECTORY_OFFSET)) && (dirp->file_number < 2))
{
if (dirp->file_number == 0) {
- n = talloc_strdup(talloc_tos(), ".");
- if (n == NULL)
- return NULL;
+ n = ".";
*poffset = dirp->offset = START_OF_DIRECTORY_OFFSET;
} else {
+ n = "..";
*poffset = dirp->offset = DOT_DOT_DIRECTORY_OFFSET;
- n = talloc_strdup(talloc_tos(), "..");
- if (n == NULL)
- return NULL;
}
dirp->file_number++;
+ *ptalloced = NULL;
return n;
} else if (*poffset == END_OF_DIRECTORY_OFFSET) {
*poffset = dirp->offset = END_OF_DIRECTORY_OFFSET;
SeekDir(dirp, *poffset);
}
- while ((n = vfs_readdirname(conn, dirp->dir, sbuf))) {
+ while ((n = vfs_readdirname(conn, dirp->dir, sbuf, &talloced))) {
/* Ignore . and .. - we've already returned them. */
if (*n == '.') {
if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
- TALLOC_FREE(n);
+ TALLOC_FREE(talloced);
continue;
}
}
*poffset = dirp->offset = SMB_VFS_TELLDIR(conn, dirp->dir);
+ *ptalloced = talloced;
dirp->file_number++;
return n;
}
*poffset = dirp->offset = END_OF_DIRECTORY_OFFSET;
+ *ptalloced = NULL;
return NULL;
}
bool SearchDir(struct smb_Dir *dirp, const char *name, long *poffset)
{
int i;
- char *entry = NULL;
+ const char *entry = NULL;
+ char *talloced = NULL;
connection_struct *conn = dirp->conn;
/* Search back in the name cache. */
SMB_VFS_REWINDDIR(conn, dirp->dir);
dirp->file_number = 0;
*poffset = START_OF_DIRECTORY_OFFSET;
- while ((entry = ReadDirName(dirp, poffset, NULL))) {
+ while ((entry = ReadDirName(dirp, poffset, NULL, &talloced))) {
if (conn->case_sensitive ? (strcmp(entry, name) == 0) : strequal(entry, name)) {
- TALLOC_FREE(entry);
+ TALLOC_FREE(talloced);
return True;
}
- TALLOC_FREE(entry);
+ TALLOC_FREE(talloced);
}
return False;
}
{
NTSTATUS status = NT_STATUS_OK;
long dirpos = 0;
- char *dname = NULL;
+ const char *dname = NULL;
+ char *talloced = NULL;
SMB_STRUCT_STAT st;
struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, dirname,
NULL, 0);
return map_nt_error_from_unix(errno);
}
- while ((dname = ReadDirName(dir_hnd, &dirpos, &st))) {
+ while ((dname = ReadDirName(dir_hnd, &dirpos, &st, &talloced))) {
/* Quick check for "." and ".." */
if (dname[0] == '.') {
if (!dname[1] || (dname[1] == '.' && !dname[2])) {
- TALLOC_FREE(dname);
+ TALLOC_FREE(talloced);
continue;
}
}
if (!is_visible_file(conn, dirname, dname, &st, True)) {
- TALLOC_FREE(dname);
+ TALLOC_FREE(talloced);
continue;
}
status = NT_STATUS_DIRECTORY_NOT_EMPTY;
break;
}
- TALLOC_FREE(dname);
+ TALLOC_FREE(talloced);
TALLOC_FREE(dir_hnd);
return status;