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;
1251 static void cli_tcon_andx_done(struct tevent_req *subreq);
1253 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
1254 struct event_context *ev,
1255 struct cli_state *cli,
1256 const char *share, const char *dev,
1257 const char *pass, int passlen,
1258 struct tevent_req **psmbreq)
1260 struct tevent_req *req, *subreq;
1261 struct cli_tcon_andx_state *state;
1267 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
1274 fstrcpy(cli->share, share);
1276 /* in user level security don't send a password now */
1277 if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
1280 } else if (pass == NULL) {
1281 DEBUG(1, ("Server not using user level security and no "
1282 "password supplied.\n"));
1286 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
1287 *pass && passlen != 24) {
1288 if (!lp_client_lanman_auth()) {
1289 DEBUG(1, ("Server requested LANMAN password "
1290 "(share-level security) but "
1291 "'client lanman auth' is disabled\n"));
1296 * Non-encrypted passwords - convert to DOS codepage before
1300 SMBencrypt(pass, cli->secblob.data, (uchar *)pword);
1302 if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
1303 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
1305 if (!lp_client_plaintext_auth() && (*pass)) {
1306 DEBUG(1, ("Server requested plaintext "
1307 "password but 'client plaintext "
1308 "auth' is disabled\n"));
1313 * Non-encrypted passwords - convert to DOS codepage
1316 passlen = clistr_push(cli, pword, pass, sizeof(pword),
1318 if (passlen == -1) {
1319 DEBUG(1, ("clistr_push(pword) failed\n"));
1324 memcpy(pword, pass, passlen);
1329 SCVAL(vwv+0, 0, 0xFF);
1332 SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
1333 SSVAL(vwv+3, 0, passlen);
1336 bytes = (uint8_t *)talloc_memdup(state, pword, passlen);
1338 bytes = talloc_array(state, uint8_t, 0);
1344 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
1345 cli->desthost, share);
1350 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
1355 * Add the devicetype
1357 tmp = talloc_strdup_upper(talloc_tos(), dev);
1362 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
1365 if (bytes == NULL) {
1370 state->bytes.iov_base = bytes;
1371 state->bytes.iov_len = talloc_get_size(bytes);
1373 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 4, vwv,
1375 if (subreq == NULL) {
1379 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
1384 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1385 return tevent_req_post(req, ev);
1388 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
1389 struct event_context *ev,
1390 struct cli_state *cli,
1391 const char *share, const char *dev,
1392 const char *pass, int passlen)
1394 struct tevent_req *req, *subreq;
1396 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
1398 if ((req == NULL) || !cli_smb_req_send(subreq)) {
1405 static void cli_tcon_andx_done(struct tevent_req *subreq)
1407 struct tevent_req *req = tevent_req_callback_data(
1408 subreq, struct tevent_req);
1409 struct cli_tcon_andx_state *state = tevent_req_data(
1410 req, struct cli_tcon_andx_state);
1411 struct cli_state *cli = state->cli;
1412 char *inbuf = (char *)cli_smb_inbuf(subreq);
1419 status = cli_smb_recv(subreq, 0, &wct, &vwv, &num_bytes, &bytes);
1420 if (!NT_STATUS_IS_OK(status)) {
1421 TALLOC_FREE(subreq);
1422 tevent_req_nterror(req, status);
1426 clistr_pull(inbuf, cli->dev, bytes, sizeof(fstring), num_bytes,
1427 STR_TERMINATE|STR_ASCII);
1429 if ((cli->protocol >= PROTOCOL_NT1) && (num_bytes == 3)) {
1430 /* almost certainly win95 - enable bug fixes */
1435 * Make sure that we have the optional support 16-bit field. WCT > 2.
1436 * Avoids issues when connecting to Win9x boxes sharing files
1439 cli->dfsroot = false;
1441 if ((wct > 2) && (cli->protocol >= PROTOCOL_LANMAN2)) {
1442 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
1445 cli->cnum = SVAL(inbuf,smb_tid);
1446 tevent_req_done(req);
1449 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
1451 return tevent_req_simple_recv_ntstatus(req);
1454 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
1455 const char *dev, const char *pass, int passlen)
1457 TALLOC_CTX *frame = talloc_stackframe();
1458 struct event_context *ev;
1459 struct tevent_req *req;
1460 NTSTATUS status = NT_STATUS_OK;
1462 if (cli_has_async_calls(cli)) {
1464 * Can't use sync call while an async call is in flight
1466 status = NT_STATUS_INVALID_PARAMETER;
1470 ev = event_context_init(frame);
1472 status = NT_STATUS_NO_MEMORY;
1476 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
1478 status = NT_STATUS_NO_MEMORY;
1482 if (!tevent_req_poll(req, ev)) {
1483 status = map_nt_error_from_unix(errno);
1487 status = cli_tcon_andx_recv(req);
1490 if (!NT_STATUS_IS_OK(status)) {
1491 cli_set_error(cli, status);
1496 /****************************************************************************
1497 Send a tree disconnect.
1498 ****************************************************************************/
1500 bool cli_tdis(struct cli_state *cli)
1502 memset(cli->outbuf,'\0',smb_size);
1503 cli_set_message(cli->outbuf,0,0,True);
1504 SCVAL(cli->outbuf,smb_com,SMBtdis);
1505 SSVAL(cli->outbuf,smb_tid,cli->cnum);
1506 cli_setup_packet(cli);
1509 if (!cli_receive_smb(cli))
1512 if (cli_is_error(cli)) {
1520 /****************************************************************************
1521 Send a negprot command.
1522 ****************************************************************************/
1524 void cli_negprot_sendsync(struct cli_state *cli)
1529 if (cli->protocol < PROTOCOL_NT1)
1530 cli->use_spnego = False;
1532 memset(cli->outbuf,'\0',smb_size);
1534 /* setup the protocol strings */
1535 cli_set_message(cli->outbuf,0,0,True);
1537 p = smb_buf(cli->outbuf);
1538 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
1539 if (prots[numprots].prot > cli->protocol) {
1543 p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE);
1546 SCVAL(cli->outbuf,smb_com,SMBnegprot);
1547 cli_setup_bcc(cli, p);
1548 cli_setup_packet(cli);
1550 SCVAL(smb_buf(cli->outbuf),0,2);
1555 /****************************************************************************
1556 Send a negprot command.
1557 ****************************************************************************/
1559 struct cli_negprot_state {
1560 struct cli_state *cli;
1563 static void cli_negprot_done(struct tevent_req *subreq);
1565 struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
1566 struct event_context *ev,
1567 struct cli_state *cli)
1569 struct tevent_req *req, *subreq;
1570 struct cli_negprot_state *state;
1571 uint8_t *bytes = NULL;
1574 req = tevent_req_create(mem_ctx, &state, struct cli_negprot_state);
1580 if (cli->protocol < PROTOCOL_NT1)
1581 cli->use_spnego = False;
1583 /* setup the protocol strings */
1584 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
1586 if (prots[numprots].prot > cli->protocol) {
1589 bytes = (uint8_t *)talloc_append_blob(
1590 state, bytes, data_blob_const(&c, sizeof(c)));
1591 if (tevent_req_nomem(bytes, req)) {
1592 return tevent_req_post(req, ev);
1594 bytes = smb_bytes_push_str(bytes, false,
1595 prots[numprots].name,
1596 strlen(prots[numprots].name)+1,
1598 if (tevent_req_nomem(bytes, req)) {
1599 return tevent_req_post(req, ev);
1603 subreq = cli_smb_send(state, ev, cli, SMBnegprot, 0, 0, NULL,
1604 talloc_get_size(bytes), bytes);
1605 if (tevent_req_nomem(subreq, req)) {
1606 return tevent_req_post(req, ev);
1608 tevent_req_set_callback(subreq, cli_negprot_done, req);
1612 static void cli_negprot_done(struct tevent_req *subreq)
1614 struct tevent_req *req = tevent_req_callback_data(
1615 subreq, struct tevent_req);
1616 struct cli_negprot_state *state = tevent_req_data(
1617 req, struct cli_negprot_state);
1618 struct cli_state *cli = state->cli;
1626 status = cli_smb_recv(subreq, 1, &wct, &vwv, &num_bytes, &bytes);
1627 if (!NT_STATUS_IS_OK(status)) {
1628 TALLOC_FREE(subreq);
1632 protnum = SVAL(vwv, 0);
1634 if ((protnum >= ARRAY_SIZE(prots))
1635 || (prots[protnum].prot > cli->protocol)) {
1636 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1640 cli->protocol = prots[protnum].prot;
1642 if ((cli->protocol < PROTOCOL_NT1) &&
1643 client_is_signing_mandatory(cli)) {
1644 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
1645 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1649 if (cli->protocol >= PROTOCOL_NT1) {
1651 bool negotiated_smb_signing = false;
1654 cli->sec_mode = CVAL(vwv + 1, 0);
1655 cli->max_mux = SVAL(vwv + 1, 1);
1656 cli->max_xmit = IVAL(vwv + 3, 1);
1657 cli->sesskey = IVAL(vwv + 7, 1);
1658 cli->serverzone = SVALS(vwv + 15, 1);
1659 cli->serverzone *= 60;
1660 /* this time arrives in real GMT */
1661 ts = interpret_long_date(((char *)(vwv+11))+1);
1662 cli->servertime = ts.tv_sec;
1663 cli->secblob = data_blob(bytes, num_bytes);
1664 cli->capabilities = IVAL(vwv + 9, 1);
1665 if (cli->capabilities & CAP_RAW_MODE) {
1666 cli->readbraw_supported = True;
1667 cli->writebraw_supported = True;
1669 /* work out if they sent us a workgroup */
1670 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
1671 smb_buflen(cli->inbuf) > 8) {
1672 clistr_pull(cli->inbuf, cli->server_domain,
1673 bytes+8, sizeof(cli->server_domain),
1675 STR_UNICODE|STR_NOALIGN);
1679 * As signing is slow we only turn it on if either the client or
1680 * the server require it. JRA.
1683 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
1684 /* Fail if server says signing is mandatory and we don't want to support it. */
1685 if (!client_is_signing_allowed(cli)) {
1686 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
1687 tevent_req_nterror(req,
1688 NT_STATUS_ACCESS_DENIED);
1691 negotiated_smb_signing = true;
1692 } else if (client_is_signing_mandatory(cli) && client_is_signing_allowed(cli)) {
1693 /* Fail if client says signing is mandatory and the server doesn't support it. */
1694 if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
1695 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
1696 tevent_req_nterror(req,
1697 NT_STATUS_ACCESS_DENIED);
1700 negotiated_smb_signing = true;
1701 } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
1702 negotiated_smb_signing = true;
1705 if (negotiated_smb_signing) {
1706 cli_set_signing_negotiated(cli);
1709 if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
1710 SAFE_FREE(cli->outbuf);
1711 SAFE_FREE(cli->inbuf);
1712 cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1713 cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1714 cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE;
1717 } else if (cli->protocol >= PROTOCOL_LANMAN1) {
1718 cli->use_spnego = False;
1719 cli->sec_mode = SVAL(vwv + 1, 0);
1720 cli->max_xmit = SVAL(vwv + 2, 0);
1721 cli->max_mux = SVAL(vwv + 3, 0);
1722 cli->sesskey = IVAL(vwv + 6, 0);
1723 cli->serverzone = SVALS(vwv + 10, 0);
1724 cli->serverzone *= 60;
1725 /* this time is converted to GMT by make_unix_date */
1726 cli->servertime = cli_make_unix_date(
1727 cli, (char *)(vwv + 8));
1728 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0);
1729 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0);
1730 cli->secblob = data_blob(bytes, num_bytes);
1732 /* the old core protocol */
1733 cli->use_spnego = False;
1735 cli->serverzone = get_time_zone(time(NULL));
1738 cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
1740 /* a way to force ascii SMB */
1741 if (getenv("CLI_FORCE_ASCII"))
1742 cli->capabilities &= ~CAP_UNICODE;
1744 tevent_req_done(req);
1747 NTSTATUS cli_negprot_recv(struct tevent_req *req)
1749 return tevent_req_simple_recv_ntstatus(req);
1752 NTSTATUS cli_negprot(struct cli_state *cli)
1754 TALLOC_CTX *frame = talloc_stackframe();
1755 struct event_context *ev;
1756 struct tevent_req *req;
1757 NTSTATUS status = NT_STATUS_OK;
1759 if (cli_has_async_calls(cli)) {
1761 * Can't use sync call while an async call is in flight
1763 status = NT_STATUS_INVALID_PARAMETER;
1767 ev = event_context_init(frame);
1769 status = NT_STATUS_NO_MEMORY;
1773 req = cli_negprot_send(frame, ev, cli);
1775 status = NT_STATUS_NO_MEMORY;
1779 if (!tevent_req_poll(req, ev)) {
1780 status = map_nt_error_from_unix(errno);
1784 status = cli_negprot_recv(req);
1787 if (!NT_STATUS_IS_OK(status)) {
1788 cli_set_error(cli, status);
1793 /****************************************************************************
1794 Send a session request. See rfc1002.txt 4.3 and 4.3.2.
1795 ****************************************************************************/
1797 bool cli_session_request(struct cli_state *cli,
1798 struct nmb_name *calling, struct nmb_name *called)
1804 /* 445 doesn't have session request */
1805 if (cli->port == 445)
1808 memcpy(&(cli->calling), calling, sizeof(*calling));
1809 memcpy(&(cli->called ), called , sizeof(*called ));
1811 /* put in the destination name */
1813 tmp = name_mangle(talloc_tos(), cli->called.name,
1814 cli->called.name_type);
1819 p = cli->outbuf+len;
1820 memcpy(p, tmp, name_len(tmp));
1821 len += name_len(tmp);
1826 tmp = name_mangle(talloc_tos(), cli->calling.name,
1827 cli->calling.name_type);
1832 p = cli->outbuf+len;
1833 memcpy(p, tmp, name_len(tmp));
1834 len += name_len(tmp);
1837 /* send a session request (RFC 1002) */
1838 /* setup the packet length
1839 * Remove four bytes from the length count, since the length
1840 * field in the NBT Session Service header counts the number
1841 * of bytes which follow. The cli_send_smb() function knows
1842 * about this and accounts for those four bytes.
1846 _smb_setlen(cli->outbuf,len);
1847 SCVAL(cli->outbuf,0,0x81);
1850 DEBUG(5,("Sent session request\n"));
1852 if (!cli_receive_smb(cli))
1855 if (CVAL(cli->inbuf,0) == 0x84) {
1856 /* C. Hoch 9/14/95 Start */
1857 /* For information, here is the response structure.
1858 * We do the byte-twiddling to for portability.
1859 struct RetargetResponse{
1861 unsigned char flags;
1867 uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
1868 struct in_addr dest_ip;
1871 /* SESSION RETARGET */
1872 putip((char *)&dest_ip,cli->inbuf+4);
1873 in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
1875 status = open_socket_out(&cli->dest_ss, port,
1876 LONG_CONNECT_TIMEOUT, &cli->fd);
1877 if (!NT_STATUS_IS_OK(status)) {
1881 DEBUG(3,("Retargeted\n"));
1883 set_socket_options(cli->fd, lp_socket_options());
1890 DEBUG(0,("Retarget recursion - failing\n"));
1894 ret = cli_session_request(cli, calling, called);
1898 } /* C. Hoch 9/14/95 End */
1900 if (CVAL(cli->inbuf,0) != 0x82) {
1901 /* This is the wrong place to put the error... JRA. */
1902 cli->rap_error = CVAL(cli->inbuf,4);
1912 static void smb_sock_connected(struct tevent_req *req)
1914 struct fd_struct *pfd = tevent_req_callback_data(
1915 req, struct fd_struct);
1919 status = open_socket_out_defer_recv(req, &fd);
1920 if (NT_STATUS_IS_OK(status)) {
1925 static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
1926 uint16_t *port, int timeout, int *pfd)
1928 struct event_context *ev;
1929 struct tevent_req *r139, *r445;
1930 struct fd_struct *fd139, *fd445;
1931 NTSTATUS status = NT_STATUS_NO_MEMORY;
1934 return open_socket_out(pss, *port, timeout, pfd);
1937 ev = event_context_init(talloc_tos());
1939 return NT_STATUS_NO_MEMORY;
1942 fd139 = talloc(ev, struct fd_struct);
1943 if (fd139 == NULL) {
1948 fd445 = talloc(ev, struct fd_struct);
1949 if (fd445 == NULL) {
1954 r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0),
1956 r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000),
1958 if ((r445 == NULL) || (r139 == NULL)) {
1961 tevent_req_set_callback(r445, smb_sock_connected, fd445);
1962 tevent_req_set_callback(r139, smb_sock_connected, fd139);
1964 while ((fd445->fd == -1) && (fd139->fd == -1)
1965 && (tevent_req_is_in_progress(r139)
1966 || tevent_req_is_in_progress(r445))) {
1967 event_loop_once(ev);
1970 if ((fd139->fd != -1) && (fd445->fd != -1)) {
1975 if (fd445->fd != -1) {
1978 status = NT_STATUS_OK;
1981 if (fd139->fd != -1) {
1984 status = NT_STATUS_OK;
1988 status = open_socket_out_defer_recv(r445, &fd445->fd);
1994 /****************************************************************************
1995 Open the client sockets.
1996 ****************************************************************************/
1998 NTSTATUS cli_connect(struct cli_state *cli,
2000 struct sockaddr_storage *dest_ss)
2003 int name_type = 0x20;
2004 TALLOC_CTX *frame = talloc_stackframe();
2005 unsigned int num_addrs = 0;
2007 struct sockaddr_storage *ss_arr = NULL;
2010 /* reasonable default hostname */
2012 host = STAR_SMBSERVER;
2015 fstrcpy(cli->desthost, host);
2017 /* allow hostnames of the form NAME#xx and do a netbios lookup */
2018 if ((p = strchr(cli->desthost, '#'))) {
2019 name_type = strtol(p+1, NULL, 16);
2023 if (!dest_ss || is_zero_addr((struct sockaddr *)dest_ss)) {
2024 NTSTATUS status =resolve_name_list(frame,
2029 if (!NT_STATUS_IS_OK(status)) {
2031 return NT_STATUS_BAD_NETWORK_NAME;
2035 ss_arr = TALLOC_P(frame, struct sockaddr_storage);
2038 return NT_STATUS_NO_MEMORY;
2043 for (i = 0; i < num_addrs; i++) {
2044 cli->dest_ss = ss_arr[i];
2045 if (getenv("LIBSMB_PROG")) {
2046 cli->fd = sock_exec(getenv("LIBSMB_PROG"));
2048 uint16_t port = cli->port;
2050 status = open_smb_socket(&cli->dest_ss, &port,
2051 cli->timeout, &cli->fd);
2052 if (NT_STATUS_IS_OK(status)) {
2056 if (cli->fd == -1) {
2057 char addr[INET6_ADDRSTRLEN];
2058 print_sockaddr(addr, sizeof(addr), &ss_arr[i]);
2059 DEBUG(2,("Error connecting to %s (%s)\n",
2060 dest_ss?addr:host,strerror(errno)));
2062 /* Exit from loop on first connection. */
2067 if (cli->fd == -1) {
2069 return map_nt_error_from_unix(errno);
2073 *dest_ss = cli->dest_ss;
2076 set_socket_options(cli->fd, lp_socket_options());
2079 return NT_STATUS_OK;
2083 establishes a connection to after the negprot.
2084 @param output_cli A fully initialised cli structure, non-null only on success
2085 @param dest_host The netbios name of the remote host
2086 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2087 @param port (optional) The destination port (0 for default)
2088 @param retry bool. Did this connection fail with a retryable error ?
2091 NTSTATUS cli_start_connection(struct cli_state **output_cli,
2092 const char *my_name,
2093 const char *dest_host,
2094 struct sockaddr_storage *dest_ss, int port,
2095 int signing_state, int flags,
2099 struct nmb_name calling;
2100 struct nmb_name called;
2101 struct cli_state *cli;
2102 struct sockaddr_storage ss;
2108 my_name = global_myname();
2110 if (!(cli = cli_initialise_ex(signing_state))) {
2111 return NT_STATUS_NO_MEMORY;
2114 make_nmb_name(&calling, my_name, 0x0);
2115 make_nmb_name(&called , dest_host, 0x20);
2117 cli_set_port(cli, port);
2118 cli_set_timeout(cli, 10000); /* 10 seconds. */
2128 DEBUG(3,("Connecting to host=%s\n", dest_host));
2130 nt_status = cli_connect(cli, dest_host, &ss);
2131 if (!NT_STATUS_IS_OK(nt_status)) {
2132 char addr[INET6_ADDRSTRLEN];
2133 print_sockaddr(addr, sizeof(addr), &ss);
2134 DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
2135 nmb_namestr(&called), addr, nt_errstr(nt_status) ));
2143 if (!cli_session_request(cli, &calling, &called)) {
2145 DEBUG(1,("session request to %s failed (%s)\n",
2146 called.name, cli_errstr(cli)));
2147 if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
2151 if (strcmp(called.name, STAR_SMBSERVER)) {
2152 make_nmb_name(&called , STAR_SMBSERVER, 0x20);
2155 return NT_STATUS_BAD_NETWORK_NAME;
2158 if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
2159 cli->use_spnego = False;
2160 else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
2161 cli->use_kerberos = True;
2163 if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) &&
2164 cli->use_kerberos) {
2165 cli->fallback_after_kerberos = true;
2168 nt_status = cli_negprot(cli);
2169 if (!NT_STATUS_IS_OK(nt_status)) {
2170 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
2176 return NT_STATUS_OK;
2181 establishes a connection right up to doing tconX, password specified.
2182 @param output_cli A fully initialised cli structure, non-null only on success
2183 @param dest_host The netbios name of the remote host
2184 @param dest_ip (optional) The the destination IP, NULL for name based lookup
2185 @param port (optional) The destination port (0 for default)
2186 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
2187 @param service_type The 'type' of serivice.
2188 @param user Username, unix string
2189 @param domain User's domain
2190 @param password User's password, unencrypted unix string.
2191 @param retry bool. Did this connection fail with a retryable error ?
2194 NTSTATUS cli_full_connection(struct cli_state **output_cli,
2195 const char *my_name,
2196 const char *dest_host,
2197 struct sockaddr_storage *dest_ss, int port,
2198 const char *service, const char *service_type,
2199 const char *user, const char *domain,
2200 const char *password, int flags,
2205 struct cli_state *cli = NULL;
2206 int pw_len = password ? strlen(password)+1 : 0;
2210 if (password == NULL) {
2214 nt_status = cli_start_connection(&cli, my_name, dest_host,
2215 dest_ss, port, signing_state,
2218 if (!NT_STATUS_IS_OK(nt_status)) {
2222 cli->use_oplocks = ((flags & CLI_FULL_CONNECTION_OPLOCKS) != 0);
2223 cli->use_level_II_oplocks =
2224 ((flags & CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS) != 0);
2226 nt_status = cli_session_setup(cli, user, password, pw_len, password,
2228 if (!NT_STATUS_IS_OK(nt_status)) {
2230 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
2231 DEBUG(1,("failed session setup with %s\n",
2232 nt_errstr(nt_status)));
2237 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
2238 if (!NT_STATUS_IS_OK(nt_status)) {
2239 DEBUG(1,("anonymous failed session setup with %s\n",
2240 nt_errstr(nt_status)));
2247 nt_status = cli_tcon_andx(cli, service, service_type, password,
2249 if (!NT_STATUS_IS_OK(nt_status)) {
2250 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
2252 if (NT_STATUS_IS_OK(nt_status)) {
2253 nt_status = NT_STATUS_UNSUCCESSFUL;
2259 nt_status = cli_init_creds(cli, user, domain, password);
2260 if (!NT_STATUS_IS_OK(nt_status)) {
2266 return NT_STATUS_OK;
2269 /****************************************************************************
2270 Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
2271 ****************************************************************************/
2273 bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
2274 struct sockaddr_storage *pdest_ss)
2276 struct nmb_name calling, called;
2278 make_nmb_name(&calling, srchost, 0x0);
2281 * If the called name is an IP address
2282 * then use *SMBSERVER immediately.
2285 if(is_ipaddress(desthost)) {
2286 make_nmb_name(&called, STAR_SMBSERVER, 0x20);
2288 make_nmb_name(&called, desthost, 0x20);
2291 if (!cli_session_request(*ppcli, &calling, &called)) {
2293 struct nmb_name smbservername;
2295 make_nmb_name(&smbservername, STAR_SMBSERVER, 0x20);
2298 * If the name wasn't *SMBSERVER then
2299 * try with *SMBSERVER if the first name fails.
2302 if (nmb_name_equal(&called, &smbservername)) {
2305 * The name used was *SMBSERVER, don't bother with another name.
2308 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
2309 with error %s.\n", desthost, cli_errstr(*ppcli) ));
2314 cli_shutdown(*ppcli);
2316 *ppcli = cli_initialise();
2318 /* Out of memory... */
2322 status = cli_connect(*ppcli, desthost, pdest_ss);
2323 if (!NT_STATUS_IS_OK(status) ||
2324 !cli_session_request(*ppcli, &calling, &smbservername)) {
2325 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
2326 name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
2334 /****************************************************************************
2335 Send an old style tcon.
2336 ****************************************************************************/
2337 NTSTATUS cli_raw_tcon(struct cli_state *cli,
2338 const char *service, const char *pass, const char *dev,
2339 uint16 *max_xmit, uint16 *tid)
2343 if (!lp_client_plaintext_auth() && (*pass)) {
2344 DEBUG(1, ("Server requested plaintext password but 'client "
2345 "plaintext auth' is disabled\n"));
2346 return NT_STATUS_ACCESS_DENIED;
2349 memset(cli->outbuf,'\0',smb_size);
2350 memset(cli->inbuf,'\0',smb_size);
2352 cli_set_message(cli->outbuf, 0, 0, True);
2353 SCVAL(cli->outbuf,smb_com,SMBtcon);
2354 cli_setup_packet(cli);
2356 p = smb_buf(cli->outbuf);
2357 *p++ = 4; p += clistr_push(cli, p, service, -1, STR_TERMINATE | STR_NOALIGN);
2358 *p++ = 4; p += clistr_push(cli, p, pass, -1, STR_TERMINATE | STR_NOALIGN);
2359 *p++ = 4; p += clistr_push(cli, p, dev, -1, STR_TERMINATE | STR_NOALIGN);
2361 cli_setup_bcc(cli, p);
2364 if (!cli_receive_smb(cli)) {
2365 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
2368 if (cli_is_error(cli)) {
2369 return cli_nt_error(cli);
2372 *max_xmit = SVAL(cli->inbuf, smb_vwv0);
2373 *tid = SVAL(cli->inbuf, smb_vwv1);
2375 return NT_STATUS_OK;
2378 /* Return a cli_state pointing at the IPC$ share for the given server */
2380 struct cli_state *get_ipc_connect(char *server,
2381 struct sockaddr_storage *server_ss,
2382 const struct user_auth_info *user_info)
2384 struct cli_state *cli;
2386 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
2388 if (user_info->use_kerberos) {
2389 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
2392 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
2393 user_info->username ? user_info->username : "",
2395 user_info->password ? user_info->password : "",
2399 if (NT_STATUS_IS_OK(nt_status)) {
2401 } else if (is_ipaddress(server)) {
2402 /* windows 9* needs a correct NMB name for connections */
2403 fstring remote_name;
2405 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
2406 cli = get_ipc_connect(remote_name, server_ss, user_info);
2415 * Given the IP address of a master browser on the network, return its
2416 * workgroup and connect to it.
2418 * This function is provided to allow additional processing beyond what
2419 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
2420 * browsers and obtain each master browsers' list of domains (in case the
2421 * first master browser is recently on the network and has not yet
2422 * synchronized with other master browsers and therefore does not yet have the
2423 * entire network browse list)
2426 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
2427 struct ip_service *mb_ip,
2428 const struct user_auth_info *user_info,
2429 char **pp_workgroup_out)
2431 char addr[INET6_ADDRSTRLEN];
2433 struct cli_state *cli;
2434 struct sockaddr_storage server_ss;
2436 *pp_workgroup_out = NULL;
2438 print_sockaddr(addr, sizeof(addr), &mb_ip->ss);
2439 DEBUG(99, ("Looking up name of master browser %s\n",
2443 * Do a name status query to find out the name of the master browser.
2444 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
2445 * master browser will not respond to a wildcard query (or, at least,
2446 * an NT4 server acting as the domain master browser will not).
2448 * We might be able to use ONLY the query on MSBROWSE, but that's not
2449 * yet been tested with all Windows versions, so until it is, leave
2450 * the original wildcard query as the first choice and fall back to
2451 * MSBROWSE if the wildcard query fails.
2453 if (!name_status_find("*", 0, 0x1d, &mb_ip->ss, name) &&
2454 !name_status_find(MSBROWSE, 1, 0x1d, &mb_ip->ss, name)) {
2456 DEBUG(99, ("Could not retrieve name status for %s\n",
2461 if (!find_master_ip(name, &server_ss)) {
2462 DEBUG(99, ("Could not find master ip for %s\n", name));
2466 *pp_workgroup_out = talloc_strdup(ctx, name);
2468 DEBUG(4, ("found master browser %s, %s\n", name, addr));
2470 print_sockaddr(addr, sizeof(addr), &server_ss);
2471 cli = get_ipc_connect(addr, &server_ss, user_info);
2477 * Return the IP address and workgroup of a master browser on the network, and
2481 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
2482 const struct user_auth_info *user_info,
2483 char **pp_workgroup_out)
2485 struct ip_service *ip_list;
2486 struct cli_state *cli;
2489 *pp_workgroup_out = NULL;
2491 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
2493 /* Go looking for workgroups by broadcasting on the local network */
2495 if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
2497 DEBUG(99, ("No master browsers responded\n"));
2501 for (i = 0; i < count; i++) {
2502 char addr[INET6_ADDRSTRLEN];
2503 print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
2504 DEBUG(99, ("Found master browser %s\n", addr));
2506 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
2507 user_info, pp_workgroup_out);