2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1992-1998
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.
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.
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.
23 extern fstring remote_proto;
24 extern enum protocol_types Protocol;
27 BOOL global_encrypted_passwords_negotiated = False;
28 BOOL global_spnego_negotiated = False;
29 struct auth_context *negprot_global_auth_context = NULL;
31 static void get_challenge(char buff[8])
34 const uint8 *cryptkey;
36 /* We might be called more than once, multiple negprots are
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);
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!");
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);
53 /****************************************************************************
54 Reply for the core protocol.
55 ****************************************************************************/
57 static int reply_corep(char *inbuf, char *outbuf)
59 int outsize = set_message(inbuf,outbuf,1,0,True);
61 Protocol = PROTOCOL_CORE;
66 /****************************************************************************
67 Reply for the coreplus protocol.
68 ****************************************************************************/
70 static int reply_coreplus(char *inbuf, char *outbuf)
72 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
73 int outsize = set_message(inbuf,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 */
80 Protocol = PROTOCOL_COREPLUS;
85 /****************************************************************************
86 Reply for the lanman 1.0 protocol.
87 ****************************************************************************/
89 static int reply_lanman1(char *inbuf, char *outbuf)
91 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
93 time_t t = time(NULL);
95 global_encrypted_passwords_negotiated = lp_encrypted_passwords();
97 if (lp_security()>=SEC_USER)
98 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
99 if (global_encrypted_passwords_negotiated)
100 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
102 set_message(inbuf,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);
110 Protocol = PROTOCOL_LANMAN1;
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);
122 srv_put_dos_date(outbuf,smb_vwv8,t);
124 return (smb_len(outbuf)+4);
127 /****************************************************************************
128 Reply for the lanman 2.0 protocol.
129 ****************************************************************************/
131 static int reply_lanman2(char *inbuf, char *outbuf)
133 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
135 time_t t = time(NULL);
137 global_encrypted_passwords_negotiated = lp_encrypted_passwords();
139 if (lp_security()>=SEC_USER)
140 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
141 if (global_encrypted_passwords_negotiated)
142 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
144 set_message(inbuf,outbuf,13,global_encrypted_passwords_negotiated?8:0,True);
145 SSVAL(outbuf,smb_vwv1,secword);
146 SIVAL(outbuf,smb_vwv6,sys_getpid());
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);
154 Protocol = PROTOCOL_LANMAN2;
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);
165 return (smb_len(outbuf)+4);
168 /****************************************************************************
169 Generate the spnego negprot reply blob. Return the number of bytes used.
170 ****************************************************************************/
172 static DATA_BLOB negprot_spnego(void)
181 const char *OIDs_krb5[] = {OID_KERBEROS5,
185 const char *OIDs_plain[] = {OID_NTLMSSP, NULL};
187 global_spnego_negotiated = True;
189 memset(guid, '\0', sizeof(guid));
191 safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1);
192 strlower_m(unix_name);
193 push_ascii_nstring(dos_name, unix_name);
194 safe_strcpy(guid, dos_name, sizeof(guid)-1);
197 /* Fix valgrind 'uninitialized bytes' issue. */
198 slen = strlen(dos_name);
199 if (slen < sizeof(guid)) {
200 memset(guid+slen, '\0', sizeof(guid) - slen);
204 /* strangely enough, NT does not sent the single OID NTLMSSP when
205 not a ADS member, it sends no OIDs at all
207 OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know
208 about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
210 Our sessionsetup code now handles raw NTLMSSP connects, so we can go
211 back to doing what W2K3 does here. This is needed to make PocketPC 2003
212 CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
217 if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) {
219 /* Code for PocketPC client */
220 blob = data_blob(guid, 16);
222 /* Code for standalone WXP client */
223 blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE");
227 char *host_princ_s = NULL;
228 name_to_fqdn(myname, global_myname());
230 asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm());
231 if (host_princ_s == NULL) {
232 blob = data_blob_null;
235 blob = spnego_gen_negTokenInit(guid, OIDs_krb5, host_princ_s);
236 SAFE_FREE(host_princ_s);
242 /****************************************************************************
243 Reply for the nt protocol.
244 ****************************************************************************/
246 static int reply_nt1(char *inbuf, char *outbuf)
248 /* dual names + lock_and_read + nt SMBs + remote API calls */
249 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
250 CAP_LEVEL_II_OPLOCKS;
254 BOOL negotiate_spnego = False;
255 time_t t = time(NULL);
257 global_encrypted_passwords_negotiated = lp_encrypted_passwords();
259 /* Check the flags field to see if this is Vista.
260 WinXP sets it and Vista does not. But we have to
261 distinguish from NT which doesn't set it either. */
263 if ( (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY) &&
264 ((SVAL(inbuf, smb_flg2) & FLAGS2_UNKNOWN_BIT4) == 0) )
266 if (get_remote_arch() != RA_SAMBA) {
267 set_remote_arch( RA_VISTA );
271 /* do spnego in user level security if the client
272 supports it and we can do encrypted passwords */
274 if (global_encrypted_passwords_negotiated &&
275 (lp_security() != SEC_SHARE) &&
277 (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) {
278 negotiate_spnego = True;
279 capabilities |= CAP_EXTENDED_SECURITY;
280 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
281 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply (already
282 partially constructed. */
283 SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_EXTENDED_SECURITY);
286 capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
288 if (lp_unix_extensions()) {
289 capabilities |= CAP_UNIX;
292 if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
293 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
295 if (SMB_OFF_T_BITS == 64)
296 capabilities |= CAP_LARGE_FILES;
298 if (lp_readraw() && lp_writeraw())
299 capabilities |= CAP_RAW_MODE;
301 if (lp_nt_status_support())
302 capabilities |= CAP_STATUS32;
305 capabilities |= CAP_DFS;
307 if (lp_security() >= SEC_USER)
308 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
309 if (global_encrypted_passwords_negotiated)
310 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
312 if (lp_server_signing()) {
313 if (lp_security() >= SEC_USER) {
314 secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
315 /* No raw mode with smb signing. */
316 capabilities &= ~CAP_RAW_MODE;
317 if (lp_server_signing() == Required)
318 secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
319 srv_set_signing_negotiated();
321 DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
322 if (lp_server_signing() == Required) {
323 exit_server_cleanly("reply_nt1: smb signing required and share level security selected.");
328 set_message(inbuf,outbuf,17,0,True);
330 SCVAL(outbuf,smb_vwv1,secword);
332 Protocol = PROTOCOL_NT1;
334 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
335 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
336 SIVAL(outbuf,smb_vwv3+1,max_recv); /* max buffer. LOTS! */
337 SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
338 SIVAL(outbuf,smb_vwv7+1,sys_getpid()); /* session key */
339 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
340 put_long_date(outbuf+smb_vwv11+1,t);
341 SSVALS(outbuf,smb_vwv15+1,set_server_zone_offset(t)/60);
343 p = q = smb_buf(outbuf);
344 if (!negotiate_spnego) {
345 /* Create a token value and add it to the outgoing packet. */
346 if (global_encrypted_passwords_negotiated) {
347 /* note that we do not send a challenge at all if
348 we are using plaintext */
350 SCVAL(outbuf,smb_vwv16+1,8);
353 p += srvstr_push(outbuf, p, lp_workgroup(), -1,
354 STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
355 DEBUG(3,("not using SPNEGO\n"));
357 DATA_BLOB spnego_blob = negprot_spnego();
359 if (spnego_blob.data == NULL) {
360 return ERROR_NT(NT_STATUS_NO_MEMORY);
363 memcpy(p, spnego_blob.data, spnego_blob.length);
364 p += spnego_blob.length;
365 data_blob_free(&spnego_blob);
367 SCVAL(outbuf,smb_vwv16+1, 0);
368 DEBUG(3,("using SPNEGO\n"));
371 SSVAL(outbuf,smb_vwv17, p - q); /* length of challenge+domain strings */
372 set_message_end(inbuf,outbuf, p);
374 return (smb_len(outbuf)+4);
377 /* these are the protocol lists used for auto architecture detection:
380 protocol [PC NETWORK PROGRAM 1.0]
381 protocol [XENIX CORE]
382 protocol [MICROSOFT NETWORKS 1.03]
384 protocol [Windows for Workgroups 3.1a]
387 protocol [NT LM 0.12]
390 protocol [PC NETWORK PROGRAM 1.0]
391 protocol [XENIX CORE]
392 protocol [MICROSOFT NETWORKS 1.03]
394 protocol [Windows for Workgroups 3.1a]
397 protocol [NT LM 0.12]
400 protocol [PC NETWORK PROGRAM 1.0]
402 protocol [Windows for Workgroups 3.1a]
405 protocol [NT LM 0.12]
408 protocol [PC NETWORK PROGRAM 1.0]
410 protocol [Windows for Workgroups 3.1a]
413 protocol [NT LM 0.12]
417 protocol [PC NETWORK PROGRAM 1.0]
418 protocol [XENIX CORE]
425 * Modified to recognize the architecture of the remote machine better.
427 * This appears to be the matrix of which protocol is used by which
429 Protocol WfWg Win95 WinNT Win2K OS/2 Vista
430 PC NETWORK PROGRAM 1.0 1 1 1 1 1 1
432 MICROSOFT NETWORKS 3.0 2 2
434 MICROSOFT NETWORKS 1.03 3
437 Windows for Workgroups 3.1a 5 5 5 3 3
443 * tim@fsg.com 09/29/95
444 * Win2K added by matty 17/7/99
447 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
448 #define ARCH_WIN95 0x2
449 #define ARCH_WINNT 0x4
450 #define ARCH_WIN2K 0xC /* Win2K is like NT */
451 #define ARCH_OS2 0x14 /* Again OS/2 is like NT */
452 #define ARCH_SAMBA 0x20
453 #define ARCH_CIFSFS 0x40
454 #define ARCH_VISTA 0x8C /* Vista is like XP/2K */
456 #define ARCH_ALL 0x7F
458 /* List of supported protocols, most desired first */
459 static const struct {
460 const char *proto_name;
461 const char *short_name;
462 int (*proto_reply_fn)(char *, char *);
464 } supported_protocols[] = {
465 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
466 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
467 {"POSIX 2", "NT1", reply_nt1, PROTOCOL_NT1},
468 {"LANMAN2.1", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
469 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
470 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
471 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
472 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
473 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
474 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
475 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
479 /****************************************************************************
481 conn POINTER CAN BE NULL HERE !
482 ****************************************************************************/
484 int reply_negprot(connection_struct *conn,
485 char *inbuf,char *outbuf, int dum_size,
488 int outsize = set_message(inbuf,outbuf,1,0,True);
493 int bcc = SVAL(smb_buf(inbuf),-2);
496 static BOOL done_negprot = False;
498 START_PROFILE(SMBnegprot);
501 END_PROFILE(SMBnegprot);
502 exit_server_cleanly("multiple negprot's are not permitted");
506 p = smb_buf(inbuf)+1;
507 while (p < (smb_buf(inbuf) + bcc)) {
509 DEBUG(3,("Requested protocol [%s]\n",p));
510 if (strcsequal(p,"Windows for Workgroups 3.1a"))
511 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K );
512 else if (strcsequal(p,"DOS LM1.2X002"))
513 arch &= ( ARCH_WFWG | ARCH_WIN95 );
514 else if (strcsequal(p,"DOS LANMAN2.1"))
515 arch &= ( ARCH_WFWG | ARCH_WIN95 );
516 else if (strcsequal(p,"NT LM 0.12"))
517 arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K | ARCH_CIFSFS);
518 else if (strcsequal(p,"SMB 2.001"))
520 else if (strcsequal(p,"LANMAN2.1"))
521 arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
522 else if (strcsequal(p,"LM1.2X002"))
523 arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
524 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
526 else if (strcsequal(p,"XENIX CORE"))
527 arch &= ( ARCH_WINNT | ARCH_OS2 );
528 else if (strcsequal(p,"Samba")) {
531 } else if (strcsequal(p,"POSIX 2")) {
539 /* CIFSFS can send one arch only, NT LM 0.12. */
540 if (Index == 1 && (arch & ARCH_CIFSFS)) {
546 set_remote_arch(RA_CIFSFS);
549 set_remote_arch(RA_SAMBA);
552 set_remote_arch(RA_WFWG);
555 set_remote_arch(RA_WIN95);
558 if(SVAL(inbuf,smb_flg2)==FLAGS2_WIN2K_SIGNATURE)
559 set_remote_arch(RA_WIN2K);
561 set_remote_arch(RA_WINNT);
564 /* Vista may have been set in the negprot so don't
566 if ( get_remote_arch() != RA_VISTA )
567 set_remote_arch(RA_WIN2K);
570 set_remote_arch(RA_VISTA);
573 set_remote_arch(RA_OS2);
576 set_remote_arch(RA_UNKNOWN);
580 /* possibly reload - change of architecture */
581 reload_services(True);
583 /* moved from the netbios session setup code since we don't have that
584 when the client connects to port 445. Of course there is a small
585 window where we are listening to messages -- jerry */
588 NULL,"",FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
590 /* Check for protocols, most desirable first */
591 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
592 p = smb_buf(inbuf)+1;
594 if ((supported_protocols[protocol].protocol_level <= lp_maxprotocol()) &&
595 (supported_protocols[protocol].protocol_level >= lp_minprotocol()))
596 while (p < (smb_buf(inbuf) + bcc)) {
597 if (strequal(p,supported_protocols[protocol].proto_name))
606 SSVAL(outbuf,smb_vwv0,choice);
608 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
609 reload_services(True);
610 outsize = supported_protocols[protocol].proto_reply_fn(inbuf, outbuf);
611 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
613 DEBUG(0,("No protocol supported !\n"));
615 SSVAL(outbuf,smb_vwv0,choice);
617 DEBUG( 5, ( "negprot index=%d\n", choice ) );
619 if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) {
620 exit_server_cleanly("SMB signing is required and "
621 "client negotiated a downlevel protocol");
624 END_PROFILE(SMBnegprot);