]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: smbd: Add utility function get_original_lcomp().
authorJeremy Allison <jra@samba.org>
Wed, 25 Mar 2020 17:00:57 +0000 (10:00 -0700)
committerRalph Boehme <slow@samba.org>
Mon, 30 Mar 2020 14:45:30 +0000 (14:45 +0000)
Gets the last component from a client passed-in
filename. Copes with @GMT snapshot and MS-DFS names.

Preparing to remove original_lcomp from
struct smb_filename.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/smbd/filename.c
source3/smbd/proto.h

index cb1f5d7ea3fc660f9024cc5c8a5fe93467cff49b..d967366a089f83dad9f212c05fb7d7bf604086e8 100644 (file)
@@ -1692,6 +1692,90 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
        return status;
 }
 
+/*
+ * Lightweight function to just get last component
+ * for rename / enumerate directory calls.
+ */
+
+char *get_original_lcomp(TALLOC_CTX *ctx,
+                       connection_struct *conn,
+                       const char *filename_in,
+                       uint32_t ucf_flags)
+{
+       struct smb_filename *smb_fname = NULL;
+       char *last_slash = NULL;
+       char *orig_lcomp;
+       char *fname = NULL;
+       NTSTATUS status;
+
+       if (ucf_flags & UCF_DFS_PATHNAME) {
+               status = resolve_dfspath_wcard(ctx,
+                               conn,
+                               filename_in,
+                               ucf_flags,
+                               !conn->sconn->using_smb2,
+                               &fname,
+                               NULL);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DBG_DEBUG("resolve_dfspath "
+                               "failed for name %s with %s\n",
+                               filename_in,
+                               nt_errstr(status));
+                       return NULL;
+               }
+               filename_in = fname;
+               ucf_flags &= ~UCF_DFS_PATHNAME;
+       }
+
+       /*
+        * NB. We don't need to care about
+        * is_fake_file_path(filename_in) here as these
+        * code paths don't ever return original_lcomp
+        * or use it anyway.
+        */
+
+       if (ucf_flags & UCF_GMT_PATHNAME) {
+               /*
+                * Ensure we don't return a @GMT
+                * value as the last component.
+                */
+               smb_fname = synthetic_smb_fname(ctx,
+                                       filename_in,
+                                       NULL,
+                                       NULL,
+                                       0);
+               if (smb_fname == NULL) {
+                       TALLOC_FREE(fname);
+                       return NULL;
+               }
+               status = canonicalize_snapshot_path(smb_fname);
+               if (!NT_STATUS_IS_OK(status)) {
+                       TALLOC_FREE(fname);
+                       TALLOC_FREE(smb_fname);
+                       return NULL;
+               }
+               filename_in = smb_fname->base_name;
+       }
+       last_slash = strrchr(filename_in, '/');
+       if (last_slash != NULL) {
+               orig_lcomp = talloc_strdup(ctx, last_slash+1);
+       } else {
+               orig_lcomp = talloc_strdup(ctx, filename_in);
+       }
+       /* We're done with any temp names here. */
+       TALLOC_FREE(smb_fname);
+       TALLOC_FREE(fname);
+       if (orig_lcomp == NULL) {
+               return NULL;
+       }
+       status = normalize_filename_case(conn, orig_lcomp);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(orig_lcomp);
+               return NULL;
+       }
+       return orig_lcomp;
+}
+
 /**
  * Go through all the steps to validate a filename.
  *
index c79e82fb69d6780688806415de5e90d234da1d7e..12d0753ae5ffbfbb97892e9a77c1fc473ff0e567 100644 (file)
@@ -357,6 +357,10 @@ NTSTATUS check_name(connection_struct *conn,
 int get_real_filename(connection_struct *conn, const char *path,
                      const char *name, TALLOC_CTX *mem_ctx,
                      char **found_name);
+char *get_original_lcomp(TALLOC_CTX *ctx,
+                       connection_struct *conn,
+                       const char *filename_in,
+                       uint32_t ucf_flags);
 NTSTATUS filename_convert(TALLOC_CTX *mem_ctx,
                        connection_struct *conn,
                        const char *name_in,