This vop is designed to work in tandem with SMB_VFS_READDIR to allow
vfs modules to make modifications to arbitrary filenames before
they're consumed by callers. Subsequently the core directory
enumeration code in smbd is now changed to free the memory that may be
allocated in a module. This vop enables the new version of catia in
the following patch.
Signed-off-by: Tim Prouty <tprouty@samba.org>
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);
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);
SMB_STRUCT_STAT *sbuf);
void RewindDir(struct smb_Dir *dirp, long *poffset);
void SeekDir(struct smb_Dir *dirp, long offset);
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. */
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
#define SMB_VFS_INTERFACE_VERSION 27
struct files_struct *fsp,
struct lock_struct *plock);
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,
/* NT ACL operations. */
NTSTATUS (*fget_nt_acl)(struct vfs_handle_struct *handle,
void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
struct files_struct *fsp,
struct lock_struct *plock);
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,
NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
struct files_struct *fsp,
uint32 security_info,
#define SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock) \
smb_vfs_call_strict_unlock((handle)->next, (fsp), (plock))
#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) \
#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) \
+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.
/********************************************************************
Given a stat buffer return the allocated size on disk, taking into
account sparse files.
.brl_cancel_windows = vfswrap_brl_cancel_windows,
.strict_lock = vfswrap_strict_lock,
.strict_unlock = vfswrap_strict_unlock,
.brl_cancel_windows = vfswrap_brl_cancel_windows,
.strict_lock = vfswrap_strict_lock,
.strict_unlock = vfswrap_strict_unlock,
+ .translate_name = vfswrap_translate_name,
SMB_VFS_OP_BRL_CANCEL_WINDOWS,
SMB_VFS_OP_STRICT_LOCK,
SMB_VFS_OP_STRICT_UNLOCK,
SMB_VFS_OP_BRL_CANCEL_WINDOWS,
SMB_VFS_OP_STRICT_LOCK,
SMB_VFS_OP_STRICT_UNLOCK,
+ SMB_VFS_OP_TRANSLATE_NAME,
{ 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_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" },
{ 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" },
+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)
static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
uint32 security_info,
SEC_DESC **ppdesc)
.brl_cancel_windows = smb_full_audit_brl_cancel_windows,
.strict_lock = smb_full_audit_strict_lock,
.strict_unlock = smb_full_audit_strict_unlock,
.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,
.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,
{
char *dirname;
SMB_STRUCT_DIR *dirhandle = NULL;
{
char *dirname;
SMB_STRUCT_DIR *dirhandle = NULL;
dirname = stream_dir(handle, smb_fname_base, &smb_fname_base->st,
false);
dirname = stream_dir(handle, smb_fname_base, &smb_fname_base->st,
false);
while ((dirent = vfs_readdirname(handle->conn, dirhandle, NULL)) != NULL) {
if (ISDOT(dirent) || ISDOTDOT(dirent)) {
while ((dirent = vfs_readdirname(handle->conn, dirhandle, NULL)) != NULL) {
if (ISDOT(dirent) || ISDOTDOT(dirent)) {
continue;
}
DEBUG(10, ("walk_streams: dirent=%s\n", dirent));
if (!fn(dirname, dirent, private_data)) {
continue;
}
DEBUG(10, ("walk_streams: dirent=%s\n", dirent));
if (!fn(dirname, dirent, private_data)) {
}
SMB_VFS_NEXT_CLOSEDIR(handle, dirhandle);
}
SMB_VFS_NEXT_CLOSEDIR(handle, dirhandle);
Return the next visible file name, skipping veto'd and invisible files.
****************************************************************************/
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. */
long *poffset, SMB_STRUCT_STAT *pst)
{
/* Normal search for the next file. */
while ((name = ReadDirName(dptr->dir_hnd, poffset, pst)) != NULL) {
if (is_visible_file(dptr->conn, dptr->path, name, pst, True)) {
return name;
}
while ((name = ReadDirName(dptr->dir_hnd, poffset, pst)) != NULL) {
if (is_visible_file(dptr->conn, dptr->path, name, pst, True)) {
return name;
}
char *pathreal = NULL;
char *found_name = NULL;
int ret;
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) {
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);
- name_temp = dptr_normal_ReadDirName(dptr, poffset, pst);
- name = talloc_strdup(ctx, name_temp);
+ name = dptr_normal_ReadDirName(dptr, poffset, pst);
+
Don't check for veto or invisible files.
********************************************************************/
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,
connection_struct *conn = dirp->conn;
/* Cheat to allow . and .. to be the first entries returned. */
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) {
(*poffset == DOT_DOT_DIRECTORY_OFFSET)) && (dirp->file_number < 2))
{
if (dirp->file_number == 0) {
+ 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;
*poffset = dirp->offset = START_OF_DIRECTORY_OFFSET;
} else {
*poffset = dirp->offset = DOT_DOT_DIRECTORY_OFFSET;
+ n = talloc_strdup(talloc_tos(), "..");
+ if (n == NULL)
+ return NULL;
}
dirp->file_number++;
return n;
}
dirp->file_number++;
return n;
/* Ignore . and .. - we've already returned them. */
if (*n == '.') {
if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
/* Ignore . and .. - we've already returned them. */
if (*n == '.') {
if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
bool SearchDir(struct smb_Dir *dirp, const char *name, long *poffset)
{
int i;
bool SearchDir(struct smb_Dir *dirp, const char *name, long *poffset)
{
int i;
connection_struct *conn = dirp->conn;
/* Search back in the name cache. */
connection_struct *conn = dirp->conn;
/* Search back in the name cache. */
*poffset = START_OF_DIRECTORY_OFFSET;
while ((entry = ReadDirName(dirp, poffset, NULL))) {
if (conn->case_sensitive ? (strcmp(entry, name) == 0) : strequal(entry, name)) {
*poffset = START_OF_DIRECTORY_OFFSET;
while ((entry = ReadDirName(dirp, poffset, NULL))) {
if (conn->case_sensitive ? (strcmp(entry, name) == 0) : strequal(entry, name)) {
{
NTSTATUS status = NT_STATUS_OK;
long dirpos = 0;
{
NTSTATUS status = NT_STATUS_OK;
long dirpos = 0;
SMB_STRUCT_STAT st;
struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, dirname,
NULL, 0);
SMB_STRUCT_STAT st;
struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, dirname,
NULL, 0);
/* Quick check for "." and ".." */
if (dname[0] == '.') {
if (!dname[1] || (dname[1] == '.' && !dname[2])) {
/* Quick check for "." and ".." */
if (dname[0] == '.') {
if (!dname[1] || (dname[1] == '.' && !dname[2])) {
continue;
}
}
if (!is_visible_file(conn, dirname, dname, &st, True)) {
continue;
}
}
if (!is_visible_file(conn, dirname, dname, &st, True)) {
status = NT_STATUS_DIRECTORY_NOT_EMPTY;
break;
}
status = NT_STATUS_DIRECTORY_NOT_EMPTY;
break;
}
TALLOC_FREE(dir_hnd);
return status;
TALLOC_FREE(dir_hnd);
return status;
TALLOC_CTX *mem_ctx, char **found_name)
{
struct smb_Dir *cur_dir;
TALLOC_CTX *mem_ctx, char **found_name)
{
struct smb_Dir *cur_dir;
char *unmangled_name = NULL;
long curpos;
char *unmangled_name = NULL;
long curpos;
/* Is it dot or dot dot. */
if (ISDOT(dname) || ISDOTDOT(dname)) {
/* Is it dot or dot dot. */
if (ISDOT(dname) || ISDOTDOT(dname)) {
TALLOC_FREE(cur_dir);
if (!*found_name) {
errno = ENOMEM;
TALLOC_FREE(cur_dir);
if (!*found_name) {
errno = ENOMEM;
}
TALLOC_FREE(unmangled_name);
}
TALLOC_FREE(unmangled_name);
}
SMB_VFS_CLOSEDIR(conn,dirp);
}
SMB_VFS_CLOSEDIR(conn,dirp);
if (cnt >= jn_remain) {
DEBUG(2, ("form_junctions: ran out of MSDFS "
"junction slots"));
if (cnt >= jn_remain) {
DEBUG(2, ("form_junctions: ran out of MSDFS "
"junction slots"));
goto out;
}
if (is_msdfs_link_internal(ctx,
goto out;
}
if (is_msdfs_link_internal(ctx,
dname);
if (!jucn[cnt].service_name ||
!jucn[cnt].volume_name) {
dname);
if (!jucn[cnt].service_name ||
!jucn[cnt].volume_name) {
goto out;
}
jucn[cnt].comment = "";
goto out;
}
jucn[cnt].comment = "";
}
TALLOC_FREE(link_target);
}
}
TALLOC_FREE(link_target);
}
} else {
struct smb_Dir *dir_hnd = NULL;
long offset = 0;
} else {
struct smb_Dir *dir_hnd = NULL;
long offset = 0;
if ((dirtype & SAMBA_ATTRIBUTES_MASK) == aDIR) {
status = NT_STATUS_OBJECT_NAME_INVALID;
if ((dirtype & SAMBA_ATTRIBUTES_MASK) == aDIR) {
status = NT_STATUS_OBJECT_NAME_INVALID;
if (!is_visible_file(conn, fname_dir, dname,
&smb_fname->st, true)) {
TALLOC_FREE(frame);
if (!is_visible_file(conn, fname_dir, dname,
&smb_fname->st, true)) {
TALLOC_FREE(frame);
continue;
}
/* Quick check for "." and ".." */
if (ISDOT(dname) || ISDOTDOT(dname)) {
TALLOC_FREE(frame);
continue;
}
/* Quick check for "." and ".." */
if (ISDOT(dname) || ISDOTDOT(dname)) {
TALLOC_FREE(frame);
continue;
}
if(!mask_match(dname, fname_mask,
conn->case_sensitive)) {
TALLOC_FREE(frame);
continue;
}
if(!mask_match(dname, fname_mask,
conn->case_sensitive)) {
TALLOC_FREE(frame);
TALLOC_FREE(dir_hnd);
status = NT_STATUS_NO_MEMORY;
TALLOC_FREE(frame);
TALLOC_FREE(dir_hnd);
status = NT_STATUS_NO_MEMORY;
TALLOC_FREE(frame);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(dir_hnd);
TALLOC_FREE(frame);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(dir_hnd);
TALLOC_FREE(frame);
goto out;
}
status = do_unlink(conn, req, smb_fname, dirtype);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(frame);
goto out;
}
status = do_unlink(conn, req, smb_fname, dirtype);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(frame);
smb_fname->base_name));
TALLOC_FREE(frame);
smb_fname->base_name));
TALLOC_FREE(frame);
}
TALLOC_FREE(dir_hnd);
}
}
TALLOC_FREE(dir_hnd);
}
connection_struct *conn,
struct smb_filename *smb_dname)
{
connection_struct *conn,
struct smb_filename *smb_dname)
{
- const char *dname = NULL;
bool ret = True;
long offset = 0;
SMB_STRUCT_STAT st;
bool ret = True;
long offset = 0;
SMB_STRUCT_STAT st;
NTSTATUS status;
if (ISDOT(dname) || ISDOTDOT(dname)) {
NTSTATUS status;
if (ISDOT(dname) || ISDOTDOT(dname)) {
continue;
}
if (!is_visible_file(conn, smb_dname->base_name, dname, &st,
false)) {
continue;
}
if (!is_visible_file(conn, smb_dname->base_name, dname, &st,
false)) {
err_break:
TALLOC_FREE(smb_dname_full);
TALLOC_FREE(fullname);
err_break:
TALLOC_FREE(smb_dname_full);
TALLOC_FREE(fullname);
if (do_break) {
ret = false;
break;
if (do_break) {
ret = false;
break;
* retry. If we fail to delete any of them (and we *don't*
* do a recursive delete) then fail the rmdir.
*/
* retry. If we fail to delete any of them (and we *don't*
* do a recursive delete) then fail the rmdir.
*/
long dirpos = 0;
struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
smb_dname->base_name, NULL,
long dirpos = 0;
struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
smb_dname->base_name, NULL,
}
while ((dname = ReadDirName(dir_hnd, &dirpos, &st))) {
}
while ((dname = ReadDirName(dir_hnd, &dirpos, &st))) {
- if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
+ if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
+ TALLOC_FREE(dname);
if (!is_visible_file(conn, smb_dname->base_name, dname,
if (!is_visible_file(conn, smb_dname->base_name, dname,
+ &st, false)) {
+ TALLOC_FREE(dname);
if(!IS_VETO_PATH(conn, dname)) {
TALLOC_FREE(dir_hnd);
if(!IS_VETO_PATH(conn, dname)) {
TALLOC_FREE(dir_hnd);
errno = ENOTEMPTY;
goto err;
}
errno = ENOTEMPTY;
goto err;
}
}
/* We only have veto files/directories.
}
/* We only have veto files/directories.
NTSTATUS status;
if (ISDOT(dname) || ISDOTDOT(dname)) {
NTSTATUS status;
if (ISDOT(dname) || ISDOTDOT(dname)) {
continue;
}
if (!is_visible_file(conn, smb_dname->base_name, dname,
&st, false)) {
continue;
}
if (!is_visible_file(conn, smb_dname->base_name, dname,
&st, false)) {
err_break:
TALLOC_FREE(fullname);
TALLOC_FREE(smb_dname_full);
err_break:
TALLOC_FREE(fullname);
TALLOC_FREE(smb_dname_full);
int count=0;
NTSTATUS status = NT_STATUS_OK;
struct smb_Dir *dir_hnd = NULL;
int count=0;
NTSTATUS status = NT_STATUS_OK;
struct smb_Dir *dir_hnd = NULL;
long offset = 0;
int create_options = 0;
bool posix_pathnames = lp_posix_pathnames();
long offset = 0;
int create_options = 0;
bool posix_pathnames = lp_posix_pathnames();
if (attrs & aDIR) {
sysdir_entry = True;
} else {
if (attrs & aDIR) {
sysdir_entry = True;
} else {
continue;
}
}
if (!is_visible_file(conn, fname_src_dir, dname,
&smb_fname_src->st, false)) {
continue;
}
}
if (!is_visible_file(conn, fname_src_dir, dname,
&smb_fname_src->st, false)) {
continue;
}
if(!mask_match(dname, fname_src_mask, conn->case_sensitive)) {
continue;
}
if(!mask_match(dname, fname_src_mask, conn->case_sensitive)) {
&destname)) {
DEBUG(6, ("resolve_wildcards %s %s failed\n",
smb_fname_src->base_name, destname));
&destname)) {
DEBUG(6, ("resolve_wildcards %s %s failed\n",
smb_fname_src->base_name, destname));
continue;
}
if (!destname) {
continue;
}
if (!destname) {
DEBUG(3,("rename_internals: doing rename on %s -> "
"%s\n", smb_fname_str_dbg(smb_fname_src),
smb_fname_str_dbg(smb_fname_src)));
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(fname_src_dir);
TALLOC_FREE(fname_src_mask);
return status;
TALLOC_FREE(fname_src_dir);
TALLOC_FREE(fname_src_mask);
return status;
}
} else {
struct smb_Dir *dir_hnd = NULL;
}
} else {
struct smb_Dir *dir_hnd = NULL;
- const char *dname = NULL;
char *destname = NULL;
if (ISDOT(dname) || ISDOTDOT(dname)) {
char *destname = NULL;
if (ISDOT(dname) || ISDOTDOT(dname)) {
continue;
}
if (!is_visible_file(conn, fname_src_dir, dname,
&smb_fname_src->st, false)) {
continue;
}
if (!is_visible_file(conn, fname_src_dir, dname,
&smb_fname_src->st, false)) {
continue;
}
if(!mask_match(dname, fname_src_mask,
conn->case_sensitive)) {
continue;
}
if(!mask_match(dname, fname_src_mask,
conn->case_sensitive)) {
if (!smb_fname_src->base_name) {
TALLOC_FREE(dir_hnd);
if (!smb_fname_src->base_name) {
TALLOC_FREE(dir_hnd);
reply_nterror(req, NT_STATUS_NO_MEMORY);
goto out;
}
reply_nterror(req, NT_STATUS_NO_MEMORY);
goto out;
}
if (!resolve_wildcards(ctx, smb_fname_src->base_name,
smb_fname_dst->base_name,
&destname)) {
if (!resolve_wildcards(ctx, smb_fname_src->base_name,
smb_fname_dst->base_name,
&destname)) {
continue;
}
if (!destname) {
TALLOC_FREE(dir_hnd);
continue;
}
if (!destname) {
TALLOC_FREE(dir_hnd);
reply_nterror(req, NT_STATUS_NO_MEMORY);
goto out;
}
reply_nterror(req, NT_STATUS_NO_MEMORY);
goto out;
}
status = check_name(conn, smb_fname_src->base_name);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(dir_hnd);
status = check_name(conn, smb_fname_src->base_name);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(dir_hnd);
reply_nterror(req, status);
goto out;
}
reply_nterror(req, status);
goto out;
}
status = check_name(conn, smb_fname_dst->base_name);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(dir_hnd);
status = check_name(conn, smb_fname_dst->base_name);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(dir_hnd);
reply_nterror(req, status);
goto out;
}
reply_nterror(req, status);
goto out;
}
if (NT_STATUS_IS_OK(status)) {
count++;
}
if (NT_STATUS_IS_OK(status)) {
count++;
}
}
TALLOC_FREE(dir_hnd);
}
}
TALLOC_FREE(dir_hnd);
}
char *vfs_readdirname(connection_struct *conn, void *p, SMB_STRUCT_STAT *sbuf)
{
SMB_STRUCT_DIRENT *ptr= NULL;
char *vfs_readdirname(connection_struct *conn, void *p, SMB_STRUCT_STAT *sbuf)
{
SMB_STRUCT_DIRENT *ptr= NULL;
+ char *dname = NULL;
+ NTSTATUS result;
+ 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)
#ifdef NEXT2
if (telldir(p) < 0)
handle->fns->strict_unlock(handle, fsp, plock);
}
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,
NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
struct files_struct *fsp,
uint32 security_info,