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/>.
22 #include "../libcli/auth/libcli_auth.h"
28 {PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"},
29 {PROTOCOL_COREPLUS, "MICROSOFT NETWORKS 1.03"},
30 {PROTOCOL_LANMAN1, "MICROSOFT NETWORKS 3.0"},
31 {PROTOCOL_LANMAN1, "LANMAN1.0"},
32 {PROTOCOL_LANMAN2, "LM1.2X002"},
33 {PROTOCOL_LANMAN2, "DOS LANMAN2.1"},
34 {PROTOCOL_LANMAN2, "LANMAN2.1"},
35 {PROTOCOL_LANMAN2, "Samba"},
36 {PROTOCOL_NT1, "NT LANMAN 1.0"},
37 {PROTOCOL_NT1, "NT LM 0.12"},
40 #define STAR_SMBSERVER "*SMBSERVER"
43 * Set the user session key for a connection
44 * @param cli The cli structure to add it too
45 * @param session_key The session key used. (A copy of this is taken for the cli struct)
49 static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key)
51 cli->user_session_key = data_blob(session_key.data, session_key.length);
54 /****************************************************************************
55 Do an old lanman2 style session setup.
56 ****************************************************************************/
58 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli,
60 const char *pass, size_t passlen,
61 const char *workgroup)
63 DATA_BLOB session_key = data_blob_null;
64 DATA_BLOB lm_response = data_blob_null;
69 if (passlen > sizeof(pword)-1) {
70 return NT_STATUS_INVALID_PARAMETER;
73 /* LANMAN servers predate NT status codes and Unicode and ignore those
74 smb flags so we must disable the corresponding default capabilities
75 that would otherwise cause the Unicode and NT Status flags to be
76 set (and even returned by the server) */
78 cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32);
80 /* if in share level security then don't send a password now */
81 if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL))
84 if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) {
85 /* Encrypted mode needed, and non encrypted password supplied. */
86 lm_response = data_blob(NULL, 24);
87 if (!SMBencrypt(pass, cli->secblob.data,(uchar *)lm_response.data)) {
88 DEBUG(1, ("Password is > 14 chars in length, and is therefore incompatible with Lanman authentication\n"));
89 return NT_STATUS_ACCESS_DENIED;
91 } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) {
92 /* Encrypted mode needed, and encrypted password supplied. */
93 lm_response = data_blob(pass, passlen);
94 } else if (passlen > 0) {
95 /* Plaintext mode needed, assume plaintext supplied. */
96 passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
97 lm_response = data_blob(pass, passlen);
100 /* send a session setup command */
101 memset(cli->outbuf,'\0',smb_size);
102 cli_set_message(cli->outbuf,10, 0, True);
103 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
104 cli_setup_packet(cli);
106 SCVAL(cli->outbuf,smb_vwv0,0xFF);
107 SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit);
108 SSVAL(cli->outbuf,smb_vwv3,2);
109 SSVAL(cli->outbuf,smb_vwv4,1);
110 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
111 SSVAL(cli->outbuf,smb_vwv7,lm_response.length);
113 p = smb_buf(cli->outbuf);
114 memcpy(p,lm_response.data,lm_response.length);
115 p += lm_response.length;
116 p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER);
117 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER);
118 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
119 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
120 cli_setup_bcc(cli, p);
122 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
123 return cli_nt_error(cli);
126 show_msg(cli->inbuf);
128 if (cli_is_error(cli)) {
129 return cli_nt_error(cli);
132 /* use the returned vuid from now on */
133 cli->vuid = SVAL(cli->inbuf,smb_uid);
134 status = cli_set_username(cli, user);
135 if (!NT_STATUS_IS_OK(status)) {
139 if (session_key.data) {
140 /* Have plaintext orginal */
141 cli_set_session_key(cli, session_key);
147 /****************************************************************************
148 Work out suitable capabilities to offer the server.
149 ****************************************************************************/
151 static uint32 cli_session_setup_capabilities(struct cli_state *cli)
153 uint32 capabilities = CAP_NT_SMBS;
155 if (!cli->force_dos_errors)
156 capabilities |= CAP_STATUS32;
158 if (cli->use_level_II_oplocks)
159 capabilities |= CAP_LEVEL_II_OPLOCKS;
161 capabilities |= (cli->capabilities & (CAP_UNICODE|CAP_LARGE_FILES|CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_DFS));
165 /****************************************************************************
166 Do a NT1 guest session setup.
167 ****************************************************************************/
169 struct cli_session_setup_guest_state {
170 struct cli_state *cli;
175 static void cli_session_setup_guest_done(struct tevent_req *subreq);
177 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
178 struct event_context *ev,
179 struct cli_state *cli,
180 struct tevent_req **psmbreq)
182 struct tevent_req *req, *subreq;
183 struct cli_session_setup_guest_state *state;
187 req = tevent_req_create(mem_ctx, &state,
188 struct cli_session_setup_guest_state);
195 SCVAL(vwv+0, 0, 0xFF);
198 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
200 SSVAL(vwv+4, 0, cli->pid);
201 SIVAL(vwv+5, 0, cli->sesskey);
206 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
208 bytes = talloc_array(state, uint8_t, 0);
210 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* username */
212 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* workgroup */
214 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
215 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
222 state->bytes.iov_base = bytes;
223 state->bytes.iov_len = talloc_get_size(bytes);
225 subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
227 if (subreq == NULL) {
231 tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
236 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
237 struct event_context *ev,
238 struct cli_state *cli)
240 struct tevent_req *req, *subreq;
242 req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
243 if ((req == NULL) || !cli_smb_req_send(subreq)) {
250 static void cli_session_setup_guest_done(struct tevent_req *subreq)
252 struct tevent_req *req = tevent_req_callback_data(
253 subreq, struct tevent_req);
254 struct cli_session_setup_guest_state *state = tevent_req_data(
255 req, struct cli_session_setup_guest_state);
256 struct cli_state *cli = state->cli;
263 status = cli_smb_recv(subreq, 0, NULL, NULL, &num_bytes, &bytes);
264 if (!NT_STATUS_IS_OK(status)) {
266 tevent_req_nterror(req, status);
270 inbuf = (char *)cli_smb_inbuf(subreq);
273 cli->vuid = SVAL(inbuf, smb_uid);
275 p += clistr_pull(inbuf, cli->server_os, (char *)p, sizeof(fstring),
276 bytes+num_bytes-p, STR_TERMINATE);
277 p += clistr_pull(inbuf, cli->server_type, (char *)p, sizeof(fstring),
278 bytes+num_bytes-p, STR_TERMINATE);
279 p += clistr_pull(inbuf, cli->server_domain, (char *)p, sizeof(fstring),
280 bytes+num_bytes-p, STR_TERMINATE);
282 if (strstr(cli->server_type, "Samba")) {
283 cli->is_samba = True;
288 status = cli_set_username(cli, "");
289 if (!NT_STATUS_IS_OK(status)) {
290 tevent_req_nterror(req, status);
293 tevent_req_done(req);
296 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
298 return tevent_req_simple_recv_ntstatus(req);
301 static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
303 TALLOC_CTX *frame = talloc_stackframe();
304 struct event_context *ev;
305 struct tevent_req *req;
306 NTSTATUS status = NT_STATUS_OK;
308 if (cli_has_async_calls(cli)) {
310 * Can't use sync call while an async call is in flight
312 status = NT_STATUS_INVALID_PARAMETER;
316 ev = event_context_init(frame);
318 status = NT_STATUS_NO_MEMORY;
322 req = cli_session_setup_guest_send(frame, ev, cli);
324 status = NT_STATUS_NO_MEMORY;
328 if (!tevent_req_poll(req, ev)) {
329 status = map_nt_error_from_unix(errno);
333 status = cli_session_setup_guest_recv(req);
336 if (!NT_STATUS_IS_OK(status)) {
337 cli_set_error(cli, status);
342 /****************************************************************************
343 Do a NT1 plaintext session setup.
344 ****************************************************************************/
346 static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli,
347 const char *user, const char *pass,
348 const char *workgroup)
350 uint32 capabilities = cli_session_setup_capabilities(cli);
355 fstr_sprintf( lanman, "Samba %s", samba_version_string());
357 memset(cli->outbuf, '\0', smb_size);
358 cli_set_message(cli->outbuf,13,0,True);
359 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
360 cli_setup_packet(cli);
362 SCVAL(cli->outbuf,smb_vwv0,0xFF);
363 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
364 SSVAL(cli->outbuf,smb_vwv3,2);
365 SSVAL(cli->outbuf,smb_vwv4,cli->pid);
366 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
367 SSVAL(cli->outbuf,smb_vwv8,0);
368 SIVAL(cli->outbuf,smb_vwv11,capabilities);
369 p = smb_buf(cli->outbuf);
371 /* check wether to send the ASCII or UNICODE version of the password */
373 if ( (capabilities & CAP_UNICODE) == 0 ) {
374 p += clistr_push(cli, p, pass, -1, STR_TERMINATE); /* password */
375 SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf)));
378 /* For ucs2 passwords clistr_push calls ucs2_align, which causes
379 * the space taken by the unicode password to be one byte too
380 * long (as we're on an odd byte boundary here). Reduce the
381 * count by 1 to cope with this. Fixes smbclient against NetApp
382 * servers which can't cope. Fix from
383 * bryan.kolodziej@allenlund.com in bug #3840.
385 p += clistr_push(cli, p, pass, -1, STR_UNICODE|STR_TERMINATE); /* unicode password */
386 SSVAL(cli->outbuf,smb_vwv8,PTR_DIFF(p, smb_buf(cli->outbuf))-1);
389 p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */
390 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */
391 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
392 p += clistr_push(cli, p, lanman, -1, STR_TERMINATE);
393 cli_setup_bcc(cli, p);
395 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
396 return cli_nt_error(cli);
399 show_msg(cli->inbuf);
401 if (cli_is_error(cli)) {
402 return cli_nt_error(cli);
405 cli->vuid = SVAL(cli->inbuf,smb_uid);
406 p = smb_buf(cli->inbuf);
407 p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring),
409 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring),
411 p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring),
413 status = cli_set_username(cli, user);
414 if (!NT_STATUS_IS_OK(status)) {
417 if (strstr(cli->server_type, "Samba")) {
418 cli->is_samba = True;
424 /****************************************************************************
425 do a NT1 NTLM/LM encrypted session setup - for when extended security
427 @param cli client state to create do session setup on
429 @param pass *either* cleartext password (passlen !=24) or LM response.
430 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
431 @param workgroup The user's domain.
432 ****************************************************************************/
434 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
435 const char *pass, size_t passlen,
436 const char *ntpass, size_t ntpasslen,
437 const char *workgroup)
439 uint32 capabilities = cli_session_setup_capabilities(cli);
440 DATA_BLOB lm_response = data_blob_null;
441 DATA_BLOB nt_response = data_blob_null;
442 DATA_BLOB session_key = data_blob_null;
448 /* do nothing - guest login */
449 } else if (passlen != 24) {
450 if (lp_client_ntlmv2_auth()) {
451 DATA_BLOB server_chal;
452 DATA_BLOB names_blob;
453 server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8));
455 /* note that the 'workgroup' here is a best guess - we don't know
456 the server's domain at this point. The 'server name' is also
459 names_blob = NTLMv2_generate_names_blob(NULL, cli->called.name, workgroup);
461 if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass, &server_chal,
463 &lm_response, &nt_response, NULL, &session_key)) {
464 data_blob_free(&names_blob);
465 data_blob_free(&server_chal);
466 return NT_STATUS_ACCESS_DENIED;
468 data_blob_free(&names_blob);
469 data_blob_free(&server_chal);
473 E_md4hash(pass, nt_hash);
476 nt_response = data_blob_null;
478 nt_response = data_blob(NULL, 24);
479 SMBNTencrypt(pass,cli->secblob.data,nt_response.data);
481 /* non encrypted password supplied. Ignore ntpass. */
482 if (lp_client_lanman_auth()) {
483 lm_response = data_blob(NULL, 24);
484 if (!SMBencrypt(pass,cli->secblob.data, lm_response.data)) {
485 /* Oops, the LM response is invalid, just put
486 the NT response there instead */
487 data_blob_free(&lm_response);
488 lm_response = data_blob(nt_response.data, nt_response.length);
491 /* LM disabled, place NT# in LM field instead */
492 lm_response = data_blob(nt_response.data, nt_response.length);
495 session_key = data_blob(NULL, 16);
497 E_deshash(pass, session_key.data);
498 memset(&session_key.data[8], '\0', 8);
500 SMBsesskeygen_ntv1(nt_hash, session_key.data);
503 cli_temp_set_signing(cli);
505 /* pre-encrypted password supplied. Only used for
506 security=server, can't do
507 signing because we don't have original key */
509 lm_response = data_blob(pass, passlen);
510 nt_response = data_blob(ntpass, ntpasslen);
513 /* send a session setup command */
514 memset(cli->outbuf,'\0',smb_size);
516 cli_set_message(cli->outbuf,13,0,True);
517 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
518 cli_setup_packet(cli);
520 SCVAL(cli->outbuf,smb_vwv0,0xFF);
521 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
522 SSVAL(cli->outbuf,smb_vwv3,2);
523 SSVAL(cli->outbuf,smb_vwv4,cli->pid);
524 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
525 SSVAL(cli->outbuf,smb_vwv7,lm_response.length);
526 SSVAL(cli->outbuf,smb_vwv8,nt_response.length);
527 SIVAL(cli->outbuf,smb_vwv11,capabilities);
528 p = smb_buf(cli->outbuf);
529 if (lm_response.length) {
530 memcpy(p,lm_response.data, lm_response.length); p += lm_response.length;
532 if (nt_response.length) {
533 memcpy(p,nt_response.data, nt_response.length); p += nt_response.length;
535 p += clistr_push(cli, p, user, -1, STR_TERMINATE);
537 /* Upper case here might help some NTLMv2 implementations */
538 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER);
539 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
540 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
541 cli_setup_bcc(cli, p);
543 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
544 result = cli_nt_error(cli);
548 /* show_msg(cli->inbuf); */
550 if (cli_is_error(cli)) {
551 result = cli_nt_error(cli);
556 ok = cli_simple_set_signing(cli, session_key, lm_response);
558 ok = cli_simple_set_signing(cli, session_key, nt_response);
561 if (!cli_check_sign_mac(cli, cli->inbuf, 1)) {
562 result = NT_STATUS_ACCESS_DENIED;
567 /* use the returned vuid from now on */
568 cli->vuid = SVAL(cli->inbuf,smb_uid);
570 p = smb_buf(cli->inbuf);
571 p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring),
573 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring),
575 p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring),
578 if (strstr(cli->server_type, "Samba")) {
579 cli->is_samba = True;
582 result = cli_set_username(cli, user);
583 if (!NT_STATUS_IS_OK(result)) {
587 if (session_key.data) {
588 /* Have plaintext orginal */
589 cli_set_session_key(cli, session_key);
592 result = NT_STATUS_OK;
594 data_blob_free(&lm_response);
595 data_blob_free(&nt_response);
596 data_blob_free(&session_key);
600 /****************************************************************************
601 Send a extended security session setup blob
602 ****************************************************************************/
604 static bool cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob)
606 uint32 capabilities = cli_session_setup_capabilities(cli);
609 capabilities |= CAP_EXTENDED_SECURITY;
611 /* send a session setup command */
612 memset(cli->outbuf,'\0',smb_size);
614 cli_set_message(cli->outbuf,12,0,True);
615 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
617 cli_setup_packet(cli);
619 SCVAL(cli->outbuf,smb_vwv0,0xFF);
620 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
621 SSVAL(cli->outbuf,smb_vwv3,2);
622 SSVAL(cli->outbuf,smb_vwv4,1);
623 SIVAL(cli->outbuf,smb_vwv5,0);
624 SSVAL(cli->outbuf,smb_vwv7,blob.length);
625 SIVAL(cli->outbuf,smb_vwv10,capabilities);
626 p = smb_buf(cli->outbuf);
627 memcpy(p, blob.data, blob.length);
629 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
630 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
631 cli_setup_bcc(cli, p);
632 return cli_send_smb(cli);
635 /****************************************************************************
636 Send a extended security session setup blob, returning a reply blob.
637 ****************************************************************************/
639 static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli)
641 DATA_BLOB blob2 = data_blob_null;
645 if (!cli_receive_smb(cli))
648 show_msg(cli->inbuf);
650 if (cli_is_error(cli) && !NT_STATUS_EQUAL(cli_nt_error(cli),
651 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
655 /* use the returned vuid from now on */
656 cli->vuid = SVAL(cli->inbuf,smb_uid);
658 p = smb_buf(cli->inbuf);
660 blob2 = data_blob(p, SVAL(cli->inbuf, smb_vwv3));
663 p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring),
666 /* w2k with kerberos doesn't properly null terminate this field */
667 len = smb_bufrem(cli->inbuf, p);
668 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring),
675 /****************************************************************************
676 Send a extended security session setup blob, returning a reply blob.
677 ****************************************************************************/
679 /* The following is calculated from :
681 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
682 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
686 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
688 static bool cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob)
690 int32 remaining = blob.length;
692 DATA_BLOB send_blob = data_blob_null;
693 int32 max_blob_size = 0;
694 DATA_BLOB receive_blob = data_blob_null;
696 if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) {
697 DEBUG(0,("cli_session_setup_blob: cli->max_xmit too small "
698 "(was %u, need minimum %u)\n",
699 (unsigned int)cli->max_xmit,
700 BASE_SESSSETUP_BLOB_PACKET_SIZE));
701 cli_set_nt_error(cli, NT_STATUS_INVALID_PARAMETER);
705 max_blob_size = cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE;
707 while ( remaining > 0) {
708 if (remaining >= max_blob_size) {
709 send_blob.length = max_blob_size;
710 remaining -= max_blob_size;
712 send_blob.length = remaining;
716 send_blob.data = &blob.data[cur];
717 cur += send_blob.length;
719 DEBUG(10, ("cli_session_setup_blob: Remaining (%u) sending (%u) current (%u)\n",
720 (unsigned int)remaining,
721 (unsigned int)send_blob.length,
722 (unsigned int)cur ));
724 if (!cli_session_setup_blob_send(cli, send_blob)) {
725 DEBUG(0, ("cli_session_setup_blob: send failed\n"));
729 receive_blob = cli_session_setup_blob_receive(cli);
730 data_blob_free(&receive_blob);
732 if (cli_is_error(cli) &&
733 !NT_STATUS_EQUAL( cli_get_nt_error(cli),
734 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
735 DEBUG(0, ("cli_session_setup_blob: receive failed "
736 "(%s)\n", nt_errstr(cli_get_nt_error(cli))));
745 /****************************************************************************
746 Use in-memory credentials cache
747 ****************************************************************************/
749 static void use_in_memory_ccache(void) {
750 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
753 /****************************************************************************
754 Do a spnego/kerberos encrypted session setup.
755 ****************************************************************************/
757 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup)
759 DATA_BLOB negTokenTarg;
760 DATA_BLOB session_key_krb5;
764 cli_temp_set_signing(cli);
766 DEBUG(2,("Doing kerberos session setup\n"));
768 /* generate the encapsulated kerberos5 ticket */
769 rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5, 0, NULL);
772 DEBUG(1, ("cli_session_setup_kerberos: spnego_gen_negTokenTarg failed: %s\n",
774 return ADS_ERROR_KRB5(rc);
778 file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length);
781 if (!cli_session_setup_blob(cli, negTokenTarg)) {
782 nt_status = cli_nt_error(cli);
786 if (cli_is_error(cli)) {
787 nt_status = cli_nt_error(cli);
788 if (NT_STATUS_IS_OK(nt_status)) {
789 nt_status = NT_STATUS_UNSUCCESSFUL;
794 cli_set_session_key(cli, session_key_krb5);
796 if (cli_simple_set_signing(
797 cli, session_key_krb5, data_blob_null)) {
799 if (!cli_check_sign_mac(cli, cli->inbuf, 1)) {
800 nt_status = NT_STATUS_ACCESS_DENIED;
805 data_blob_free(&negTokenTarg);
806 data_blob_free(&session_key_krb5);
808 return ADS_ERROR_NT(NT_STATUS_OK);
811 data_blob_free(&negTokenTarg);
812 data_blob_free(&session_key_krb5);
814 return ADS_ERROR_NT(nt_status);
816 #endif /* HAVE_KRB5 */
819 /****************************************************************************
820 Do a spnego/NTLMSSP encrypted session setup.
821 ****************************************************************************/
823 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
824 const char *pass, const char *domain)
826 struct ntlmssp_state *ntlmssp_state;
830 DATA_BLOB blob = data_blob_null;
831 DATA_BLOB blob_in = data_blob_null;
832 DATA_BLOB blob_out = data_blob_null;
834 cli_temp_set_signing(cli);
836 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) {
839 ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
841 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
844 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
847 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) {
852 nt_status = ntlmssp_update(ntlmssp_state,
854 data_blob_free(&blob_in);
855 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(nt_status)) {
857 /* and wrap it in a SPNEGO wrapper */
858 msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out);
860 /* wrap it in SPNEGO */
861 msg1 = spnego_gen_auth(blob_out);
864 /* now send that blob on its way */
865 if (!cli_session_setup_blob_send(cli, msg1)) {
866 DEBUG(3, ("Failed to send NTLMSSP/SPNEGO blob to server!\n"));
867 nt_status = NT_STATUS_UNSUCCESSFUL;
869 blob = cli_session_setup_blob_receive(cli);
871 nt_status = cli_nt_error(cli);
872 if (cli_is_error(cli) && NT_STATUS_IS_OK(nt_status)) {
873 if (cli->smb_rw_error == SMB_READ_BAD_SIG) {
874 nt_status = NT_STATUS_ACCESS_DENIED;
876 nt_status = NT_STATUS_UNSUCCESSFUL;
880 data_blob_free(&msg1);
884 if (NT_STATUS_IS_OK(nt_status)) {
885 nt_status = NT_STATUS_UNSUCCESSFUL;
887 } else if ((turn == 1) &&
888 NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
889 DATA_BLOB tmp_blob = data_blob_null;
890 /* the server might give us back two challenges */
891 if (!spnego_parse_challenge(blob, &blob_in,
893 DEBUG(3,("Failed to parse challenges\n"));
894 nt_status = NT_STATUS_INVALID_PARAMETER;
896 data_blob_free(&tmp_blob);
898 if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP,
900 DEBUG(3,("Failed to parse auth response\n"));
901 if (NT_STATUS_IS_OK(nt_status)
902 || NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED))
903 nt_status = NT_STATUS_INVALID_PARAMETER;
906 data_blob_free(&blob);
907 data_blob_free(&blob_out);
909 } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED));
911 data_blob_free(&blob_in);
913 if (NT_STATUS_IS_OK(nt_status)) {
915 fstrcpy(cli->server_domain, ntlmssp_state->server_domain);
916 cli_set_session_key(cli, ntlmssp_state->session_key);
918 if (cli_simple_set_signing(
919 cli, ntlmssp_state->session_key, data_blob_null)) {
921 if (!cli_check_sign_mac(cli, cli->inbuf, 1)) {
922 nt_status = NT_STATUS_ACCESS_DENIED;
927 /* we have a reference conter on ntlmssp_state, if we are signing
928 then the state will be kept by the signing engine */
930 ntlmssp_end(&ntlmssp_state);
932 if (!NT_STATUS_IS_OK(nt_status)) {
938 /****************************************************************************
939 Do a spnego encrypted session setup.
941 user_domain: The shortname of the domain the user/machine is a member of.
942 dest_realm: The realm we're connecting to, if NULL we use our default realm.
943 ****************************************************************************/
945 ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
946 const char *pass, const char *user_domain,
947 const char * dest_realm)
949 char *principal = NULL;
950 char *OIDs[ASN1_MAX_OIDS];
953 const char *p = NULL;
954 char *account = NULL;
957 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
959 /* the server might not even do spnego */
960 if (cli->secblob.length <= 16) {
961 DEBUG(3,("server didn't supply a full spnego negprot\n"));
966 file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
969 /* there is 16 bytes of GUID before the real spnego packet starts */
970 blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);
972 /* The server sent us the first part of the SPNEGO exchange in the
973 * negprot reply. It is WRONG to depend on the principal sent in the
974 * negprot reply, but right now we do it. If we don't receive one,
975 * we try to best guess, then fall back to NTLM. */
976 if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) {
977 data_blob_free(&blob);
978 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
980 data_blob_free(&blob);
982 /* make sure the server understands kerberos */
983 for (i=0;OIDs[i];i++) {
984 DEBUG(3,("got OID=%s\n", OIDs[i]));
985 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
986 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
987 cli->got_kerberos_mechanism = True;
989 talloc_free(OIDs[i]);
992 DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
994 status = cli_set_username(cli, user);
995 if (!NT_STATUS_IS_OK(status)) {
996 return ADS_ERROR_NT(status);
1000 /* If password is set we reauthenticate to kerberos server
1001 * and do not store results */
1003 if (cli->got_kerberos_mechanism && cli->use_kerberos) {
1006 if (pass && *pass) {
1009 use_in_memory_ccache();
1010 ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
1013 TALLOC_FREE(principal);
1014 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
1015 if (cli->fallback_after_kerberos)
1017 return ADS_ERROR_KRB5(ret);
1021 /* If we get a bad principal, try to guess it if
1022 we have a valid host NetBIOS name.
1024 if (strequal(principal, ADS_IGNORE_PRINCIPAL)) {
1025 TALLOC_FREE(principal);
1028 if (principal == NULL &&
1029 !is_ipaddress(cli->desthost) &&
1030 !strequal(STAR_SMBSERVER,
1033 char *machine = NULL;
1035 DEBUG(3,("cli_session_setup_spnego: got a "
1036 "bad server principal, trying to guess ...\n"));
1038 host = strchr_m(cli->desthost, '.');
1040 machine = SMB_STRNDUP(cli->desthost,
1041 host - cli->desthost);
1043 machine = SMB_STRDUP(cli->desthost);
1045 if (machine == NULL) {
1046 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1050 realm = SMB_STRDUP(dest_realm);
1053 realm = kerberos_get_default_realm_from_ccache();
1055 if (realm && *realm) {
1056 principal = talloc_asprintf(NULL, "%s$@%s",
1061 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1063 DEBUG(3,("cli_session_setup_spnego: guessed "
1064 "server principal=%s\n",
1065 principal ? principal : "<null>"));
1072 rc = cli_session_setup_kerberos(cli, principal,
1074 if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
1075 TALLOC_FREE(principal);
1082 TALLOC_FREE(principal);
1086 account = talloc_strdup(talloc_tos(), user);
1088 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1091 /* when falling back to ntlmssp while authenticating with a machine
1092 * account strip off the realm - gd */
1094 if ((p = strchr_m(user, '@')) != NULL) {
1095 account[PTR_DIFF(p,user)] = '\0';
1098 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
1101 /****************************************************************************
1102 Send a session setup. The username and workgroup is in UNIX character
1103 format and must be converted to DOS codepage format before sending. If the
1104 password is in plaintext, the same should be done.
1105 ****************************************************************************/
1107 NTSTATUS cli_session_setup(struct cli_state *cli,
1109 const char *pass, int passlen,
1110 const char *ntpass, int ntpasslen,
1111 const char *workgroup)
1117 fstrcpy(user2, user);
1126 /* allow for workgroups as part of the username */
1127 if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
1128 (p=strchr_m(user2,*lp_winbind_separator()))) {
1134 if (cli->protocol < PROTOCOL_LANMAN1) {
1135 return NT_STATUS_OK;
1138 /* now work out what sort of session setup we are going to
1139 do. I have split this into separate functions to make the
1140 flow a bit easier to understand (tridge) */
1142 /* if its an older server then we have to use the older request format */
1144 if (cli->protocol < PROTOCOL_NT1) {
1145 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
1146 DEBUG(1, ("Server requested LM password but 'client lanman auth'"
1148 return NT_STATUS_ACCESS_DENIED;
1151 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
1152 !lp_client_plaintext_auth() && (*pass)) {
1153 DEBUG(1, ("Server requested plaintext password but "
1154 "'client plaintext auth' is disabled\n"));
1155 return NT_STATUS_ACCESS_DENIED;
1158 return cli_session_setup_lanman2(cli, user, pass, passlen,
1162 /* if no user is supplied then we have to do an anonymous connection.
1163 passwords are ignored */
1165 if (!user || !*user)
1166 return cli_session_setup_guest(cli);
1168 /* if the server is share level then send a plaintext null
1169 password at this point. The password is sent in the tree
1172 if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
1173 return cli_session_setup_plaintext(cli, user, "", workgroup);
1175 /* if the server doesn't support encryption then we have to use
1176 plaintext. The second password is ignored */
1178 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1179 if (!lp_client_plaintext_auth() && (*pass)) {
1180 DEBUG(1, ("Server requested plaintext password but "
1181 "'client plaintext auth' is disabled\n"));
1182 return NT_STATUS_ACCESS_DENIED;
1184 return cli_session_setup_plaintext(cli, user, pass, workgroup);
1187 /* if the server supports extended security then use SPNEGO */
1189 if (cli->capabilities & CAP_EXTENDED_SECURITY) {
1190 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
1192 if (!ADS_ERR_OK(status)) {
1193 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1194 return ads_ntstatus(status);
1199 /* otherwise do a NT1 style session setup */
1200 status = cli_session_setup_nt1(cli, user, pass, passlen,
1201 ntpass, ntpasslen, workgroup);
1202 if (!NT_STATUS_IS_OK(status)) {
1203 DEBUG(3,("cli_session_setup: NT1 session setup "
1204 "failed: %s\n", nt_errstr(status)));
1209 if (strstr(cli->server_type, "Samba")) {
1210 cli->is_samba = True;
1213 return NT_STATUS_OK;
1216 /****************************************************************************
1218 *****************************************************************************/
1220 bool cli_ulogoff(struct cli_state *cli)
1222 memset(cli->outbuf,'\0',smb_size);
1223 cli_set_message(cli->outbuf,2,0,True);
1224 SCVAL(cli->outbuf,smb_com,SMBulogoffX);
1225 cli_setup_packet(cli);
1226 SSVAL(cli->outbuf,smb_vwv0,0xFF);
1227 SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */
1230 if (!cli_receive_smb(cli))
1233 if (cli_is_error(cli)) {
1241 /****************************************************************************
1243 ****************************************************************************/
1245 struct cli_tcon_andx_state {
1246 struct cli_state *cli;
1250 static void cli_tcon_andx_done(struct tevent_req *subreq);
1252 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
1253 struct event_context *ev,
1254 struct cli_state *cli,
1255 const char *share, const char *dev,
1256 const char *pass, int passlen)
1258 struct tevent_req *req, *subreq;
1259 struct cli_tcon_andx_state *state;
1265 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
1272 fstrcpy(cli->share, share);
1274 /* in user level security don't send a password now */
1275 if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
1278 } else if (pass == NULL) {
1279 DEBUG(1, ("Server not using user level security and no "
1280 "password supplied.\n"));
1284 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
1285 *pass && passlen != 24) {
1286 if (!lp_client_lanman_auth()) {
1287 DEBUG(1, ("Server requested LANMAN password "
1288 "(share-level security) but "
1289 "'client lanman auth' is disabled\n"));
1294 * Non-encrypted passwords - convert to DOS codepage before
1298 SMBencrypt(pass, cli->secblob.data, (uchar *)pword);
1300 if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
1301 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
1303 if (!lp_client_plaintext_auth() && (*pass)) {
1304 DEBUG(1, ("Server requested plaintext "
1305 "password but 'client plaintext "
1306 "auth' is disabled\n"));
1311 * Non-encrypted passwords - convert to DOS codepage
1314 passlen = clistr_push(cli, pword, pass, sizeof(pword),
1316 if (passlen == -1) {
1317 DEBUG(1, ("clistr_push(pword) failed\n"));
1322 memcpy(pword, pass, passlen);
1327 SCVAL(vwv+0, 0, 0xFF);
1330 SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
1331 SSVAL(vwv+3, 0, passlen);
1334 bytes = (uint8_t *)talloc_memdup(state, pword, passlen);
1336 bytes = talloc_array(state, uint8_t, 0);
1342 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
1343 cli->desthost, share);
1344 if (tevent_req_nomem(tmp, req)) {
1345 return tevent_req_post(req, ev);
1347 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
1352 * Add the devicetype
1354 tmp = talloc_strdup_upper(talloc_tos(), dev);
1355 if (tevent_req_nomem(tmp, req)) {
1356 return tevent_req_post(req, ev);
1358 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
1361 if (tevent_req_nomem(bytes, req)) {
1362 return tevent_req_post(req, ev);
1365 subreq = cli_smb_send(state, ev, cli, SMBtconX, 0, 4, vwv,
1366 talloc_get_size(bytes), bytes);
1367 if (tevent_req_nomem(subreq, req)) {
1368 return tevent_req_post(req, ev);
1370 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
1374 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1375 return tevent_req_post(req, ev);
1378 static void cli_tcon_andx_done(struct tevent_req *subreq)
1380 struct tevent_req *req = tevent_req_callback_data(
1381 subreq, struct tevent_req);
1382 struct cli_tcon_andx_state *state = tevent_req_data(
1383 req, struct cli_tcon_andx_state);
1384 struct cli_state *cli = state->cli;
1385 char *inbuf = (char *)cli_smb_inbuf(subreq);
1392 status = cli_smb_recv(subreq, 0, &wct, &vwv, &num_bytes, &bytes);
1393 if (!NT_STATUS_IS_OK(status)) {
1394 TALLOC_FREE(subreq);
1395 tevent_req_nterror(req, status);
1399 clistr_pull(inbuf, cli->dev, bytes, sizeof(fstring), num_bytes,
1400 STR_TERMINATE|STR_ASCII);
1402 if ((cli->protocol >= PROTOCOL_NT1) && (num_bytes == 3)) {
1403 /* almost certainly win95 - enable bug fixes */
1408 * Make sure that we have the optional support 16-bit field. WCT > 2.
1409 * Avoids issues when connecting to Win9x boxes sharing files
1412 cli->dfsroot = false;
1414 if ((wct > 2) && (cli->protocol >= PROTOCOL_LANMAN2)) {
1415 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
1418 cli->cnum = SVAL(inbuf,smb_tid);
1419 tevent_req_done(req);
1422 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
1424 return tevent_req_simple_recv_ntstatus(req);
1427 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
1428 const char *dev, const char *pass, int passlen)
1430 TALLOC_CTX *frame = talloc_stackframe();
1431 struct event_context *ev;
1432 struct tevent_req *req;
1433 NTSTATUS status = NT_STATUS_OK;
1435 if (cli_has_async_calls(cli)) {
1437 * Can't use sync call while an async call is in flight
1439 status = NT_STATUS_INVALID_PARAMETER;
1443 ev = event_context_init(frame);
1445 status = NT_STATUS_NO_MEMORY;
1449 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
1451 status = NT_STATUS_NO_MEMORY;
1455 if (!tevent_req_poll(req, ev)) {
1456 status = map_nt_error_from_unix(errno);
1460 status = cli_tcon_andx_recv(req);
1463 if (!NT_STATUS_IS_OK(status)) {
1464 cli_set_error(cli, status);
1469 /****************************************************************************
1470 Send a tree disconnect.
1471 ****************************************************************************/
1473 bool cli_tdis(struct cli_state *cli)
1475 memset(cli->outbuf,'\0',smb_size);
1476 cli_set_message(cli->outbuf,0,0,True);
1477 SCVAL(cli->outbuf,smb_com,SMBtdis);
1478 SSVAL(cli->outbuf,smb_tid,cli->cnum);
1479 cli_setup_packet(cli);
1482 if (!cli_receive_smb(cli))
1485 if (cli_is_error(cli)) {
1493 /****************************************************************************
1494 Send a negprot command.
1495 ****************************************************************************/
1497 void cli_negprot_sendsync(struct cli_state *cli)
1502 if (cli->protocol < PROTOCOL_NT1)
1503 cli->use_spnego = False;
1505 memset(cli->outbuf,'\0',smb_size);
1507 /* setup the protocol strings */
1508 cli_set_message(cli->outbuf,0,0,True);
1510 p = smb_buf(cli->outbuf);
1511 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
1512 if (prots[numprots].prot > cli->protocol) {
1516 p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE);
1519 SCVAL(cli->outbuf,smb_com,SMBnegprot);
1520 cli_setup_bcc(cli, p);
1521 cli_setup_packet(cli);
1523 SCVAL(smb_buf(cli->outbuf),0,2);
1528 /****************************************************************************
1529 Send a negprot command.
1530 ****************************************************************************/
1532 struct cli_negprot_state {
1533 struct cli_state *cli;
1536 static void cli_negprot_done(struct tevent_req *subreq);
1538 struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
1539 struct event_context *ev,
1540 struct cli_state *cli)
1542 struct tevent_req *req, *subreq;
1543 struct cli_negprot_state *state;
1544 uint8_t *bytes = NULL;
1547 req = tevent_req_create(mem_ctx, &state, struct cli_negprot_state);
1553 if (cli->protocol < PROTOCOL_NT1)
1554 cli->use_spnego = False;
1556 /* setup the protocol strings */
1557 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
1559 if (prots[numprots].prot > cli->protocol) {
1562 bytes = (uint8_t *)talloc_append_blob(
1563 state, bytes, data_blob_const(&c, sizeof(c)));
1564 if (tevent_req_nomem(bytes, req)) {
1565 return tevent_req_post(req, ev);
1567 bytes = smb_bytes_push_str(bytes, false,
1568 prots[numprots].name,
1569 strlen(prots[numprots].name)+1,
1571 if (tevent_req_nomem(bytes, req)) {
1572 return tevent_req_post(req, ev);
1576 subreq = cli_smb_send(state, ev, cli, SMBnegprot, 0, 0, NULL,
1577 talloc_get_size(bytes), bytes);
1578 if (tevent_req_nomem(subreq, req)) {
1579 return tevent_req_post(req, ev);
1581 tevent_req_set_callback(subreq, cli_negprot_done, req);
1585 static void cli_negprot_done(struct tevent_req *subreq)
1587 struct tevent_req *req = tevent_req_callback_data(
1588 subreq, struct tevent_req);
1589 struct cli_negprot_state *state = tevent_req_data(
1590 req, struct cli_negprot_state);
1591 struct cli_state *cli = state->cli;
1599 status = cli_smb_recv(subreq, 1, &wct, &vwv, &num_bytes, &bytes);
1600 if (!NT_STATUS_IS_OK(status)) {
1601 TALLOC_FREE(subreq);
1605 protnum = SVAL(vwv, 0);
1607 if ((protnum >= ARRAY_SIZE(prots))
1608 || (prots[protnum].prot > cli->protocol)) {
1609 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1613 cli->protocol = prots[protnum].prot;
1615 if ((cli->protocol < PROTOCOL_NT1) &&
1616 client_is_signing_mandatory(cli)) {
1617 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
1618 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1622 if (cli->protocol >= PROTOCOL_NT1) {
1624 bool negotiated_smb_signing = false;
1627 cli->sec_mode = CVAL(vwv + 1, 0);
1628 cli->max_mux = SVAL(vwv + 1, 1);
1629 cli->max_xmit = IVAL(vwv + 3, 1);
1630 cli->sesskey = IVAL(vwv + 7, 1);
1631 cli->serverzone = SVALS(vwv + 15, 1);
1632 cli->serverzone *= 60;
1633 /* this time arrives in real GMT */
1634 ts = interpret_long_date(((char *)(vwv+11))+1);
1635 cli->servertime = ts.tv_sec;
1636 cli->secblob = data_blob(bytes, num_bytes);
1637 cli->capabilities = IVAL(vwv + 9, 1);
1638 if (cli->capabilities & CAP_RAW_MODE) {
1639 cli->readbraw_supported = True;
1640 cli->writebraw_supported = True;
1642 /* work out if they sent us a workgroup */
1643 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
1644 smb_buflen(cli->inbuf) > 8) {
1645 clistr_pull(cli->inbuf, cli->server_domain,
1646 bytes+8, sizeof(cli->server_domain),
1648 STR_UNICODE|STR_NOALIGN);
1652 * As signing is slow we only turn it on if either the client or
1653 * the server require it. JRA.
1656 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
1657 /* Fail if server says signing is mandatory and we don't want to support it. */
1658 if (!client_is_signing_allowed(cli)) {
1659 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
1660 tevent_req_nterror(req,
1661 NT_STATUS_ACCESS_DENIED);
1664 negotiated_smb_signing = true;
1665 } else if (client_is_signing_mandatory(cli) && client_is_signing_allowed(cli)) {
1666 /* Fail if client says signing is mandatory and the server doesn't support it. */
1667 if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
1668 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
1669 tevent_req_nterror(req,
1670 NT_STATUS_ACCESS_DENIED);
1673 negotiated_smb_signing = true;
1674 } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
1675 negotiated_smb_signing = true;
1678 if (negotiated_smb_signing) {
1679 cli_set_signing_negotiated(cli);
1682 if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
1683 SAFE_FREE(cli->outbuf);
1684 SAFE_FREE(cli->inbuf);
1685 cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1686 cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1687 cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE;
1690 } else if (cli->protocol >= PROTOCOL_LANMAN1) {
1691 cli->use_spnego = False;
1692 cli->sec_mode = SVAL(vwv + 1, 0);
1693 cli->max_xmit = SVAL(vwv + 2, 0);
1694 cli->max_mux = SVAL(vwv + 3, 0);
1695 cli->sesskey = IVAL(vwv + 6, 0);
1696 cli->serverzone = SVALS(vwv + 10, 0);
1697 cli->serverzone *= 60;
1698 /* this time is converted to GMT by make_unix_date */
1699 cli->servertime = cli_make_unix_date(
1700 cli, (char *)(vwv + 8));
1701 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0);
1702 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0);
1703 cli->secblob = data_blob(bytes, num_bytes);
1705 /* the old core protocol */
1706 cli->use_spnego = False;
1708 cli->serverzone = get_time_zone(time(NULL));
1711 cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
1713 /* a way to force ascii SMB */
1714 if (getenv("CLI_FORCE_ASCII"))
1715 cli->capabilities &= ~CAP_UNICODE;
1717 tevent_req_done(req);
1720 NTSTATUS cli_negprot_recv(struct tevent_req *req)
1722 return tevent_req_simple_recv_ntstatus(req);
1725 NTSTATUS cli_negprot(struct cli_state *cli)
1727 TALLOC_CTX *frame = talloc_stackframe();
1728 struct event_context *ev;
1729 struct tevent_req *req;
1730 NTSTATUS status = NT_STATUS_OK;
1732 if (cli_has_async_calls(cli)) {
1734 * Can't use sync call while an async call is in flight
1736 status = NT_STATUS_INVALID_PARAMETER;
1740 ev = event_context_init(frame);
1742 status = NT_STATUS_NO_MEMORY;
1746 req = cli_negprot_send(frame, ev, cli);
1748 status = NT_STATUS_NO_MEMORY;
1752 if (!tevent_req_poll(req, ev)) {
1753 status = map_nt_error_from_unix(errno);
1757 status = cli_negprot_recv(req);
1760 if (!NT_STATUS_IS_OK(status)) {
1761 cli_set_error(cli, status);
1766 /****************************************************************************
1767 Send a session request. See rfc1002.txt 4.3 and 4.3.2.
1768 ****************************************************************************/
1770 bool cli_session_request(struct cli_state *cli,
1771 struct nmb_name *calling, struct nmb_name *called)
1777 /* 445 doesn't have session request */
1778 if (cli->port == 445)
1781 memcpy(&(cli->calling), calling, sizeof(*calling));
1782 memcpy(&(cli->called ), called , sizeof(*called ));
1784 /* put in the destination name */
1786 tmp = name_mangle(talloc_tos(), cli->called.name,
1787 cli->called.name_type);
1792 p = cli->outbuf+len;
1793 memcpy(p, tmp, name_len(tmp));
1794 len += name_len(tmp);
1799 tmp = name_mangle(talloc_tos(), cli->calling.name,
1800 cli->calling.name_type);
1805 p = cli->outbuf+len;
1806 memcpy(p, tmp, name_len(tmp));
1807 len += name_len(tmp);
1810 /* send a session request (RFC 1002) */
1811 /* setup the packet length
1812 * Remove four bytes from the length count, since the length
1813 * field in the NBT Session Service header counts the number
1814 * of bytes which follow. The cli_send_smb() function knows
1815 * about this and accounts for those four bytes.
1819 _smb_setlen(cli->outbuf,len);
1820 SCVAL(cli->outbuf,0,0x81);
1823 DEBUG(5,("Sent session request\n"));
1825 if (!cli_receive_smb(cli))
1828 if (CVAL(cli->inbuf,0) == 0x84) {
1829 /* C. Hoch 9/14/95 Start */
1830 /* For information, here is the response structure.
1831 * We do the byte-twiddling to for portability.
1832 struct RetargetResponse{
1834 unsigned char flags;
1840 uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
1841 struct in_addr dest_ip;
1844 /* SESSION RETARGET */
1845 putip((char *)&dest_ip,cli->inbuf+4);
1846 in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
1848 status = open_socket_out(&cli->dest_ss, port,
1849 LONG_CONNECT_TIMEOUT, &cli->fd);
1850 if (!NT_STATUS_IS_OK(status)) {
1854 DEBUG(3,("Retargeted\n"));
1856 set_socket_options(cli->fd, lp_socket_options());
1863 DEBUG(0,("Retarget recursion - failing\n"));
1867 ret = cli_session_request(cli, calling, called);
1871 } /* C. Hoch 9/14/95 End */
1873 if (CVAL(cli->inbuf,0) != 0x82) {
1874 /* This is the wrong place to put the error... JRA. */
1875 cli->rap_error = CVAL(cli->inbuf,4);
1885 static void smb_sock_connected(struct tevent_req *req)
1887 struct fd_struct *pfd = tevent_req_callback_data(
1888 req, struct fd_struct);
1892 status = open_socket_out_defer_recv(req, &fd);
1893 if (NT_STATUS_IS_OK(status)) {
1898 static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
1899 uint16_t *port, int timeout, int *pfd)
1901 struct event_context *ev;
1902 struct tevent_req *r139, *r445;
1903 struct fd_struct *fd139, *fd445;
1904 NTSTATUS status = NT_STATUS_NO_MEMORY;
1907 return open_socket_out(pss, *port, timeout, pfd);
1910 ev = event_context_init(talloc_tos());
1912 return NT_STATUS_NO_MEMORY;
1915 fd139 = talloc(ev, struct fd_struct);
1916 if (fd139 == NULL) {
1921 fd445 = talloc(ev, struct fd_struct);
1922 if (fd445 == NULL) {
1927 r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0),
1929 r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000),
1931 if ((r445 == NULL) || (r139 == NULL)) {
1934 tevent_req_set_callback(r445, smb_sock_connected, fd445);
1935 tevent_req_set_callback(r139, smb_sock_connected, fd139);
1937 while ((fd445->fd == -1) && (fd139->fd == -1)
1938 && (tevent_req_is_in_progress(r139)
1939 || tevent_req_is_in_progress(r445))) {
1940 event_loop_once(ev);
1943 if ((fd139->fd != -1) && (fd445->fd != -1)) {
1948 if (fd445->fd != -1) {
1951 status = NT_STATUS_OK;
1954 if (fd139->fd != -1) {
1957 status = NT_STATUS_OK;
1961 status = open_socket_out_defer_recv(r445, &fd445->fd);
1967 /****************************************************************************
1968 Open the client sockets.
1969 ****************************************************************************/
1971 NTSTATUS cli_connect(struct cli_state *cli,
1973 struct sockaddr_storage *dest_ss)
1976 int name_type = 0x20;
1977 TALLOC_CTX *frame = talloc_stackframe();
1978 unsigned int num_addrs = 0;
1980 struct sockaddr_storage *ss_arr = NULL;
1983 /* reasonable default hostname */
1985 host = STAR_SMBSERVER;
1988 fstrcpy(cli->desthost, host);
1990 /* allow hostnames of the form NAME#xx and do a netbios lookup */
1991 if ((p = strchr(cli->desthost, '#'))) {
1992 name_type = strtol(p+1, NULL, 16);
1996 if (!dest_ss || is_zero_addr((struct sockaddr *)dest_ss)) {
1997 NTSTATUS status =resolve_name_list(frame,
2002 if (!NT_STATUS_IS_OK(status)) {
2004 return NT_STATUS_BAD_NETWORK_NAME;
2008 ss_arr = TALLOC_P(frame, struct sockaddr_storage);
2011 return NT_STATUS_NO_MEMORY;
2016 for (i = 0; i < num_addrs; i++) {
2017 cli->dest_ss = ss_arr[i];
2018 if (getenv("LIBSMB_PROG")) {
2019 cli->fd = sock_exec(getenv("LIBSMB_PROG"));
2021 uint16_t port = cli->port;
2023 status = open_smb_socket(&cli->dest_ss, &port,
2024 cli->timeout, &cli->fd);
2025 if (NT_STATUS_IS_OK(status)) {
2029 if (cli->fd == -1) {
2030 char addr[INET6_ADDRSTRLEN];
2031 print_sockaddr(addr, sizeof(addr), &ss_arr[i]);
2032 DEBUG(2,("Error connecting to %s (%s)\n",
2033 dest_ss?addr:host,strerror(errno)));
2035 /* Exit from loop on first connection. */
2040 if (cli->fd == -1) {
2042 return map_nt_error_from_unix(errno);
2046 *dest_ss = cli->dest_ss;
2049 set_socket_options(cli->fd, lp_socket_options());
2052 return NT_STATUS_OK;
2056 establishes a connection to after the negprot.
2057 @param output_cli A fully initialised cli structure, non-null only on success
2058 @param dest_host The netbios name of the remote host
2059 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2060 @param port (optional) The destination port (0 for default)
2061 @param retry bool. Did this connection fail with a retryable error ?
2064 NTSTATUS cli_start_connection(struct cli_state **output_cli,
2065 const char *my_name,
2066 const char *dest_host,
2067 struct sockaddr_storage *dest_ss, int port,
2068 int signing_state, int flags,
2072 struct nmb_name calling;
2073 struct nmb_name called;
2074 struct cli_state *cli;
2075 struct sockaddr_storage ss;
2081 my_name = global_myname();
2083 if (!(cli = cli_initialise_ex(signing_state))) {
2084 return NT_STATUS_NO_MEMORY;
2087 make_nmb_name(&calling, my_name, 0x0);
2088 make_nmb_name(&called , dest_host, 0x20);
2090 cli_set_port(cli, port);
2091 cli_set_timeout(cli, 10000); /* 10 seconds. */
2101 DEBUG(3,("Connecting to host=%s\n", dest_host));
2103 nt_status = cli_connect(cli, dest_host, &ss);
2104 if (!NT_STATUS_IS_OK(nt_status)) {
2105 char addr[INET6_ADDRSTRLEN];
2106 print_sockaddr(addr, sizeof(addr), &ss);
2107 DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
2108 nmb_namestr(&called), addr, nt_errstr(nt_status) ));
2116 if (!cli_session_request(cli, &calling, &called)) {
2118 DEBUG(1,("session request to %s failed (%s)\n",
2119 called.name, cli_errstr(cli)));
2120 if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
2124 if (strcmp(called.name, STAR_SMBSERVER)) {
2125 make_nmb_name(&called , STAR_SMBSERVER, 0x20);
2128 return NT_STATUS_BAD_NETWORK_NAME;
2131 if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
2132 cli->use_spnego = False;
2133 else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
2134 cli->use_kerberos = True;
2136 if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) &&
2137 cli->use_kerberos) {
2138 cli->fallback_after_kerberos = true;
2141 nt_status = cli_negprot(cli);
2142 if (!NT_STATUS_IS_OK(nt_status)) {
2143 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
2149 return NT_STATUS_OK;
2154 establishes a connection right up to doing tconX, password specified.
2155 @param output_cli A fully initialised cli structure, non-null only on success
2156 @param dest_host The netbios name of the remote host
2157 @param dest_ip (optional) The the destination IP, NULL for name based lookup
2158 @param port (optional) The destination port (0 for default)
2159 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
2160 @param service_type The 'type' of serivice.
2161 @param user Username, unix string
2162 @param domain User's domain
2163 @param password User's password, unencrypted unix string.
2164 @param retry bool. Did this connection fail with a retryable error ?
2167 NTSTATUS cli_full_connection(struct cli_state **output_cli,
2168 const char *my_name,
2169 const char *dest_host,
2170 struct sockaddr_storage *dest_ss, int port,
2171 const char *service, const char *service_type,
2172 const char *user, const char *domain,
2173 const char *password, int flags,
2178 struct cli_state *cli = NULL;
2179 int pw_len = password ? strlen(password)+1 : 0;
2183 if (password == NULL) {
2187 nt_status = cli_start_connection(&cli, my_name, dest_host,
2188 dest_ss, port, signing_state,
2191 if (!NT_STATUS_IS_OK(nt_status)) {
2195 cli->use_oplocks = ((flags & CLI_FULL_CONNECTION_OPLOCKS) != 0);
2196 cli->use_level_II_oplocks =
2197 ((flags & CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS) != 0);
2199 nt_status = cli_session_setup(cli, user, password, pw_len, password,
2201 if (!NT_STATUS_IS_OK(nt_status)) {
2203 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
2204 DEBUG(1,("failed session setup with %s\n",
2205 nt_errstr(nt_status)));
2210 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
2211 if (!NT_STATUS_IS_OK(nt_status)) {
2212 DEBUG(1,("anonymous failed session setup with %s\n",
2213 nt_errstr(nt_status)));
2220 nt_status = cli_tcon_andx(cli, service, service_type, password,
2222 if (!NT_STATUS_IS_OK(nt_status)) {
2223 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
2225 if (NT_STATUS_IS_OK(nt_status)) {
2226 nt_status = NT_STATUS_UNSUCCESSFUL;
2232 nt_status = cli_init_creds(cli, user, domain, password);
2233 if (!NT_STATUS_IS_OK(nt_status)) {
2239 return NT_STATUS_OK;
2242 /****************************************************************************
2243 Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
2244 ****************************************************************************/
2246 bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
2247 struct sockaddr_storage *pdest_ss)
2249 struct nmb_name calling, called;
2251 make_nmb_name(&calling, srchost, 0x0);
2254 * If the called name is an IP address
2255 * then use *SMBSERVER immediately.
2258 if(is_ipaddress(desthost)) {
2259 make_nmb_name(&called, STAR_SMBSERVER, 0x20);
2261 make_nmb_name(&called, desthost, 0x20);
2264 if (!cli_session_request(*ppcli, &calling, &called)) {
2266 struct nmb_name smbservername;
2268 make_nmb_name(&smbservername, STAR_SMBSERVER, 0x20);
2271 * If the name wasn't *SMBSERVER then
2272 * try with *SMBSERVER if the first name fails.
2275 if (nmb_name_equal(&called, &smbservername)) {
2278 * The name used was *SMBSERVER, don't bother with another name.
2281 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
2282 with error %s.\n", desthost, cli_errstr(*ppcli) ));
2287 cli_shutdown(*ppcli);
2289 *ppcli = cli_initialise();
2291 /* Out of memory... */
2295 status = cli_connect(*ppcli, desthost, pdest_ss);
2296 if (!NT_STATUS_IS_OK(status) ||
2297 !cli_session_request(*ppcli, &calling, &smbservername)) {
2298 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
2299 name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
2307 /****************************************************************************
2308 Send an old style tcon.
2309 ****************************************************************************/
2310 NTSTATUS cli_raw_tcon(struct cli_state *cli,
2311 const char *service, const char *pass, const char *dev,
2312 uint16 *max_xmit, uint16 *tid)
2316 if (!lp_client_plaintext_auth() && (*pass)) {
2317 DEBUG(1, ("Server requested plaintext password but 'client "
2318 "plaintext auth' is disabled\n"));
2319 return NT_STATUS_ACCESS_DENIED;
2322 memset(cli->outbuf,'\0',smb_size);
2323 memset(cli->inbuf,'\0',smb_size);
2325 cli_set_message(cli->outbuf, 0, 0, True);
2326 SCVAL(cli->outbuf,smb_com,SMBtcon);
2327 cli_setup_packet(cli);
2329 p = smb_buf(cli->outbuf);
2330 *p++ = 4; p += clistr_push(cli, p, service, -1, STR_TERMINATE | STR_NOALIGN);
2331 *p++ = 4; p += clistr_push(cli, p, pass, -1, STR_TERMINATE | STR_NOALIGN);
2332 *p++ = 4; p += clistr_push(cli, p, dev, -1, STR_TERMINATE | STR_NOALIGN);
2334 cli_setup_bcc(cli, p);
2337 if (!cli_receive_smb(cli)) {
2338 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
2341 if (cli_is_error(cli)) {
2342 return cli_nt_error(cli);
2345 *max_xmit = SVAL(cli->inbuf, smb_vwv0);
2346 *tid = SVAL(cli->inbuf, smb_vwv1);
2348 return NT_STATUS_OK;
2351 /* Return a cli_state pointing at the IPC$ share for the given server */
2353 struct cli_state *get_ipc_connect(char *server,
2354 struct sockaddr_storage *server_ss,
2355 const struct user_auth_info *user_info)
2357 struct cli_state *cli;
2359 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
2361 if (user_info->use_kerberos) {
2362 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
2365 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
2366 user_info->username ? user_info->username : "",
2368 user_info->password ? user_info->password : "",
2372 if (NT_STATUS_IS_OK(nt_status)) {
2374 } else if (is_ipaddress(server)) {
2375 /* windows 9* needs a correct NMB name for connections */
2376 fstring remote_name;
2378 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
2379 cli = get_ipc_connect(remote_name, server_ss, user_info);
2388 * Given the IP address of a master browser on the network, return its
2389 * workgroup and connect to it.
2391 * This function is provided to allow additional processing beyond what
2392 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
2393 * browsers and obtain each master browsers' list of domains (in case the
2394 * first master browser is recently on the network and has not yet
2395 * synchronized with other master browsers and therefore does not yet have the
2396 * entire network browse list)
2399 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
2400 struct ip_service *mb_ip,
2401 const struct user_auth_info *user_info,
2402 char **pp_workgroup_out)
2404 char addr[INET6_ADDRSTRLEN];
2406 struct cli_state *cli;
2407 struct sockaddr_storage server_ss;
2409 *pp_workgroup_out = NULL;
2411 print_sockaddr(addr, sizeof(addr), &mb_ip->ss);
2412 DEBUG(99, ("Looking up name of master browser %s\n",
2416 * Do a name status query to find out the name of the master browser.
2417 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
2418 * master browser will not respond to a wildcard query (or, at least,
2419 * an NT4 server acting as the domain master browser will not).
2421 * We might be able to use ONLY the query on MSBROWSE, but that's not
2422 * yet been tested with all Windows versions, so until it is, leave
2423 * the original wildcard query as the first choice and fall back to
2424 * MSBROWSE if the wildcard query fails.
2426 if (!name_status_find("*", 0, 0x1d, &mb_ip->ss, name) &&
2427 !name_status_find(MSBROWSE, 1, 0x1d, &mb_ip->ss, name)) {
2429 DEBUG(99, ("Could not retrieve name status for %s\n",
2434 if (!find_master_ip(name, &server_ss)) {
2435 DEBUG(99, ("Could not find master ip for %s\n", name));
2439 *pp_workgroup_out = talloc_strdup(ctx, name);
2441 DEBUG(4, ("found master browser %s, %s\n", name, addr));
2443 print_sockaddr(addr, sizeof(addr), &server_ss);
2444 cli = get_ipc_connect(addr, &server_ss, user_info);
2450 * Return the IP address and workgroup of a master browser on the network, and
2454 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
2455 const struct user_auth_info *user_info,
2456 char **pp_workgroup_out)
2458 struct ip_service *ip_list;
2459 struct cli_state *cli;
2462 *pp_workgroup_out = NULL;
2464 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
2466 /* Go looking for workgroups by broadcasting on the local network */
2468 if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
2470 DEBUG(99, ("No master browsers responded\n"));
2474 for (i = 0; i < count; i++) {
2475 char addr[INET6_ADDRSTRLEN];
2476 print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
2477 DEBUG(99, ("Found master browser %s\n", addr));
2479 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
2480 user_info, pp_workgroup_out);