2 Unix SMB/CIFS implementation.
3 client connect/disconnect routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Andrew Bartlett 2001-2003
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/>.
27 {PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"},
28 {PROTOCOL_COREPLUS, "MICROSOFT NETWORKS 1.03"},
29 {PROTOCOL_LANMAN1, "MICROSOFT NETWORKS 3.0"},
30 {PROTOCOL_LANMAN1, "LANMAN1.0"},
31 {PROTOCOL_LANMAN2, "LM1.2X002"},
32 {PROTOCOL_LANMAN2, "DOS LANMAN2.1"},
33 {PROTOCOL_LANMAN2, "LANMAN2.1"},
34 {PROTOCOL_LANMAN2, "Samba"},
35 {PROTOCOL_NT1, "NT LANMAN 1.0"},
36 {PROTOCOL_NT1, "NT LM 0.12"},
39 #define STAR_SMBSERVER "*SMBSERVER"
42 * Set the user session key for a connection
43 * @param cli The cli structure to add it too
44 * @param session_key The session key used. (A copy of this is taken for the cli struct)
48 static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key)
50 cli->user_session_key = data_blob(session_key.data, session_key.length);
53 /****************************************************************************
54 Do an old lanman2 style session setup.
55 ****************************************************************************/
57 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli,
59 const char *pass, size_t passlen,
60 const char *workgroup)
62 DATA_BLOB session_key = data_blob_null;
63 DATA_BLOB lm_response = data_blob_null;
67 if (passlen > sizeof(pword)-1) {
68 return NT_STATUS_INVALID_PARAMETER;
71 /* LANMAN servers predate NT status codes and Unicode and ignore those
72 smb flags so we must disable the corresponding default capabilities
73 that would otherwise cause the Unicode and NT Status flags to be
74 set (and even returned by the server) */
76 cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32);
78 /* if in share level security then don't send a password now */
79 if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL))
82 if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) {
83 /* Encrypted mode needed, and non encrypted password supplied. */
84 lm_response = data_blob(NULL, 24);
85 if (!SMBencrypt(pass, cli->secblob.data,(uchar *)lm_response.data)) {
86 DEBUG(1, ("Password is > 14 chars in length, and is therefore incompatible with Lanman authentication\n"));
87 return NT_STATUS_ACCESS_DENIED;
89 } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) {
90 /* Encrypted mode needed, and encrypted password supplied. */
91 lm_response = data_blob(pass, passlen);
92 } else if (passlen > 0) {
93 /* Plaintext mode needed, assume plaintext supplied. */
94 passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
95 lm_response = data_blob(pass, passlen);
98 /* send a session setup command */
99 memset(cli->outbuf,'\0',smb_size);
100 cli_set_message(cli->outbuf,10, 0, True);
101 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
102 cli_setup_packet(cli);
104 SCVAL(cli->outbuf,smb_vwv0,0xFF);
105 SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit);
106 SSVAL(cli->outbuf,smb_vwv3,2);
107 SSVAL(cli->outbuf,smb_vwv4,1);
108 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
109 SSVAL(cli->outbuf,smb_vwv7,lm_response.length);
111 p = smb_buf(cli->outbuf);
112 memcpy(p,lm_response.data,lm_response.length);
113 p += lm_response.length;
114 p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER);
115 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER);
116 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
117 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
118 cli_setup_bcc(cli, p);
120 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
121 return cli_nt_error(cli);
124 show_msg(cli->inbuf);
126 if (cli_is_error(cli)) {
127 return cli_nt_error(cli);
130 /* use the returned vuid from now on */
131 cli->vuid = SVAL(cli->inbuf,smb_uid);
132 fstrcpy(cli->user_name, user);
134 if (session_key.data) {
135 /* Have plaintext orginal */
136 cli_set_session_key(cli, session_key);
142 /****************************************************************************
143 Work out suitable capabilities to offer the server.
144 ****************************************************************************/
146 static uint32 cli_session_setup_capabilities(struct cli_state *cli)
148 uint32 capabilities = CAP_NT_SMBS;
150 if (!cli->force_dos_errors)
151 capabilities |= CAP_STATUS32;
153 if (cli->use_level_II_oplocks)
154 capabilities |= CAP_LEVEL_II_OPLOCKS;
156 capabilities |= (cli->capabilities & (CAP_UNICODE|CAP_LARGE_FILES|CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_DFS));
160 /****************************************************************************
161 Do a NT1 guest session setup.
162 ****************************************************************************/
164 static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
167 uint32 capabilities = cli_session_setup_capabilities(cli);
169 memset(cli->outbuf, '\0', smb_size);
170 cli_set_message(cli->outbuf,13,0,True);
171 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
172 cli_setup_packet(cli);
174 SCVAL(cli->outbuf,smb_vwv0,0xFF);
175 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
176 SSVAL(cli->outbuf,smb_vwv3,2);
177 SSVAL(cli->outbuf,smb_vwv4,cli->pid);
178 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
179 SSVAL(cli->outbuf,smb_vwv7,0);
180 SSVAL(cli->outbuf,smb_vwv8,0);
181 SIVAL(cli->outbuf,smb_vwv11,capabilities);
182 p = smb_buf(cli->outbuf);
183 p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* username */
184 p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* workgroup */
185 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
186 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
187 cli_setup_bcc(cli, p);
189 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
190 return cli_nt_error(cli);
193 show_msg(cli->inbuf);
195 if (cli_is_error(cli)) {
196 return cli_nt_error(cli);
199 cli->vuid = SVAL(cli->inbuf,smb_uid);
201 p = smb_buf(cli->inbuf);
202 p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring),
204 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring),
206 p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring),
209 if (strstr(cli->server_type, "Samba")) {
210 cli->is_samba = True;
213 fstrcpy(cli->user_name, "");
218 /****************************************************************************
219 Do a NT1 plaintext session setup.
220 ****************************************************************************/
222 static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli,
223 const char *user, const char *pass,
224 const char *workgroup)
226 uint32 capabilities = cli_session_setup_capabilities(cli);
230 fstr_sprintf( lanman, "Samba %s", samba_version_string());
232 memset(cli->outbuf, '\0', smb_size);
233 cli_set_message(cli->outbuf,13,0,True);
234 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
235 cli_setup_packet(cli);
237 SCVAL(cli->outbuf,smb_vwv0,0xFF);
238 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
239 SSVAL(cli->outbuf,smb_vwv3,2);
240 SSVAL(cli->outbuf,smb_vwv4,cli->pid);
241 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
242 SSVAL(cli->outbuf,smb_vwv8,0);
243 SIVAL(cli->outbuf,smb_vwv11,capabilities);
244 p = smb_buf(cli->outbuf);
246 /* check wether to send the ASCII or UNICODE version of the password */
248 if ( (capabilities & CAP_UNICODE) == 0 ) {
249 p += clistr_push(cli, p, pass, -1, STR_TERMINATE); /* password */
250 SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf)));
253 /* For ucs2 passwords clistr_push calls ucs2_align, which causes
254 * the space taken by the unicode password to be one byte too
255 * long (as we're on an odd byte boundary here). Reduce the
256 * count by 1 to cope with this. Fixes smbclient against NetApp
257 * servers which can't cope. Fix from
258 * bryan.kolodziej@allenlund.com in bug #3840.
260 p += clistr_push(cli, p, pass, -1, STR_UNICODE|STR_TERMINATE); /* unicode password */
261 SSVAL(cli->outbuf,smb_vwv8,PTR_DIFF(p, smb_buf(cli->outbuf))-1);
264 p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */
265 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */
266 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
267 p += clistr_push(cli, p, lanman, -1, STR_TERMINATE);
268 cli_setup_bcc(cli, p);
270 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
271 return cli_nt_error(cli);
274 show_msg(cli->inbuf);
276 if (cli_is_error(cli)) {
277 return cli_nt_error(cli);
280 cli->vuid = SVAL(cli->inbuf,smb_uid);
281 p = smb_buf(cli->inbuf);
282 p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring),
284 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring),
286 p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring),
288 fstrcpy(cli->user_name, user);
290 if (strstr(cli->server_type, "Samba")) {
291 cli->is_samba = True;
297 /****************************************************************************
298 do a NT1 NTLM/LM encrypted session setup - for when extended security
300 @param cli client state to create do session setup on
302 @param pass *either* cleartext password (passlen !=24) or LM response.
303 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
304 @param workgroup The user's domain.
305 ****************************************************************************/
307 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
308 const char *pass, size_t passlen,
309 const char *ntpass, size_t ntpasslen,
310 const char *workgroup)
312 uint32 capabilities = cli_session_setup_capabilities(cli);
313 DATA_BLOB lm_response = data_blob_null;
314 DATA_BLOB nt_response = data_blob_null;
315 DATA_BLOB session_key = data_blob_null;
320 /* do nothing - guest login */
321 } else if (passlen != 24) {
322 if (lp_client_ntlmv2_auth()) {
323 DATA_BLOB server_chal;
324 DATA_BLOB names_blob;
325 server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8));
327 /* note that the 'workgroup' here is a best guess - we don't know
328 the server's domain at this point. The 'server name' is also
331 names_blob = NTLMv2_generate_names_blob(cli->called.name, workgroup);
333 if (!SMBNTLMv2encrypt(user, workgroup, pass, &server_chal,
335 &lm_response, &nt_response, &session_key)) {
336 data_blob_free(&names_blob);
337 data_blob_free(&server_chal);
338 return NT_STATUS_ACCESS_DENIED;
340 data_blob_free(&names_blob);
341 data_blob_free(&server_chal);
345 E_md4hash(pass, nt_hash);
348 nt_response = data_blob_null;
350 nt_response = data_blob(NULL, 24);
351 SMBNTencrypt(pass,cli->secblob.data,nt_response.data);
353 /* non encrypted password supplied. Ignore ntpass. */
354 if (lp_client_lanman_auth()) {
355 lm_response = data_blob(NULL, 24);
356 if (!SMBencrypt(pass,cli->secblob.data, lm_response.data)) {
357 /* Oops, the LM response is invalid, just put
358 the NT response there instead */
359 data_blob_free(&lm_response);
360 lm_response = data_blob(nt_response.data, nt_response.length);
363 /* LM disabled, place NT# in LM field instead */
364 lm_response = data_blob(nt_response.data, nt_response.length);
367 session_key = data_blob(NULL, 16);
369 E_deshash(pass, session_key.data);
370 memset(&session_key.data[8], '\0', 8);
372 SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
376 cli_simple_set_signing(cli, session_key, lm_response);
378 cli_simple_set_signing(cli, session_key, nt_response);
381 /* pre-encrypted password supplied. Only used for
382 security=server, can't do
383 signing because we don't have original key */
385 lm_response = data_blob(pass, passlen);
386 nt_response = data_blob(ntpass, ntpasslen);
389 /* send a session setup command */
390 memset(cli->outbuf,'\0',smb_size);
392 cli_set_message(cli->outbuf,13,0,True);
393 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
394 cli_setup_packet(cli);
396 SCVAL(cli->outbuf,smb_vwv0,0xFF);
397 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
398 SSVAL(cli->outbuf,smb_vwv3,2);
399 SSVAL(cli->outbuf,smb_vwv4,cli->pid);
400 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
401 SSVAL(cli->outbuf,smb_vwv7,lm_response.length);
402 SSVAL(cli->outbuf,smb_vwv8,nt_response.length);
403 SIVAL(cli->outbuf,smb_vwv11,capabilities);
404 p = smb_buf(cli->outbuf);
405 if (lm_response.length) {
406 memcpy(p,lm_response.data, lm_response.length); p += lm_response.length;
408 if (nt_response.length) {
409 memcpy(p,nt_response.data, nt_response.length); p += nt_response.length;
411 p += clistr_push(cli, p, user, -1, STR_TERMINATE);
413 /* Upper case here might help some NTLMv2 implementations */
414 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER);
415 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
416 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
417 cli_setup_bcc(cli, p);
419 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
420 result = cli_nt_error(cli);
424 /* show_msg(cli->inbuf); */
426 if (cli_is_error(cli)) {
427 result = cli_nt_error(cli);
431 /* use the returned vuid from now on */
432 cli->vuid = SVAL(cli->inbuf,smb_uid);
434 p = smb_buf(cli->inbuf);
435 p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring),
437 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring),
439 p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring),
442 if (strstr(cli->server_type, "Samba")) {
443 cli->is_samba = True;
446 fstrcpy(cli->user_name, user);
448 if (session_key.data) {
449 /* Have plaintext orginal */
450 cli_set_session_key(cli, session_key);
453 result = NT_STATUS_OK;
455 data_blob_free(&lm_response);
456 data_blob_free(&nt_response);
457 data_blob_free(&session_key);
461 /****************************************************************************
462 Send a extended security session setup blob
463 ****************************************************************************/
465 static bool cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob)
467 uint32 capabilities = cli_session_setup_capabilities(cli);
470 capabilities |= CAP_EXTENDED_SECURITY;
472 /* send a session setup command */
473 memset(cli->outbuf,'\0',smb_size);
475 cli_set_message(cli->outbuf,12,0,True);
476 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
478 cli_setup_packet(cli);
480 SCVAL(cli->outbuf,smb_vwv0,0xFF);
481 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
482 SSVAL(cli->outbuf,smb_vwv3,2);
483 SSVAL(cli->outbuf,smb_vwv4,1);
484 SIVAL(cli->outbuf,smb_vwv5,0);
485 SSVAL(cli->outbuf,smb_vwv7,blob.length);
486 SIVAL(cli->outbuf,smb_vwv10,capabilities);
487 p = smb_buf(cli->outbuf);
488 memcpy(p, blob.data, blob.length);
490 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
491 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
492 cli_setup_bcc(cli, p);
493 return cli_send_smb(cli);
496 /****************************************************************************
497 Send a extended security session setup blob, returning a reply blob.
498 ****************************************************************************/
500 static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli)
502 DATA_BLOB blob2 = data_blob_null;
506 if (!cli_receive_smb(cli))
509 show_msg(cli->inbuf);
511 if (cli_is_error(cli) && !NT_STATUS_EQUAL(cli_nt_error(cli),
512 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
516 /* use the returned vuid from now on */
517 cli->vuid = SVAL(cli->inbuf,smb_uid);
519 p = smb_buf(cli->inbuf);
521 blob2 = data_blob(p, SVAL(cli->inbuf, smb_vwv3));
524 p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring),
527 /* w2k with kerberos doesn't properly null terminate this field */
528 len = smb_bufrem(cli->inbuf, p);
529 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring),
536 /****************************************************************************
537 Send a extended security session setup blob, returning a reply blob.
538 ****************************************************************************/
540 /* The following is calculated from :
542 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
543 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
547 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
549 static bool cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob)
551 int32 remaining = blob.length;
553 DATA_BLOB send_blob = data_blob_null;
554 int32 max_blob_size = 0;
555 DATA_BLOB receive_blob = data_blob_null;
557 if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) {
558 DEBUG(0,("cli_session_setup_blob: cli->max_xmit too small "
559 "(was %u, need minimum %u)\n",
560 (unsigned int)cli->max_xmit,
561 BASE_SESSSETUP_BLOB_PACKET_SIZE));
562 cli_set_nt_error(cli, NT_STATUS_INVALID_PARAMETER);
566 max_blob_size = cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE;
568 while ( remaining > 0) {
569 if (remaining >= max_blob_size) {
570 send_blob.length = max_blob_size;
571 remaining -= max_blob_size;
573 send_blob.length = remaining;
577 send_blob.data = &blob.data[cur];
578 cur += send_blob.length;
580 DEBUG(10, ("cli_session_setup_blob: Remaining (%u) sending (%u) current (%u)\n",
581 (unsigned int)remaining,
582 (unsigned int)send_blob.length,
583 (unsigned int)cur ));
585 if (!cli_session_setup_blob_send(cli, send_blob)) {
586 DEBUG(0, ("cli_session_setup_blob: send failed\n"));
590 receive_blob = cli_session_setup_blob_receive(cli);
591 data_blob_free(&receive_blob);
593 if (cli_is_error(cli) &&
594 !NT_STATUS_EQUAL( cli_get_nt_error(cli),
595 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
596 DEBUG(0, ("cli_session_setup_blob: receive failed "
597 "(%s)\n", nt_errstr(cli_get_nt_error(cli))));
606 /****************************************************************************
607 Use in-memory credentials cache
608 ****************************************************************************/
610 static void use_in_memory_ccache(void) {
611 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
614 /****************************************************************************
615 Do a spnego/kerberos encrypted session setup.
616 ****************************************************************************/
618 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup)
620 DATA_BLOB negTokenTarg;
621 DATA_BLOB session_key_krb5;
625 cli_temp_set_signing(cli);
627 DEBUG(2,("Doing kerberos session setup\n"));
629 /* generate the encapsulated kerberos5 ticket */
630 rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5, 0, NULL);
633 DEBUG(1, ("cli_session_setup_kerberos: spnego_gen_negTokenTarg failed: %s\n",
635 return ADS_ERROR_KRB5(rc);
639 file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length);
642 if (!cli_session_setup_blob(cli, negTokenTarg)) {
643 nt_status = cli_nt_error(cli);
647 if (cli_is_error(cli)) {
648 nt_status = cli_nt_error(cli);
649 if (NT_STATUS_IS_OK(nt_status)) {
650 nt_status = NT_STATUS_UNSUCCESSFUL;
655 cli_set_session_key(cli, session_key_krb5);
657 if (cli_simple_set_signing(
658 cli, session_key_krb5, data_blob_null)) {
660 /* 'resign' the last message, so we get the right sequence numbers
661 for checking the first reply from the server */
662 cli_calculate_sign_mac(cli, cli->outbuf);
664 if (!cli_check_sign_mac(cli, cli->inbuf)) {
665 nt_status = NT_STATUS_ACCESS_DENIED;
670 data_blob_free(&negTokenTarg);
671 data_blob_free(&session_key_krb5);
673 return ADS_ERROR_NT(NT_STATUS_OK);
676 data_blob_free(&negTokenTarg);
677 data_blob_free(&session_key_krb5);
679 return ADS_ERROR_NT(nt_status);
681 #endif /* HAVE_KRB5 */
684 /****************************************************************************
685 Do a spnego/NTLMSSP encrypted session setup.
686 ****************************************************************************/
688 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
689 const char *pass, const char *domain)
691 struct ntlmssp_state *ntlmssp_state;
695 DATA_BLOB blob = data_blob_null;
696 DATA_BLOB blob_in = data_blob_null;
697 DATA_BLOB blob_out = data_blob_null;
699 cli_temp_set_signing(cli);
701 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) {
704 ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
706 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
709 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
712 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) {
717 nt_status = ntlmssp_update(ntlmssp_state,
719 data_blob_free(&blob_in);
720 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(nt_status)) {
722 /* and wrap it in a SPNEGO wrapper */
723 msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out);
725 /* wrap it in SPNEGO */
726 msg1 = spnego_gen_auth(blob_out);
729 /* now send that blob on its way */
730 if (!cli_session_setup_blob_send(cli, msg1)) {
731 DEBUG(3, ("Failed to send NTLMSSP/SPNEGO blob to server!\n"));
732 nt_status = NT_STATUS_UNSUCCESSFUL;
734 blob = cli_session_setup_blob_receive(cli);
736 nt_status = cli_nt_error(cli);
737 if (cli_is_error(cli) && NT_STATUS_IS_OK(nt_status)) {
738 if (cli->smb_rw_error == SMB_READ_BAD_SIG) {
739 nt_status = NT_STATUS_ACCESS_DENIED;
741 nt_status = NT_STATUS_UNSUCCESSFUL;
745 data_blob_free(&msg1);
749 if (NT_STATUS_IS_OK(nt_status)) {
750 nt_status = NT_STATUS_UNSUCCESSFUL;
752 } else if ((turn == 1) &&
753 NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
754 DATA_BLOB tmp_blob = data_blob_null;
755 /* the server might give us back two challenges */
756 if (!spnego_parse_challenge(blob, &blob_in,
758 DEBUG(3,("Failed to parse challenges\n"));
759 nt_status = NT_STATUS_INVALID_PARAMETER;
761 data_blob_free(&tmp_blob);
763 if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP,
765 DEBUG(3,("Failed to parse auth response\n"));
766 if (NT_STATUS_IS_OK(nt_status)
767 || NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED))
768 nt_status = NT_STATUS_INVALID_PARAMETER;
771 data_blob_free(&blob);
772 data_blob_free(&blob_out);
774 } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED));
776 data_blob_free(&blob_in);
778 if (NT_STATUS_IS_OK(nt_status)) {
780 fstrcpy(cli->server_domain, ntlmssp_state->server_domain);
781 cli_set_session_key(cli, ntlmssp_state->session_key);
783 if (cli_simple_set_signing(
784 cli, ntlmssp_state->session_key, data_blob_null)) {
786 /* 'resign' the last message, so we get the right sequence numbers
787 for checking the first reply from the server */
788 cli_calculate_sign_mac(cli, cli->outbuf);
790 if (!cli_check_sign_mac(cli, cli->inbuf)) {
791 nt_status = NT_STATUS_ACCESS_DENIED;
796 /* we have a reference conter on ntlmssp_state, if we are signing
797 then the state will be kept by the signing engine */
799 ntlmssp_end(&ntlmssp_state);
801 if (!NT_STATUS_IS_OK(nt_status)) {
807 /****************************************************************************
808 Do a spnego encrypted session setup.
810 user_domain: The shortname of the domain the user/machine is a member of.
811 dest_realm: The realm we're connecting to, if NULL we use our default realm.
812 ****************************************************************************/
814 ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
815 const char *pass, const char *user_domain,
816 const char * dest_realm)
818 char *principal = NULL;
819 char *OIDs[ASN1_MAX_OIDS];
822 const char *p = NULL;
823 char *account = NULL;
825 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
827 /* the server might not even do spnego */
828 if (cli->secblob.length <= 16) {
829 DEBUG(3,("server didn't supply a full spnego negprot\n"));
834 file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
837 /* there is 16 bytes of GUID before the real spnego packet starts */
838 blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);
840 /* The server sent us the first part of the SPNEGO exchange in the
841 * negprot reply. It is WRONG to depend on the principal sent in the
842 * negprot reply, but right now we do it. If we don't receive one,
843 * we try to best guess, then fall back to NTLM. */
844 if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) {
845 data_blob_free(&blob);
846 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
848 data_blob_free(&blob);
850 /* make sure the server understands kerberos */
851 for (i=0;OIDs[i];i++) {
852 DEBUG(3,("got OID=%s\n", OIDs[i]));
853 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
854 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
855 cli->got_kerberos_mechanism = True;
857 talloc_free(OIDs[i]);
860 DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
862 fstrcpy(cli->user_name, user);
865 /* If password is set we reauthenticate to kerberos server
866 * and do not store results */
868 if (cli->got_kerberos_mechanism && cli->use_kerberos) {
874 use_in_memory_ccache();
875 ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
878 TALLOC_FREE(principal);
879 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
880 if (cli->fallback_after_kerberos)
882 return ADS_ERROR_KRB5(ret);
886 /* If we get a bad principal, try to guess it if
887 we have a valid host NetBIOS name.
889 if (strequal(principal, ADS_IGNORE_PRINCIPAL)) {
890 TALLOC_FREE(principal);
893 if (principal == NULL &&
894 !is_ipaddress(cli->desthost) &&
895 !strequal(STAR_SMBSERVER,
898 char *machine = NULL;
900 DEBUG(3,("cli_session_setup_spnego: got a "
901 "bad server principal, trying to guess ...\n"));
903 host = strchr_m(cli->desthost, '.');
905 machine = SMB_STRNDUP(cli->desthost,
906 host - cli->desthost);
908 machine = SMB_STRDUP(cli->desthost);
910 if (machine == NULL) {
911 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
915 realm = SMB_STRDUP(dest_realm);
918 realm = kerberos_get_default_realm_from_ccache();
920 if (realm && *realm) {
921 principal = talloc_asprintf(NULL, "%s$@%s",
926 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
928 DEBUG(3,("cli_session_setup_spnego: guessed "
929 "server principal=%s\n",
930 principal ? principal : "<null>"));
937 rc = cli_session_setup_kerberos(cli, principal,
939 if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
940 TALLOC_FREE(principal);
947 TALLOC_FREE(principal);
951 account = talloc_strdup(talloc_tos(), user);
953 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
956 /* when falling back to ntlmssp while authenticating with a machine
957 * account strip off the realm - gd */
959 if ((p = strchr_m(user, '@')) != NULL) {
960 account[PTR_DIFF(p,user)] = '\0';
963 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
966 /****************************************************************************
967 Send a session setup. The username and workgroup is in UNIX character
968 format and must be converted to DOS codepage format before sending. If the
969 password is in plaintext, the same should be done.
970 ****************************************************************************/
972 NTSTATUS cli_session_setup(struct cli_state *cli,
974 const char *pass, int passlen,
975 const char *ntpass, int ntpasslen,
976 const char *workgroup)
982 fstrcpy(user2, user);
991 /* allow for workgroups as part of the username */
992 if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
993 (p=strchr_m(user2,*lp_winbind_separator()))) {
999 if (cli->protocol < PROTOCOL_LANMAN1) {
1000 return NT_STATUS_OK;
1003 /* now work out what sort of session setup we are going to
1004 do. I have split this into separate functions to make the
1005 flow a bit easier to understand (tridge) */
1007 /* if its an older server then we have to use the older request format */
1009 if (cli->protocol < PROTOCOL_NT1) {
1010 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
1011 DEBUG(1, ("Server requested LM password but 'client lanman auth'"
1013 return NT_STATUS_ACCESS_DENIED;
1016 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
1017 !lp_client_plaintext_auth() && (*pass)) {
1018 DEBUG(1, ("Server requested plaintext password but "
1019 "'client plaintext auth' is disabled\n"));
1020 return NT_STATUS_ACCESS_DENIED;
1023 return cli_session_setup_lanman2(cli, user, pass, passlen,
1027 /* if no user is supplied then we have to do an anonymous connection.
1028 passwords are ignored */
1030 if (!user || !*user)
1031 return cli_session_setup_guest(cli);
1033 /* if the server is share level then send a plaintext null
1034 password at this point. The password is sent in the tree
1037 if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
1038 return cli_session_setup_plaintext(cli, user, "", workgroup);
1040 /* if the server doesn't support encryption then we have to use
1041 plaintext. The second password is ignored */
1043 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1044 if (!lp_client_plaintext_auth() && (*pass)) {
1045 DEBUG(1, ("Server requested plaintext password but "
1046 "'client plaintext auth' is disabled\n"));
1047 return NT_STATUS_ACCESS_DENIED;
1049 return cli_session_setup_plaintext(cli, user, pass, workgroup);
1052 /* if the server supports extended security then use SPNEGO */
1054 if (cli->capabilities & CAP_EXTENDED_SECURITY) {
1055 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
1057 if (!ADS_ERR_OK(status)) {
1058 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1059 return ads_ntstatus(status);
1064 /* otherwise do a NT1 style session setup */
1065 status = cli_session_setup_nt1(cli, user, pass, passlen,
1066 ntpass, ntpasslen, workgroup);
1067 if (!NT_STATUS_IS_OK(status)) {
1068 DEBUG(3,("cli_session_setup: NT1 session setup "
1069 "failed: %s\n", nt_errstr(status)));
1074 if (strstr(cli->server_type, "Samba")) {
1075 cli->is_samba = True;
1078 return NT_STATUS_OK;
1081 /****************************************************************************
1083 *****************************************************************************/
1085 bool cli_ulogoff(struct cli_state *cli)
1087 memset(cli->outbuf,'\0',smb_size);
1088 cli_set_message(cli->outbuf,2,0,True);
1089 SCVAL(cli->outbuf,smb_com,SMBulogoffX);
1090 cli_setup_packet(cli);
1091 SSVAL(cli->outbuf,smb_vwv0,0xFF);
1092 SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */
1095 if (!cli_receive_smb(cli))
1098 if (cli_is_error(cli)) {
1106 /****************************************************************************
1108 ****************************************************************************/
1110 bool cli_send_tconX(struct cli_state *cli,
1111 const char *share, const char *dev, const char *pass, int passlen)
1113 fstring fullshare, pword;
1115 memset(cli->outbuf,'\0',smb_size);
1116 memset(cli->inbuf,'\0',smb_size);
1118 fstrcpy(cli->share, share);
1120 /* in user level security don't send a password now */
1121 if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
1125 DEBUG(1, ("Server not using user level security and no password supplied.\n"));
1129 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
1130 *pass && passlen != 24) {
1131 if (!lp_client_lanman_auth()) {
1132 DEBUG(1, ("Server requested LANMAN password "
1133 "(share-level security) but "
1134 "'client lanman auth' is disabled\n"));
1139 * Non-encrypted passwords - convert to DOS codepage before encryption.
1142 SMBencrypt(pass,cli->secblob.data,(uchar *)pword);
1144 if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL|NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) {
1145 if (!lp_client_plaintext_auth() && (*pass)) {
1146 DEBUG(1, ("Server requested plaintext "
1147 "password but 'client plaintext "
1148 "auth' is disabled\n"));
1153 * Non-encrypted passwords - convert to DOS codepage before using.
1155 passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
1159 memcpy(pword, pass, passlen);
1164 slprintf(fullshare, sizeof(fullshare)-1,
1165 "\\\\%s\\%s", cli->desthost, share);
1167 cli_set_message(cli->outbuf,4, 0, True);
1168 SCVAL(cli->outbuf,smb_com,SMBtconX);
1169 cli_setup_packet(cli);
1171 SSVAL(cli->outbuf,smb_vwv0,0xFF);
1172 SSVAL(cli->outbuf,smb_vwv2,TCONX_FLAG_EXTENDED_RESPONSE);
1173 SSVAL(cli->outbuf,smb_vwv3,passlen);
1175 p = smb_buf(cli->outbuf);
1177 memcpy(p,pword,passlen);
1180 p += clistr_push(cli, p, fullshare, -1, STR_TERMINATE |STR_UPPER);
1181 p += clistr_push(cli, p, dev, -1, STR_TERMINATE |STR_UPPER | STR_ASCII);
1183 cli_setup_bcc(cli, p);
1186 if (!cli_receive_smb(cli))
1189 if (cli_is_error(cli))
1192 clistr_pull(cli->inbuf, cli->dev, smb_buf(cli->inbuf), sizeof(fstring),
1193 -1, STR_TERMINATE|STR_ASCII);
1195 if (cli->protocol >= PROTOCOL_NT1 &&
1196 smb_buflen(cli->inbuf) == 3) {
1197 /* almost certainly win95 - enable bug fixes */
1201 /* Make sure that we have the optional support 16-bit field. WCT > 2 */
1202 /* Avoids issues when connecting to Win9x boxes sharing files */
1204 cli->dfsroot = False;
1205 if ( (CVAL(cli->inbuf, smb_wct))>2 && cli->protocol >= PROTOCOL_LANMAN2 )
1206 cli->dfsroot = (SVAL( cli->inbuf, smb_vwv2 ) & SMB_SHARE_IN_DFS) ? True : False;
1208 cli->cnum = SVAL(cli->inbuf,smb_tid);
1212 /****************************************************************************
1213 Send a tree disconnect.
1214 ****************************************************************************/
1216 bool cli_tdis(struct cli_state *cli)
1218 memset(cli->outbuf,'\0',smb_size);
1219 cli_set_message(cli->outbuf,0,0,True);
1220 SCVAL(cli->outbuf,smb_com,SMBtdis);
1221 SSVAL(cli->outbuf,smb_tid,cli->cnum);
1222 cli_setup_packet(cli);
1225 if (!cli_receive_smb(cli))
1228 if (cli_is_error(cli)) {
1236 /****************************************************************************
1237 Send a negprot command.
1238 ****************************************************************************/
1240 void cli_negprot_sendsync(struct cli_state *cli)
1245 if (cli->protocol < PROTOCOL_NT1)
1246 cli->use_spnego = False;
1248 memset(cli->outbuf,'\0',smb_size);
1250 /* setup the protocol strings */
1251 cli_set_message(cli->outbuf,0,0,True);
1253 p = smb_buf(cli->outbuf);
1254 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
1255 if (prots[numprots].prot > cli->protocol) {
1259 p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE);
1262 SCVAL(cli->outbuf,smb_com,SMBnegprot);
1263 cli_setup_bcc(cli, p);
1264 cli_setup_packet(cli);
1266 SCVAL(smb_buf(cli->outbuf),0,2);
1271 /****************************************************************************
1272 Send a negprot command.
1273 ****************************************************************************/
1275 struct async_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
1276 struct event_context *ev,
1277 struct cli_state *cli)
1279 struct async_req *result;
1280 uint8_t *bytes = NULL;
1283 if (cli->protocol < PROTOCOL_NT1)
1284 cli->use_spnego = False;
1286 /* setup the protocol strings */
1287 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
1289 if (prots[numprots].prot > cli->protocol) {
1292 bytes = (uint8_t *)talloc_append_blob(
1293 talloc_tos(), bytes, data_blob_const(&c, sizeof(c)));
1294 if (bytes == NULL) {
1297 bytes = smb_bytes_push_str(bytes, false, prots[numprots].name);
1298 if (bytes == NULL) {
1303 result = cli_request_send(mem_ctx, ev, cli, SMBnegprot, 0, 0, NULL, 0,
1304 talloc_get_size(bytes), bytes);
1309 NTSTATUS cli_negprot_recv(struct async_req *req)
1311 struct cli_request *cli_req = talloc_get_type_abort(
1312 req->private_data, struct cli_request);
1313 struct cli_state *cli = cli_req->cli;
1321 if (async_req_is_error(req, &status)) {
1325 status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
1326 if (!NT_STATUS_IS_OK(status)) {
1330 protnum = SVAL(vwv, 0);
1332 if ((protnum >= ARRAY_SIZE(prots))
1333 || (prots[protnum].prot > cli_req->cli->protocol)) {
1334 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1337 cli->protocol = prots[protnum].prot;
1339 if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) {
1340 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
1341 return NT_STATUS_ACCESS_DENIED;
1344 if (cli->protocol >= PROTOCOL_NT1) {
1347 cli->sec_mode = CVAL(vwv + 1, 0);
1348 cli->max_mux = SVAL(vwv + 1, 1);
1349 cli->max_xmit = IVAL(vwv + 3, 1);
1350 cli->sesskey = IVAL(vwv + 7, 1);
1351 cli->serverzone = SVALS(vwv + 15, 1);
1352 cli->serverzone *= 60;
1353 /* this time arrives in real GMT */
1354 ts = interpret_long_date(((char *)(vwv+11))+1);
1355 cli->servertime = ts.tv_sec;
1356 cli->secblob = data_blob(bytes, num_bytes);
1357 cli->capabilities = IVAL(vwv + 9, 1);
1358 if (cli->capabilities & CAP_RAW_MODE) {
1359 cli->readbraw_supported = True;
1360 cli->writebraw_supported = True;
1362 /* work out if they sent us a workgroup */
1363 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
1364 smb_buflen(cli->inbuf) > 8) {
1365 clistr_pull(cli->inbuf, cli->server_domain,
1366 bytes+8, sizeof(cli->server_domain),
1368 STR_UNICODE|STR_NOALIGN);
1372 * As signing is slow we only turn it on if either the client or
1373 * the server require it. JRA.
1376 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
1377 /* Fail if server says signing is mandatory and we don't want to support it. */
1378 if (!cli->sign_info.allow_smb_signing) {
1379 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
1380 return NT_STATUS_ACCESS_DENIED;
1382 cli->sign_info.negotiated_smb_signing = True;
1383 cli->sign_info.mandatory_signing = True;
1384 } else if (cli->sign_info.mandatory_signing && cli->sign_info.allow_smb_signing) {
1385 /* Fail if client says signing is mandatory and the server doesn't support it. */
1386 if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
1387 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
1388 return NT_STATUS_ACCESS_DENIED;
1390 cli->sign_info.negotiated_smb_signing = True;
1391 cli->sign_info.mandatory_signing = True;
1392 } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
1393 cli->sign_info.negotiated_smb_signing = True;
1396 if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
1397 SAFE_FREE(cli->outbuf);
1398 SAFE_FREE(cli->inbuf);
1399 cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1400 cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1401 cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE;
1404 } else if (cli->protocol >= PROTOCOL_LANMAN1) {
1405 cli->use_spnego = False;
1406 cli->sec_mode = SVAL(vwv + 1, 0);
1407 cli->max_xmit = SVAL(vwv + 2, 0);
1408 cli->max_mux = SVAL(vwv + 3, 0);
1409 cli->sesskey = IVAL(vwv + 6, 0);
1410 cli->serverzone = SVALS(vwv + 10, 0);
1411 cli->serverzone *= 60;
1412 /* this time is converted to GMT by make_unix_date */
1413 cli->servertime = cli_make_unix_date(
1414 cli, (char *)(vwv + 8));
1415 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0);
1416 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0);
1417 cli->secblob = data_blob(bytes, num_bytes);
1419 /* the old core protocol */
1420 cli->use_spnego = False;
1422 cli->serverzone = get_time_zone(time(NULL));
1425 cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
1427 /* a way to force ascii SMB */
1428 if (getenv("CLI_FORCE_ASCII"))
1429 cli->capabilities &= ~CAP_UNICODE;
1431 return NT_STATUS_OK;
1434 NTSTATUS cli_negprot(struct cli_state *cli)
1436 TALLOC_CTX *frame = talloc_stackframe();
1437 struct event_context *ev;
1438 struct async_req *req;
1439 NTSTATUS status = NT_STATUS_NO_MEMORY;
1441 if (cli->fd_event != NULL) {
1443 * Can't use sync call while an async call is in flight
1445 cli_set_error(cli, NT_STATUS_INVALID_PARAMETER);
1449 ev = event_context_init(frame);
1454 req = cli_negprot_send(frame, ev, cli);
1459 while (req->state < ASYNC_REQ_DONE) {
1460 event_loop_once(ev);
1463 status = cli_negprot_recv(req);
1469 /****************************************************************************
1470 Send a session request. See rfc1002.txt 4.3 and 4.3.2.
1471 ****************************************************************************/
1473 bool cli_session_request(struct cli_state *cli,
1474 struct nmb_name *calling, struct nmb_name *called)
1479 /* 445 doesn't have session request */
1480 if (cli->port == 445)
1483 memcpy(&(cli->calling), calling, sizeof(*calling));
1484 memcpy(&(cli->called ), called , sizeof(*called ));
1486 /* put in the destination name */
1487 p = cli->outbuf+len;
1488 name_mangle(cli->called .name, p, cli->called .name_type);
1492 p = cli->outbuf+len;
1493 name_mangle(cli->calling.name, p, cli->calling.name_type);
1496 /* send a session request (RFC 1002) */
1497 /* setup the packet length
1498 * Remove four bytes from the length count, since the length
1499 * field in the NBT Session Service header counts the number
1500 * of bytes which follow. The cli_send_smb() function knows
1501 * about this and accounts for those four bytes.
1505 _smb_setlen(cli->outbuf,len);
1506 SCVAL(cli->outbuf,0,0x81);
1509 DEBUG(5,("Sent session request\n"));
1511 if (!cli_receive_smb(cli))
1514 if (CVAL(cli->inbuf,0) == 0x84) {
1515 /* C. Hoch 9/14/95 Start */
1516 /* For information, here is the response structure.
1517 * We do the byte-twiddling to for portability.
1518 struct RetargetResponse{
1520 unsigned char flags;
1526 uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
1527 struct in_addr dest_ip;
1530 /* SESSION RETARGET */
1531 putip((char *)&dest_ip,cli->inbuf+4);
1532 in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
1534 status = open_socket_out(&cli->dest_ss, port,
1535 LONG_CONNECT_TIMEOUT, &cli->fd);
1536 if (!NT_STATUS_IS_OK(status)) {
1540 DEBUG(3,("Retargeted\n"));
1542 set_socket_options(cli->fd, lp_socket_options());
1549 DEBUG(0,("Retarget recursion - failing\n"));
1553 ret = cli_session_request(cli, calling, called);
1557 } /* C. Hoch 9/14/95 End */
1559 if (CVAL(cli->inbuf,0) != 0x82) {
1560 /* This is the wrong place to put the error... JRA. */
1561 cli->rap_error = CVAL(cli->inbuf,4);
1567 static void smb_sock_connected(struct async_req *req)
1569 int *pfd = (int *)req->async.priv;
1573 status = open_socket_out_defer_recv(req, &fd);
1574 if (NT_STATUS_IS_OK(status)) {
1579 static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
1580 uint16_t *port, int timeout, int *pfd)
1582 struct event_context *ev;
1583 struct async_req *r139, *r445;
1589 return open_socket_out(pss, *port, timeout, pfd);
1592 ev = event_context_init(talloc_tos());
1594 return NT_STATUS_NO_MEMORY;
1597 r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0),
1599 r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000),
1601 if ((r445 == NULL) || (r139 == NULL)) {
1602 status = NT_STATUS_NO_MEMORY;
1605 r445->async.fn = smb_sock_connected;
1606 r445->async.priv = &fd445;
1607 r139->async.fn = smb_sock_connected;
1608 r139->async.priv = &fd139;
1610 while ((fd139 == -1) && (r139->state < ASYNC_REQ_DONE)
1611 && (fd445 == -1) && (r445->state < ASYNC_REQ_DONE)) {
1612 event_loop_once(ev);
1615 if ((fd139 != -1) && (fd445 != -1)) {
1623 status = NT_STATUS_OK;
1629 status = NT_STATUS_OK;
1633 status = open_socket_out_defer_recv(r445, &fd445);
1639 /****************************************************************************
1640 Open the client sockets.
1641 ****************************************************************************/
1643 NTSTATUS cli_connect(struct cli_state *cli,
1645 struct sockaddr_storage *dest_ss)
1648 int name_type = 0x20;
1649 TALLOC_CTX *frame = talloc_stackframe();
1650 unsigned int num_addrs = 0;
1652 struct sockaddr_storage *ss_arr = NULL;
1655 /* reasonable default hostname */
1657 host = STAR_SMBSERVER;
1660 fstrcpy(cli->desthost, host);
1662 /* allow hostnames of the form NAME#xx and do a netbios lookup */
1663 if ((p = strchr(cli->desthost, '#'))) {
1664 name_type = strtol(p+1, NULL, 16);
1668 if (!dest_ss || is_zero_addr((struct sockaddr *)dest_ss)) {
1669 NTSTATUS status =resolve_name_list(frame,
1674 if (!NT_STATUS_IS_OK(status)) {
1676 return NT_STATUS_BAD_NETWORK_NAME;
1680 ss_arr = TALLOC_P(frame, struct sockaddr_storage);
1683 return NT_STATUS_NO_MEMORY;
1688 for (i = 0; i < num_addrs; i++) {
1689 cli->dest_ss = ss_arr[i];
1690 if (getenv("LIBSMB_PROG")) {
1691 cli->fd = sock_exec(getenv("LIBSMB_PROG"));
1693 uint16_t port = cli->port;
1695 status = open_smb_socket(&cli->dest_ss, &port,
1696 cli->timeout, &cli->fd);
1697 if (NT_STATUS_IS_OK(status)) {
1701 if (cli->fd == -1) {
1702 char addr[INET6_ADDRSTRLEN];
1703 print_sockaddr(addr, sizeof(addr), &ss_arr[i]);
1704 DEBUG(2,("Error connecting to %s (%s)\n",
1705 dest_ss?addr:host,strerror(errno)));
1707 /* Exit from loop on first connection. */
1712 if (cli->fd == -1) {
1714 return map_nt_error_from_unix(errno);
1718 *dest_ss = cli->dest_ss;
1721 set_socket_options(cli->fd, lp_socket_options());
1724 return NT_STATUS_OK;
1728 establishes a connection to after the negprot.
1729 @param output_cli A fully initialised cli structure, non-null only on success
1730 @param dest_host The netbios name of the remote host
1731 @param dest_ss (optional) The the destination IP, NULL for name based lookup
1732 @param port (optional) The destination port (0 for default)
1733 @param retry bool. Did this connection fail with a retryable error ?
1736 NTSTATUS cli_start_connection(struct cli_state **output_cli,
1737 const char *my_name,
1738 const char *dest_host,
1739 struct sockaddr_storage *dest_ss, int port,
1740 int signing_state, int flags,
1744 struct nmb_name calling;
1745 struct nmb_name called;
1746 struct cli_state *cli;
1747 struct sockaddr_storage ss;
1753 my_name = global_myname();
1755 if (!(cli = cli_initialise())) {
1756 return NT_STATUS_NO_MEMORY;
1759 make_nmb_name(&calling, my_name, 0x0);
1760 make_nmb_name(&called , dest_host, 0x20);
1762 cli_set_port(cli, port);
1763 cli_set_timeout(cli, 10000); /* 10 seconds. */
1773 DEBUG(3,("Connecting to host=%s\n", dest_host));
1775 nt_status = cli_connect(cli, dest_host, &ss);
1776 if (!NT_STATUS_IS_OK(nt_status)) {
1777 char addr[INET6_ADDRSTRLEN];
1778 print_sockaddr(addr, sizeof(addr), &ss);
1779 DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
1780 nmb_namestr(&called), addr, nt_errstr(nt_status) ));
1788 if (!cli_session_request(cli, &calling, &called)) {
1790 DEBUG(1,("session request to %s failed (%s)\n",
1791 called.name, cli_errstr(cli)));
1792 if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
1796 if (strcmp(called.name, STAR_SMBSERVER)) {
1797 make_nmb_name(&called , STAR_SMBSERVER, 0x20);
1800 return NT_STATUS_BAD_NETWORK_NAME;
1803 cli_setup_signing_state(cli, signing_state);
1805 if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
1806 cli->use_spnego = False;
1807 else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
1808 cli->use_kerberos = True;
1810 if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) &&
1811 cli->use_kerberos) {
1812 cli->fallback_after_kerberos = true;
1815 nt_status = cli_negprot(cli);
1816 if (!NT_STATUS_IS_OK(nt_status)) {
1817 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
1823 return NT_STATUS_OK;
1828 establishes a connection right up to doing tconX, password specified.
1829 @param output_cli A fully initialised cli structure, non-null only on success
1830 @param dest_host The netbios name of the remote host
1831 @param dest_ip (optional) The the destination IP, NULL for name based lookup
1832 @param port (optional) The destination port (0 for default)
1833 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
1834 @param service_type The 'type' of serivice.
1835 @param user Username, unix string
1836 @param domain User's domain
1837 @param password User's password, unencrypted unix string.
1838 @param retry bool. Did this connection fail with a retryable error ?
1841 NTSTATUS cli_full_connection(struct cli_state **output_cli,
1842 const char *my_name,
1843 const char *dest_host,
1844 struct sockaddr_storage *dest_ss, int port,
1845 const char *service, const char *service_type,
1846 const char *user, const char *domain,
1847 const char *password, int flags,
1852 struct cli_state *cli = NULL;
1853 int pw_len = password ? strlen(password)+1 : 0;
1857 if (password == NULL) {
1861 nt_status = cli_start_connection(&cli, my_name, dest_host,
1862 dest_ss, port, signing_state,
1865 if (!NT_STATUS_IS_OK(nt_status)) {
1869 nt_status = cli_session_setup(cli, user, password, pw_len, password,
1871 if (!NT_STATUS_IS_OK(nt_status)) {
1873 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
1874 DEBUG(1,("failed session setup with %s\n",
1875 nt_errstr(nt_status)));
1880 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
1881 if (!NT_STATUS_IS_OK(nt_status)) {
1882 DEBUG(1,("anonymous failed session setup with %s\n",
1883 nt_errstr(nt_status)));
1890 if (!cli_send_tconX(cli, service, service_type, password, pw_len)) {
1891 nt_status = cli_nt_error(cli);
1892 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
1894 if (NT_STATUS_IS_OK(nt_status)) {
1895 nt_status = NT_STATUS_UNSUCCESSFUL;
1901 cli_init_creds(cli, user, domain, password);
1904 return NT_STATUS_OK;
1907 /****************************************************************************
1908 Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
1909 ****************************************************************************/
1911 bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
1912 struct sockaddr_storage *pdest_ss)
1914 struct nmb_name calling, called;
1916 make_nmb_name(&calling, srchost, 0x0);
1919 * If the called name is an IP address
1920 * then use *SMBSERVER immediately.
1923 if(is_ipaddress(desthost)) {
1924 make_nmb_name(&called, STAR_SMBSERVER, 0x20);
1926 make_nmb_name(&called, desthost, 0x20);
1929 if (!cli_session_request(*ppcli, &calling, &called)) {
1931 struct nmb_name smbservername;
1933 make_nmb_name(&smbservername, STAR_SMBSERVER, 0x20);
1936 * If the name wasn't *SMBSERVER then
1937 * try with *SMBSERVER if the first name fails.
1940 if (nmb_name_equal(&called, &smbservername)) {
1943 * The name used was *SMBSERVER, don't bother with another name.
1946 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
1947 with error %s.\n", desthost, cli_errstr(*ppcli) ));
1952 cli_shutdown(*ppcli);
1954 *ppcli = cli_initialise();
1956 /* Out of memory... */
1960 status = cli_connect(*ppcli, desthost, pdest_ss);
1961 if (!NT_STATUS_IS_OK(status) ||
1962 !cli_session_request(*ppcli, &calling, &smbservername)) {
1963 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
1964 name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
1972 /****************************************************************************
1973 Send an old style tcon.
1974 ****************************************************************************/
1975 NTSTATUS cli_raw_tcon(struct cli_state *cli,
1976 const char *service, const char *pass, const char *dev,
1977 uint16 *max_xmit, uint16 *tid)
1981 if (!lp_client_plaintext_auth() && (*pass)) {
1982 DEBUG(1, ("Server requested plaintext password but 'client "
1983 "plaintext auth' is disabled\n"));
1984 return NT_STATUS_ACCESS_DENIED;
1987 memset(cli->outbuf,'\0',smb_size);
1988 memset(cli->inbuf,'\0',smb_size);
1990 cli_set_message(cli->outbuf, 0, 0, True);
1991 SCVAL(cli->outbuf,smb_com,SMBtcon);
1992 cli_setup_packet(cli);
1994 p = smb_buf(cli->outbuf);
1995 *p++ = 4; p += clistr_push(cli, p, service, -1, STR_TERMINATE | STR_NOALIGN);
1996 *p++ = 4; p += clistr_push(cli, p, pass, -1, STR_TERMINATE | STR_NOALIGN);
1997 *p++ = 4; p += clistr_push(cli, p, dev, -1, STR_TERMINATE | STR_NOALIGN);
1999 cli_setup_bcc(cli, p);
2002 if (!cli_receive_smb(cli)) {
2003 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
2006 if (cli_is_error(cli)) {
2007 return cli_nt_error(cli);
2010 *max_xmit = SVAL(cli->inbuf, smb_vwv0);
2011 *tid = SVAL(cli->inbuf, smb_vwv1);
2013 return NT_STATUS_OK;
2016 /* Return a cli_state pointing at the IPC$ share for the given server */
2018 struct cli_state *get_ipc_connect(char *server,
2019 struct sockaddr_storage *server_ss,
2020 const struct user_auth_info *user_info)
2022 struct cli_state *cli;
2024 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
2026 if (user_info->use_kerberos) {
2027 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
2030 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
2031 user_info->username ? user_info->username : "",
2033 user_info->password ? user_info->password : "",
2037 if (NT_STATUS_IS_OK(nt_status)) {
2039 } else if (is_ipaddress(server)) {
2040 /* windows 9* needs a correct NMB name for connections */
2041 fstring remote_name;
2043 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
2044 cli = get_ipc_connect(remote_name, server_ss, user_info);
2053 * Given the IP address of a master browser on the network, return its
2054 * workgroup and connect to it.
2056 * This function is provided to allow additional processing beyond what
2057 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
2058 * browsers and obtain each master browsers' list of domains (in case the
2059 * first master browser is recently on the network and has not yet
2060 * synchronized with other master browsers and therefore does not yet have the
2061 * entire network browse list)
2064 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
2065 struct ip_service *mb_ip,
2066 const struct user_auth_info *user_info,
2067 char **pp_workgroup_out)
2069 char addr[INET6_ADDRSTRLEN];
2071 struct cli_state *cli;
2072 struct sockaddr_storage server_ss;
2074 *pp_workgroup_out = NULL;
2076 print_sockaddr(addr, sizeof(addr), &mb_ip->ss);
2077 DEBUG(99, ("Looking up name of master browser %s\n",
2081 * Do a name status query to find out the name of the master browser.
2082 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
2083 * master browser will not respond to a wildcard query (or, at least,
2084 * an NT4 server acting as the domain master browser will not).
2086 * We might be able to use ONLY the query on MSBROWSE, but that's not
2087 * yet been tested with all Windows versions, so until it is, leave
2088 * the original wildcard query as the first choice and fall back to
2089 * MSBROWSE if the wildcard query fails.
2091 if (!name_status_find("*", 0, 0x1d, &mb_ip->ss, name) &&
2092 !name_status_find(MSBROWSE, 1, 0x1d, &mb_ip->ss, name)) {
2094 DEBUG(99, ("Could not retrieve name status for %s\n",
2099 if (!find_master_ip(name, &server_ss)) {
2100 DEBUG(99, ("Could not find master ip for %s\n", name));
2104 *pp_workgroup_out = talloc_strdup(ctx, name);
2106 DEBUG(4, ("found master browser %s, %s\n", name, addr));
2108 print_sockaddr(addr, sizeof(addr), &server_ss);
2109 cli = get_ipc_connect(addr, &server_ss, user_info);
2115 * Return the IP address and workgroup of a master browser on the network, and
2119 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
2120 const struct user_auth_info *user_info,
2121 char **pp_workgroup_out)
2123 struct ip_service *ip_list;
2124 struct cli_state *cli;
2127 *pp_workgroup_out = NULL;
2129 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
2131 /* Go looking for workgroups by broadcasting on the local network */
2133 if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
2135 DEBUG(99, ("No master browsers responded\n"));
2139 for (i = 0; i < count; i++) {
2140 char addr[INET6_ADDRSTRLEN];
2141 print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
2142 DEBUG(99, ("Found master browser %s\n", addr));
2144 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
2145 user_info, pp_workgroup_out);