]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Simplify canonicalize_snapshot_path()
authorVolker Lendecke <vl@samba.org>
Tue, 12 Jul 2022 15:08:19 +0000 (17:08 +0200)
committerRalph Boehme <slow@samba.org>
Mon, 25 Jul 2022 12:04:33 +0000 (12:04 +0000)
All we need to do is to convert the @GMT-Token and move the
rest. Before this patch we did a lot of talloc to move the @GMT token
to the beginning of the path only to cut it off immediately
again. Merge that logic into a simple memmove()

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/smbd/filename.c

index bcbd44680275284d4f846ff64062c05af1e8ff4d..58fec6f9113b0eac286f04492d9255f691614eb9 100644 (file)
@@ -247,83 +247,57 @@ static NTSTATUS check_parent_exists(TALLOC_CTX *ctx,
        return NT_STATUS_OK;
 }
 
-/*
- * Re-order a known good @GMT-token path.
- */
-
-static NTSTATUS rearrange_snapshot_path(struct smb_filename *smb_fname,
-                               char *startp,
-                               char *endp)
+static bool find_snapshot_token(
+       const char *filename,
+       const char **_start,
+       const char **_next_component,
+       NTTIME *twrp)
 {
-       size_t endlen = 0;
-       size_t gmt_len = endp - startp;
-       char gmt_store[gmt_len + 1];
-       char *parent = NULL;
-       const char *last_component = NULL;
-       char *newstr;
-       bool ret;
+       const char *start = NULL;
+       const char *end = NULL;
+       struct tm tm;
+       time_t t;
 
-       DBG_DEBUG("|%s| -> ", smb_fname->base_name);
+       start = strstr_m(filename, "@GMT-");
 
-       /* Save off the @GMT-token. */
-       memcpy(gmt_store, startp, gmt_len);
-       gmt_store[gmt_len] = '\0';
+       if (start == NULL) {
+               return false;
+       }
 
-       if (*endp == '/') {
-               /* Remove any trailing '/' */
-               endp++;
+       if ((start > filename) && (start[-1] != '/')) {
+               /* the GMT-token does not start a path-component */
+               return false;
        }
 
-       if (*endp == '\0') {
+       end = strptime(start, GMT_FORMAT, &tm);
+       if (end == NULL) {
+               /* Not a valid timestring. */
+               return false;
+       }
+
+       if ((end[0] != '\0') && (end[0] != '/')) {
                /*
-                * @GMT-token was at end of path.
-                * Remove any preceding '/'
+                * It is not a complete path component, i.e. the path
+                * component continues after the gmt-token.
                 */
-               if (startp > smb_fname->base_name && startp[-1] == '/') {
-                       startp--;
-               }
+               return false;
        }
 
-       /* Remove @GMT-token from the path. */
-       endlen = strlen(endp);
-       memmove(startp, endp, endlen + 1);
+       tm.tm_isdst = -1;
+       t = timegm(&tm);
+       unix_to_nt_time(twrp, t);
 
-       /* Split the remaining path into components. */
-       ret = parent_dirname(smb_fname,
-                               smb_fname->base_name,
-                               &parent,
-                               &last_component);
-       if (!ret) {
-               /* Must terminate debug with \n */
-               DBG_DEBUG("NT_STATUS_NO_MEMORY\n");
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if (ISDOT(parent)) {
-               if (last_component[0] == '\0') {
-                       newstr = talloc_strdup(smb_fname,
-                                       gmt_store);
-               } else {
-                       newstr = talloc_asprintf(smb_fname,
-                                       "%s/%s",
-                                       gmt_store,
-                                       last_component);
-               }
-       } else {
-               newstr = talloc_asprintf(smb_fname,
-                                       "%s/%s/%s",
-                                       gmt_store,
-                                       parent,
-                                       last_component);
-       }
+       DBG_DEBUG("Extracted @GMT-Timestamp %s\n",
+                 nt_time_string(talloc_tos(), *twrp));
 
-       TALLOC_FREE(parent);
-       TALLOC_FREE(smb_fname->base_name);
-       smb_fname->base_name = newstr;
+       *_start = start;
 
-       DBG_DEBUG("|%s|\n", newstr);
+       if (end[0] == '/') {
+               end += 1;
+       }
+       *_next_component = end;
 
-       return NT_STATUS_OK;
+       return true;
 }
 
 /*
@@ -344,13 +318,10 @@ NTSTATUS canonicalize_snapshot_path(struct smb_filename *smb_fname,
                                    uint32_t ucf_flags,
                                    NTTIME twrp)
 {
-       char *startp = NULL;
-       char *endp = NULL;
-       char *tmp = NULL;
-       struct tm tm;
-       time_t t;
-       NTTIME nt;
-       NTSTATUS status;
+       const char *start = NULL;
+       const char *next = NULL;
+       size_t remaining;
+       bool found;
 
        if (twrp != 0) {
                smb_fname->twrp = twrp;
@@ -360,60 +331,18 @@ NTSTATUS canonicalize_snapshot_path(struct smb_filename *smb_fname,
                return NT_STATUS_OK;
        }
 
-       startp = strchr_m(smb_fname->base_name, '@');
-       if (startp == NULL) {
-               /* No @ */
+       found = find_snapshot_token(
+               smb_fname->base_name, &start, &next, &twrp);
+       if (!found) {
                return NT_STATUS_OK;
        }
 
-       startp = strstr_m(startp, "@GMT-");
-       if (startp == NULL) {
-               /* No @ */
-               return NT_STATUS_OK;
-       }
+       remaining = strlen(next);
 
-       if ((startp > smb_fname->base_name) && (startp[-1] != '/')) {
-               /* the GMT-token does not start a path-component */
-               return NT_STATUS_OK;
-       }
-
-       endp = strptime(startp, GMT_FORMAT, &tm);
-       if (endp == NULL) {
-               /* Not a valid timestring. */
-               return NT_STATUS_OK;
-       }
-
-       if (endp[0] != '\0' && endp[0] != '/') {
-               /*
-                * It is not a complete path component, i.e. the path
-                * component continues after the gmt-token.
-                */
-               return NT_STATUS_OK;
-       }
-
-       status = rearrange_snapshot_path(smb_fname, startp, endp);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       startp = smb_fname->base_name + GMT_NAME_LEN;
-       if (startp[0] == '/') {
-               startp++;
-       }
-
-       tmp = talloc_strdup(smb_fname, startp);
-       if (tmp == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       TALLOC_FREE(smb_fname->base_name);
-       smb_fname->base_name = tmp;
+       memmove(discard_const_p(char, start), next, remaining+1);
 
        if (smb_fname->twrp == 0) {
-               tm.tm_isdst = -1;
-               t = timegm(&tm);
-               unix_to_nt_time(&nt, t);
-               smb_fname->twrp = nt;
+               smb_fname->twrp = twrp;
        }
 
        return NT_STATUS_OK;