s3: smbd: SMB2 - change smbd_dirptr_lanman2_entry() to return an NTSTATUS.
authorJeremy Allison <jra@samba.org>
Tue, 26 Aug 2014 21:49:37 +0000 (14:49 -0700)
committerDavid Disseldorp <ddiss@samba.org>
Mon, 15 Sep 2014 23:56:55 +0000 (01:56 +0200)
Handle the errors correctly at the top level inside the SMB2 server.

Bug 10775 - smbd crashes when accessing garbage filenames

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

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: David Disseldorp <ddiss@samba.org>
source3/smbd/globals.h
source3/smbd/smb2_find.c
source3/smbd/trans2.c

index f78ce45827680998db91f2ad595669d242c9ee08..20ab75d446d844a7a214722bdf04634d6bd40807 100644 (file)
@@ -185,7 +185,7 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
                           uint32_t *_mode,
                           long *_prev_offset);
 
-bool smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
+NTSTATUS smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
                               connection_struct *conn,
                               struct dptr_struct *dirptr,
                               uint16 flags2,
index 45b0890c10c8b5654cb8afaa9c0c73e7dfd44419..af9995e4239a0c560fab8627b4cdecad1a476140 100644 (file)
@@ -432,14 +432,13 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
                                     true);
 
        while (true) {
-               bool ok;
                bool got_exact_match = false;
                bool out_of_space = false;
                int space_remaining = in_output_buffer_length - off;
 
                SMB_ASSERT(space_remaining >= 0);
 
-               ok = smbd_dirptr_lanman2_entry(state,
+               status = smbd_dirptr_lanman2_entry(state,
                                               conn,
                                               fsp->dptr,
                                               smbreq->flags2,
@@ -462,12 +461,18 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
 
                off = (int)PTR_DIFF(pdata, base_data);
 
-               if (!ok) {
-                       if (num > 0) {
+               if (!NT_STATUS_IS_OK(status)) {
+                       if (NT_STATUS_EQUAL(status, NT_STATUS_ILLEGAL_CHARACTER)) {
+                               /*
+                                * Bad character conversion on name. Ignore this
+                                * entry.
+                                */
+                               continue;
+                       } else if (num > 0) {
                                SIVAL(state->out_output_buffer.data, last_entry_off, 0);
                                tevent_req_done(req);
                                return tevent_req_post(req, ev);
-                       } else if (out_of_space) {
+                       } else if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
                                tevent_req_nterror(req, NT_STATUS_INFO_LENGTH_MISMATCH);
                                return tevent_req_post(req, ev);
                        } else {
index b950820671b5f416ab984fe6530533b72383d2c9..2d6c261f189b44d380a8f8f8464cb9b21e30dd19 100644 (file)
@@ -2212,7 +2212,7 @@ static NTSTATUS smbd_marshall_dir_entry(TALLOC_CTX *ctx,
        return NT_STATUS_OK;
 }
 
-bool smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
+NTSTATUS smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
                               connection_struct *conn,
                               struct dptr_struct *dirptr,
                               uint16 flags2,
@@ -2279,7 +2279,7 @@ bool smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
                                   &mode,
                                   &prev_dirpos);
        if (!ok) {
-               return false;
+               return NT_STATUS_END_OF_FILE;
        }
 
        *got_exact_match = state.got_exact_match;
@@ -2306,14 +2306,14 @@ bool smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
        if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
                *out_of_space = true;
                dptr_SeekDir(dirptr, prev_dirpos);
-               return false;
+               return status;
        }
        if (!NT_STATUS_IS_OK(status)) {
-               return false;
+               return status;
        }
 
        *_last_entry_off = last_entry_off;
-       return true;
+       return NT_STATUS_OK;
 }
 
 static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
@@ -2337,13 +2337,14 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
 {
        uint8_t align = 4;
        const bool do_pad = true;
+       NTSTATUS status;
 
        if (info_level >= 1 && info_level <= 3) {
                /* No alignment on earlier info levels. */
                align = 1;
        }
 
-       return smbd_dirptr_lanman2_entry(ctx, conn, dirptr, flags2,
+       status = smbd_dirptr_lanman2_entry(ctx, conn, dirptr, flags2,
                                         path_mask, dirtype, info_level,
                                         requires_resume_key, dont_descend, ask_sharemode,
                                         align, do_pad,
@@ -2351,6 +2352,7 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
                                         space_remaining,
                                         out_of_space, got_exact_match,
                                         last_entry_off, name_list);
+       return NT_STATUS_IS_OK(status);
 }
 
 /****************************************************************************