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