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