source: vendor/current/source3/smbd/negprot.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

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