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