33 * smb2_tcp_bufsize is the TCP buffer size, applied to the network socket
34 * with setsockopt SO_SNDBUF, SO_RCVBUF. These set the TCP window size.
35 * This is also used as a "sanity limit" for internal send/reply message
36 * allocations. Note that with compounding SMB2 messages may contain
37 * multiple requests/responses. This size should be large enough for
38 * at least a few SMB2 requests, and at least 2X smb2_max_rwsize.
39 *
40 * smb2_max_rwsize is what we put in the SMB2 negotiate response to tell
41 * the client the largest read and write request size we'll support.
42 * One megabyte is a compromise between efficiency on fast networks
43 * and memory consumption (for the buffers) on the server side.
44 *
45 * smb2_max_trans is the largest "transact" send or receive, which is
46 * used for directory listings and info set/get operations.
47 */
48 uint32_t smb2_tcp_bufsize = (1<<22); /* 4MB */
49 uint32_t smb2_max_rwsize = (1<<20); /* 1MB */
50 uint32_t smb2_max_trans = (1<<16); /* 64KB */
51
52 /*
53 * List of all SMB2 versions we implement. Note that the
54 * highest version we support may be limited by the
55 * _cfg.skc_max_protocol setting.
56 */
57 static uint16_t smb2_versions[] = {
58 0x202, /* SMB 2.002 */
59 0x210, /* SMB 2.1 */
60 };
61 static uint16_t smb2_nversions =
62 sizeof (smb2_versions) / sizeof (smb2_versions[0]);
63
64 static boolean_t
65 smb2_supported_version(smb_session_t *s, uint16_t version)
66 {
67 int i;
68
69 if (version > s->s_cfg.skc_max_protocol)
70 return (B_FALSE);
71 for (i = 0; i < smb2_nversions; i++)
72 if (version == smb2_versions[i])
232 s->newrq_func = smb2sr_newrq;
233
234 rc = smb2_negotiate_common(sr, best_version);
235 if (rc != 0)
236 return (SDRC_DROP_VC);
237
238 return (0);
239 }
240
241 /*
242 * Common parts of SMB2 Negotiate, used for both the
243 * SMB1-to-SMB2 style, and straight SMB2 style.
244 * Do negotiation decisions, encode, send the reply.
245 */
246 static int
247 smb2_negotiate_common(smb_request_t *sr, uint16_t version)
248 {
249 timestruc_t boot_tv, now_tv;
250 smb_session_t *s = sr->session;
251 int rc;
252 uint16_t secmode;
253
254 sr->smb2_status = 0;
255
256 /*
257 * Negotiation itself. First the Security Mode.
258 * The caller stashed the client's secmode in s->secmode,
259 * which we validate, and then replace with the server's
260 * secmode, which is all we care about after this.
261 */
262 secmode = SMB2_NEGOTIATE_SIGNING_ENABLED;
263 if (sr->sr_cfg->skc_signing_required) {
264 secmode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
265 /* Make sure client at least enables signing. */
266 if ((s->secmode & secmode) == 0) {
267 sr->smb2_status = NT_STATUS_INVALID_PARAMETER;
268 }
269 }
270 s->secmode = secmode;
271
280 */
281 s->s_cur_credits = s->s_max_credits = 1;
282 sr->smb2_credit_response = 1;
283
284 boot_tv.tv_sec = smb_get_boottime();
285 boot_tv.tv_nsec = 0;
286 now_tv.tv_sec = gethrestime_sec();
287 now_tv.tv_nsec = 0;
288
289 /*
290 * SMB2 negotiate reply
291 */
292 sr->smb2_hdr_flags = SMB2_FLAGS_SERVER_TO_REDIR;
293 (void) smb2_encode_header(sr, B_FALSE);
294 if (sr->smb2_status != 0) {
295 smb2sr_put_error(sr, sr->smb2_status);
296 smb2_send_reply(sr);
297 return (-1); /* will drop */
298 }
299
300 rc = smb_mbc_encodef(
301 &sr->reply,
302 "wwww#cllllTTwwl#c",
303 65, /* StructSize */ /* w */
304 s->secmode, /* w */
305 version, /* w */
306 0, /* reserved */ /* w */
307 UUID_LEN, /* # */
308 &s->s_cfg.skc_machine_uuid, /* c */
309 smb2srv_capabilities, /* l */
310 smb2_max_trans, /* l */
311 smb2_max_rwsize, /* l */
312 smb2_max_rwsize, /* l */
313 &now_tv, /* T */
314 &boot_tv, /* T */
315 128, /* SecBufOff */ /* w */
316 sr->sr_cfg->skc_negtok_len, /* w */
317 0, /* reserved */ /* l */
318 sr->sr_cfg->skc_negtok_len, /* # */
319 sr->sr_cfg->skc_negtok); /* c */
320
321 smb2_send_reply(sr);
322
323 (void) ksocket_setsockopt(s->sock, SOL_SOCKET,
324 SO_SNDBUF, (const void *)&smb2_tcp_bufsize,
325 sizeof (smb2_tcp_bufsize), CRED());
326 (void) ksocket_setsockopt(s->sock, SOL_SOCKET,
327 SO_RCVBUF, (const void *)&smb2_tcp_bufsize,
328 sizeof (smb2_tcp_bufsize), CRED());
329
330 return (rc);
331 }
332
|
33 * smb2_tcp_bufsize is the TCP buffer size, applied to the network socket
34 * with setsockopt SO_SNDBUF, SO_RCVBUF. These set the TCP window size.
35 * This is also used as a "sanity limit" for internal send/reply message
36 * allocations. Note that with compounding SMB2 messages may contain
37 * multiple requests/responses. This size should be large enough for
38 * at least a few SMB2 requests, and at least 2X smb2_max_rwsize.
39 *
40 * smb2_max_rwsize is what we put in the SMB2 negotiate response to tell
41 * the client the largest read and write request size we'll support.
42 * One megabyte is a compromise between efficiency on fast networks
43 * and memory consumption (for the buffers) on the server side.
44 *
45 * smb2_max_trans is the largest "transact" send or receive, which is
46 * used for directory listings and info set/get operations.
47 */
48 uint32_t smb2_tcp_bufsize = (1<<22); /* 4MB */
49 uint32_t smb2_max_rwsize = (1<<20); /* 1MB */
50 uint32_t smb2_max_trans = (1<<16); /* 64KB */
51
52 /*
53 * With clients (e.g. HP scanners) that don't advertise SMB2_CAP_LARGE_MTU
54 * (including all clients using dialect < SMB 2.1), use a "conservative" value
55 * for max r/w size because some older clients misbehave with larger values.
56 * 64KB is recommended in the [MS-SMB2] spec. (3.3.5.3.1 SMB 2.1 or SMB 3.x
57 * Support) as the minimum so we'll use that.
58 */
59 uint32_t smb2_old_rwsize = (1<<16); /* 64KB */
60
61 /*
62 * List of all SMB2 versions we implement. Note that the
63 * highest version we support may be limited by the
64 * _cfg.skc_max_protocol setting.
65 */
66 static uint16_t smb2_versions[] = {
67 0x202, /* SMB 2.002 */
68 0x210, /* SMB 2.1 */
69 };
70 static uint16_t smb2_nversions =
71 sizeof (smb2_versions) / sizeof (smb2_versions[0]);
72
73 static boolean_t
74 smb2_supported_version(smb_session_t *s, uint16_t version)
75 {
76 int i;
77
78 if (version > s->s_cfg.skc_max_protocol)
79 return (B_FALSE);
80 for (i = 0; i < smb2_nversions; i++)
81 if (version == smb2_versions[i])
241 s->newrq_func = smb2sr_newrq;
242
243 rc = smb2_negotiate_common(sr, best_version);
244 if (rc != 0)
245 return (SDRC_DROP_VC);
246
247 return (0);
248 }
249
250 /*
251 * Common parts of SMB2 Negotiate, used for both the
252 * SMB1-to-SMB2 style, and straight SMB2 style.
253 * Do negotiation decisions, encode, send the reply.
254 */
255 static int
256 smb2_negotiate_common(smb_request_t *sr, uint16_t version)
257 {
258 timestruc_t boot_tv, now_tv;
259 smb_session_t *s = sr->session;
260 int rc;
261 uint32_t max_rwsize;
262 uint16_t secmode;
263
264 sr->smb2_status = 0;
265
266 /*
267 * Negotiation itself. First the Security Mode.
268 * The caller stashed the client's secmode in s->secmode,
269 * which we validate, and then replace with the server's
270 * secmode, which is all we care about after this.
271 */
272 secmode = SMB2_NEGOTIATE_SIGNING_ENABLED;
273 if (sr->sr_cfg->skc_signing_required) {
274 secmode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
275 /* Make sure client at least enables signing. */
276 if ((s->secmode & secmode) == 0) {
277 sr->smb2_status = NT_STATUS_INVALID_PARAMETER;
278 }
279 }
280 s->secmode = secmode;
281
290 */
291 s->s_cur_credits = s->s_max_credits = 1;
292 sr->smb2_credit_response = 1;
293
294 boot_tv.tv_sec = smb_get_boottime();
295 boot_tv.tv_nsec = 0;
296 now_tv.tv_sec = gethrestime_sec();
297 now_tv.tv_nsec = 0;
298
299 /*
300 * SMB2 negotiate reply
301 */
302 sr->smb2_hdr_flags = SMB2_FLAGS_SERVER_TO_REDIR;
303 (void) smb2_encode_header(sr, B_FALSE);
304 if (sr->smb2_status != 0) {
305 smb2sr_put_error(sr, sr->smb2_status);
306 smb2_send_reply(sr);
307 return (-1); /* will drop */
308 }
309
310 /*
311 * See notes above smb2_max_rwsize, smb2_old_rwsize
312 */
313 if (s->capabilities & SMB2_CAP_LARGE_MTU)
314 max_rwsize = smb2_max_rwsize;
315 else
316 max_rwsize = smb2_old_rwsize;
317
318 rc = smb_mbc_encodef(
319 &sr->reply,
320 "wwww#cllllTTwwl#c",
321 65, /* StructSize */ /* w */
322 s->secmode, /* w */
323 version, /* w */
324 0, /* reserved */ /* w */
325 UUID_LEN, /* # */
326 &s->s_cfg.skc_machine_uuid, /* c */
327 smb2srv_capabilities, /* l */
328 smb2_max_trans, /* l */
329 max_rwsize, /* l */
330 max_rwsize, /* l */
331 &now_tv, /* T */
332 &boot_tv, /* T */
333 128, /* SecBufOff */ /* w */
334 sr->sr_cfg->skc_negtok_len, /* w */
335 0, /* reserved */ /* l */
336 sr->sr_cfg->skc_negtok_len, /* # */
337 sr->sr_cfg->skc_negtok); /* c */
338
339 smb2_send_reply(sr);
340
341 (void) ksocket_setsockopt(s->sock, SOL_SOCKET,
342 SO_SNDBUF, (const void *)&smb2_tcp_bufsize,
343 sizeof (smb2_tcp_bufsize), CRED());
344 (void) ksocket_setsockopt(s->sock, SOL_SOCKET,
345 SO_RCVBUF, (const void *)&smb2_tcp_bufsize,
346 sizeof (smb2_tcp_bufsize), CRED());
347
348 return (rc);
349 }
350
|