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,
1298 prots[numprots].name,
1299 strlen(prots[numprots].name)+1,
1301 if (bytes == NULL) {
1306 result = cli_request_send(mem_ctx, ev, cli, SMBnegprot, 0, 0, NULL, 0,
1307 talloc_get_size(bytes), bytes);
1312 NTSTATUS cli_negprot_recv(struct async_req *req)
1314 struct cli_request *cli_req = talloc_get_type_abort(
1315 req->private_data, struct cli_request);
1316 struct cli_state *cli = cli_req->cli;
1324 if (async_req_is_error(req, &status)) {
1328 status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
1329 if (!NT_STATUS_IS_OK(status)) {
1333 protnum = SVAL(vwv, 0);
1335 if ((protnum >= ARRAY_SIZE(prots))
1336 || (prots[protnum].prot > cli_req->cli->protocol)) {
1337 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1340 cli->protocol = prots[protnum].prot;
1342 if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) {
1343 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
1344 return NT_STATUS_ACCESS_DENIED;
1347 if (cli->protocol >= PROTOCOL_NT1) {
1350 cli->sec_mode = CVAL(vwv + 1, 0);
1351 cli->max_mux = SVAL(vwv + 1, 1);
1352 cli->max_xmit = IVAL(vwv + 3, 1);
1353 cli->sesskey = IVAL(vwv + 7, 1);
1354 cli->serverzone = SVALS(vwv + 15, 1);
1355 cli->serverzone *= 60;
1356 /* this time arrives in real GMT */
1357 ts = interpret_long_date(((char *)(vwv+11))+1);
1358 cli->servertime = ts.tv_sec;
1359 cli->secblob = data_blob(bytes, num_bytes);
1360 cli->capabilities = IVAL(vwv + 9, 1);
1361 if (cli->capabilities & CAP_RAW_MODE) {
1362 cli->readbraw_supported = True;
1363 cli->writebraw_supported = True;
1365 /* work out if they sent us a workgroup */
1366 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
1367 smb_buflen(cli->inbuf) > 8) {
1368 clistr_pull(cli->inbuf, cli->server_domain,
1369 bytes+8, sizeof(cli->server_domain),
1371 STR_UNICODE|STR_NOALIGN);
1375 * As signing is slow we only turn it on if either the client or
1376 * the server require it. JRA.
1379 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
1380 /* Fail if server says signing is mandatory and we don't want to support it. */
1381 if (!cli->sign_info.allow_smb_signing) {
1382 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
1383 return NT_STATUS_ACCESS_DENIED;
1385 cli->sign_info.negotiated_smb_signing = True;
1386 cli->sign_info.mandatory_signing = True;
1387 } else if (cli->sign_info.mandatory_signing && cli->sign_info.allow_smb_signing) {
1388 /* Fail if client says signing is mandatory and the server doesn't support it. */
1389 if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
1390 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
1391 return NT_STATUS_ACCESS_DENIED;
1393 cli->sign_info.negotiated_smb_signing = True;
1394 cli->sign_info.mandatory_signing = True;
1395 } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
1396 cli->sign_info.negotiated_smb_signing = True;
1399 if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
1400 SAFE_FREE(cli->outbuf);
1401 SAFE_FREE(cli->inbuf);
1402 cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1403 cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1404 cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE;
1407 } else if (cli->protocol >= PROTOCOL_LANMAN1) {
1408 cli->use_spnego = False;
1409 cli->sec_mode = SVAL(vwv + 1, 0);
1410 cli->max_xmit = SVAL(vwv + 2, 0);
1411 cli->max_mux = SVAL(vwv + 3, 0);
1412 cli->sesskey = IVAL(vwv + 6, 0);
1413 cli->serverzone = SVALS(vwv + 10, 0);
1414 cli->serverzone *= 60;
1415 /* this time is converted to GMT by make_unix_date */
1416 cli->servertime = cli_make_unix_date(
1417 cli, (char *)(vwv + 8));
1418 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0);
1419 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0);
1420 cli->secblob = data_blob(bytes, num_bytes);
1422 /* the old core protocol */
1423 cli->use_spnego = False;
1425 cli->serverzone = get_time_zone(time(NULL));
1428 cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
1430 /* a way to force ascii SMB */
1431 if (getenv("CLI_FORCE_ASCII"))
1432 cli->capabilities &= ~CAP_UNICODE;
1434 return NT_STATUS_OK;
1437 NTSTATUS cli_negprot(struct cli_state *cli)
1439 TALLOC_CTX *frame = talloc_stackframe();
1440 struct event_context *ev;
1441 struct async_req *req;
1442 NTSTATUS status = NT_STATUS_NO_MEMORY;
1444 if (cli->fd_event != NULL) {
1446 * Can't use sync call while an async call is in flight
1448 cli_set_error(cli, NT_STATUS_INVALID_PARAMETER);
1452 ev = event_context_init(frame);
1457 req = cli_negprot_send(frame, ev, cli);
1462 while (req->state < ASYNC_REQ_DONE) {
1463 event_loop_once(ev);
1466 status = cli_negprot_recv(req);
1472 /****************************************************************************
1473 Send a session request. See rfc1002.txt 4.3 and 4.3.2.
1474 ****************************************************************************/
1476 bool cli_session_request(struct cli_state *cli,
1477 struct nmb_name *calling, struct nmb_name *called)
1482 /* 445 doesn't have session request */
1483 if (cli->port == 445)
1486 memcpy(&(cli->calling), calling, sizeof(*calling));
1487 memcpy(&(cli->called ), called , sizeof(*called ));
1489 /* put in the destination name */
1490 p = cli->outbuf+len;
1491 name_mangle(cli->called .name, p, cli->called .name_type);
1495 p = cli->outbuf+len;
1496 name_mangle(cli->calling.name, p, cli->calling.name_type);
1499 /* send a session request (RFC 1002) */
1500 /* setup the packet length
1501 * Remove four bytes from the length count, since the length
1502 * field in the NBT Session Service header counts the number
1503 * of bytes which follow. The cli_send_smb() function knows
1504 * about this and accounts for those four bytes.
1508 _smb_setlen(cli->outbuf,len);
1509 SCVAL(cli->outbuf,0,0x81);
1512 DEBUG(5,("Sent session request\n"));
1514 if (!cli_receive_smb(cli))
1517 if (CVAL(cli->inbuf,0) == 0x84) {
1518 /* C. Hoch 9/14/95 Start */
1519 /* For information, here is the response structure.
1520 * We do the byte-twiddling to for portability.
1521 struct RetargetResponse{
1523 unsigned char flags;
1529 uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
1530 struct in_addr dest_ip;
1533 /* SESSION RETARGET */
1534 putip((char *)&dest_ip,cli->inbuf+4);
1535 in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
1537 status = open_socket_out(&cli->dest_ss, port,
1538 LONG_CONNECT_TIMEOUT, &cli->fd);
1539 if (!NT_STATUS_IS_OK(status)) {
1543 DEBUG(3,("Retargeted\n"));
1545 set_socket_options(cli->fd, lp_socket_options());
1552 DEBUG(0,("Retarget recursion - failing\n"));
1556 ret = cli_session_request(cli, calling, called);
1560 } /* C. Hoch 9/14/95 End */
1562 if (CVAL(cli->inbuf,0) != 0x82) {
1563 /* This is the wrong place to put the error... JRA. */
1564 cli->rap_error = CVAL(cli->inbuf,4);
1570 static void smb_sock_connected(struct async_req *req)
1572 int *pfd = (int *)req->async.priv;
1576 status = open_socket_out_defer_recv(req, &fd);
1577 if (NT_STATUS_IS_OK(status)) {
1582 static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
1583 uint16_t *port, int timeout, int *pfd)
1585 struct event_context *ev;
1586 struct async_req *r139, *r445;
1592 return open_socket_out(pss, *port, timeout, pfd);
1595 ev = event_context_init(talloc_tos());
1597 return NT_STATUS_NO_MEMORY;
1600 r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0),
1602 r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000),
1604 if ((r445 == NULL) || (r139 == NULL)) {
1605 status = NT_STATUS_NO_MEMORY;
1608 r445->async.fn = smb_sock_connected;
1609 r445->async.priv = &fd445;
1610 r139->async.fn = smb_sock_connected;
1611 r139->async.priv = &fd139;
1613 while ((fd139 == -1) && (r139->state < ASYNC_REQ_DONE)
1614 && (fd445 == -1) && (r445->state < ASYNC_REQ_DONE)) {
1615 event_loop_once(ev);
1618 if ((fd139 != -1) && (fd445 != -1)) {
1626 status = NT_STATUS_OK;
1632 status = NT_STATUS_OK;
1636 status = open_socket_out_defer_recv(r445, &fd445);
1642 /****************************************************************************
1643 Open the client sockets.
1644 ****************************************************************************/
1646 NTSTATUS cli_connect(struct cli_state *cli,
1648 struct sockaddr_storage *dest_ss)
1651 int name_type = 0x20;
1652 TALLOC_CTX *frame = talloc_stackframe();
1653 unsigned int num_addrs = 0;
1655 struct sockaddr_storage *ss_arr = NULL;
1658 /* reasonable default hostname */
1660 host = STAR_SMBSERVER;
1663 fstrcpy(cli->desthost, host);
1665 /* allow hostnames of the form NAME#xx and do a netbios lookup */
1666 if ((p = strchr(cli->desthost, '#'))) {
1667 name_type = strtol(p+1, NULL, 16);
1671 if (!dest_ss || is_zero_addr((struct sockaddr *)dest_ss)) {
1672 NTSTATUS status =resolve_name_list(frame,
1677 if (!NT_STATUS_IS_OK(status)) {
1679 return NT_STATUS_BAD_NETWORK_NAME;
1683 ss_arr = TALLOC_P(frame, struct sockaddr_storage);
1686 return NT_STATUS_NO_MEMORY;
1691 for (i = 0; i < num_addrs; i++) {
1692 cli->dest_ss = ss_arr[i];
1693 if (getenv("LIBSMB_PROG")) {
1694 cli->fd = sock_exec(getenv("LIBSMB_PROG"));
1696 uint16_t port = cli->port;
1698 status = open_smb_socket(&cli->dest_ss, &port,
1699 cli->timeout, &cli->fd);
1700 if (NT_STATUS_IS_OK(status)) {
1704 if (cli->fd == -1) {
1705 char addr[INET6_ADDRSTRLEN];
1706 print_sockaddr(addr, sizeof(addr), &ss_arr[i]);
1707 DEBUG(2,("Error connecting to %s (%s)\n",
1708 dest_ss?addr:host,strerror(errno)));
1710 /* Exit from loop on first connection. */
1715 if (cli->fd == -1) {
1717 return map_nt_error_from_unix(errno);
1721 *dest_ss = cli->dest_ss;
1724 set_socket_options(cli->fd, lp_socket_options());
1727 return NT_STATUS_OK;
1731 establishes a connection to after the negprot.
1732 @param output_cli A fully initialised cli structure, non-null only on success
1733 @param dest_host The netbios name of the remote host
1734 @param dest_ss (optional) The the destination IP, NULL for name based lookup
1735 @param port (optional) The destination port (0 for default)
1736 @param retry bool. Did this connection fail with a retryable error ?
1739 NTSTATUS cli_start_connection(struct cli_state **output_cli,
1740 const char *my_name,
1741 const char *dest_host,
1742 struct sockaddr_storage *dest_ss, int port,
1743 int signing_state, int flags,
1747 struct nmb_name calling;
1748 struct nmb_name called;
1749 struct cli_state *cli;
1750 struct sockaddr_storage ss;
1756 my_name = global_myname();
1758 if (!(cli = cli_initialise())) {
1759 return NT_STATUS_NO_MEMORY;
1762 make_nmb_name(&calling, my_name, 0x0);
1763 make_nmb_name(&called , dest_host, 0x20);
1765 cli_set_port(cli, port);
1766 cli_set_timeout(cli, 10000); /* 10 seconds. */
1776 DEBUG(3,("Connecting to host=%s\n", dest_host));
1778 nt_status = cli_connect(cli, dest_host, &ss);
1779 if (!NT_STATUS_IS_OK(nt_status)) {
1780 char addr[INET6_ADDRSTRLEN];
1781 print_sockaddr(addr, sizeof(addr), &ss);
1782 DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
1783 nmb_namestr(&called), addr, nt_errstr(nt_status) ));
1791 if (!cli_session_request(cli, &calling, &called)) {
1793 DEBUG(1,("session request to %s failed (%s)\n",
1794 called.name, cli_errstr(cli)));
1795 if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
1799 if (strcmp(called.name, STAR_SMBSERVER)) {
1800 make_nmb_name(&called , STAR_SMBSERVER, 0x20);
1803 return NT_STATUS_BAD_NETWORK_NAME;
1806 cli_setup_signing_state(cli, signing_state);
1808 if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
1809 cli->use_spnego = False;
1810 else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
1811 cli->use_kerberos = True;
1813 if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) &&
1814 cli->use_kerberos) {
1815 cli->fallback_after_kerberos = true;
1818 nt_status = cli_negprot(cli);
1819 if (!NT_STATUS_IS_OK(nt_status)) {
1820 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
1826 return NT_STATUS_OK;
1831 establishes a connection right up to doing tconX, password specified.
1832 @param output_cli A fully initialised cli structure, non-null only on success
1833 @param dest_host The netbios name of the remote host
1834 @param dest_ip (optional) The the destination IP, NULL for name based lookup
1835 @param port (optional) The destination port (0 for default)
1836 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
1837 @param service_type The 'type' of serivice.
1838 @param user Username, unix string
1839 @param domain User's domain
1840 @param password User's password, unencrypted unix string.
1841 @param retry bool. Did this connection fail with a retryable error ?
1844 NTSTATUS cli_full_connection(struct cli_state **output_cli,
1845 const char *my_name,
1846 const char *dest_host,
1847 struct sockaddr_storage *dest_ss, int port,
1848 const char *service, const char *service_type,
1849 const char *user, const char *domain,
1850 const char *password, int flags,
1855 struct cli_state *cli = NULL;
1856 int pw_len = password ? strlen(password)+1 : 0;
1860 if (password == NULL) {
1864 nt_status = cli_start_connection(&cli, my_name, dest_host,
1865 dest_ss, port, signing_state,
1868 if (!NT_STATUS_IS_OK(nt_status)) {
1872 nt_status = cli_session_setup(cli, user, password, pw_len, password,
1874 if (!NT_STATUS_IS_OK(nt_status)) {
1876 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
1877 DEBUG(1,("failed session setup with %s\n",
1878 nt_errstr(nt_status)));
1883 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
1884 if (!NT_STATUS_IS_OK(nt_status)) {
1885 DEBUG(1,("anonymous failed session setup with %s\n",
1886 nt_errstr(nt_status)));
1893 if (!cli_send_tconX(cli, service, service_type, password, pw_len)) {
1894 nt_status = cli_nt_error(cli);
1895 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
1897 if (NT_STATUS_IS_OK(nt_status)) {
1898 nt_status = NT_STATUS_UNSUCCESSFUL;
1904 cli_init_creds(cli, user, domain, password);
1907 return NT_STATUS_OK;
1910 /****************************************************************************
1911 Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
1912 ****************************************************************************/
1914 bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
1915 struct sockaddr_storage *pdest_ss)
1917 struct nmb_name calling, called;
1919 make_nmb_name(&calling, srchost, 0x0);
1922 * If the called name is an IP address
1923 * then use *SMBSERVER immediately.
1926 if(is_ipaddress(desthost)) {
1927 make_nmb_name(&called, STAR_SMBSERVER, 0x20);
1929 make_nmb_name(&called, desthost, 0x20);
1932 if (!cli_session_request(*ppcli, &calling, &called)) {
1934 struct nmb_name smbservername;
1936 make_nmb_name(&smbservername, STAR_SMBSERVER, 0x20);
1939 * If the name wasn't *SMBSERVER then
1940 * try with *SMBSERVER if the first name fails.
1943 if (nmb_name_equal(&called, &smbservername)) {
1946 * The name used was *SMBSERVER, don't bother with another name.
1949 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
1950 with error %s.\n", desthost, cli_errstr(*ppcli) ));
1955 cli_shutdown(*ppcli);
1957 *ppcli = cli_initialise();
1959 /* Out of memory... */
1963 status = cli_connect(*ppcli, desthost, pdest_ss);
1964 if (!NT_STATUS_IS_OK(status) ||
1965 !cli_session_request(*ppcli, &calling, &smbservername)) {
1966 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
1967 name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
1975 /****************************************************************************
1976 Send an old style tcon.
1977 ****************************************************************************/
1978 NTSTATUS cli_raw_tcon(struct cli_state *cli,
1979 const char *service, const char *pass, const char *dev,
1980 uint16 *max_xmit, uint16 *tid)
1984 if (!lp_client_plaintext_auth() && (*pass)) {
1985 DEBUG(1, ("Server requested plaintext password but 'client "
1986 "plaintext auth' is disabled\n"));
1987 return NT_STATUS_ACCESS_DENIED;
1990 memset(cli->outbuf,'\0',smb_size);
1991 memset(cli->inbuf,'\0',smb_size);
1993 cli_set_message(cli->outbuf, 0, 0, True);
1994 SCVAL(cli->outbuf,smb_com,SMBtcon);
1995 cli_setup_packet(cli);
1997 p = smb_buf(cli->outbuf);
1998 *p++ = 4; p += clistr_push(cli, p, service, -1, STR_TERMINATE | STR_NOALIGN);
1999 *p++ = 4; p += clistr_push(cli, p, pass, -1, STR_TERMINATE | STR_NOALIGN);
2000 *p++ = 4; p += clistr_push(cli, p, dev, -1, STR_TERMINATE | STR_NOALIGN);
2002 cli_setup_bcc(cli, p);
2005 if (!cli_receive_smb(cli)) {
2006 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
2009 if (cli_is_error(cli)) {
2010 return cli_nt_error(cli);
2013 *max_xmit = SVAL(cli->inbuf, smb_vwv0);
2014 *tid = SVAL(cli->inbuf, smb_vwv1);
2016 return NT_STATUS_OK;
2019 /* Return a cli_state pointing at the IPC$ share for the given server */
2021 struct cli_state *get_ipc_connect(char *server,
2022 struct sockaddr_storage *server_ss,
2023 const struct user_auth_info *user_info)
2025 struct cli_state *cli;
2027 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
2029 if (user_info->use_kerberos) {
2030 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
2033 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
2034 user_info->username ? user_info->username : "",
2036 user_info->password ? user_info->password : "",
2040 if (NT_STATUS_IS_OK(nt_status)) {
2042 } else if (is_ipaddress(server)) {
2043 /* windows 9* needs a correct NMB name for connections */
2044 fstring remote_name;
2046 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
2047 cli = get_ipc_connect(remote_name, server_ss, user_info);
2056 * Given the IP address of a master browser on the network, return its
2057 * workgroup and connect to it.
2059 * This function is provided to allow additional processing beyond what
2060 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
2061 * browsers and obtain each master browsers' list of domains (in case the
2062 * first master browser is recently on the network and has not yet
2063 * synchronized with other master browsers and therefore does not yet have the
2064 * entire network browse list)
2067 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
2068 struct ip_service *mb_ip,
2069 const struct user_auth_info *user_info,
2070 char **pp_workgroup_out)
2072 char addr[INET6_ADDRSTRLEN];
2074 struct cli_state *cli;
2075 struct sockaddr_storage server_ss;
2077 *pp_workgroup_out = NULL;
2079 print_sockaddr(addr, sizeof(addr), &mb_ip->ss);
2080 DEBUG(99, ("Looking up name of master browser %s\n",
2084 * Do a name status query to find out the name of the master browser.
2085 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
2086 * master browser will not respond to a wildcard query (or, at least,
2087 * an NT4 server acting as the domain master browser will not).
2089 * We might be able to use ONLY the query on MSBROWSE, but that's not
2090 * yet been tested with all Windows versions, so until it is, leave
2091 * the original wildcard query as the first choice and fall back to
2092 * MSBROWSE if the wildcard query fails.
2094 if (!name_status_find("*", 0, 0x1d, &mb_ip->ss, name) &&
2095 !name_status_find(MSBROWSE, 1, 0x1d, &mb_ip->ss, name)) {
2097 DEBUG(99, ("Could not retrieve name status for %s\n",
2102 if (!find_master_ip(name, &server_ss)) {
2103 DEBUG(99, ("Could not find master ip for %s\n", name));
2107 *pp_workgroup_out = talloc_strdup(ctx, name);
2109 DEBUG(4, ("found master browser %s, %s\n", name, addr));
2111 print_sockaddr(addr, sizeof(addr), &server_ss);
2112 cli = get_ipc_connect(addr, &server_ss, user_info);
2118 * Return the IP address and workgroup of a master browser on the network, and
2122 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
2123 const struct user_auth_info *user_info,
2124 char **pp_workgroup_out)
2126 struct ip_service *ip_list;
2127 struct cli_state *cli;
2130 *pp_workgroup_out = NULL;
2132 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
2134 /* Go looking for workgroups by broadcasting on the local network */
2136 if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
2138 DEBUG(99, ("No master browsers responded\n"));
2142 for (i = 0; i < count; i++) {
2143 char addr[INET6_ADDRSTRLEN];
2144 print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
2145 DEBUG(99, ("Found master browser %s\n", addr));
2147 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
2148 user_info, pp_workgroup_out);