r18771: Sequel to r18761: If we always set the keylen to 0 there's no point in passing
[jra/samba/.git] / source3 / smbd / negprot.c
1 /* 
2    Unix SMB/CIFS implementation.
3    negprot reply code
4    Copyright (C) Andrew Tridgell 1992-1998
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23 extern fstring remote_proto;
24 extern enum protocol_types Protocol;
25 extern int max_recv;
26
27 BOOL global_encrypted_passwords_negotiated = False;
28 BOOL global_spnego_negotiated = False;
29 struct auth_context *negprot_global_auth_context = NULL;
30
31 static void get_challenge(char buff[8]) 
32 {
33         NTSTATUS nt_status;
34         const uint8 *cryptkey;
35
36         /* We might be called more than once, multiple negprots are
37          * permitted */
38         if (negprot_global_auth_context) {
39                 DEBUG(3, ("get challenge: is this a secondary negprot?  negprot_global_auth_context is non-NULL!\n"));
40                 (negprot_global_auth_context->free)(&negprot_global_auth_context);
41         }
42
43         DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
44         if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&negprot_global_auth_context))) {
45                 DEBUG(0, ("make_auth_context_subsystem returned %s", nt_errstr(nt_status)));
46                 smb_panic("cannot make_negprot_global_auth_context!\n");
47         }
48         DEBUG(10, ("get challenge: getting challenge\n"));
49         cryptkey = negprot_global_auth_context->get_ntlm_challenge(negprot_global_auth_context);
50         memcpy(buff, cryptkey, 8);
51 }
52
53 /****************************************************************************
54  Reply for the core protocol.
55 ****************************************************************************/
56
57 static int reply_corep(char *inbuf, char *outbuf)
58 {
59         int outsize = set_message(outbuf,1,0,True);
60
61         Protocol = PROTOCOL_CORE;
62         
63         return outsize;
64 }
65
66 /****************************************************************************
67  Reply for the coreplus protocol.
68 ****************************************************************************/
69
70 static int reply_coreplus(char *inbuf, char *outbuf)
71 {
72         int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
73         int outsize = set_message(outbuf,13,0,True);
74         SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
75                         readbraw and writebraw (possibly) */
76         /* Reply, SMBlockread, SMBwritelock supported. */
77         SCVAL(outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
78         SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */    
79
80         Protocol = PROTOCOL_COREPLUS;
81
82         return outsize;
83 }
84
85 /****************************************************************************
86  Reply for the lanman 1.0 protocol.
87 ****************************************************************************/
88
89 static int reply_lanman1(char *inbuf, char *outbuf)
90 {
91         int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
92         int secword=0;
93         time_t t = time(NULL);
94
95         global_encrypted_passwords_negotiated = lp_encrypted_passwords();
96
97         if (lp_security()>=SEC_USER)
98                 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
99         if (global_encrypted_passwords_negotiated)
100                 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
101
102         set_message(outbuf,13,global_encrypted_passwords_negotiated?8:0,True);
103         SSVAL(outbuf,smb_vwv1,secword); 
104         /* Create a token value and add it to the outgoing packet. */
105         if (global_encrypted_passwords_negotiated) {
106                 get_challenge(smb_buf(outbuf));
107                 SSVAL(outbuf,smb_vwv11, 8);
108         }
109
110         Protocol = PROTOCOL_LANMAN1;
111
112         /* Reply, SMBlockread, SMBwritelock supported. */
113         SCVAL(outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
114         SSVAL(outbuf,smb_vwv2,max_recv);
115         SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
116         SSVAL(outbuf,smb_vwv4,1);
117         SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
118                 readbraw writebraw (possibly) */
119         SIVAL(outbuf,smb_vwv6,sys_getpid());
120         SSVAL(outbuf,smb_vwv10, set_server_zone_offset(t)/60);
121
122         srv_put_dos_date(outbuf,smb_vwv8,t);
123
124         return (smb_len(outbuf)+4);
125 }
126
127 /****************************************************************************
128  Reply for the lanman 2.0 protocol.
129 ****************************************************************************/
130
131 static int reply_lanman2(char *inbuf, char *outbuf)
132 {
133         int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
134         int secword=0;
135         time_t t = time(NULL);
136
137         global_encrypted_passwords_negotiated = lp_encrypted_passwords();
138   
139         if (lp_security()>=SEC_USER)
140                 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
141         if (global_encrypted_passwords_negotiated)
142                 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
143
144         set_message(outbuf,13,global_encrypted_passwords_negotiated?8:0,True);
145         SSVAL(outbuf,smb_vwv1,secword); 
146         SIVAL(outbuf,smb_vwv6,sys_getpid());
147
148         /* Create a token value and add it to the outgoing packet. */
149         if (global_encrypted_passwords_negotiated) {
150                 get_challenge(smb_buf(outbuf));
151                 SSVAL(outbuf,smb_vwv11, 8);
152         }
153
154         Protocol = PROTOCOL_LANMAN2;
155
156         /* Reply, SMBlockread, SMBwritelock supported. */
157         SCVAL(outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
158         SSVAL(outbuf,smb_vwv2,max_recv);
159         SSVAL(outbuf,smb_vwv3,lp_maxmux()); 
160         SSVAL(outbuf,smb_vwv4,1);
161         SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
162         SSVAL(outbuf,smb_vwv10, set_server_zone_offset(t)/60);
163         srv_put_dos_date(outbuf,smb_vwv8,t);
164
165         return (smb_len(outbuf)+4);
166 }
167
168 /****************************************************************************
169  Generate the spnego negprot reply blob. Return the number of bytes used.
170 ****************************************************************************/
171
172 static int negprot_spnego(char *p)
173 {
174         DATA_BLOB blob;
175         nstring dos_name;
176         fstring unix_name;
177         char guid[17];
178         const char *OIDs_krb5[] = {OID_KERBEROS5,
179                                    OID_KERBEROS5_OLD,
180                                    OID_NTLMSSP,
181                                    NULL};
182         const char *OIDs_plain[] = {OID_NTLMSSP, NULL};
183         int len;
184
185         global_spnego_negotiated = True;
186
187         ZERO_STRUCT(guid);
188
189         safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1);
190         strlower_m(unix_name);
191         push_ascii_nstring(dos_name, unix_name);
192         safe_strcpy(guid, dos_name, sizeof(guid)-1);
193
194         /* strangely enough, NT does not sent the single OID NTLMSSP when
195            not a ADS member, it sends no OIDs at all
196
197            OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know
198                    about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
199
200            Our sessionsetup code now handles raw NTLMSSP connects, so we can go
201            back to doing what W2K3 does here. This is needed to make PocketPC 2003
202            CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
203            for details. JRA.
204
205         */
206
207         if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) {
208 #if 0
209                 /* Code for PocketPC client */
210                 blob = data_blob(guid, 16);
211 #else
212                 /* Code for standalone WXP client */
213                 blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE");
214 #endif
215         } else {
216                 fstring myname;
217                 char *host_princ_s = NULL;
218                 name_to_fqdn(myname, global_myname());
219                 strlower_m(myname);
220                 asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm());
221                 blob = spnego_gen_negTokenInit(guid, OIDs_krb5, host_princ_s);
222                 SAFE_FREE(host_princ_s);
223         }
224
225         memcpy(p, blob.data, blob.length);
226         len = blob.length;
227         if (len > 256) {
228                 DEBUG(0,("negprot_spnego: blob length too long (%d)\n", len));
229                 len = 255;
230         }
231         data_blob_free(&blob);
232
233         return len;
234 }
235
236 /****************************************************************************
237  Reply for the nt protocol.
238 ****************************************************************************/
239
240 static int reply_nt1(char *inbuf, char *outbuf)
241 {
242         /* dual names + lock_and_read + nt SMBs + remote API calls */
243         int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
244                 CAP_LEVEL_II_OPLOCKS;
245
246         int secword=0;
247         char *p, *q;
248         BOOL negotiate_spnego = False;
249         time_t t = time(NULL);
250
251         global_encrypted_passwords_negotiated = lp_encrypted_passwords();
252
253         /* do spnego in user level security if the client
254            supports it and we can do encrypted passwords */
255         
256         if (global_encrypted_passwords_negotiated && 
257             (lp_security() != SEC_SHARE) &&
258             lp_use_spnego() &&
259             (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) {
260                 negotiate_spnego = True;
261                 capabilities |= CAP_EXTENDED_SECURITY;
262                 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
263                 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply (already
264                         partially constructed. */
265                 SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_EXTENDED_SECURITY);
266         }
267         
268         capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
269
270         if (lp_unix_extensions()) {
271                 capabilities |= CAP_UNIX;
272         }
273         
274         if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
275                 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
276         
277         if (SMB_OFF_T_BITS == 64)
278                 capabilities |= CAP_LARGE_FILES;
279
280         if (lp_readraw() && lp_writeraw())
281                 capabilities |= CAP_RAW_MODE;
282         
283         if (lp_nt_status_support())
284                 capabilities |= CAP_STATUS32;
285         
286         if (lp_host_msdfs())
287                 capabilities |= CAP_DFS;
288         
289         if (lp_security() >= SEC_USER)
290                 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
291         if (global_encrypted_passwords_negotiated)
292                 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
293         
294         if (lp_server_signing()) {
295                 if (lp_security() >= SEC_USER) {
296                         secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
297                         /* No raw mode with smb signing. */
298                         capabilities &= ~CAP_RAW_MODE;
299                         if (lp_server_signing() == Required)
300                                 secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
301                         srv_set_signing_negotiated();
302                 } else {
303                         DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
304                         if (lp_server_signing() == Required) {
305                                 exit_server("reply_nt1: smb signing required and share level security selected.");
306                         }
307                 }
308         }
309
310         set_message(outbuf,17,0,True);
311         
312         SCVAL(outbuf,smb_vwv1,secword);
313         
314         Protocol = PROTOCOL_NT1;
315         
316         SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
317         SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
318         SIVAL(outbuf,smb_vwv3+1,max_recv); /* max buffer. LOTS! */
319         SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
320         SIVAL(outbuf,smb_vwv7+1,sys_getpid()); /* session key */
321         SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
322         put_long_date(outbuf+smb_vwv11+1,t);
323         SSVALS(outbuf,smb_vwv15+1,set_server_zone_offset(t)/60);
324         
325         p = q = smb_buf(outbuf);
326         if (!negotiate_spnego) {
327                 /* Create a token value and add it to the outgoing packet. */
328                 if (global_encrypted_passwords_negotiated) {
329                         /* note that we do not send a challenge at all if
330                            we are using plaintext */
331                         get_challenge(p);
332                         SCVAL(outbuf,smb_vwv16+1,8);
333                         p += 8;
334                 }
335                 p += srvstr_push(outbuf, p, lp_workgroup(), -1, 
336                                  STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
337                 DEBUG(3,("not using SPNEGO\n"));
338         } else {
339                 int len = negprot_spnego(p);
340                 
341                 SCVAL(outbuf,smb_vwv16+1, 0);
342                 p += len;
343                 DEBUG(3,("using SPNEGO\n"));
344         }
345         
346         SSVAL(outbuf,smb_vwv17, p - q); /* length of challenge+domain strings */
347         set_message_end(outbuf, p);
348         
349         return (smb_len(outbuf)+4);
350 }
351
352 /* these are the protocol lists used for auto architecture detection:
353
354 WinNT 3.51:
355 protocol [PC NETWORK PROGRAM 1.0]
356 protocol [XENIX CORE]
357 protocol [MICROSOFT NETWORKS 1.03]
358 protocol [LANMAN1.0]
359 protocol [Windows for Workgroups 3.1a]
360 protocol [LM1.2X002]
361 protocol [LANMAN2.1]
362 protocol [NT LM 0.12]
363
364 Win95:
365 protocol [PC NETWORK PROGRAM 1.0]
366 protocol [XENIX CORE]
367 protocol [MICROSOFT NETWORKS 1.03]
368 protocol [LANMAN1.0]
369 protocol [Windows for Workgroups 3.1a]
370 protocol [LM1.2X002]
371 protocol [LANMAN2.1]
372 protocol [NT LM 0.12]
373
374 Win2K:
375 protocol [PC NETWORK PROGRAM 1.0]
376 protocol [LANMAN1.0]
377 protocol [Windows for Workgroups 3.1a]
378 protocol [LM1.2X002]
379 protocol [LANMAN2.1]
380 protocol [NT LM 0.12]
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
390 /*
391   * Modified to recognize the architecture of the remote machine better.
392   *
393   * This appears to be the matrix of which protocol is used by which
394   * MS product.
395        Protocol                       WfWg    Win95   WinNT  Win2K  OS/2
396        PC NETWORK PROGRAM 1.0          1       1       1      1      1
397        XENIX CORE                                      2             2
398        MICROSOFT NETWORKS 3.0          2       2       
399        DOS LM1.2X002                   3       3       
400        MICROSOFT NETWORKS 1.03                         3
401        DOS LANMAN2.1                   4       4       
402        LANMAN1.0                                       4      2      3
403        Windows for Workgroups 3.1a     5       5       5      3
404        LM1.2X002                                       6      4      4
405        LANMAN2.1                                       7      5      5
406        NT LM 0.12                              6       8      6
407   *
408   *  tim@fsg.com 09/29/95
409   *  Win2K added by matty 17/7/99
410   */
411   
412 #define ARCH_WFWG     0x3      /* This is a fudge because WfWg is like Win95 */
413 #define ARCH_WIN95    0x2
414 #define ARCH_WINNT    0x4
415 #define ARCH_WIN2K    0xC      /* Win2K is like NT */
416 #define ARCH_OS2      0x14     /* Again OS/2 is like NT */
417 #define ARCH_SAMBA    0x20
418 #define ARCH_CIFSFS   0x40
419  
420 #define ARCH_ALL      0x7F
421  
422 /* List of supported protocols, most desired first */
423 static const struct {
424         const char *proto_name;
425         const char *short_name;
426         int (*proto_reply_fn)(char *, char *);
427         int protocol_level;
428 } supported_protocols[] = {
429         {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
430         {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
431         {"POSIX 2",                 "NT1",      reply_nt1,      PROTOCOL_NT1},
432         {"LANMAN2.1",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
433         {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
434         {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
435         {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
436         {"LANMAN1.0",               "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
437         {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
438         {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
439         {"PC NETWORK PROGRAM 1.0",  "CORE",     reply_corep,    PROTOCOL_CORE}, 
440         {NULL,NULL,NULL,0},
441 };
442
443 /****************************************************************************
444  Reply to a negprot.
445  conn POINTER CAN BE NULL HERE !
446 ****************************************************************************/
447
448 int reply_negprot(connection_struct *conn, 
449                   char *inbuf,char *outbuf, int dum_size, 
450                   int dum_buffsize)
451 {
452         int outsize = set_message(outbuf,1,0,True);
453         int Index=0;
454         int choice= -1;
455         int protocol;
456         char *p;
457         int bcc = SVAL(smb_buf(inbuf),-2);
458         int arch = ARCH_ALL;
459
460         static BOOL done_negprot = False;
461
462         START_PROFILE(SMBnegprot);
463
464         if (done_negprot) {
465                 END_PROFILE(SMBnegprot);
466                 exit_server("multiple negprot's are not permitted");
467         }
468         done_negprot = True;
469
470         p = smb_buf(inbuf)+1;
471         while (p < (smb_buf(inbuf) + bcc)) { 
472                 Index++;
473                 DEBUG(3,("Requested protocol [%s]\n",p));
474                 if (strcsequal(p,"Windows for Workgroups 3.1a"))
475                         arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K );
476                 else if (strcsequal(p,"DOS LM1.2X002"))
477                         arch &= ( ARCH_WFWG | ARCH_WIN95 );
478                 else if (strcsequal(p,"DOS LANMAN2.1"))
479                         arch &= ( ARCH_WFWG | ARCH_WIN95 );
480                 else if (strcsequal(p,"NT LM 0.12"))
481                         arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K | ARCH_CIFSFS);
482                 else if (strcsequal(p,"LANMAN2.1"))
483                         arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
484                 else if (strcsequal(p,"LM1.2X002"))
485                         arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
486                 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
487                         arch &= ARCH_WINNT;
488                 else if (strcsequal(p,"XENIX CORE"))
489                         arch &= ( ARCH_WINNT | ARCH_OS2 );
490                 else if (strcsequal(p,"Samba")) {
491                         arch = ARCH_SAMBA;
492                         break;
493                 } else if (strcsequal(p,"POSIX 2")) {
494                         arch = ARCH_CIFSFS;
495                         break;
496                 }
497  
498                 p += strlen(p) + 2;
499         }
500
501         /* CIFSFS can send one arch only, NT LM 0.12. */
502         if (Index == 1 && (arch & ARCH_CIFSFS)) {
503                 arch = ARCH_CIFSFS;
504         }
505
506         switch ( arch ) {
507                 case ARCH_CIFSFS:
508                         set_remote_arch(RA_CIFSFS);
509                         break;
510                 case ARCH_SAMBA:
511                         set_remote_arch(RA_SAMBA);
512                         break;
513                 case ARCH_WFWG:
514                         set_remote_arch(RA_WFWG);
515                         break;
516                 case ARCH_WIN95:
517                         set_remote_arch(RA_WIN95);
518                         break;
519                 case ARCH_WINNT:
520                         if(SVAL(inbuf,smb_flg2)==FLAGS2_WIN2K_SIGNATURE)
521                                 set_remote_arch(RA_WIN2K);
522                         else
523                                 set_remote_arch(RA_WINNT);
524                         break;
525                 case ARCH_WIN2K:
526                         set_remote_arch(RA_WIN2K);
527                         break;
528                 case ARCH_OS2:
529                         set_remote_arch(RA_OS2);
530                         break;
531                 default:
532                         set_remote_arch(RA_UNKNOWN);
533                 break;
534         }
535  
536         /* possibly reload - change of architecture */
537         reload_services(True);      
538         
539         /* moved from the netbios session setup code since we don't have that 
540            when the client connects to port 445.  Of course there is a small
541            window where we are listening to messages   -- jerry */
542
543         claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
544     
545         /* Check for protocols, most desirable first */
546         for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
547                 p = smb_buf(inbuf)+1;
548                 Index = 0;
549                 if ((supported_protocols[protocol].protocol_level <= lp_maxprotocol()) &&
550                                 (supported_protocols[protocol].protocol_level >= lp_minprotocol()))
551                         while (p < (smb_buf(inbuf) + bcc)) { 
552                                 if (strequal(p,supported_protocols[protocol].proto_name))
553                                         choice = Index;
554                                 Index++;
555                                 p += strlen(p) + 2;
556                         }
557                 if(choice != -1)
558                         break;
559         }
560   
561         SSVAL(outbuf,smb_vwv0,choice);
562         if(choice != -1) {
563                 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
564                 reload_services(True);          
565                 outsize = supported_protocols[protocol].proto_reply_fn(inbuf, outbuf);
566                 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
567         } else {
568                 DEBUG(0,("No protocol supported !\n"));
569         }
570         SSVAL(outbuf,smb_vwv0,choice);
571   
572         DEBUG( 5, ( "negprot index=%d\n", choice ) );
573
574         if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) {
575                 exit_server("SMB signing is required and client negotiated a downlevel protocol");
576         }
577
578         END_PROFILE(SMBnegprot);
579         return(outsize);
580 }