1/* 2 Unix SMB/CIFS implementation. 3 4 test suite for SMB2 write operations 5 6 Copyright (C) Andrew Tridgell 2006 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20*/ 21 22#include "includes.h" 23#include "librpc/gen_ndr/security.h" 24#include "libcli/smb2/smb2.h" 25#include "libcli/smb2/smb2_calls.h" 26#include "torture/torture.h" 27#include "torture/smb2/proto.h" 28 29#define FNAME "testmaxwrite.dat" 30 31/* 32 test writing 33*/ 34static NTSTATUS torture_smb2_write(struct torture_context *tctx, 35 struct smb2_tree *tree, 36 struct smb2_handle handle) 37{ 38 struct smb2_write w; 39 struct smb2_read r; 40 NTSTATUS status; 41 int i, len; 42 int max = 80000000; 43 int min = 1; 44 45 while (max > min) { 46 TALLOC_CTX *tmp_ctx = talloc_new(tctx); 47 48 49 len = 1+(min+max)/2; 50 51 ZERO_STRUCT(w); 52 w.in.file.handle = handle; 53 w.in.offset = 0; 54 w.in.data = data_blob_talloc(tmp_ctx, NULL, len); 55 56 for (i=0;i<len;i++) { 57 w.in.data.data[i] = i % 256; 58 } 59 60 printf("trying to write %d bytes (min=%d max=%d)\n", 61 len, min, max); 62 63 status = smb2_write(tree, &w); 64 if (!NT_STATUS_IS_OK(status)) { 65 printf("write failed - %s\n", nt_errstr(status)); 66 max = len-1; 67 status = smb2_util_close(tree, handle); 68 if (!NT_STATUS_IS_OK(status)) { 69 /* vista bug */ 70 printf("coping with server disconnect\n"); 71 talloc_free(tree); 72 if (!torture_smb2_connection(torture, &tree)) { 73 printf("failed to reconnect\n"); 74 return NT_STATUS_NET_WRITE_FAULT; 75 } 76 } 77 handle = torture_smb2_create(tree, FNAME); 78 continue; 79 } else { 80 min = len; 81 } 82 83 84 ZERO_STRUCT(r); 85 r.in.file.handle = handle; 86 r.in.length = len; 87 r.in.offset = 0; 88 89 printf("reading %d bytes\n", len); 90 91 status = smb2_read(tree, tmp_ctx, &r); 92 if (!NT_STATUS_IS_OK(status)) { 93 printf("read failed - %s\n", nt_errstr(status)); 94 } else if (w.in.data.length != r.out.data.length || 95 memcmp(w.in.data.data, r.out.data.data, len) != 0) { 96 printf("read data mismatch\n"); 97 } 98 99 talloc_free(tmp_ctx); 100 } 101 102 printf("converged: len=%d\n", max); 103 smb2_util_close(tree, handle); 104 smb2_util_unlink(tree, FNAME); 105 106 return NT_STATUS_OK; 107} 108 109 110 111/* 112 basic testing of SMB2 connection calls 113*/ 114bool torture_smb2_maxwrite(struct torture_context *torture) 115{ 116 struct smb2_tree *tree; 117 struct smb2_handle h1; 118 NTSTATUS status; 119 120 if (!torture_smb2_connection(torture, &tree)) { 121 return false; 122 } 123 124 h1 = torture_smb2_create(tree, FNAME); 125 status = torture_smb2_write(torture, tree, h1); 126 if (!NT_STATUS_IS_OK(status)) { 127 printf("Write failed - %s\n", nt_errstr(status)); 128 return false; 129 } 130 131 return true; 132} 133