56 */
57 smb_sdrc_t
58 smb_pre_read(smb_request_t *sr)
59 {
60 smb_rw_param_t *param;
61 uint32_t off_low;
62 uint16_t count;
63 uint16_t remcnt;
64 int rc;
65
66 param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
67 sr->arg.rw = param;
68
69 rc = smbsr_decode_vwv(sr, "wwlw", &sr->smb_fid,
70 &count, &off_low, &remcnt);
71
72 param->rw_offset = (uint64_t)off_low;
73 param->rw_count = (uint32_t)count;
74 param->rw_mincnt = 0;
75
76 DTRACE_SMB_2(op__Read__start, smb_request_t *, sr,
77 smb_rw_param_t *, param);
78
79 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
80 }
81
82 void
83 smb_post_read(smb_request_t *sr)
84 {
85 DTRACE_SMB_2(op__Read__done, smb_request_t *, sr,
86 smb_rw_param_t *, sr->arg.rw);
87
88 kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
89 }
90
91 smb_sdrc_t
92 smb_com_read(smb_request_t *sr)
93 {
94 smb_rw_param_t *param = sr->arg.rw;
95 uint16_t count;
96 int rc;
97
98 smbsr_lookup_file(sr);
99 if (sr->fid_ofile == NULL) {
100 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
101 return (SDRC_ERROR);
102 }
103
104 sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
105
106 if (param->rw_count > SMB_CORE_READ_MAX)
142 */
143 smb_sdrc_t
144 smb_pre_lock_and_read(smb_request_t *sr)
145 {
146 smb_rw_param_t *param;
147 uint32_t off_low;
148 uint16_t count;
149 uint16_t remcnt;
150 int rc;
151
152 param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
153 sr->arg.rw = param;
154
155 rc = smbsr_decode_vwv(sr, "wwlw", &sr->smb_fid,
156 &count, &off_low, &remcnt);
157
158 param->rw_offset = (uint64_t)off_low;
159 param->rw_count = (uint32_t)count;
160 param->rw_mincnt = 0;
161
162 DTRACE_SMB_2(op__LockAndRead__start, smb_request_t *, sr,
163 smb_rw_param_t *, param);
164
165 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
166 }
167
168 void
169 smb_post_lock_and_read(smb_request_t *sr)
170 {
171 DTRACE_SMB_2(op__LockAndRead__done, smb_request_t *, sr,
172 smb_rw_param_t *, sr->arg.rw);
173
174 kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
175 }
176
177 smb_sdrc_t
178 smb_com_lock_and_read(smb_request_t *sr)
179 {
180 smb_rw_param_t *param = sr->arg.rw;
181 DWORD status;
182 uint32_t lk_pid;
183 uint16_t count;
184 int rc;
185
186 if (STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) {
187 smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
188 return (SDRC_ERROR);
189 }
190
191 smbsr_lookup_file(sr);
192 if (sr->fid_ofile == NULL) {
206 smb_lock_range_error(sr, status);
207 return (SDRC_ERROR);
208 }
209
210 if (param->rw_count > SMB_CORE_READ_MAX)
211 param->rw_count = SMB_CORE_READ_MAX;
212
213 if ((rc = smb_common_read(sr, param)) != 0) {
214 smbsr_errno(sr, rc);
215 return (SDRC_ERROR);
216 }
217
218 count = (uint16_t)param->rw_count;
219 rc = smbsr_encode_result(sr, 5, VAR_BCC, "bw8.wbwC",
220 5, count, VAR_BCC, 0x1, count, &sr->raw_data);
221
222 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
223 }
224
225 /*
226 * Read bytes from a file (SMB Core). This request was extended in
227 * LM 0.12 to support 64-bit offsets, indicated by sending a wct of
228 * 12 and including additional offset information.
229 *
230 * MS-SMB 3.3.5.7 update to LM 0.12 4.2.4:
231 * If wct is 12 and CAP_LARGE_READX is set, the count may be larger
232 * than the negotiated buffer size. If maxcnt_high is 0xFF, it must
233 * be ignored. Otherwise, maxcnt_high represents the upper 16 bits
234 * of rw_count.
235 */
236 smb_sdrc_t
237 smb_pre_read_andx(smb_request_t *sr)
238 {
239 smb_rw_param_t *param;
240 uint32_t off_low;
241 uint32_t off_high;
242 uint32_t maxcnt_high;
243 uint16_t maxcnt_low;
244 uint16_t mincnt;
245 uint16_t remcnt;
255
256 param->rw_offset = ((uint64_t)off_high << 32) |
257 (uint64_t)off_low;
258
259 param->rw_count = (uint32_t)maxcnt_low;
260
261 if ((sr->session->capabilities & CAP_LARGE_READX) &&
262 (maxcnt_high < 0xFF))
263 param->rw_count |= maxcnt_high << 16;
264 } else {
265 rc = smbsr_decode_vwv(sr, "b3.wlwwlw", ¶m->rw_andx,
266 &sr->smb_fid, &off_low, &maxcnt_low, &mincnt, &maxcnt_high,
267 &remcnt);
268
269 param->rw_offset = (uint64_t)off_low;
270 param->rw_count = (uint32_t)maxcnt_low;
271 }
272
273 param->rw_mincnt = 0;
274
275 DTRACE_SMB_2(op__ReadX__start, smb_request_t *, sr,
276 smb_rw_param_t *, param);
277
278 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
279 }
280
281 void
282 smb_post_read_andx(smb_request_t *sr)
283 {
284 DTRACE_SMB_2(op__ReadX__done, smb_request_t *, sr,
285 smb_rw_param_t *, sr->arg.rw);
286
287 kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
288 }
289
290 smb_sdrc_t
291 smb_com_read_andx(smb_request_t *sr)
292 {
293 smb_rw_param_t *param = sr->arg.rw;
294 uint16_t datalen_high;
295 uint16_t datalen_low;
296 uint16_t data_offset;
297 uint16_t offset2;
298 int rc;
299
300 smbsr_lookup_file(sr);
301 if (sr->fid_ofile == NULL) {
302 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
303 return (SDRC_ERROR);
304 }
305
|
56 */
57 smb_sdrc_t
58 smb_pre_read(smb_request_t *sr)
59 {
60 smb_rw_param_t *param;
61 uint32_t off_low;
62 uint16_t count;
63 uint16_t remcnt;
64 int rc;
65
66 param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
67 sr->arg.rw = param;
68
69 rc = smbsr_decode_vwv(sr, "wwlw", &sr->smb_fid,
70 &count, &off_low, &remcnt);
71
72 param->rw_offset = (uint64_t)off_low;
73 param->rw_count = (uint32_t)count;
74 param->rw_mincnt = 0;
75
76 DTRACE_SMB_1(op__Read__start, smb_request_t *, sr); /* arg.rw */
77
78 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
79 }
80
81 void
82 smb_post_read(smb_request_t *sr)
83 {
84 DTRACE_SMB_1(op__Read__done, smb_request_t *, sr); /* arg.rw */
85
86 kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
87 }
88
89 smb_sdrc_t
90 smb_com_read(smb_request_t *sr)
91 {
92 smb_rw_param_t *param = sr->arg.rw;
93 uint16_t count;
94 int rc;
95
96 smbsr_lookup_file(sr);
97 if (sr->fid_ofile == NULL) {
98 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
99 return (SDRC_ERROR);
100 }
101
102 sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
103
104 if (param->rw_count > SMB_CORE_READ_MAX)
140 */
141 smb_sdrc_t
142 smb_pre_lock_and_read(smb_request_t *sr)
143 {
144 smb_rw_param_t *param;
145 uint32_t off_low;
146 uint16_t count;
147 uint16_t remcnt;
148 int rc;
149
150 param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
151 sr->arg.rw = param;
152
153 rc = smbsr_decode_vwv(sr, "wwlw", &sr->smb_fid,
154 &count, &off_low, &remcnt);
155
156 param->rw_offset = (uint64_t)off_low;
157 param->rw_count = (uint32_t)count;
158 param->rw_mincnt = 0;
159
160 DTRACE_SMB_1(op__LockAndRead__start, smb_request_t *, sr); /* arg.rw */
161
162 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
163 }
164
165 void
166 smb_post_lock_and_read(smb_request_t *sr)
167 {
168 DTRACE_SMB_1(op__LockAndRead__done, smb_request_t *, sr); /* arg.rw */
169
170 kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
171 }
172
173 smb_sdrc_t
174 smb_com_lock_and_read(smb_request_t *sr)
175 {
176 smb_rw_param_t *param = sr->arg.rw;
177 DWORD status;
178 uint32_t lk_pid;
179 uint16_t count;
180 int rc;
181
182 if (STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) {
183 smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
184 return (SDRC_ERROR);
185 }
186
187 smbsr_lookup_file(sr);
188 if (sr->fid_ofile == NULL) {
202 smb_lock_range_error(sr, status);
203 return (SDRC_ERROR);
204 }
205
206 if (param->rw_count > SMB_CORE_READ_MAX)
207 param->rw_count = SMB_CORE_READ_MAX;
208
209 if ((rc = smb_common_read(sr, param)) != 0) {
210 smbsr_errno(sr, rc);
211 return (SDRC_ERROR);
212 }
213
214 count = (uint16_t)param->rw_count;
215 rc = smbsr_encode_result(sr, 5, VAR_BCC, "bw8.wbwC",
216 5, count, VAR_BCC, 0x1, count, &sr->raw_data);
217
218 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
219 }
220
221 /*
222 * The SMB_COM_READ_RAW protocol was a negotiated option introduced in
223 * SMB Core Plus to maximize performance when reading a large block
224 * of data from a server. It's obsolete and no longer supported.
225 *
226 * We keep a handler for it so the dtrace provider can see if
227 * the client tried to use this command.
228 */
229 smb_sdrc_t
230 smb_pre_read_raw(smb_request_t *sr)
231 {
232 smb_rw_param_t *param;
233 uint32_t off_low;
234 uint32_t off_high;
235 uint32_t timeout;
236 uint16_t count;
237 int rc;
238
239 param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
240 sr->arg.rw = param;
241 if (sr->smb_wct == 8) {
242 rc = smbsr_decode_vwv(sr, "wlwwl2.", &sr->smb_fid,
243 &off_low, &count, ¶m->rw_mincnt, &timeout);
244 if (rc == 0) {
245 param->rw_offset = (uint64_t)off_low;
246 param->rw_count = (uint32_t)count;
247 }
248 } else {
249 rc = smbsr_decode_vwv(sr, "wlwwl2.l", &sr->smb_fid,
250 &off_low, &count, ¶m->rw_mincnt, &timeout, &off_high);
251 if (rc == 0) {
252 param->rw_offset = ((uint64_t)off_high << 32) | off_low;
253 param->rw_count = (uint32_t)count;
254 }
255 }
256 DTRACE_SMB_1(op__ReadRaw__start, smb_request_t *, sr); /* arg.rw */
257 return (SDRC_SUCCESS);
258 }
259
260 void
261 smb_post_read_raw(smb_request_t *sr)
262 {
263 DTRACE_SMB_1(op__ReadRaw__done, smb_request_t *, sr); /* arg.rw */
264
265 kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
266 }
267
268 smb_sdrc_t
269 smb_com_read_raw(smb_request_t *sr)
270 {
271 smbsr_error(sr, NT_STATUS_NOT_SUPPORTED, ERRDOS,
272 ERROR_NOT_SUPPORTED);
273 return (SDRC_ERROR);
274 }
275
276 /*
277 * Read bytes from a file (SMB Core). This request was extended in
278 * LM 0.12 to support 64-bit offsets, indicated by sending a wct of
279 * 12 and including additional offset information.
280 *
281 * MS-SMB 3.3.5.7 update to LM 0.12 4.2.4:
282 * If wct is 12 and CAP_LARGE_READX is set, the count may be larger
283 * than the negotiated buffer size. If maxcnt_high is 0xFF, it must
284 * be ignored. Otherwise, maxcnt_high represents the upper 16 bits
285 * of rw_count.
286 */
287 smb_sdrc_t
288 smb_pre_read_andx(smb_request_t *sr)
289 {
290 smb_rw_param_t *param;
291 uint32_t off_low;
292 uint32_t off_high;
293 uint32_t maxcnt_high;
294 uint16_t maxcnt_low;
295 uint16_t mincnt;
296 uint16_t remcnt;
306
307 param->rw_offset = ((uint64_t)off_high << 32) |
308 (uint64_t)off_low;
309
310 param->rw_count = (uint32_t)maxcnt_low;
311
312 if ((sr->session->capabilities & CAP_LARGE_READX) &&
313 (maxcnt_high < 0xFF))
314 param->rw_count |= maxcnt_high << 16;
315 } else {
316 rc = smbsr_decode_vwv(sr, "b3.wlwwlw", ¶m->rw_andx,
317 &sr->smb_fid, &off_low, &maxcnt_low, &mincnt, &maxcnt_high,
318 &remcnt);
319
320 param->rw_offset = (uint64_t)off_low;
321 param->rw_count = (uint32_t)maxcnt_low;
322 }
323
324 param->rw_mincnt = 0;
325
326 DTRACE_SMB_1(op__ReadX__start, smb_request_t *, sr); /* arg.rw */
327
328 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
329 }
330
331 void
332 smb_post_read_andx(smb_request_t *sr)
333 {
334 DTRACE_SMB_1(op__ReadX__done, smb_request_t *, sr); /* arg.rw */
335
336 kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
337 }
338
339 smb_sdrc_t
340 smb_com_read_andx(smb_request_t *sr)
341 {
342 smb_rw_param_t *param = sr->arg.rw;
343 uint16_t datalen_high;
344 uint16_t datalen_low;
345 uint16_t data_offset;
346 uint16_t offset2;
347 int rc;
348
349 smbsr_lookup_file(sr);
350 if (sr->fid_ofile == NULL) {
351 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
352 return (SDRC_ERROR);
353 }
354
|