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!\n");
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(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(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(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(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 int negprot_spnego(char *p)
178 const char *OIDs_krb5[] = {OID_KERBEROS5,
182 const char *OIDs_plain[] = {OID_NTLMSSP, NULL};
185 global_spnego_negotiated = True;
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);
194 /* strangely enough, NT does not sent the single OID NTLMSSP when
195 not a ADS member, it sends no OIDs at all
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)"
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
207 if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) {
209 /* Code for PocketPC client */
210 blob = data_blob(guid, 16);
212 /* Code for standalone WXP client */
213 blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE");
217 char *host_princ_s = NULL;
218 name_to_fqdn(myname, global_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);
225 memcpy(p, blob.data, blob.length);
228 DEBUG(0,("negprot_spnego: blob length too long (%d)\n", len));
231 data_blob_free(&blob);
236 /****************************************************************************
237 Reply for the nt protocol.
238 ****************************************************************************/
240 static int reply_nt1(char *inbuf, char *outbuf)
242 /* dual names + lock_and_read + nt SMBs + remote API calls */
243 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
244 CAP_LEVEL_II_OPLOCKS;
248 BOOL negotiate_spnego = False;
249 time_t t = time(NULL);
251 global_encrypted_passwords_negotiated = lp_encrypted_passwords();
253 /* do spnego in user level security if the client
254 supports it and we can do encrypted passwords */
256 if (global_encrypted_passwords_negotiated &&
257 (lp_security() != SEC_SHARE) &&
259 (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) {
260 negotiate_spnego = True;
261 capabilities |= CAP_EXTENDED_SECURITY;
262 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
263 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply (already
264 partially constructed. */
265 SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_EXTENDED_SECURITY);
268 capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
270 if (lp_unix_extensions()) {
271 capabilities |= CAP_UNIX;
274 if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
275 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
277 if (SMB_OFF_T_BITS == 64)
278 capabilities |= CAP_LARGE_FILES;
280 if (lp_readraw() && lp_writeraw())
281 capabilities |= CAP_RAW_MODE;
283 if (lp_nt_status_support())
284 capabilities |= CAP_STATUS32;
287 capabilities |= CAP_DFS;
289 if (lp_security() >= SEC_USER)
290 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
291 if (global_encrypted_passwords_negotiated)
292 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
294 if (lp_server_signing()) {
295 if (lp_security() >= SEC_USER) {
296 secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
297 /* No raw mode with smb signing. */
298 capabilities &= ~CAP_RAW_MODE;
299 if (lp_server_signing() == Required)
300 secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
301 srv_set_signing_negotiated();
303 DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
304 if (lp_server_signing() == Required) {
305 exit_server("reply_nt1: smb signing required and share level security selected.");
310 set_message(outbuf,17,0,True);
312 SCVAL(outbuf,smb_vwv1,secword);
314 Protocol = PROTOCOL_NT1;
316 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
317 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
318 SIVAL(outbuf,smb_vwv3+1,max_recv); /* max buffer. LOTS! */
319 SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
320 SIVAL(outbuf,smb_vwv7+1,sys_getpid()); /* session key */
321 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
322 put_long_date(outbuf+smb_vwv11+1,t);
323 SSVALS(outbuf,smb_vwv15+1,set_server_zone_offset(t)/60);
325 p = q = smb_buf(outbuf);
326 if (!negotiate_spnego) {
327 /* Create a token value and add it to the outgoing packet. */
328 if (global_encrypted_passwords_negotiated) {
329 /* note that we do not send a challenge at all if
330 we are using plaintext */
332 SCVAL(outbuf,smb_vwv16+1,8);
335 p += srvstr_push(outbuf, p, lp_workgroup(), -1,
336 STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
337 DEBUG(3,("not using SPNEGO\n"));
339 int len = negprot_spnego(p);
341 SCVAL(outbuf,smb_vwv16+1, 0);
343 DEBUG(3,("using SPNEGO\n"));
346 SSVAL(outbuf,smb_vwv17, p - q); /* length of challenge+domain strings */
347 set_message_end(outbuf, p);
349 return (smb_len(outbuf)+4);
352 /* these are the protocol lists used for auto architecture detection:
355 protocol [PC NETWORK PROGRAM 1.0]
356 protocol [XENIX CORE]
357 protocol [MICROSOFT NETWORKS 1.03]
359 protocol [Windows for Workgroups 3.1a]
362 protocol [NT LM 0.12]
365 protocol [PC NETWORK PROGRAM 1.0]
366 protocol [XENIX CORE]
367 protocol [MICROSOFT NETWORKS 1.03]
369 protocol [Windows for Workgroups 3.1a]
372 protocol [NT LM 0.12]
375 protocol [PC NETWORK PROGRAM 1.0]
377 protocol [Windows for Workgroups 3.1a]
380 protocol [NT LM 0.12]
383 protocol [PC NETWORK PROGRAM 1.0]
384 protocol [XENIX CORE]
391 * Modified to recognize the architecture of the remote machine better.
393 * This appears to be the matrix of which protocol is used by which
395 Protocol WfWg Win95 WinNT Win2K OS/2
396 PC NETWORK PROGRAM 1.0 1 1 1 1 1
398 MICROSOFT NETWORKS 3.0 2 2
400 MICROSOFT NETWORKS 1.03 3
403 Windows for Workgroups 3.1a 5 5 5 3
408 * tim@fsg.com 09/29/95
409 * Win2K added by matty 17/7/99
412 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
413 #define ARCH_WIN95 0x2
414 #define ARCH_WINNT 0x4
415 #define ARCH_WIN2K 0xC /* Win2K is like NT */
416 #define ARCH_OS2 0x14 /* Again OS/2 is like NT */
417 #define ARCH_SAMBA 0x20
418 #define ARCH_CIFSFS 0x40
420 #define ARCH_ALL 0x7F
422 /* List of supported protocols, most desired first */
423 static const struct {
424 const char *proto_name;
425 const char *short_name;
426 int (*proto_reply_fn)(char *, char *);
428 } supported_protocols[] = {
429 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
430 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
431 {"POSIX 2", "NT1", reply_nt1, PROTOCOL_NT1},
432 {"LANMAN2.1", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
433 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
434 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
435 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
436 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
437 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
438 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
439 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
443 /****************************************************************************
445 conn POINTER CAN BE NULL HERE !
446 ****************************************************************************/
448 int reply_negprot(connection_struct *conn,
449 char *inbuf,char *outbuf, int dum_size,
452 int outsize = set_message(outbuf,1,0,True);
457 int bcc = SVAL(smb_buf(inbuf),-2);
460 static BOOL done_negprot = False;
462 START_PROFILE(SMBnegprot);
465 END_PROFILE(SMBnegprot);
466 exit_server("multiple negprot's are not permitted");
470 p = smb_buf(inbuf)+1;
471 while (p < (smb_buf(inbuf) + bcc)) {
473 DEBUG(3,("Requested protocol [%s]\n",p));
474 if (strcsequal(p,"Windows for Workgroups 3.1a"))
475 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K );
476 else if (strcsequal(p,"DOS LM1.2X002"))
477 arch &= ( ARCH_WFWG | ARCH_WIN95 );
478 else if (strcsequal(p,"DOS LANMAN2.1"))
479 arch &= ( ARCH_WFWG | ARCH_WIN95 );
480 else if (strcsequal(p,"NT LM 0.12"))
481 arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K | ARCH_CIFSFS);
482 else if (strcsequal(p,"LANMAN2.1"))
483 arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
484 else if (strcsequal(p,"LM1.2X002"))
485 arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
486 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
488 else if (strcsequal(p,"XENIX CORE"))
489 arch &= ( ARCH_WINNT | ARCH_OS2 );
490 else if (strcsequal(p,"Samba")) {
493 } else if (strcsequal(p,"POSIX 2")) {
501 /* CIFSFS can send one arch only, NT LM 0.12. */
502 if (Index == 1 && (arch & ARCH_CIFSFS)) {
508 set_remote_arch(RA_CIFSFS);
511 set_remote_arch(RA_SAMBA);
514 set_remote_arch(RA_WFWG);
517 set_remote_arch(RA_WIN95);
520 if(SVAL(inbuf,smb_flg2)==FLAGS2_WIN2K_SIGNATURE)
521 set_remote_arch(RA_WIN2K);
523 set_remote_arch(RA_WINNT);
526 set_remote_arch(RA_WIN2K);
529 set_remote_arch(RA_OS2);
532 set_remote_arch(RA_UNKNOWN);
536 /* possibly reload - change of architecture */
537 reload_services(True);
539 /* moved from the netbios session setup code since we don't have that
540 when the client connects to port 445. Of course there is a small
541 window where we are listening to messages -- jerry */
543 claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
545 /* Check for protocols, most desirable first */
546 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
547 p = smb_buf(inbuf)+1;
549 if ((supported_protocols[protocol].protocol_level <= lp_maxprotocol()) &&
550 (supported_protocols[protocol].protocol_level >= lp_minprotocol()))
551 while (p < (smb_buf(inbuf) + bcc)) {
552 if (strequal(p,supported_protocols[protocol].proto_name))
561 SSVAL(outbuf,smb_vwv0,choice);
563 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
564 reload_services(True);
565 outsize = supported_protocols[protocol].proto_reply_fn(inbuf, outbuf);
566 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
568 DEBUG(0,("No protocol supported !\n"));
570 SSVAL(outbuf,smb_vwv0,choice);
572 DEBUG( 5, ( "negprot index=%d\n", choice ) );
574 if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) {
575 exit_server("SMB signing is required and client negotiated a downlevel protocol");
578 END_PROFILE(SMBnegprot);