s3: smbd: Fix "follow symlink = no" regression part 2.
authorJeremy Allison <jra@samba.org>
Tue, 28 Mar 2017 00:09:38 +0000 (17:09 -0700)
committerRalph Boehme <slow@samba.org>
Tue, 28 Mar 2017 11:20:26 +0000 (13:20 +0200)
Use the cwd_name parameter to reconstruct the original
client name for symlink testing.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721

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

index 95a8fc1ba62ff534af7cbf2eb4c71e7b974d39a0..b7364b7c7bd81ad9b7384bd493bed759a91ed7be 100644 (file)
@@ -1192,6 +1192,7 @@ NTSTATUS check_reduced_name(connection_struct *conn,
                                const char *fname)
 {
        char *resolved_name = NULL;
+       char *new_fname = NULL;
        bool allow_symlinks = true;
        bool allow_widelinks = false;
 
@@ -1333,11 +1334,32 @@ NTSTATUS check_reduced_name(connection_struct *conn,
                        }
 
                        p++;
+
+                       /*
+                        * If cwd_name is present and not ".",
+                        * then fname is relative to that, not
+                        * the root of the share. Make sure the
+                        * path we check is the one the client
+                        * sent (cwd_name+fname).
+                        */
+                       if (cwd_name != NULL && !ISDOT(cwd_name)) {
+                               new_fname = talloc_asprintf(talloc_tos(),
+                                                       "%s/%s",
+                                                       cwd_name,
+                                                       fname);
+                               if (new_fname == NULL) {
+                                       SAFE_FREE(resolved_name);
+                                       return NT_STATUS_NO_MEMORY;
+                               }
+                               fname = new_fname;
+                       }
+
                        if (strcmp(fname, p)!=0) {
                                DEBUG(2, ("check_reduced_name: Bad access "
                                        "attempt: %s is a symlink to %s\n",
                                          fname, p));
                                SAFE_FREE(resolved_name);
+                               TALLOC_FREE(new_fname);
                                return NT_STATUS_ACCESS_DENIED;
                        }
                }
@@ -1347,6 +1369,7 @@ NTSTATUS check_reduced_name(connection_struct *conn,
 
        DBG_INFO("%s reduced to %s\n", fname, resolved_name);
        SAFE_FREE(resolved_name);
+       TALLOC_FREE(new_fname);
        return NT_STATUS_OK;
 }