summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h2
-rw-r--r--source3/include/vfs.h7
-rw-r--r--source3/include/vfs_macros.h8
-rw-r--r--source3/modules/vfs_default.c11
-rw-r--r--source3/modules/vfs_full_audit.c15
-rw-r--r--source3/modules/vfs_streams_depot.c5
-rw-r--r--source3/smbd/dir.c35
-rw-r--r--source3/smbd/filename.c6
-rw-r--r--source3/smbd/msdfs.c4
-rw-r--r--source3/smbd/reply.c50
-rw-r--r--source3/smbd/vfs.c21
11 files changed, 138 insertions, 26 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index ac0eed2b5b..9314e57cc2 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -6216,7 +6216,7 @@ bool get_dir_entry(TALLOC_CTX *ctx,
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,
const char *name, const char *mask, uint32 attr);
-const char *ReadDirName(struct smb_Dir *dirp, long *poffset,
+char *ReadDirName(struct smb_Dir *dirp, long *poffset,
SMB_STRUCT_STAT *sbuf);
void RewindDir(struct smb_Dir *dirp, long *poffset);
void SeekDir(struct smb_Dir *dirp, long offset);
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 38a972f04c..38d60a0aec 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -123,6 +123,8 @@
SMB_VFS_RENAME, SMB_VFS_UNLINK, SMB_VFS_NTIMES. */
/* Changed to version 27 - not yet released. Added enum timestamp_set_resolution
* return to fs_capabilities call. JRA. */
+/* Leave at 27 - not yet released. Add translate_name VFS call to convert
+ UNIX names to Windows supported names -- asrinivasan. */
#define SMB_VFS_INTERFACE_VERSION 27
@@ -299,6 +301,9 @@ struct vfs_fn_pointers {
struct files_struct *fsp,
struct lock_struct *plock);
+ NTSTATUS (*translate_name)(struct vfs_handle_struct *handle,
+ char **mapped_name);
+
/* NT ACL operations. */
NTSTATUS (*fget_nt_acl)(struct vfs_handle_struct *handle,
@@ -644,6 +649,8 @@ bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
struct files_struct *fsp,
struct lock_struct *plock);
+NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
+ char **mapped_name);
NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
struct files_struct *fsp,
uint32 security_info,
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index e271cdee61..7cc5579e25 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -345,6 +345,14 @@
#define SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock) \
smb_vfs_call_strict_unlock((handle)->next, (fsp), (plock))
+#define SMB_VFS_TRANSLATE_NAME(conn, mapped_name) \
+ smb_vfs_call_translate_name((conn)->vfs_handles, (mapped_name))
+#define SMB_VFS_NEXT_TRANSLATE_NAME(handle, mapped_name) \
+ smb_vfs_call_translate_name((handle)->next, (mapped_name))
+
+#define SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock) \
+ smb_vfs_call_strict_unlock((handle)->next, (fsp), (plock))
+
#define SMB_VFS_FGET_NT_ACL(fsp, security_info, ppdesc) \
smb_vfs_call_fget_nt_acl((fsp)->conn->vfs_handles, (fsp), (security_info), (ppdesc))
#define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc) \
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index b70868eb9f..e78ddf242c 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -651,6 +651,16 @@ static int vfswrap_lstat(vfs_handle_struct *handle,
return result;
}
+static NTSTATUS vfswrap_translate_name(vfs_handle_struct *handle,
+ char **mapped_name)
+{
+ /* Default behavior is a NOOP */
+
+ if (*mapped_name != NULL)
+ return NT_STATUS_OK;
+
+ return NT_STATUS_INVALID_PARAMETER;
+}
/********************************************************************
Given a stat buffer return the allocated size on disk, taking into
account sparse files.
@@ -1725,6 +1735,7 @@ static struct vfs_fn_pointers vfs_default_fns = {
.brl_cancel_windows = vfswrap_brl_cancel_windows,
.strict_lock = vfswrap_strict_lock,
.strict_unlock = vfswrap_strict_unlock,
+ .translate_name = vfswrap_translate_name,
/* NT ACL operations. */
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 0f6de79bcf..b5c9e6bd9c 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -143,6 +143,7 @@ typedef enum _vfs_op_type {
SMB_VFS_OP_BRL_CANCEL_WINDOWS,
SMB_VFS_OP_STRICT_LOCK,
SMB_VFS_OP_STRICT_UNLOCK,
+ SMB_VFS_OP_TRANSLATE_NAME,
/* NT ACL operations. */
@@ -280,6 +281,7 @@ static struct {
{ SMB_VFS_OP_BRL_CANCEL_WINDOWS, "brl_cancel_windows" },
{ SMB_VFS_OP_STRICT_LOCK, "strict_lock" },
{ SMB_VFS_OP_STRICT_UNLOCK, "strict_unlock" },
+ { SMB_VFS_OP_TRANSLATE_NAME, "translate_name" },
{ SMB_VFS_OP_FGET_NT_ACL, "fget_nt_acl" },
{ SMB_VFS_OP_GET_NT_ACL, "get_nt_acl" },
{ SMB_VFS_OP_FSET_NT_ACL, "fset_nt_acl" },
@@ -1515,6 +1517,18 @@ static void smb_full_audit_strict_unlock(struct vfs_handle_struct *handle,
return;
}
+static NTSTATUS smb_full_audit_translate_name(vfs_handle_struct *handle,
+ char **mapped_name)
+{
+ NTSTATUS result;
+
+ result = SMB_VFS_NEXT_TRANSLATE_NAME(handle, mapped_name);
+
+ do_log(SMB_VFS_OP_TRANSLATE_NAME, NT_STATUS_IS_OK(result), handle, "");
+
+ return result;
+}
+
static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
uint32 security_info,
SEC_DESC **ppdesc)
@@ -2229,6 +2243,7 @@ static struct vfs_fn_pointers vfs_full_audit_fns = {
.brl_cancel_windows = smb_full_audit_brl_cancel_windows,
.strict_lock = smb_full_audit_strict_lock,
.strict_unlock = smb_full_audit_strict_unlock,
+ .translate_name = smb_full_audit_translate_name,
.fget_nt_acl = smb_full_audit_fget_nt_acl,
.get_nt_acl = smb_full_audit_get_nt_acl,
.fset_nt_acl = smb_full_audit_fset_nt_acl,
diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c
index aa0189123b..51cd56e8fb 100644
--- a/source3/modules/vfs_streams_depot.c
+++ b/source3/modules/vfs_streams_depot.c
@@ -384,7 +384,7 @@ static NTSTATUS walk_streams(vfs_handle_struct *handle,
{
char *dirname;
SMB_STRUCT_DIR *dirhandle = NULL;
- char *dirent;
+ char *dirent = NULL;
dirname = stream_dir(handle, smb_fname_base, &smb_fname_base->st,
false);
@@ -411,14 +411,17 @@ static NTSTATUS walk_streams(vfs_handle_struct *handle,
while ((dirent = vfs_readdirname(handle->conn, dirhandle, NULL)) != NULL) {
if (ISDOT(dirent) || ISDOTDOT(dirent)) {
+ TALLOC_FREE(dirent);
continue;
}
DEBUG(10, ("walk_streams: dirent=%s\n", dirent));
if (!fn(dirname, dirent, private_data)) {
+ TALLOC_FREE(dirent);
break;
}
+ TALLOC_FREE(dirent);
}
SMB_VFS_NEXT_CLOSEDIR(handle, dirhandle);
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index 73c4cbb3e7..60fa0306b9 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -585,15 +585,16 @@ int dptr_dnum(struct dptr_struct *dptr)
Return the next visible file name, skipping veto'd and invisible files.
****************************************************************************/
-static const char *dptr_normal_ReadDirName(struct dptr_struct *dptr,
+static char *dptr_normal_ReadDirName(struct dptr_struct *dptr,
long *poffset, SMB_STRUCT_STAT *pst)
{
/* Normal search for the next file. */
- const char *name;
+ char *name;
while ((name = ReadDirName(dptr->dir_hnd, poffset, pst)) != NULL) {
if (is_visible_file(dptr->conn, dptr->path, name, pst, True)) {
return name;
}
+ TALLOC_FREE(name);
}
return NULL;
}
@@ -612,14 +613,12 @@ char *dptr_ReadDirName(TALLOC_CTX *ctx,
char *pathreal = NULL;
char *found_name = NULL;
int ret;
- const char *name_temp = NULL;
NTSTATUS status;
SET_STAT_INVALID(*pst);
if (dptr->has_wild || dptr->did_stat) {
- name_temp = dptr_normal_ReadDirName(dptr, poffset, pst);
- name = talloc_strdup(ctx, name_temp);
+ name = dptr_normal_ReadDirName(dptr, poffset, pst);
return name;
}
@@ -707,8 +706,8 @@ char *dptr_ReadDirName(TALLOC_CTX *ctx,
TALLOC_FREE(pathreal);
- name_temp = dptr_normal_ReadDirName(dptr, poffset, pst);
- name = talloc_strdup(ctx, name_temp);
+ name = dptr_normal_ReadDirName(dptr, poffset, pst);
+
return name;
clean:
@@ -1337,10 +1336,10 @@ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn,
Don't check for veto or invisible files.
********************************************************************/
-const char *ReadDirName(struct smb_Dir *dirp, long *poffset,
+char *ReadDirName(struct smb_Dir *dirp, long *poffset,
SMB_STRUCT_STAT *sbuf)
{
- const char *n;
+ char *n;
connection_struct *conn = dirp->conn;
/* Cheat to allow . and .. to be the first entries returned. */
@@ -1348,11 +1347,15 @@ const char *ReadDirName(struct smb_Dir *dirp, long *poffset,
(*poffset == DOT_DOT_DIRECTORY_OFFSET)) && (dirp->file_number < 2))
{
if (dirp->file_number == 0) {
- n = ".";
+ n = talloc_strdup(talloc_tos(), ".");
+ if (n == NULL)
+ return NULL;
*poffset = dirp->offset = START_OF_DIRECTORY_OFFSET;
} else {
*poffset = dirp->offset = DOT_DOT_DIRECTORY_OFFSET;
- n = "..";
+ n = talloc_strdup(talloc_tos(), "..");
+ if (n == NULL)
+ return NULL;
}
dirp->file_number++;
return n;
@@ -1368,6 +1371,7 @@ const char *ReadDirName(struct smb_Dir *dirp, long *poffset,
/* Ignore . and .. - we've already returned them. */
if (*n == '.') {
if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
+ TALLOC_FREE(n);
continue;
}
}
@@ -1470,7 +1474,7 @@ void DirCacheAdd(struct smb_Dir *dirp, const char *name, long offset)
bool SearchDir(struct smb_Dir *dirp, const char *name, long *poffset)
{
int i;
- const char *entry;
+ char *entry = NULL;
connection_struct *conn = dirp->conn;
/* Search back in the name cache. */
@@ -1499,8 +1503,10 @@ bool SearchDir(struct smb_Dir *dirp, const char *name, long *poffset)
*poffset = START_OF_DIRECTORY_OFFSET;
while ((entry = ReadDirName(dirp, poffset, NULL))) {
if (conn->case_sensitive ? (strcmp(entry, name) == 0) : strequal(entry, name)) {
+ TALLOC_FREE(entry);
return True;
}
+ TALLOC_FREE(entry);
}
return False;
}
@@ -1514,7 +1520,7 @@ NTSTATUS can_delete_directory(struct connection_struct *conn,
{
NTSTATUS status = NT_STATUS_OK;
long dirpos = 0;
- const char *dname;
+ char *dname = NULL;
SMB_STRUCT_STAT st;
struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, dirname,
NULL, 0);
@@ -1527,11 +1533,13 @@ NTSTATUS can_delete_directory(struct connection_struct *conn,
/* Quick check for "." and ".." */
if (dname[0] == '.') {
if (!dname[1] || (dname[1] == '.' && !dname[2])) {
+ TALLOC_FREE(dname);
continue;
}
}
if (!is_visible_file(conn, dirname, dname, &st, True)) {
+ TALLOC_FREE(dname);
continue;
}
@@ -1540,6 +1548,7 @@ NTSTATUS can_delete_directory(struct connection_struct *conn,
status = NT_STATUS_DIRECTORY_NOT_EMPTY;
break;
}
+ TALLOC_FREE(dname);
TALLOC_FREE(dir_hnd);
return status;
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 2538bc1ea6..ee97388da2 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -829,7 +829,7 @@ static int get_real_filename_full_scan(connection_struct *conn,
TALLOC_CTX *mem_ctx, char **found_name)
{
struct smb_Dir *cur_dir;
- const char *dname;
+ char *dname = NULL;
char *unmangled_name = NULL;
long curpos;
@@ -885,6 +885,7 @@ static int get_real_filename_full_scan(connection_struct *conn,
/* Is it dot or dot dot. */
if (ISDOT(dname) || ISDOTDOT(dname)) {
+ TALLOC_FREE(dname);
continue;
}
@@ -907,10 +908,13 @@ static int get_real_filename_full_scan(connection_struct *conn,
TALLOC_FREE(cur_dir);
if (!*found_name) {
errno = ENOMEM;
+ TALLOC_FREE(dname);
return -1;
}
+ TALLOC_FREE(dname);
return 0;
}
+ TALLOC_FREE(dname);
}
TALLOC_FREE(unmangled_name);
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 74e46527bc..4a338fa590 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -1548,6 +1548,7 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
NULL)) {
cnt++;
}
+ TALLOC_FREE(dname);
}
SMB_VFS_CLOSEDIR(conn,dirp);
@@ -1647,6 +1648,7 @@ static int form_junctions(TALLOC_CTX *ctx,
if (cnt >= jn_remain) {
DEBUG(2, ("form_junctions: ran out of MSDFS "
"junction slots"));
+ TALLOC_FREE(dname);
goto out;
}
if (is_msdfs_link_internal(ctx,
@@ -1664,6 +1666,7 @@ static int form_junctions(TALLOC_CTX *ctx,
dname);
if (!jucn[cnt].service_name ||
!jucn[cnt].volume_name) {
+ TALLOC_FREE(dname);
goto out;
}
jucn[cnt].comment = "";
@@ -1671,6 +1674,7 @@ static int form_junctions(TALLOC_CTX *ctx,
}
TALLOC_FREE(link_target);
}
+ TALLOC_FREE(dname);
}
out:
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index bdc71c2404..a3280cb9d4 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -2577,7 +2577,7 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
} else {
struct smb_Dir *dir_hnd = NULL;
long offset = 0;
- const char *dname;
+ char *dname = NULL;
if ((dirtype & SAMBA_ATTRIBUTES_MASK) == aDIR) {
status = NT_STATUS_OBJECT_NAME_INVALID;
@@ -2619,18 +2619,21 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
if (!is_visible_file(conn, fname_dir, dname,
&smb_fname->st, true)) {
TALLOC_FREE(frame);
+ TALLOC_FREE(dname);
continue;
}
/* Quick check for "." and ".." */
if (ISDOT(dname) || ISDOTDOT(dname)) {
TALLOC_FREE(frame);
+ TALLOC_FREE(dname);
continue;
}
if(!mask_match(dname, fname_mask,
conn->case_sensitive)) {
TALLOC_FREE(frame);
+ TALLOC_FREE(dname);
continue;
}
@@ -2643,6 +2646,7 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
TALLOC_FREE(dir_hnd);
status = NT_STATUS_NO_MEMORY;
TALLOC_FREE(frame);
+ TALLOC_FREE(dname);
goto out;
}
@@ -2650,12 +2654,14 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(dir_hnd);
TALLOC_FREE(frame);
+ TALLOC_FREE(dname);
goto out;
}
status = do_unlink(conn, req, smb_fname, dirtype);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(frame);
+ TALLOC_FREE(dname);
continue;
}
@@ -2664,6 +2670,7 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
smb_fname->base_name));
TALLOC_FREE(frame);
+ TALLOC_FREE(dname);
}
TALLOC_FREE(dir_hnd);
}
@@ -5287,7 +5294,7 @@ static bool recursive_rmdir(TALLOC_CTX *ctx,
connection_struct *conn,
struct smb_filename *smb_dname)
{
- const char *dname = NULL;
+ char *dname = NULL;
bool ret = True;
long offset = 0;
SMB_STRUCT_STAT st;
@@ -5306,11 +5313,13 @@ static bool recursive_rmdir(TALLOC_CTX *ctx,
NTSTATUS status;
if (ISDOT(dname) || ISDOTDOT(dname)) {
+ TALLOC_FREE(dname);
continue;
}
if (!is_visible_file(conn, smb_dname->base_name, dname, &st,
false)) {
+ TALLOC_FREE(dname);
continue;
}
@@ -5353,6 +5362,7 @@ static bool recursive_rmdir(TALLOC_CTX *ctx,
err_break:
TALLOC_FREE(smb_dname_full);
TALLOC_FREE(fullname);
+ TALLOC_FREE(dname);
if (do_break) {
ret = false;
break;
@@ -5406,7 +5416,7 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx,
* retry. If we fail to delete any of them (and we *don't*
* do a recursive delete) then fail the rmdir.
*/
- const char *dname;
+ char *dname = NULL;
long dirpos = 0;
struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
smb_dname->base_name, NULL,
@@ -5418,16 +5428,22 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx,
}
while ((dname = ReadDirName(dir_hnd, &dirpos, &st))) {
- if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
+ if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
+ TALLOC_FREE(dname);
continue;
+ }
if (!is_visible_file(conn, smb_dname->base_name, dname,
- &st, false))
+ &st, false)) {
+ TALLOC_FREE(dname);
continue;
+ }
if(!IS_VETO_PATH(conn, dname)) {
TALLOC_FREE(dir_hnd);
+ TALLOC_FREE(dname);
errno = ENOTEMPTY;
goto err;
}
+ TALLOC_FREE(dname);
}
/* We only have veto files/directories.
@@ -5448,10 +5464,12 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx,
NTSTATUS status;
if (ISDOT(dname) || ISDOTDOT(dname)) {
+ TALLOC_FREE(dname);
continue;
}
if (!is_visible_file(conn, smb_dname->base_name, dname,
&st, false)) {
+ TALLOC_FREE(dname);
continue;
}
@@ -5496,6 +5514,7 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx,
err_break:
TALLOC_FREE(fullname);
TALLOC_FREE(smb_dname_full);
+ TALLOC_FREE(dname);
if (do_break)
break;
}
@@ -6132,7 +6151,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
int count=0;
NTSTATUS status = NT_STATUS_OK;
struct smb_Dir *dir_hnd = NULL;
- const char *dname;
+ char *dname = NULL;
long offset = 0;
int create_options = 0;
bool posix_pathnames = lp_posix_pathnames();
@@ -6320,16 +6339,19 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
if (attrs & aDIR) {
sysdir_entry = True;
} else {
+ TALLOC_FREE(dname);
continue;
}
}
if (!is_visible_file(conn, fname_src_dir, dname,
&smb_fname_src->st, false)) {
+ TALLOC_FREE(dname);
continue;
}
if(!mask_match(dname, fname_src_mask, conn->case_sensitive)) {
+ TALLOC_FREE(dname);
continue;
}
@@ -6353,6 +6375,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
&destname)) {
DEBUG(6, ("resolve_wildcards %s %s failed\n",
smb_fname_src->base_name, destname));
+ TALLOC_FREE(dname);
continue;
}
if (!destname) {
@@ -6428,7 +6451,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
DEBUG(3,("rename_internals: doing rename on %s -> "
"%s\n", smb_fname_str_dbg(smb_fname_src),
smb_fname_str_dbg(smb_fname_src)));
-
+ TALLOC_FREE(dname);
}
TALLOC_FREE(dir_hnd);
@@ -6437,6 +6460,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
}
out:
+ TALLOC_FREE(dname);
TALLOC_FREE(fname_src_dir);
TALLOC_FREE(fname_src_mask);
return status;
@@ -6901,7 +6925,7 @@ void reply_copy(struct smb_request *req)
}
} else {
struct smb_Dir *dir_hnd = NULL;
- const char *dname = NULL;
+ char *dname = NULL;
long offset = 0;
/*
@@ -6946,16 +6970,19 @@ void reply_copy(struct smb_request *req)
char *destname = NULL;
if (ISDOT(dname) || ISDOTDOT(dname)) {
+ TALLOC_FREE(dname);
continue;
}
if (!is_visible_file(conn, fname_src_dir, dname,
&smb_fname_src->st, false)) {
+ TALLOC_FREE(dname);
continue;
}
if(!mask_match(dname, fname_src_mask,
conn->case_sensitive)) {
+ TALLOC_FREE(dname);
continue;
}
@@ -6969,6 +6996,7 @@ void reply_copy(struct smb_request *req)
if (!smb_fname_src->base_name) {
TALLOC_FREE(dir_hnd);
+ TALLOC_FREE(dname);
reply_nterror(req, NT_STATUS_NO_MEMORY);
goto out;
}
@@ -6976,10 +7004,12 @@ void reply_copy(struct smb_request *req)
if (!resolve_wildcards(ctx, smb_fname_src->base_name,
smb_fname_dst->base_name,
&destname)) {
+ TALLOC_FREE(dname);
continue;
}
if (!destname) {
TALLOC_FREE(dir_hnd);
+ TALLOC_FREE(dname);
reply_nterror(req, NT_STATUS_NO_MEMORY);
goto out;
}
@@ -6990,6 +7020,7 @@ void reply_copy(struct smb_request *req)
status = check_name(conn, smb_fname_src->base_name);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(dir_hnd);
+ TALLOC_FREE(dname);
reply_nterror(req, status);
goto out;
}
@@ -6997,6 +7028,7 @@ void reply_copy(struct smb_request *req)
status = check_name(conn, smb_fname_dst->base_name);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(dir_hnd);
+ TALLOC_FREE(dname);
reply_nterror(req, status);
goto out;
}
@@ -7011,6 +7043,8 @@ void reply_copy(struct smb_request *req)
if (NT_STATUS_IS_OK(status)) {
count++;
}
+
+ TALLOC_FREE(dname);
}
TALLOC_FREE(dir_hnd);
}
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 5425c55198..42ff8b19cd 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -662,7 +662,8 @@ SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n)
char *vfs_readdirname(connection_struct *conn, void *p, SMB_STRUCT_STAT *sbuf)
{
SMB_STRUCT_DIRENT *ptr= NULL;
- char *dname;
+ char *dname = NULL;
+ NTSTATUS result;
if (!p)
return(NULL);
@@ -671,7 +672,16 @@ char *vfs_readdirname(connection_struct *conn, void *p, SMB_STRUCT_STAT *sbuf)
if (!ptr)
return(NULL);
- dname = ptr->d_name;
+ dname = talloc_strdup(talloc_tos(), ptr->d_name);
+ if (dname == NULL) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ result = SMB_VFS_TRANSLATE_NAME(conn, &dname);
+ if (!NT_STATUS_IS_OK(result)) {
+ TALLOC_FREE(dname);
+ return NULL;
+ }
#ifdef NEXT2
if (telldir(p) < 0)
@@ -1495,6 +1505,13 @@ void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
handle->fns->strict_unlock(handle, fsp, plock);
}
+NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
+ char **mapped_name)
+{
+ VFS_FIND(translate_name);
+ return handle->fns->translate_name(handle, mapped_name);
+}
+
NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
struct files_struct *fsp,
uint32 security_info,