From 06674319f82e5ee26a71ff16018b27f64fdf98f0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 20 Aug 2018 16:51:18 -0700 Subject: [PATCH] s3: smbd: Ensure check_parent_exists() returns valid paths for non-optimization return. Needed for vfs_glusterfs, as Gluster requires ".". Based on a fix from Anoop C S BUG: https://bugzilla.samba.org/show_bug.cgi?id=13585 Signed-off-by: Jeremy Allison --- source3/smbd/filename.c | 54 ++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 9e15af1916d..3f73b6713df 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -164,13 +164,11 @@ static NTSTATUS check_parent_exists(TALLOC_CTX *ctx, char **pp_dirpath, char **pp_start) { - struct smb_filename parent_fname; + struct smb_filename parent_fname = { 0 }; const char *last_component = NULL; NTSTATUS status; int ret; - bool parent_fname_has_wild = false; - ZERO_STRUCT(parent_fname); if (!parent_dirname(ctx, smb_fname->base_name, &parent_fname.base_name, &last_component)) { @@ -178,18 +176,18 @@ static NTSTATUS check_parent_exists(TALLOC_CTX *ctx, } if (!posix_pathnames) { - parent_fname_has_wild = ms_has_wild(parent_fname.base_name); + if (ms_has_wild(parent_fname.base_name)) { + goto no_optimization_out; + } } /* * If there was no parent component in - * smb_fname->base_name of the parent name - * contained a wildcard then don't do this + * smb_fname->base_name then don't do this * optimization. */ - if ((smb_fname->base_name == last_component) || - parent_fname_has_wild) { - return NT_STATUS_OK; + if (smb_fname->base_name == last_component) { + goto no_optimization_out; } if (posix_pathnames) { @@ -202,7 +200,7 @@ static NTSTATUS check_parent_exists(TALLOC_CTX *ctx, with the normal tree walk. */ if (ret == -1) { - return NT_STATUS_OK; + goto no_optimization_out; } status = check_for_dot_component(&parent_fname); @@ -235,6 +233,28 @@ static NTSTATUS check_parent_exists(TALLOC_CTX *ctx, *pp_start)); return NT_STATUS_OK; + + no_optimization_out: + + /* + * We must still return an *pp_dirpath + * initialized to ".", and a *pp_start + * pointing at smb_fname->base_name. + */ + + TALLOC_FREE(parent_fname.base_name); + + *pp_dirpath = talloc_strdup(ctx, "."); + if (*pp_dirpath == NULL) { + return NT_STATUS_NO_MEMORY; + } + /* + * Safe to use discard_const_p + * here as by convention smb_fname->base_name + * is allocated off ctx. + */ + *pp_start = discard_const_p(char, smb_fname->base_name); + return NT_STATUS_OK; } /* @@ -599,7 +619,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, goto err; } /* dirpath must exist. */ - dirpath = talloc_strdup(ctx,""); + dirpath = talloc_strdup(ctx,"."); if (dirpath == NULL) { status = NT_STATUS_NO_MEMORY; goto err; @@ -636,7 +656,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, * building the directories with talloc_asprintf and free it. */ - if ((dirpath == NULL) && (!(dirpath = talloc_strdup(ctx,"")))) { + if ((dirpath == NULL) && (!(dirpath = talloc_strdup(ctx,".")))) { DEBUG(0, ("talloc_strdup failed\n")); status = NT_STATUS_NO_MEMORY; goto err; @@ -1036,7 +1056,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, size_t start_ofs = start - smb_fname->base_name; - if (*dirpath != '\0') { + if (!ISDOT(dirpath)) { tmp = talloc_asprintf( smb_fname, "%s/%s", dirpath, unmangled); @@ -1071,7 +1091,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, size_t start_ofs = start - smb_fname->base_name; - if (*dirpath != '\0') { + if (!ISDOT(dirpath)) { tmp = talloc_asprintf(smb_fname, "%s/%s/%s", dirpath, found_name, end+1); @@ -1096,7 +1116,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, size_t start_ofs = start - smb_fname->base_name; - if (*dirpath != '\0') { + if (!ISDOT(dirpath)) { tmp = talloc_asprintf(smb_fname, "%s/%s", dirpath, found_name); @@ -1137,7 +1157,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, * Add to the dirpath that we have resolved so far. */ - if (*dirpath != '\0') { + if (!ISDOT(dirpath)) { char *tmp = talloc_asprintf(ctx, "%s/%s", dirpath, start); if (!tmp) { @@ -1207,7 +1227,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, return NT_STATUS_OK; fail: DEBUG(10, ("dirpath = [%s] start = [%s]\n", dirpath, start)); - if (dirpath && *dirpath != '\0') { + if (dirpath && !ISDOT(dirpath)) { smb_fname->base_name = talloc_asprintf(smb_fname, "%s/%s", dirpath, start); } else { -- 2.18.0.865.gffc8e1a3cd6-goog