]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Fix previous_slash()
authorVolker Lendecke <vl@samba.org>
Tue, 24 Oct 2023 11:18:32 +0000 (13:18 +0200)
committerJeremy Allison <jra@samba.org>
Wed, 1 Nov 2023 18:55:32 +0000 (18:55 +0000)
Untested code is broken code... previous_slash() did not return a
pointer to the slash but after it. This went undetected because so far
we never call symlink_target_path() with "unparsed==0". Once we
started doing that, we would find that the "unparsed==0" case actually
puts parent on the "previous slash", not the character behind it.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/smbd/filename.c

index 3c54ab1776297b41f09387c8f4375c9c4e49d9b2..29e3d9d19cfc213cf21d2cee449066f30ff6a7ac 100644 (file)
@@ -879,26 +879,27 @@ lookup:
 
 static const char *previous_slash(const char *name_in, const char *slash)
 {
-       const char *prev = name_in;
+       const char *prev = NULL;
 
-       while (true) {
-               const char *next = strchr_m(prev, '/');
+       SMB_ASSERT((name_in <= slash) && (slash[0] == '/'));
 
-               SMB_ASSERT(next != NULL); /* we have at least one slash */
+       prev = strchr_m(name_in, '/');
 
-               if (next == slash) {
-                       break;
-               }
+       if (prev == slash) {
+               /* No previous slash */
+               return NULL;
+       }
 
-               prev = next+1;
-       };
+       while (true) {
+               const char *next = strchr_m(prev + 1, '/');
 
-       if (prev == name_in) {
-               /* no previous slash */
-               return NULL;
+               if (next == slash) {
+                       return prev;
+               }
+               prev = next;
        }
 
-       return prev;
+       return NULL; /* unreachable */
 }
 
 static char *symlink_target_path(
@@ -928,17 +929,16 @@ static char *symlink_target_path(
        }
 
        if (parent == NULL) {
-               /* no previous slash */
-               parent = name_in;
+               ret = talloc_asprintf(mem_ctx, "%s%s", substitute, p_unparsed);
+       } else {
+               ret = talloc_asprintf(mem_ctx,
+                                     "%.*s/%s%s",
+                                     (int)(parent - name_in),
+                                     name_in,
+                                     substitute,
+                                     p_unparsed);
        }
 
-       ret = talloc_asprintf(
-               mem_ctx,
-               "%.*s%s%s",
-               (int)(parent - name_in),
-               name_in,
-               substitute,
-               p_unparsed);
        return ret;
 }