r18761: Even if only offering NTLMSSP Windows (tested with Vista & XP) sends 0 as the
[tprouty/samba.git] / source / 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, uint8 *pkeylen)
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         *pkeylen = 0;
234
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  conn POINTER CAN BE NULL HERE !
449 ****************************************************************************/
450
451 int reply_negprot(connection_struct *conn, 
452                   char *inbuf,char *outbuf, int dum_size, 
453                   int dum_buffsize)
454 {
455         int outsize = set_message(outbuf,1,0,True);
456         int Index=0;
457         int choice= -1;
458         int protocol;
459         char *p;
460         int bcc = SVAL(smb_buf(inbuf),-2);
461         int arch = ARCH_ALL;
462
463         static BOOL done_negprot = False;
464
465         START_PROFILE(SMBnegprot);
466
467         if (done_negprot) {
468                 END_PROFILE(SMBnegprot);
469                 exit_server("multiple negprot's are not permitted");
470         }
471         done_negprot = True;
472
473         p = smb_buf(inbuf)+1;
474         while (p < (smb_buf(inbuf) + bcc)) { 
475                 Index++;
476                 DEBUG(3,("Requested protocol [%s]\n",p));
477                 if (strcsequal(p,"Windows for Workgroups 3.1a"))
478                         arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K );
479                 else if (strcsequal(p,"DOS LM1.2X002"))
480                         arch &= ( ARCH_WFWG | ARCH_WIN95 );
481                 else if (strcsequal(p,"DOS LANMAN2.1"))
482                         arch &= ( ARCH_WFWG | ARCH_WIN95 );
483                 else if (strcsequal(p,"NT LM 0.12"))
484                         arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K | ARCH_CIFSFS);
485                 else if (strcsequal(p,"LANMAN2.1"))
486                         arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
487                 else if (strcsequal(p,"LM1.2X002"))
488                         arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
489                 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
490                         arch &= ARCH_WINNT;
491                 else if (strcsequal(p,"XENIX CORE"))
492                         arch &= ( ARCH_WINNT | ARCH_OS2 );
493                 else if (strcsequal(p,"Samba")) {
494                         arch = ARCH_SAMBA;
495                         break;
496                 } else if (strcsequal(p,"POSIX 2")) {
497                         arch = ARCH_CIFSFS;
498                         break;
499                 }
500  
501                 p += strlen(p) + 2;
502         }
503
504         /* CIFSFS can send one arch only, NT LM 0.12. */
505         if (Index == 1 && (arch & ARCH_CIFSFS)) {
506                 arch = ARCH_CIFSFS;
507         }
508
509         switch ( arch ) {
510                 case ARCH_CIFSFS:
511                         set_remote_arch(RA_CIFSFS);
512                         break;
513                 case ARCH_SAMBA:
514                         set_remote_arch(RA_SAMBA);
515                         break;
516                 case ARCH_WFWG:
517                         set_remote_arch(RA_WFWG);
518                         break;
519                 case ARCH_WIN95:
520                         set_remote_arch(RA_WIN95);
521                         break;
522                 case ARCH_WINNT:
523                         if(SVAL(inbuf,smb_flg2)==FLAGS2_WIN2K_SIGNATURE)
524                                 set_remote_arch(RA_WIN2K);
525                         else
526                                 set_remote_arch(RA_WINNT);
527                         break;
528                 case ARCH_WIN2K:
529                         set_remote_arch(RA_WIN2K);
530                         break;
531                 case ARCH_OS2:
532                         set_remote_arch(RA_OS2);
533                         break;
534                 default:
535                         set_remote_arch(RA_UNKNOWN);
536                 break;
537         }
538  
539         /* possibly reload - change of architecture */
540         reload_services(True);      
541         
542         /* moved from the netbios session setup code since we don't have that 
543            when the client connects to port 445.  Of course there is a small
544            window where we are listening to messages   -- jerry */
545
546         claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
547     
548         /* Check for protocols, most desirable first */
549         for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
550                 p = smb_buf(inbuf)+1;
551                 Index = 0;
552                 if ((supported_protocols[protocol].protocol_level <= lp_maxprotocol()) &&
553                                 (supported_protocols[protocol].protocol_level >= lp_minprotocol()))
554                         while (p < (smb_buf(inbuf) + bcc)) { 
555                                 if (strequal(p,supported_protocols[protocol].proto_name))
556                                         choice = Index;
557                                 Index++;
558                                 p += strlen(p) + 2;
559                         }
560                 if(choice != -1)
561                         break;
562         }
563   
564         SSVAL(outbuf,smb_vwv0,choice);
565         if(choice != -1) {
566                 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
567                 reload_services(True);          
568                 outsize = supported_protocols[protocol].proto_reply_fn(inbuf, outbuf);
569                 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
570         } else {
571                 DEBUG(0,("No protocol supported !\n"));
572         }
573         SSVAL(outbuf,smb_vwv0,choice);
574   
575         DEBUG( 5, ( "negprot index=%d\n", choice ) );
576
577         if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) {
578                 exit_server("SMB signing is required and client negotiated a downlevel protocol");
579         }
580
581         END_PROFILE(SMBnegprot);
582         return(outsize);
583 }