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, uint8 *pkeylen)
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);
238 /****************************************************************************
239 Reply for the nt protocol.
240 ****************************************************************************/
242 static int reply_nt1(char *inbuf, char *outbuf)
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;
250 BOOL negotiate_spnego = False;
251 time_t t = time(NULL);
253 global_encrypted_passwords_negotiated = lp_encrypted_passwords();
255 /* do spnego in user level security if the client
256 supports it and we can do encrypted passwords */
258 if (global_encrypted_passwords_negotiated &&
259 (lp_security() != SEC_SHARE) &&
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);
270 capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
272 if (lp_unix_extensions()) {
273 capabilities |= CAP_UNIX;
276 if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
277 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
279 if (SMB_OFF_T_BITS == 64)
280 capabilities |= CAP_LARGE_FILES;
282 if (lp_readraw() && lp_writeraw())
283 capabilities |= CAP_RAW_MODE;
285 if (lp_nt_status_support())
286 capabilities |= CAP_STATUS32;
289 capabilities |= CAP_DFS;
291 if (lp_security() >= SEC_USER)
292 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
293 if (global_encrypted_passwords_negotiated)
294 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
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();
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.");
312 set_message(outbuf,17,0,True);
314 SCVAL(outbuf,smb_vwv1,secword);
316 Protocol = PROTOCOL_NT1;
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);
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 */
334 SCVAL(outbuf,smb_vwv16+1,8);
337 p += srvstr_push(outbuf, p, lp_workgroup(), -1,
338 STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
339 DEBUG(3,("not using SPNEGO\n"));
342 int len = negprot_spnego(p, &keylen);
344 SCVAL(outbuf,smb_vwv16+1,keylen);
346 DEBUG(3,("using SPNEGO\n"));
349 SSVAL(outbuf,smb_vwv17, p - q); /* length of challenge+domain strings */
350 set_message_end(outbuf, p);
352 return (smb_len(outbuf)+4);
355 /* these are the protocol lists used for auto architecture detection:
358 protocol [PC NETWORK PROGRAM 1.0]
359 protocol [XENIX CORE]
360 protocol [MICROSOFT NETWORKS 1.03]
362 protocol [Windows for Workgroups 3.1a]
365 protocol [NT LM 0.12]
368 protocol [PC NETWORK PROGRAM 1.0]
369 protocol [XENIX CORE]
370 protocol [MICROSOFT NETWORKS 1.03]
372 protocol [Windows for Workgroups 3.1a]
375 protocol [NT LM 0.12]
378 protocol [PC NETWORK PROGRAM 1.0]
380 protocol [Windows for Workgroups 3.1a]
383 protocol [NT LM 0.12]
386 protocol [PC NETWORK PROGRAM 1.0]
387 protocol [XENIX CORE]
394 * Modified to recognize the architecture of the remote machine better.
396 * This appears to be the matrix of which protocol is used by which
398 Protocol WfWg Win95 WinNT Win2K OS/2
399 PC NETWORK PROGRAM 1.0 1 1 1 1 1
401 MICROSOFT NETWORKS 3.0 2 2
403 MICROSOFT NETWORKS 1.03 3
406 Windows for Workgroups 3.1a 5 5 5 3
411 * tim@fsg.com 09/29/95
412 * Win2K added by matty 17/7/99
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
423 #define ARCH_ALL 0x7F
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 *);
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},
446 /****************************************************************************
448 conn POINTER CAN BE NULL HERE !
449 ****************************************************************************/
451 int reply_negprot(connection_struct *conn,
452 char *inbuf,char *outbuf, int dum_size,
455 int outsize = set_message(outbuf,1,0,True);
460 int bcc = SVAL(smb_buf(inbuf),-2);
463 static BOOL done_negprot = False;
465 START_PROFILE(SMBnegprot);
468 END_PROFILE(SMBnegprot);
469 exit_server("multiple negprot's are not permitted");
473 p = smb_buf(inbuf)+1;
474 while (p < (smb_buf(inbuf) + bcc)) {
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"))
491 else if (strcsequal(p,"XENIX CORE"))
492 arch &= ( ARCH_WINNT | ARCH_OS2 );
493 else if (strcsequal(p,"Samba")) {
496 } else if (strcsequal(p,"POSIX 2")) {
504 /* CIFSFS can send one arch only, NT LM 0.12. */
505 if (Index == 1 && (arch & ARCH_CIFSFS)) {
511 set_remote_arch(RA_CIFSFS);
514 set_remote_arch(RA_SAMBA);
517 set_remote_arch(RA_WFWG);
520 set_remote_arch(RA_WIN95);
523 if(SVAL(inbuf,smb_flg2)==FLAGS2_WIN2K_SIGNATURE)
524 set_remote_arch(RA_WIN2K);
526 set_remote_arch(RA_WINNT);
529 set_remote_arch(RA_WIN2K);
532 set_remote_arch(RA_OS2);
535 set_remote_arch(RA_UNKNOWN);
539 /* possibly reload - change of architecture */
540 reload_services(True);
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 */
546 claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
548 /* Check for protocols, most desirable first */
549 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
550 p = smb_buf(inbuf)+1;
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))
564 SSVAL(outbuf,smb_vwv0,choice);
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));
571 DEBUG(0,("No protocol supported !\n"));
573 SSVAL(outbuf,smb_vwv0,choice);
575 DEBUG( 5, ( "negprot index=%d\n", choice ) );
577 if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) {
578 exit_server("SMB signing is required and client negotiated a downlevel protocol");
581 END_PROFILE(SMBnegprot);