bbd101305090517bdccfe333345af1eb33314c38
[nivanova/samba-autobuild/.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 DATA_BLOB negprot_spnego(void)
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
184         global_spnego_negotiated = True;
185
186         ZERO_STRUCT(guid);
187
188         safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1);
189         strlower_m(unix_name);
190         push_ascii_nstring(dos_name, unix_name);
191         safe_strcpy(guid, dos_name, sizeof(guid)-1);
192
193         /* strangely enough, NT does not sent the single OID NTLMSSP when
194            not a ADS member, it sends no OIDs at all
195
196            OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know
197                    about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
198
199            Our sessionsetup code now handles raw NTLMSSP connects, so we can go
200            back to doing what W2K3 does here. This is needed to make PocketPC 2003
201            CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
202            for details. JRA.
203
204         */
205
206         if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) {
207 #if 0
208                 /* Code for PocketPC client */
209                 blob = data_blob(guid, 16);
210 #else
211                 /* Code for standalone WXP client */
212                 blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE");
213 #endif
214         } else {
215                 fstring myname;
216                 char *host_princ_s = NULL;
217                 name_to_fqdn(myname, global_myname());
218                 strlower_m(myname);
219                 asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm());
220                 blob = spnego_gen_negTokenInit(guid, OIDs_krb5, host_princ_s);
221                 SAFE_FREE(host_princ_s);
222         }
223
224         return blob;
225 }
226
227 /****************************************************************************
228  Reply for the nt protocol.
229 ****************************************************************************/
230
231 static int reply_nt1(char *inbuf, char *outbuf)
232 {
233         /* dual names + lock_and_read + nt SMBs + remote API calls */
234         int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
235                 CAP_LEVEL_II_OPLOCKS;
236
237         int secword=0;
238         char *p, *q;
239         BOOL negotiate_spnego = False;
240         time_t t = time(NULL);
241
242         global_encrypted_passwords_negotiated = lp_encrypted_passwords();
243
244         /* do spnego in user level security if the client
245            supports it and we can do encrypted passwords */
246         
247         if (global_encrypted_passwords_negotiated && 
248             (lp_security() != SEC_SHARE) &&
249             lp_use_spnego() &&
250             (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) {
251                 negotiate_spnego = True;
252                 capabilities |= CAP_EXTENDED_SECURITY;
253                 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
254                 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply (already
255                         partially constructed. */
256                 SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_EXTENDED_SECURITY);
257         }
258         
259         capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
260
261         if (lp_unix_extensions()) {
262                 capabilities |= CAP_UNIX;
263         }
264         
265         if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
266                 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
267         
268         if (SMB_OFF_T_BITS == 64)
269                 capabilities |= CAP_LARGE_FILES;
270
271         if (lp_readraw() && lp_writeraw())
272                 capabilities |= CAP_RAW_MODE;
273         
274         if (lp_nt_status_support())
275                 capabilities |= CAP_STATUS32;
276         
277         if (lp_host_msdfs())
278                 capabilities |= CAP_DFS;
279         
280         if (lp_security() >= SEC_USER)
281                 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
282         if (global_encrypted_passwords_negotiated)
283                 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
284         
285         if (lp_server_signing()) {
286                 if (lp_security() >= SEC_USER) {
287                         secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
288                         /* No raw mode with smb signing. */
289                         capabilities &= ~CAP_RAW_MODE;
290                         if (lp_server_signing() == Required)
291                                 secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
292                         srv_set_signing_negotiated();
293                 } else {
294                         DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
295                         if (lp_server_signing() == Required) {
296                                 exit_server("reply_nt1: smb signing required and share level security selected.");
297                         }
298                 }
299         }
300
301         set_message(outbuf,17,0,True);
302         
303         SCVAL(outbuf,smb_vwv1,secword);
304         
305         Protocol = PROTOCOL_NT1;
306         
307         SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
308         SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
309         SIVAL(outbuf,smb_vwv3+1,max_recv); /* max buffer. LOTS! */
310         SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
311         SIVAL(outbuf,smb_vwv7+1,sys_getpid()); /* session key */
312         SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
313         put_long_date(outbuf+smb_vwv11+1,t);
314         SSVALS(outbuf,smb_vwv15+1,set_server_zone_offset(t)/60);
315         
316         p = q = smb_buf(outbuf);
317         if (!negotiate_spnego) {
318                 /* Create a token value and add it to the outgoing packet. */
319                 if (global_encrypted_passwords_negotiated) {
320                         /* note that we do not send a challenge at all if
321                            we are using plaintext */
322                         get_challenge(p);
323                         SCVAL(outbuf,smb_vwv16+1,8);
324                         p += 8;
325                 }
326                 p += srvstr_push(outbuf, p, lp_workgroup(), -1, 
327                                  STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
328                 DEBUG(3,("not using SPNEGO\n"));
329         } else {
330                 DATA_BLOB spnego_blob = negprot_spnego();
331
332                 if (spnego_blob.data == NULL) {
333                         return ERROR_NT(NT_STATUS_NO_MEMORY);
334                 }
335
336                 memcpy(p, spnego_blob.data, spnego_blob.length);
337                 p += spnego_blob.length;
338                 data_blob_free(&spnego_blob);
339
340                 SCVAL(outbuf,smb_vwv16+1, 0);
341                 DEBUG(3,("using SPNEGO\n"));
342         }
343         
344         SSVAL(outbuf,smb_vwv17, p - q); /* length of challenge+domain strings */
345         set_message_end(outbuf, p);
346         
347         return (smb_len(outbuf)+4);
348 }
349
350 /* these are the protocol lists used for auto architecture detection:
351
352 WinNT 3.51:
353 protocol [PC NETWORK PROGRAM 1.0]
354 protocol [XENIX CORE]
355 protocol [MICROSOFT NETWORKS 1.03]
356 protocol [LANMAN1.0]
357 protocol [Windows for Workgroups 3.1a]
358 protocol [LM1.2X002]
359 protocol [LANMAN2.1]
360 protocol [NT LM 0.12]
361
362 Win95:
363 protocol [PC NETWORK PROGRAM 1.0]
364 protocol [XENIX CORE]
365 protocol [MICROSOFT NETWORKS 1.03]
366 protocol [LANMAN1.0]
367 protocol [Windows for Workgroups 3.1a]
368 protocol [LM1.2X002]
369 protocol [LANMAN2.1]
370 protocol [NT LM 0.12]
371
372 Win2K:
373 protocol [PC NETWORK PROGRAM 1.0]
374 protocol [LANMAN1.0]
375 protocol [Windows for Workgroups 3.1a]
376 protocol [LM1.2X002]
377 protocol [LANMAN2.1]
378 protocol [NT LM 0.12]
379
380 OS/2:
381 protocol [PC NETWORK PROGRAM 1.0]
382 protocol [XENIX CORE]
383 protocol [LANMAN1.0]
384 protocol [LM1.2X002]
385 protocol [LANMAN2.1]
386 */
387
388 /*
389   * Modified to recognize the architecture of the remote machine better.
390   *
391   * This appears to be the matrix of which protocol is used by which
392   * MS product.
393        Protocol                       WfWg    Win95   WinNT  Win2K  OS/2
394        PC NETWORK PROGRAM 1.0          1       1       1      1      1
395        XENIX CORE                                      2             2
396        MICROSOFT NETWORKS 3.0          2       2       
397        DOS LM1.2X002                   3       3       
398        MICROSOFT NETWORKS 1.03                         3
399        DOS LANMAN2.1                   4       4       
400        LANMAN1.0                                       4      2      3
401        Windows for Workgroups 3.1a     5       5       5      3
402        LM1.2X002                                       6      4      4
403        LANMAN2.1                                       7      5      5
404        NT LM 0.12                              6       8      6
405   *
406   *  tim@fsg.com 09/29/95
407   *  Win2K added by matty 17/7/99
408   */
409   
410 #define ARCH_WFWG     0x3      /* This is a fudge because WfWg is like Win95 */
411 #define ARCH_WIN95    0x2
412 #define ARCH_WINNT    0x4
413 #define ARCH_WIN2K    0xC      /* Win2K is like NT */
414 #define ARCH_OS2      0x14     /* Again OS/2 is like NT */
415 #define ARCH_SAMBA    0x20
416 #define ARCH_CIFSFS   0x40
417  
418 #define ARCH_ALL      0x7F
419  
420 /* List of supported protocols, most desired first */
421 static const struct {
422         const char *proto_name;
423         const char *short_name;
424         int (*proto_reply_fn)(char *, char *);
425         int protocol_level;
426 } supported_protocols[] = {
427         {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
428         {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
429         {"POSIX 2",                 "NT1",      reply_nt1,      PROTOCOL_NT1},
430         {"LANMAN2.1",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
431         {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
432         {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
433         {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
434         {"LANMAN1.0",               "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
435         {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
436         {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
437         {"PC NETWORK PROGRAM 1.0",  "CORE",     reply_corep,    PROTOCOL_CORE}, 
438         {NULL,NULL,NULL,0},
439 };
440
441 /****************************************************************************
442  Reply to a negprot.
443  conn POINTER CAN BE NULL HERE !
444 ****************************************************************************/
445
446 int reply_negprot(connection_struct *conn, 
447                   char *inbuf,char *outbuf, int dum_size, 
448                   int dum_buffsize)
449 {
450         int outsize = set_message(outbuf,1,0,True);
451         int Index=0;
452         int choice= -1;
453         int protocol;
454         char *p;
455         int bcc = SVAL(smb_buf(inbuf),-2);
456         int arch = ARCH_ALL;
457
458         static BOOL done_negprot = False;
459
460         START_PROFILE(SMBnegprot);
461
462         if (done_negprot) {
463                 END_PROFILE(SMBnegprot);
464                 exit_server("multiple negprot's are not permitted");
465         }
466         done_negprot = True;
467
468         p = smb_buf(inbuf)+1;
469         while (p < (smb_buf(inbuf) + bcc)) { 
470                 Index++;
471                 DEBUG(3,("Requested protocol [%s]\n",p));
472                 if (strcsequal(p,"Windows for Workgroups 3.1a"))
473                         arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K );
474                 else if (strcsequal(p,"DOS LM1.2X002"))
475                         arch &= ( ARCH_WFWG | ARCH_WIN95 );
476                 else if (strcsequal(p,"DOS LANMAN2.1"))
477                         arch &= ( ARCH_WFWG | ARCH_WIN95 );
478                 else if (strcsequal(p,"NT LM 0.12"))
479                         arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K | ARCH_CIFSFS);
480                 else if (strcsequal(p,"LANMAN2.1"))
481                         arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
482                 else if (strcsequal(p,"LM1.2X002"))
483                         arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
484                 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
485                         arch &= ARCH_WINNT;
486                 else if (strcsequal(p,"XENIX CORE"))
487                         arch &= ( ARCH_WINNT | ARCH_OS2 );
488                 else if (strcsequal(p,"Samba")) {
489                         arch = ARCH_SAMBA;
490                         break;
491                 } else if (strcsequal(p,"POSIX 2")) {
492                         arch = ARCH_CIFSFS;
493                         break;
494                 }
495  
496                 p += strlen(p) + 2;
497         }
498
499         /* CIFSFS can send one arch only, NT LM 0.12. */
500         if (Index == 1 && (arch & ARCH_CIFSFS)) {
501                 arch = ARCH_CIFSFS;
502         }
503
504         switch ( arch ) {
505                 case ARCH_CIFSFS:
506                         set_remote_arch(RA_CIFSFS);
507                         break;
508                 case ARCH_SAMBA:
509                         set_remote_arch(RA_SAMBA);
510                         break;
511                 case ARCH_WFWG:
512                         set_remote_arch(RA_WFWG);
513                         break;
514                 case ARCH_WIN95:
515                         set_remote_arch(RA_WIN95);
516                         break;
517                 case ARCH_WINNT:
518                         if(SVAL(inbuf,smb_flg2)==FLAGS2_WIN2K_SIGNATURE)
519                                 set_remote_arch(RA_WIN2K);
520                         else
521                                 set_remote_arch(RA_WINNT);
522                         break;
523                 case ARCH_WIN2K:
524                         set_remote_arch(RA_WIN2K);
525                         break;
526                 case ARCH_OS2:
527                         set_remote_arch(RA_OS2);
528                         break;
529                 default:
530                         set_remote_arch(RA_UNKNOWN);
531                 break;
532         }
533  
534         /* possibly reload - change of architecture */
535         reload_services(True);      
536         
537         /* moved from the netbios session setup code since we don't have that 
538            when the client connects to port 445.  Of course there is a small
539            window where we are listening to messages   -- jerry */
540
541         claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
542     
543         /* Check for protocols, most desirable first */
544         for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
545                 p = smb_buf(inbuf)+1;
546                 Index = 0;
547                 if ((supported_protocols[protocol].protocol_level <= lp_maxprotocol()) &&
548                                 (supported_protocols[protocol].protocol_level >= lp_minprotocol()))
549                         while (p < (smb_buf(inbuf) + bcc)) { 
550                                 if (strequal(p,supported_protocols[protocol].proto_name))
551                                         choice = Index;
552                                 Index++;
553                                 p += strlen(p) + 2;
554                         }
555                 if(choice != -1)
556                         break;
557         }
558   
559         SSVAL(outbuf,smb_vwv0,choice);
560         if(choice != -1) {
561                 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
562                 reload_services(True);          
563                 outsize = supported_protocols[protocol].proto_reply_fn(inbuf, outbuf);
564                 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
565         } else {
566                 DEBUG(0,("No protocol supported !\n"));
567         }
568         SSVAL(outbuf,smb_vwv0,choice);
569   
570         DEBUG( 5, ( "negprot index=%d\n", choice ) );
571
572         if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) {
573                 exit_server("SMB signing is required and client negotiated a downlevel protocol");
574         }
575
576         END_PROFILE(SMBnegprot);
577         return(outsize);
578 }