2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "smbd/globals.h"
24 extern fstring remote_proto
;
25 extern enum protocol_types Protocol
;
27 static void get_challenge(uint8 buff
[8])
31 /* We might be called more than once, multiple negprots are
33 if (negprot_global_auth_context
) {
34 DEBUG(3, ("get challenge: is this a secondary negprot? negprot_global_auth_context is non-NULL!\n"));
35 (negprot_global_auth_context
->free
)(&negprot_global_auth_context
);
38 DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
39 if (!NT_STATUS_IS_OK(nt_status
= make_auth_context_subsystem(&negprot_global_auth_context
))) {
40 DEBUG(0, ("make_auth_context_subsystem returned %s", nt_errstr(nt_status
)));
41 smb_panic("cannot make_negprot_global_auth_context!");
43 DEBUG(10, ("get challenge: getting challenge\n"));
44 negprot_global_auth_context
->get_ntlm_challenge(
45 negprot_global_auth_context
, buff
);
48 /****************************************************************************
49 Reply for the core protocol.
50 ****************************************************************************/
52 static void reply_corep(struct smb_request
*req
, uint16 choice
)
54 reply_outbuf(req
, 1, 0);
55 SSVAL(req
->outbuf
, smb_vwv0
, choice
);
57 Protocol
= PROTOCOL_CORE
;
60 /****************************************************************************
61 Reply for the coreplus protocol.
62 ****************************************************************************/
64 static void reply_coreplus(struct smb_request
*req
, uint16 choice
)
66 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
68 reply_outbuf(req
, 13, 0);
70 SSVAL(req
->outbuf
,smb_vwv0
,choice
);
71 SSVAL(req
->outbuf
,smb_vwv5
,raw
); /* tell redirector we support
72 readbraw and writebraw (possibly) */
73 /* Reply, SMBlockread, SMBwritelock supported. */
74 SCVAL(req
->outbuf
,smb_flg
,FLAG_REPLY
|FLAG_SUPPORT_LOCKREAD
);
75 SSVAL(req
->outbuf
,smb_vwv1
,0x1); /* user level security, don't
77 Protocol
= PROTOCOL_COREPLUS
;
80 /****************************************************************************
81 Reply for the lanman 1.0 protocol.
82 ****************************************************************************/
84 static void reply_lanman1(struct smb_request
*req
, uint16 choice
)
86 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
88 time_t t
= time(NULL
);
90 global_encrypted_passwords_negotiated
= lp_encrypted_passwords();
92 if (lp_security()>=SEC_USER
)
93 secword
|= NEGOTIATE_SECURITY_USER_LEVEL
;
94 if (global_encrypted_passwords_negotiated
)
95 secword
|= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
;
97 reply_outbuf(req
, 13, global_encrypted_passwords_negotiated
?8:0);
99 SSVAL(req
->outbuf
,smb_vwv0
,choice
);
100 SSVAL(req
->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((uint8
*)smb_buf(req
->outbuf
));
104 SSVAL(req
->outbuf
,smb_vwv11
, 8);
107 Protocol
= PROTOCOL_LANMAN1
;
109 /* Reply, SMBlockread, SMBwritelock supported. */
110 SCVAL(req
->outbuf
,smb_flg
,FLAG_REPLY
|FLAG_SUPPORT_LOCKREAD
);
111 SSVAL(req
->outbuf
,smb_vwv2
,max_recv
);
112 SSVAL(req
->outbuf
,smb_vwv3
,lp_maxmux()); /* maxmux */
113 SSVAL(req
->outbuf
,smb_vwv4
,1);
114 SSVAL(req
->outbuf
,smb_vwv5
,raw
); /* tell redirector we support
115 readbraw writebraw (possibly) */
116 SIVAL(req
->outbuf
,smb_vwv6
,sys_getpid());
117 SSVAL(req
->outbuf
,smb_vwv10
, set_server_zone_offset(t
)/60);
119 srv_put_dos_date((char *)req
->outbuf
,smb_vwv8
,t
);
124 /****************************************************************************
125 Reply for the lanman 2.0 protocol.
126 ****************************************************************************/
128 static void reply_lanman2(struct smb_request
*req
, uint16 choice
)
130 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
132 time_t t
= time(NULL
);
134 global_encrypted_passwords_negotiated
= lp_encrypted_passwords();
136 if (lp_security()>=SEC_USER
)
137 secword
|= NEGOTIATE_SECURITY_USER_LEVEL
;
138 if (global_encrypted_passwords_negotiated
)
139 secword
|= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
;
141 reply_outbuf(req
, 13, global_encrypted_passwords_negotiated
?8:0);
143 SSVAL(req
->outbuf
,smb_vwv0
,choice
);
144 SSVAL(req
->outbuf
,smb_vwv1
,secword
);
145 SIVAL(req
->outbuf
,smb_vwv6
,sys_getpid());
147 /* Create a token value and add it to the outgoing packet. */
148 if (global_encrypted_passwords_negotiated
) {
149 get_challenge((uint8
*)smb_buf(req
->outbuf
));
150 SSVAL(req
->outbuf
,smb_vwv11
, 8);
153 Protocol
= PROTOCOL_LANMAN2
;
155 /* Reply, SMBlockread, SMBwritelock supported. */
156 SCVAL(req
->outbuf
,smb_flg
,FLAG_REPLY
|FLAG_SUPPORT_LOCKREAD
);
157 SSVAL(req
->outbuf
,smb_vwv2
,max_recv
);
158 SSVAL(req
->outbuf
,smb_vwv3
,lp_maxmux());
159 SSVAL(req
->outbuf
,smb_vwv4
,1);
160 SSVAL(req
->outbuf
,smb_vwv5
,raw
); /* readbraw and/or writebraw */
161 SSVAL(req
->outbuf
,smb_vwv10
, set_server_zone_offset(t
)/60);
162 srv_put_dos_date((char *)req
->outbuf
,smb_vwv8
,t
);
165 /****************************************************************************
166 Generate the spnego negprot reply blob. Return the number of bytes used.
167 ****************************************************************************/
169 static DATA_BLOB
negprot_spnego(void)
178 const char *OIDs_krb5
[] = {OID_KERBEROS5
,
182 const char *OIDs_plain
[] = {OID_NTLMSSP
, NULL
};
184 global_spnego_negotiated
= True
;
186 memset(guid
, '\0', sizeof(guid
));
188 safe_strcpy(unix_name
, global_myname(), sizeof(unix_name
)-1);
189 strlower_m(unix_name
);
190 push_ascii_nstring(dos_name
, unix_name
);
191 safe_strcpy(guid
, dos_name
, sizeof(guid
)-1);
194 /* Fix valgrind 'uninitialized bytes' issue. */
195 slen
= strlen(dos_name
);
196 if (slen
< sizeof(guid
)) {
197 memset(guid
+slen
, '\0', sizeof(guid
) - slen
);
201 /* strangely enough, NT does not sent the single OID NTLMSSP when
202 not a ADS member, it sends no OIDs at all
204 OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know
205 about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
207 Our sessionsetup code now handles raw NTLMSSP connects, so we can go
208 back to doing what W2K3 does here. This is needed to make PocketPC 2003
209 CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
214 if (lp_security() != SEC_ADS
&& !USE_KERBEROS_KEYTAB
) {
216 /* Code for PocketPC client */
217 blob
= data_blob(guid
, 16);
219 /* Code for standalone WXP client */
220 blob
= spnego_gen_negTokenInit(guid
, OIDs_plain
, "NONE");
224 char *host_princ_s
= NULL
;
225 name_to_fqdn(myname
, global_myname());
227 if (asprintf(&host_princ_s
, "cifs/%s@%s", myname
, lp_realm())
229 return data_blob_null
;
231 blob
= spnego_gen_negTokenInit(guid
, OIDs_krb5
, host_princ_s
);
232 SAFE_FREE(host_princ_s
);
238 /****************************************************************************
239 Reply for the nt protocol.
240 ****************************************************************************/
242 static void reply_nt1(struct smb_request
*req
, uint16 choice
)
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
);
254 global_encrypted_passwords_negotiated
= lp_encrypted_passwords();
256 /* Check the flags field to see if this is Vista.
257 WinXP sets it and Vista does not. But we have to
258 distinguish from NT which doesn't set it either. */
260 if ( (req
->flags2
& FLAGS2_EXTENDED_SECURITY
) &&
261 ((req
->flags2
& FLAGS2_UNKNOWN_BIT4
) == 0) )
263 if (get_remote_arch() != RA_SAMBA
) {
264 set_remote_arch( RA_VISTA
);
268 reply_outbuf(req
,17,0);
270 /* do spnego in user level security if the client
271 supports it and we can do encrypted passwords */
273 if (global_encrypted_passwords_negotiated
&&
274 (lp_security() != SEC_SHARE
) &&
276 (req
->flags2
& FLAGS2_EXTENDED_SECURITY
)) {
277 negotiate_spnego
= True
;
278 capabilities
|= CAP_EXTENDED_SECURITY
;
279 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY
);
280 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply
281 (already partially constructed. */
282 SSVAL(req
->outbuf
, smb_flg2
,
283 req
->flags2
| 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 SSVAL(req
->outbuf
,smb_vwv0
,choice
);
329 SCVAL(req
->outbuf
,smb_vwv1
,secword
);
331 Protocol
= PROTOCOL_NT1
;
333 SSVAL(req
->outbuf
,smb_vwv1
+1,lp_maxmux()); /* maxmpx */
334 SSVAL(req
->outbuf
,smb_vwv2
+1,1); /* num vcs */
335 SIVAL(req
->outbuf
,smb_vwv3
+1,max_recv
); /* max buffer. LOTS! */
336 SIVAL(req
->outbuf
,smb_vwv5
+1,0x10000); /* raw size. full 64k */
337 SIVAL(req
->outbuf
,smb_vwv7
+1,sys_getpid()); /* session key */
338 SIVAL(req
->outbuf
,smb_vwv9
+1,capabilities
); /* capabilities */
339 put_long_date((char *)req
->outbuf
+smb_vwv11
+1,t
);
340 SSVALS(req
->outbuf
,smb_vwv15
+1,set_server_zone_offset(t
)/60);
342 p
= q
= smb_buf(req
->outbuf
);
343 if (!negotiate_spnego
) {
344 /* Create a token value and add it to the outgoing packet. */
345 if (global_encrypted_passwords_negotiated
) {
347 /* note that we do not send a challenge at all if
348 we are using plaintext */
350 ret
= message_push_blob(
351 &req
->outbuf
, data_blob_const(chal
, sizeof(chal
)));
353 DEBUG(0, ("Could not push challenge\n"));
354 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
357 SCVAL(req
->outbuf
, smb_vwv16
+1, ret
);
360 ret
= message_push_string(&req
->outbuf
, lp_workgroup(),
361 STR_UNICODE
|STR_TERMINATE
364 DEBUG(0, ("Could not push challenge\n"));
365 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
368 DEBUG(3,("not using SPNEGO\n"));
370 DATA_BLOB spnego_blob
= negprot_spnego();
372 if (spnego_blob
.data
== NULL
) {
373 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
377 ret
= message_push_blob(&req
->outbuf
, spnego_blob
);
379 DEBUG(0, ("Could not push spnego blob\n"));
380 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
384 data_blob_free(&spnego_blob
);
386 SCVAL(req
->outbuf
,smb_vwv16
+1, 0);
387 DEBUG(3,("using SPNEGO\n"));
390 SSVAL(req
->outbuf
,smb_vwv17
, p
- q
); /* length of challenge+domain
396 /* these are the protocol lists used for auto architecture detection:
399 protocol [PC NETWORK PROGRAM 1.0]
400 protocol [XENIX CORE]
401 protocol [MICROSOFT NETWORKS 1.03]
403 protocol [Windows for Workgroups 3.1a]
406 protocol [NT LM 0.12]
409 protocol [PC NETWORK PROGRAM 1.0]
410 protocol [XENIX CORE]
411 protocol [MICROSOFT NETWORKS 1.03]
413 protocol [Windows for Workgroups 3.1a]
416 protocol [NT LM 0.12]
419 protocol [PC NETWORK PROGRAM 1.0]
421 protocol [Windows for Workgroups 3.1a]
424 protocol [NT LM 0.12]
427 protocol [PC NETWORK PROGRAM 1.0]
429 protocol [Windows for Workgroups 3.1a]
432 protocol [NT LM 0.12]
436 protocol [PC NETWORK PROGRAM 1.0]
437 protocol [XENIX CORE]
444 * Modified to recognize the architecture of the remote machine better.
446 * This appears to be the matrix of which protocol is used by which
448 Protocol WfWg Win95 WinNT Win2K OS/2 Vista
449 PC NETWORK PROGRAM 1.0 1 1 1 1 1 1
451 MICROSOFT NETWORKS 3.0 2 2
453 MICROSOFT NETWORKS 1.03 3
456 Windows for Workgroups 3.1a 5 5 5 3 3
462 * tim@fsg.com 09/29/95
463 * Win2K added by matty 17/7/99
466 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
467 #define ARCH_WIN95 0x2
468 #define ARCH_WINNT 0x4
469 #define ARCH_WIN2K 0xC /* Win2K is like NT */
470 #define ARCH_OS2 0x14 /* Again OS/2 is like NT */
471 #define ARCH_SAMBA 0x20
472 #define ARCH_CIFSFS 0x40
473 #define ARCH_VISTA 0x8C /* Vista is like XP/2K */
475 #define ARCH_ALL 0x7F
477 /* List of supported protocols, most desired first */
478 static const struct {
479 const char *proto_name
;
480 const char *short_name
;
481 void (*proto_reply_fn
)(struct smb_request
*req
, uint16 choice
);
483 } supported_protocols
[] = {
484 {"NT LANMAN 1.0", "NT1", reply_nt1
, PROTOCOL_NT1
},
485 {"NT LM 0.12", "NT1", reply_nt1
, PROTOCOL_NT1
},
486 {"POSIX 2", "NT1", reply_nt1
, PROTOCOL_NT1
},
487 {"LANMAN2.1", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
488 {"LM1.2X002", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
489 {"Samba", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
490 {"DOS LM1.2X002", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
491 {"LANMAN1.0", "LANMAN1", reply_lanman1
, PROTOCOL_LANMAN1
},
492 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1
, PROTOCOL_LANMAN1
},
493 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus
, PROTOCOL_COREPLUS
},
494 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep
, PROTOCOL_CORE
},
498 /****************************************************************************
500 conn POINTER CAN BE NULL HERE !
501 ****************************************************************************/
503 void reply_negprot(struct smb_request
*req
)
512 size_t converted_size
;
514 START_PROFILE(SMBnegprot
);
517 END_PROFILE(SMBnegprot
);
518 exit_server_cleanly("multiple negprot's are not permitted");
522 if (req
->buflen
== 0) {
523 DEBUG(0, ("negprot got no protocols\n"));
524 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
525 END_PROFILE(SMBnegprot
);
529 if (req
->buf
[req
->buflen
-1] != '\0') {
530 DEBUG(0, ("negprot protocols not 0-terminated\n"));
531 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
532 END_PROFILE(SMBnegprot
);
536 p
= (const char *)req
->buf
+ 1;
541 while (smbreq_bufrem(req
, p
) > 0) {
545 tmp
= TALLOC_REALLOC_ARRAY(talloc_tos(), cliprotos
, char *,
548 DEBUG(0, ("talloc failed\n"));
549 TALLOC_FREE(cliprotos
);
550 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
551 END_PROFILE(SMBnegprot
);
557 if (!pull_ascii_talloc(cliprotos
, &cliprotos
[num_cliprotos
], p
,
559 DEBUG(0, ("pull_ascii_talloc failed\n"));
560 TALLOC_FREE(cliprotos
);
561 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
562 END_PROFILE(SMBnegprot
);
566 DEBUG(3, ("Requested protocol [%s]\n",
567 cliprotos
[num_cliprotos
]));
573 for (i
=0; i
<num_cliprotos
; i
++) {
574 if (strcsequal(cliprotos
[i
], "Windows for Workgroups 3.1a"))
575 arch
&= ( ARCH_WFWG
| ARCH_WIN95
| ARCH_WINNT
577 else if (strcsequal(cliprotos
[i
], "DOS LM1.2X002"))
578 arch
&= ( ARCH_WFWG
| ARCH_WIN95
);
579 else if (strcsequal(cliprotos
[i
], "DOS LANMAN2.1"))
580 arch
&= ( ARCH_WFWG
| ARCH_WIN95
);
581 else if (strcsequal(cliprotos
[i
], "NT LM 0.12"))
582 arch
&= ( ARCH_WIN95
| ARCH_WINNT
| ARCH_WIN2K
584 else if (strcsequal(cliprotos
[i
], "SMB 2.001"))
586 else if (strcsequal(cliprotos
[i
], "LANMAN2.1"))
587 arch
&= ( ARCH_WINNT
| ARCH_WIN2K
| ARCH_OS2
);
588 else if (strcsequal(cliprotos
[i
], "LM1.2X002"))
589 arch
&= ( ARCH_WINNT
| ARCH_WIN2K
| ARCH_OS2
);
590 else if (strcsequal(cliprotos
[i
], "MICROSOFT NETWORKS 1.03"))
592 else if (strcsequal(cliprotos
[i
], "XENIX CORE"))
593 arch
&= ( ARCH_WINNT
| ARCH_OS2
);
594 else if (strcsequal(cliprotos
[i
], "Samba")) {
597 } else if (strcsequal(cliprotos
[i
], "POSIX 2")) {
603 /* CIFSFS can send one arch only, NT LM 0.12. */
604 if (i
== 1 && (arch
& ARCH_CIFSFS
)) {
610 set_remote_arch(RA_CIFSFS
);
613 set_remote_arch(RA_SAMBA
);
616 set_remote_arch(RA_WFWG
);
619 set_remote_arch(RA_WIN95
);
622 if(req
->flags2
== FLAGS2_WIN2K_SIGNATURE
)
623 set_remote_arch(RA_WIN2K
);
625 set_remote_arch(RA_WINNT
);
628 /* Vista may have been set in the negprot so don't
630 if ( get_remote_arch() != RA_VISTA
)
631 set_remote_arch(RA_WIN2K
);
634 set_remote_arch(RA_VISTA
);
637 set_remote_arch(RA_OS2
);
640 set_remote_arch(RA_UNKNOWN
);
644 /* possibly reload - change of architecture */
645 reload_services(True
);
647 /* moved from the netbios session setup code since we don't have that
648 when the client connects to port 445. Of course there is a small
649 window where we are listening to messages -- jerry */
652 NULL
,"",FLAG_MSG_GENERAL
|FLAG_MSG_SMBD
|FLAG_MSG_PRINT_GENERAL
);
654 /* Check for protocols, most desirable first */
655 for (protocol
= 0; supported_protocols
[protocol
].proto_name
; protocol
++) {
657 if ((supported_protocols
[protocol
].protocol_level
<= lp_maxprotocol()) &&
658 (supported_protocols
[protocol
].protocol_level
>= lp_minprotocol()))
659 while (i
< num_cliprotos
) {
660 if (strequal(cliprotos
[i
],supported_protocols
[protocol
].proto_name
))
669 fstrcpy(remote_proto
,supported_protocols
[protocol
].short_name
);
670 reload_services(True
);
671 supported_protocols
[protocol
].proto_reply_fn(req
, choice
);
672 DEBUG(3,("Selected protocol %s\n",supported_protocols
[protocol
].proto_name
));
674 DEBUG(0,("No protocol supported !\n"));
675 reply_outbuf(req
, 1, 0);
676 SSVAL(req
->outbuf
, smb_vwv0
, choice
);
679 DEBUG( 5, ( "negprot index=%d\n", choice
) );
681 if ((lp_server_signing() == Required
) && (Protocol
< PROTOCOL_NT1
)) {
682 exit_server_cleanly("SMB signing is required and "
683 "client negotiated a downlevel protocol");
686 TALLOC_FREE(cliprotos
);
687 END_PROFILE(SMBnegprot
);