Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : negprot reply code
4 : Copyright (C) Andrew Tridgell 1992-1998
5 : Copyright (C) Volker Lendecke 2007
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "includes.h"
22 : #include "smbd/smbd.h"
23 : #include "smbd/globals.h"
24 : #include "serverid.h"
25 : #include "auth.h"
26 : #include "messages.h"
27 : #include "smbprofile.h"
28 : #include "auth/gensec/gensec.h"
29 : #include "../libcli/smb/smb_signing.h"
30 : #include "lib/util/string_wrappers.h"
31 :
32 : /*
33 : * MS-CIFS, 2.2.4.52.2 SMB_COM_NEGOTIATE Response:
34 : * If the server does not support any of the listed dialects, it MUST return a
35 : * DialectIndex of 0XFFFF
36 : */
37 : #define NO_PROTOCOL_CHOSEN 0xffff
38 :
39 : extern fstring remote_proto;
40 :
41 0 : static void get_challenge(struct smbXsrv_connection *xconn, uint8_t buff[8])
42 : {
43 : NTSTATUS nt_status;
44 :
45 : /* We might be called more than once, multiple negprots are
46 : * permitted */
47 0 : if (xconn->smb1.negprot.auth_context) {
48 0 : DEBUG(3, ("get challenge: is this a secondary negprot? "
49 : "sconn->negprot.auth_context is non-NULL!\n"));
50 0 : TALLOC_FREE(xconn->smb1.negprot.auth_context);
51 : }
52 :
53 0 : DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
54 0 : nt_status = make_auth4_context(
55 : xconn, &xconn->smb1.negprot.auth_context);
56 0 : if (!NT_STATUS_IS_OK(nt_status)) {
57 0 : DEBUG(0, ("make_auth_context_subsystem returned %s",
58 : nt_errstr(nt_status)));
59 0 : smb_panic("cannot make_negprot_global_auth_context!");
60 : }
61 0 : DEBUG(10, ("get challenge: getting challenge\n"));
62 0 : xconn->smb1.negprot.auth_context->get_ntlm_challenge(
63 : xconn->smb1.negprot.auth_context, buff);
64 0 : }
65 :
66 : /****************************************************************************
67 : Reply for the lanman 1.0 protocol.
68 : ****************************************************************************/
69 :
70 0 : static NTSTATUS reply_lanman1(struct smb_request *req, uint16_t choice)
71 : {
72 0 : int secword=0;
73 0 : time_t t = time(NULL);
74 0 : struct smbXsrv_connection *xconn = req->xconn;
75 : uint16_t raw;
76 : NTSTATUS status;
77 :
78 0 : if (lp_async_smb_echo_handler()) {
79 0 : raw = 0;
80 : } else {
81 0 : raw = (lp_read_raw()?1:0) | (lp_write_raw()?2:0);
82 : }
83 :
84 0 : xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
85 :
86 0 : secword |= NEGOTIATE_SECURITY_USER_LEVEL;
87 0 : if (xconn->smb1.negprot.encrypted_passwords) {
88 0 : secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
89 : }
90 :
91 0 : reply_smb1_outbuf(req, 13, xconn->smb1.negprot.encrypted_passwords?8:0);
92 :
93 0 : SSVAL(req->outbuf,smb_vwv0,choice);
94 0 : SSVAL(req->outbuf,smb_vwv1,secword);
95 : /* Create a token value and add it to the outgoing packet. */
96 0 : if (xconn->smb1.negprot.encrypted_passwords) {
97 0 : get_challenge(xconn, (uint8_t *)smb_buf(req->outbuf));
98 0 : SSVAL(req->outbuf,smb_vwv11, 8);
99 : }
100 :
101 0 : status = smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN1);
102 0 : if (!NT_STATUS_IS_OK(status)) {
103 0 : reply_nterror(req, status);
104 0 : return status;
105 : }
106 :
107 : /* Reply, SMBlockread, SMBwritelock supported. */
108 0 : SCVAL(req->outbuf,smb_flg, FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
109 0 : SSVAL(req->outbuf,smb_vwv2, xconn->smb1.negprot.max_recv);
110 0 : SSVAL(req->outbuf,smb_vwv3, lp_max_mux()); /* maxmux */
111 0 : SSVAL(req->outbuf,smb_vwv4, 1);
112 0 : SSVAL(req->outbuf,smb_vwv5, raw); /* tell redirector we support
113 : readbraw writebraw (possibly) */
114 0 : SIVAL(req->outbuf,smb_vwv6, getpid());
115 0 : SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
116 :
117 0 : srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
118 :
119 0 : return NT_STATUS_OK;
120 : }
121 :
122 : /****************************************************************************
123 : Reply for the lanman 2.0 protocol.
124 : ****************************************************************************/
125 :
126 0 : static NTSTATUS reply_lanman2(struct smb_request *req, uint16_t choice)
127 : {
128 0 : int secword=0;
129 0 : time_t t = time(NULL);
130 0 : struct smbXsrv_connection *xconn = req->xconn;
131 : uint16_t raw;
132 : NTSTATUS status;
133 :
134 0 : if (lp_async_smb_echo_handler()) {
135 0 : raw = 0;
136 : } else {
137 0 : raw = (lp_read_raw()?1:0) | (lp_write_raw()?2:0);
138 : }
139 :
140 0 : xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
141 :
142 0 : secword |= NEGOTIATE_SECURITY_USER_LEVEL;
143 0 : if (xconn->smb1.negprot.encrypted_passwords) {
144 0 : secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
145 : }
146 :
147 0 : reply_smb1_outbuf(req, 13, xconn->smb1.negprot.encrypted_passwords?8:0);
148 :
149 0 : SSVAL(req->outbuf,smb_vwv0, choice);
150 0 : SSVAL(req->outbuf,smb_vwv1, secword);
151 0 : SIVAL(req->outbuf,smb_vwv6, getpid());
152 :
153 : /* Create a token value and add it to the outgoing packet. */
154 0 : if (xconn->smb1.negprot.encrypted_passwords) {
155 0 : get_challenge(xconn, (uint8_t *)smb_buf(req->outbuf));
156 0 : SSVAL(req->outbuf,smb_vwv11, 8);
157 : }
158 :
159 0 : status = smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN2);
160 0 : if (!NT_STATUS_IS_OK(status)) {
161 0 : reply_nterror(req, status);
162 0 : return status;
163 : }
164 :
165 : /* Reply, SMBlockread, SMBwritelock supported. */
166 0 : SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
167 0 : SSVAL(req->outbuf,smb_vwv2,xconn->smb1.negprot.max_recv);
168 0 : SSVAL(req->outbuf,smb_vwv3,lp_max_mux());
169 0 : SSVAL(req->outbuf,smb_vwv4,1);
170 0 : SSVAL(req->outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
171 0 : SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
172 0 : srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
173 0 : return NT_STATUS_OK;
174 : }
175 :
176 : /****************************************************************************
177 : Reply for the nt protocol.
178 : ****************************************************************************/
179 :
180 38 : static NTSTATUS reply_nt1(struct smb_request *req, uint16_t choice)
181 : {
182 : /* dual names + lock_and_read + nt SMBs + remote API calls */
183 38 : int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
184 : CAP_LEVEL_II_OPLOCKS;
185 :
186 38 : int secword=0;
187 38 : bool negotiate_spnego = False;
188 : struct timespec ts;
189 : ssize_t ret;
190 38 : struct smbXsrv_connection *xconn = req->xconn;
191 38 : bool signing_desired = false;
192 38 : bool signing_required = false;
193 : NTSTATUS status;
194 :
195 38 : xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
196 :
197 : /* Check the flags field to see if this is Vista.
198 : WinXP sets it and Vista does not. But we have to
199 : distinguish from NT which doesn't set it either. */
200 :
201 66 : if ( (req->flags2 & FLAGS2_EXTENDED_SECURITY) &&
202 38 : ((req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) == 0) )
203 : {
204 56 : if ((get_remote_arch() != RA_SAMBA) &&
205 18 : (get_remote_arch() != RA_CIFSFS)) {
206 0 : set_remote_arch( RA_VISTA );
207 : }
208 : }
209 :
210 38 : reply_smb1_outbuf(req,17,0);
211 :
212 : /* do spnego in user level security if the client
213 : supports it and we can do encrypted passwords */
214 :
215 66 : if (xconn->smb1.negprot.encrypted_passwords &&
216 38 : (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
217 38 : negotiate_spnego = True;
218 38 : capabilities |= CAP_EXTENDED_SECURITY;
219 38 : add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
220 : /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply
221 : (already partially constructed. */
222 38 : SSVAL(req->outbuf, smb_flg2,
223 : req->flags2 | FLAGS2_EXTENDED_SECURITY);
224 : }
225 :
226 38 : capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
227 :
228 38 : if (lp_unicode()) {
229 38 : capabilities |= CAP_UNICODE;
230 : }
231 :
232 38 : if (lp_smb1_unix_extensions()) {
233 38 : capabilities |= CAP_UNIX;
234 : }
235 :
236 38 : if (lp_large_readwrite())
237 38 : capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
238 :
239 38 : capabilities |= CAP_LARGE_FILES;
240 :
241 38 : if (!lp_async_smb_echo_handler() && lp_read_raw() && lp_write_raw())
242 38 : capabilities |= CAP_RAW_MODE;
243 :
244 38 : if (lp_nt_status_support())
245 38 : capabilities |= CAP_STATUS32;
246 :
247 38 : if (lp_host_msdfs())
248 38 : capabilities |= CAP_DFS;
249 :
250 38 : secword |= NEGOTIATE_SECURITY_USER_LEVEL;
251 38 : if (xconn->smb1.negprot.encrypted_passwords) {
252 38 : secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
253 : }
254 :
255 38 : signing_desired = smb1_signing_is_desired(xconn->smb1.signing_state);
256 38 : signing_required = smb1_signing_is_mandatory(xconn->smb1.signing_state);
257 :
258 38 : if (signing_desired) {
259 18 : secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
260 : /* No raw mode with smb signing. */
261 18 : capabilities &= ~CAP_RAW_MODE;
262 18 : if (signing_required) {
263 18 : secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
264 : }
265 : }
266 :
267 38 : SSVAL(req->outbuf,smb_vwv0,choice);
268 38 : SCVAL(req->outbuf,smb_vwv1,secword);
269 :
270 38 : status = smbXsrv_connection_init_tables(xconn, PROTOCOL_NT1);
271 38 : if (!NT_STATUS_IS_OK(status)) {
272 0 : reply_nterror(req, status);
273 0 : return status;
274 : }
275 :
276 38 : SSVAL(req->outbuf,smb_vwv1+1, lp_max_mux()); /* maxmpx */
277 38 : SSVAL(req->outbuf,smb_vwv2+1, 1); /* num vcs */
278 38 : SIVAL(req->outbuf,smb_vwv3+1,
279 : xconn->smb1.negprot.max_recv); /* max buffer. LOTS! */
280 38 : SIVAL(req->outbuf,smb_vwv5+1, 0x10000); /* raw size. full 64k */
281 38 : SIVAL(req->outbuf,smb_vwv7+1, getpid()); /* session key */
282 38 : SIVAL(req->outbuf,smb_vwv9+1, capabilities); /* capabilities */
283 38 : clock_gettime(CLOCK_REALTIME,&ts);
284 38 : put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER,(char *)req->outbuf+smb_vwv11+1,&ts);
285 38 : SSVALS(req->outbuf,smb_vwv15+1,set_server_zone_offset(ts.tv_sec)/60);
286 :
287 38 : if (!negotiate_spnego) {
288 : /* Create a token value and add it to the outgoing packet. */
289 0 : if (xconn->smb1.negprot.encrypted_passwords) {
290 : uint8_t chal[8];
291 : /* note that we do not send a challenge at all if
292 : we are using plaintext */
293 0 : get_challenge(xconn, chal);
294 0 : ret = message_push_blob(
295 : &req->outbuf, data_blob_const(chal, sizeof(chal)));
296 0 : if (ret == -1) {
297 0 : DEBUG(0, ("Could not push challenge\n"));
298 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
299 0 : return NT_STATUS_NO_MEMORY;
300 : }
301 0 : SCVAL(req->outbuf, smb_vwv16+1, ret);
302 : }
303 0 : ret = message_push_string(&req->outbuf, lp_workgroup(),
304 : STR_UNICODE|STR_TERMINATE
305 : |STR_NOALIGN);
306 0 : if (ret == -1) {
307 0 : DEBUG(0, ("Could not push workgroup string\n"));
308 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
309 0 : return NT_STATUS_NO_MEMORY;
310 : }
311 0 : ret = message_push_string(&req->outbuf, lp_netbios_name(),
312 : STR_UNICODE|STR_TERMINATE
313 : |STR_NOALIGN);
314 0 : if (ret == -1) {
315 0 : DEBUG(0, ("Could not push netbios name string\n"));
316 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
317 0 : return NT_STATUS_NO_MEMORY;
318 : }
319 0 : DEBUG(3,("not using SPNEGO\n"));
320 : } else {
321 38 : DATA_BLOB spnego_blob = negprot_spnego(req, xconn);
322 :
323 38 : if (spnego_blob.data == NULL) {
324 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
325 0 : return NT_STATUS_NO_MEMORY;
326 : }
327 :
328 38 : ret = message_push_blob(&req->outbuf, spnego_blob);
329 38 : if (ret == -1) {
330 0 : DEBUG(0, ("Could not push spnego blob\n"));
331 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
332 0 : return NT_STATUS_NO_MEMORY;
333 : }
334 38 : data_blob_free(&spnego_blob);
335 :
336 38 : SCVAL(req->outbuf,smb_vwv16+1, 0);
337 38 : DEBUG(3,("using SPNEGO\n"));
338 : }
339 :
340 38 : return NT_STATUS_OK;
341 : }
342 :
343 : /* these are the protocol lists used for auto architecture detection:
344 :
345 : WinNT 3.51:
346 : protocol [PC NETWORK PROGRAM 1.0]
347 : protocol [XENIX CORE]
348 : protocol [MICROSOFT NETWORKS 1.03]
349 : protocol [LANMAN1.0]
350 : protocol [Windows for Workgroups 3.1a]
351 : protocol [LM1.2X002]
352 : protocol [LANMAN2.1]
353 : protocol [NT LM 0.12]
354 :
355 : Win95:
356 : protocol [PC NETWORK PROGRAM 1.0]
357 : protocol [XENIX CORE]
358 : protocol [MICROSOFT NETWORKS 1.03]
359 : protocol [LANMAN1.0]
360 : protocol [Windows for Workgroups 3.1a]
361 : protocol [LM1.2X002]
362 : protocol [LANMAN2.1]
363 : protocol [NT LM 0.12]
364 :
365 : Win2K:
366 : protocol [PC NETWORK PROGRAM 1.0]
367 : protocol [LANMAN1.0]
368 : protocol [Windows for Workgroups 3.1a]
369 : protocol [LM1.2X002]
370 : protocol [LANMAN2.1]
371 : protocol [NT LM 0.12]
372 :
373 : Vista:
374 : protocol [PC NETWORK PROGRAM 1.0]
375 : protocol [LANMAN1.0]
376 : protocol [Windows for Workgroups 3.1a]
377 : protocol [LM1.2X002]
378 : protocol [LANMAN2.1]
379 : protocol [NT LM 0.12]
380 : protocol [SMB 2.001]
381 :
382 : OS/2:
383 : protocol [PC NETWORK PROGRAM 1.0]
384 : protocol [XENIX CORE]
385 : protocol [LANMAN1.0]
386 : protocol [LM1.2X002]
387 : protocol [LANMAN2.1]
388 :
389 : OSX:
390 : protocol [NT LM 0.12]
391 : protocol [SMB 2.002]
392 : protocol [SMB 2.???]
393 : */
394 :
395 : /*
396 : * Modified to recognize the architecture of the remote machine better.
397 : *
398 : * This appears to be the matrix of which protocol is used by which
399 : * product.
400 : Protocol WfWg Win95 WinNT Win2K OS/2 Vista OSX
401 : PC NETWORK PROGRAM 1.0 1 1 1 1 1 1
402 : XENIX CORE 2 2
403 : MICROSOFT NETWORKS 3.0 2 2
404 : DOS LM1.2X002 3 3
405 : MICROSOFT NETWORKS 1.03 3
406 : DOS LANMAN2.1 4 4
407 : LANMAN1.0 4 2 3 2
408 : Windows for Workgroups 3.1a 5 5 5 3 3
409 : LM1.2X002 6 4 4 4
410 : LANMAN2.1 7 5 5 5
411 : NT LM 0.12 6 8 6 6 6 1
412 : SMB 2.001 7
413 : SMB 2.002 2
414 : SMB 2.??? 3
415 : *
416 : * tim@fsg.com 09/29/95
417 : * Win2K added by matty 17/7/99
418 : */
419 :
420 : #define PROT_PC_NETWORK_PROGRAM_1_0 0x0001
421 : #define PROT_XENIX_CORE 0x0002
422 : #define PROT_MICROSOFT_NETWORKS_3_0 0x0004
423 : #define PROT_DOS_LM1_2X002 0x0008
424 : #define PROT_MICROSOFT_NETWORKS_1_03 0x0010
425 : #define PROT_DOS_LANMAN2_1 0x0020
426 : #define PROT_LANMAN1_0 0x0040
427 : #define PROT_WFWG 0x0080
428 : #define PROT_LM1_2X002 0x0100
429 : #define PROT_LANMAN2_1 0x0200
430 : #define PROT_NT_LM_0_12 0x0400
431 : #define PROT_SMB_2_001 0x0800
432 : #define PROT_SMB_2_002 0x1000
433 : #define PROT_SMB_2_FF 0x2000
434 : #define PROT_SAMBA 0x4000
435 : #define PROT_POSIX_2 0x8000
436 :
437 : #define ARCH_WFWG ( PROT_PC_NETWORK_PROGRAM_1_0 | PROT_MICROSOFT_NETWORKS_3_0 | \
438 : PROT_DOS_LM1_2X002 | PROT_DOS_LANMAN2_1 | PROT_WFWG )
439 : #define ARCH_WIN95 ( ARCH_WFWG | PROT_NT_LM_0_12 )
440 : #define ARCH_WINNT ( PROT_PC_NETWORK_PROGRAM_1_0 | PROT_XENIX_CORE | \
441 : PROT_MICROSOFT_NETWORKS_1_03 | PROT_LANMAN1_0 | PROT_WFWG | \
442 : PROT_LM1_2X002 | PROT_LANMAN2_1 | PROT_NT_LM_0_12 )
443 : #define ARCH_WIN2K ( ARCH_WINNT & ~(PROT_XENIX_CORE | PROT_MICROSOFT_NETWORKS_1_03) )
444 : #define ARCH_OS2 ( ARCH_WINNT & ~(PROT_MICROSOFT_NETWORKS_1_03 | PROT_WFWG) )
445 : #define ARCH_VISTA ( ARCH_WIN2K | PROT_SMB_2_001 )
446 : #define ARCH_SAMBA ( PROT_SAMBA )
447 : #define ARCH_CIFSFS ( PROT_POSIX_2 )
448 : #define ARCH_OSX ( PROT_NT_LM_0_12 | PROT_SMB_2_002 | PROT_SMB_2_FF )
449 :
450 : /* List of supported protocols, most desired first */
451 : static const struct {
452 : const char *proto_name;
453 : const char *short_name;
454 : NTSTATUS (*proto_reply_fn)(struct smb_request *req, uint16_t choice);
455 : int protocol_level;
456 : } supported_protocols[] = {
457 : {"SMB 2.???", "SMB2_FF", reply_smb20ff, PROTOCOL_SMB2_10},
458 : {"SMB 2.002", "SMB2_02", reply_smb2002, PROTOCOL_SMB2_02},
459 : {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
460 : {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
461 : {"POSIX 2", "NT1", reply_nt1, PROTOCOL_NT1},
462 : {"LANMAN2.1", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
463 : {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
464 : {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
465 : {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
466 : {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
467 : {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
468 : {NULL,NULL,NULL,0},
469 : };
470 :
471 : /****************************************************************************
472 : Reply to a negprot.
473 : conn POINTER CAN BE NULL HERE !
474 : ****************************************************************************/
475 :
476 98 : void reply_negprot(struct smb_request *req)
477 : {
478 98 : size_t choice = 0;
479 98 : int chosen_level = -1;
480 98 : bool choice_set = false;
481 : int protocol;
482 : const char *p;
483 98 : int protocols = 0;
484 : int num_cliprotos;
485 : char **cliprotos;
486 : size_t i;
487 : size_t converted_size;
488 98 : struct smbXsrv_connection *xconn = req->xconn;
489 98 : struct smbd_server_connection *sconn = req->sconn;
490 98 : bool signing_required = true;
491 : int max_proto;
492 : int min_proto;
493 : NTSTATUS status;
494 :
495 98 : START_PROFILE(SMBnegprot);
496 :
497 98 : if (xconn->smb1.negprot.done) {
498 0 : END_PROFILE(SMBnegprot);
499 0 : exit_server_cleanly("multiple negprot's are not permitted");
500 : }
501 :
502 98 : if (req->buflen == 0) {
503 0 : DEBUG(0, ("negprot got no protocols\n"));
504 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
505 0 : END_PROFILE(SMBnegprot);
506 0 : return;
507 : }
508 :
509 98 : if (req->buf[req->buflen-1] != '\0') {
510 0 : DEBUG(0, ("negprot protocols not 0-terminated\n"));
511 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
512 0 : END_PROFILE(SMBnegprot);
513 0 : return;
514 : }
515 :
516 98 : p = (const char *)req->buf + 1;
517 :
518 98 : num_cliprotos = 0;
519 98 : cliprotos = NULL;
520 :
521 885 : while (smbreq_bufrem(req, p) > 0) {
522 :
523 : char **tmp;
524 :
525 708 : tmp = talloc_realloc(talloc_tos(), cliprotos, char *,
526 : num_cliprotos+1);
527 708 : if (tmp == NULL) {
528 0 : DEBUG(0, ("talloc failed\n"));
529 0 : TALLOC_FREE(cliprotos);
530 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
531 0 : END_PROFILE(SMBnegprot);
532 0 : return;
533 : }
534 :
535 708 : cliprotos = tmp;
536 :
537 708 : if (!pull_ascii_talloc(cliprotos, &cliprotos[num_cliprotos], p,
538 : &converted_size)) {
539 0 : DEBUG(0, ("pull_ascii_talloc failed\n"));
540 0 : TALLOC_FREE(cliprotos);
541 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
542 0 : END_PROFILE(SMBnegprot);
543 0 : return;
544 : }
545 :
546 708 : DEBUG(3, ("Requested protocol [%s]\n",
547 : cliprotos[num_cliprotos]));
548 :
549 708 : num_cliprotos += 1;
550 708 : p += strlen(p) + 2;
551 : }
552 :
553 601 : for (i=0; i<num_cliprotos; i++) {
554 552 : if (strcsequal(cliprotos[i], "Windows for Workgroups 3.1a")) {
555 0 : protocols |= PROT_WFWG;
556 552 : } else if (strcsequal(cliprotos[i], "DOS LM1.2X002")) {
557 0 : protocols |= PROT_DOS_LM1_2X002;
558 552 : } else if (strcsequal(cliprotos[i], "DOS LANMAN2.1")) {
559 49 : protocols |= PROT_DOS_LANMAN2_1;
560 503 : } else if (strcsequal(cliprotos[i], "LANMAN1.0")) {
561 49 : protocols |= PROT_LANMAN1_0;
562 454 : } else if (strcsequal(cliprotos[i], "NT LM 0.12")) {
563 49 : protocols |= PROT_NT_LM_0_12;
564 405 : } else if (strcsequal(cliprotos[i], "SMB 2.001")) {
565 0 : protocols |= PROT_SMB_2_001;
566 405 : } else if (strcsequal(cliprotos[i], "SMB 2.002")) {
567 31 : protocols |= PROT_SMB_2_002;
568 374 : } else if (strcsequal(cliprotos[i], "SMB 2.???")) {
569 31 : protocols |= PROT_SMB_2_FF;
570 343 : } else if (strcsequal(cliprotos[i], "LANMAN2.1")) {
571 49 : protocols |= PROT_LANMAN2_1;
572 294 : } else if (strcsequal(cliprotos[i], "LM1.2X002")) {
573 49 : protocols |= PROT_LM1_2X002;
574 245 : } else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 1.03")) {
575 49 : protocols |= PROT_MICROSOFT_NETWORKS_1_03;
576 196 : } else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 3.0")) {
577 49 : protocols |= PROT_MICROSOFT_NETWORKS_3_0;
578 147 : } else if (strcsequal(cliprotos[i], "PC NETWORK PROGRAM 1.0")) {
579 49 : protocols |= PROT_PC_NETWORK_PROGRAM_1_0;
580 98 : } else if (strcsequal(cliprotos[i], "XENIX CORE")) {
581 0 : protocols |= PROT_XENIX_CORE;
582 98 : } else if (strcsequal(cliprotos[i], "Samba")) {
583 49 : protocols = PROT_SAMBA;
584 49 : break;
585 49 : } else if (strcsequal(cliprotos[i], "POSIX 2")) {
586 0 : protocols = PROT_POSIX_2;
587 0 : break;
588 : }
589 : }
590 :
591 98 : switch ( protocols ) {
592 : /* Old CIFSFS can send one arch only, NT LM 0.12. */
593 18 : case PROT_NT_LM_0_12:
594 : case ARCH_CIFSFS:
595 18 : set_remote_arch(RA_CIFSFS);
596 18 : break;
597 49 : case ARCH_SAMBA:
598 49 : set_remote_arch(RA_SAMBA);
599 49 : break;
600 0 : case ARCH_WFWG:
601 0 : set_remote_arch(RA_WFWG);
602 0 : break;
603 0 : case ARCH_WIN95:
604 0 : set_remote_arch(RA_WIN95);
605 0 : break;
606 0 : case ARCH_WINNT:
607 0 : set_remote_arch(RA_WINNT);
608 0 : break;
609 0 : case ARCH_WIN2K:
610 0 : set_remote_arch(RA_WIN2K);
611 0 : break;
612 0 : case ARCH_VISTA:
613 0 : set_remote_arch(RA_VISTA);
614 0 : break;
615 0 : case ARCH_OS2:
616 0 : set_remote_arch(RA_OS2);
617 0 : break;
618 31 : case ARCH_OSX:
619 31 : set_remote_arch(RA_OSX);
620 31 : break;
621 0 : default:
622 0 : set_remote_arch(RA_UNKNOWN);
623 0 : break;
624 : }
625 :
626 : /* possibly reload - change of architecture */
627 98 : reload_services(sconn, conn_snum_used, true);
628 :
629 : /*
630 : * Anything higher than PROTOCOL_SMB2_10 still
631 : * needs to go via "SMB 2.???", which is marked
632 : * as PROTOCOL_SMB2_10.
633 : *
634 : * The real negotiation happens via reply_smb20ff()
635 : * using SMB2 Negotiation.
636 : */
637 98 : max_proto = lp_server_max_protocol();
638 98 : if (max_proto > PROTOCOL_SMB2_10) {
639 98 : max_proto = PROTOCOL_SMB2_10;
640 : }
641 98 : min_proto = lp_server_min_protocol();
642 98 : if (min_proto > PROTOCOL_SMB2_10) {
643 0 : min_proto = PROTOCOL_SMB2_10;
644 : }
645 :
646 : /* Check for protocols, most desirable first */
647 174 : for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
648 174 : i = 0;
649 309 : if ((supported_protocols[protocol].protocol_level <= max_proto) &&
650 174 : (supported_protocols[protocol].protocol_level >= min_proto))
651 1489 : while (i < num_cliprotos) {
652 1180 : if (strequal(cliprotos[i],supported_protocols[protocol].proto_name)) {
653 98 : choice = i;
654 98 : chosen_level = supported_protocols[protocol].protocol_level;
655 98 : choice_set = true;
656 : }
657 1180 : i++;
658 : }
659 174 : if (choice_set) {
660 98 : break;
661 : }
662 : }
663 :
664 98 : if (!choice_set) {
665 : bool ok;
666 :
667 0 : DBG_NOTICE("No protocol supported !\n");
668 0 : reply_smb1_outbuf(req, 1, 0);
669 0 : SSVAL(req->outbuf, smb_vwv0, NO_PROTOCOL_CHOSEN);
670 :
671 0 : ok = smb1_srv_send(xconn, (char *)req->outbuf,
672 : false, 0, false, NULL);
673 0 : if (!ok) {
674 0 : DBG_NOTICE("smb1_srv_send failed\n");
675 : }
676 0 : exit_server_cleanly("no protocol supported\n");
677 : }
678 :
679 98 : fstrcpy(remote_proto,supported_protocols[protocol].short_name);
680 98 : reload_services(sconn, conn_snum_used, true);
681 98 : status = supported_protocols[protocol].proto_reply_fn(req, choice);
682 98 : if (!NT_STATUS_IS_OK(status)) {
683 0 : exit_server_cleanly("negprot function failed\n");
684 : }
685 :
686 98 : DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
687 :
688 98 : DBG_INFO("negprot index=%zu\n", choice);
689 :
690 98 : xconn->smb1.negprot.done = true;
691 :
692 : /* We always have xconn->smb1.signing_state also for >= SMB2_02 */
693 98 : signing_required = smb1_signing_is_mandatory(xconn->smb1.signing_state);
694 98 : if (signing_required && (chosen_level < PROTOCOL_NT1)) {
695 0 : exit_server_cleanly("SMB signing is required and "
696 : "client negotiated a downlevel protocol");
697 : }
698 :
699 98 : TALLOC_FREE(cliprotos);
700 :
701 98 : if (lp_async_smb_echo_handler() && (chosen_level < PROTOCOL_SMB2_02) &&
702 0 : !fork_echo_handler(xconn)) {
703 0 : exit_server("Failed to fork echo handler");
704 : }
705 :
706 98 : END_PROFILE(SMBnegprot);
707 98 : return;
708 : }
|