WHATSNEW: Start WHATSNEW for 3.2.12.
[Samba.git] / source / libsmb / cliconnect.c
blob2be220f61e295ad596a6065fc9010ac8b52620d7
1 /*
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/>.
21 #include "includes.h"
23 static const struct {
24 int prot;
25 const char *name;
26 } prots[] = {
27 {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
28 {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
29 {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
30 {PROTOCOL_LANMAN1,"LANMAN1.0"},
31 {PROTOCOL_LANMAN2,"LM1.2X002"},
32 {PROTOCOL_LANMAN2,"DOS LANMAN2.1"},
33 {PROTOCOL_LANMAN2,"LANMAN2.1"},
34 {PROTOCOL_LANMAN2,"Samba"},
35 {PROTOCOL_NT1,"NT LANMAN 1.0"},
36 {PROTOCOL_NT1,"NT LM 0.12"},
37 {-1,NULL}
40 static const char *star_smbserver_name = "*SMBSERVER";
42 /**
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,
59 const char *user,
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;
65 fstring pword;
66 char *p;
68 if (passlen > sizeof(pword)-1) {
69 return NT_STATUS_INVALID_PARAMETER;
72 /* LANMAN servers predate NT status codes and Unicode and ignore those
73 smb flags so we must disable the corresponding default capabilities
74 that would otherwise cause the Unicode and NT Status flags to be
75 set (and even returned by the server) */
77 cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32);
79 /* if in share level security then don't send a password now */
80 if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL))
81 passlen = 0;
83 if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) {
84 /* Encrypted mode needed, and non encrypted password supplied. */
85 lm_response = data_blob(NULL, 24);
86 if (!SMBencrypt(pass, cli->secblob.data,(uchar *)lm_response.data)) {
87 DEBUG(1, ("Password is > 14 chars in length, and is therefore incompatible with Lanman authentication\n"));
88 return NT_STATUS_ACCESS_DENIED;
90 } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) {
91 /* Encrypted mode needed, and encrypted password supplied. */
92 lm_response = data_blob(pass, passlen);
93 } else if (passlen > 0) {
94 /* Plaintext mode needed, assume plaintext supplied. */
95 passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
96 lm_response = data_blob(pass, passlen);
99 /* send a session setup command */
100 memset(cli->outbuf,'\0',smb_size);
101 cli_set_message(cli->outbuf,10, 0, True);
102 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
103 cli_setup_packet(cli);
105 SCVAL(cli->outbuf,smb_vwv0,0xFF);
106 SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit);
107 SSVAL(cli->outbuf,smb_vwv3,2);
108 SSVAL(cli->outbuf,smb_vwv4,1);
109 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
110 SSVAL(cli->outbuf,smb_vwv7,lm_response.length);
112 p = smb_buf(cli->outbuf);
113 memcpy(p,lm_response.data,lm_response.length);
114 p += lm_response.length;
115 p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER);
116 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER);
117 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
118 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
119 cli_setup_bcc(cli, p);
121 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
122 return cli_nt_error(cli);
125 show_msg(cli->inbuf);
127 if (cli_is_error(cli)) {
128 return cli_nt_error(cli);
131 /* use the returned vuid from now on */
132 cli->vuid = SVAL(cli->inbuf,smb_uid);
133 fstrcpy(cli->user_name, user);
135 if (session_key.data) {
136 /* Have plaintext orginal */
137 cli_set_session_key(cli, session_key);
140 return NT_STATUS_OK;
143 /****************************************************************************
144 Work out suitable capabilities to offer the server.
145 ****************************************************************************/
147 static uint32 cli_session_setup_capabilities(struct cli_state *cli)
149 uint32 capabilities = CAP_NT_SMBS;
151 if (!cli->force_dos_errors)
152 capabilities |= CAP_STATUS32;
154 if (cli->use_level_II_oplocks)
155 capabilities |= CAP_LEVEL_II_OPLOCKS;
157 capabilities |= (cli->capabilities & (CAP_UNICODE|CAP_LARGE_FILES|CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_DFS));
158 return capabilities;
161 /****************************************************************************
162 Do a NT1 guest session setup.
163 ****************************************************************************/
165 static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
167 char *p;
168 uint32 capabilities = cli_session_setup_capabilities(cli);
170 memset(cli->outbuf, '\0', smb_size);
171 cli_set_message(cli->outbuf,13,0,True);
172 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
173 cli_setup_packet(cli);
175 SCVAL(cli->outbuf,smb_vwv0,0xFF);
176 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
177 SSVAL(cli->outbuf,smb_vwv3,2);
178 SSVAL(cli->outbuf,smb_vwv4,cli->pid);
179 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
180 SSVAL(cli->outbuf,smb_vwv7,0);
181 SSVAL(cli->outbuf,smb_vwv8,0);
182 SIVAL(cli->outbuf,smb_vwv11,capabilities);
183 p = smb_buf(cli->outbuf);
184 p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* username */
185 p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* workgroup */
186 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
187 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
188 cli_setup_bcc(cli, p);
190 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
191 return cli_nt_error(cli);
194 show_msg(cli->inbuf);
196 if (cli_is_error(cli)) {
197 return cli_nt_error(cli);
200 cli->vuid = SVAL(cli->inbuf,smb_uid);
202 p = smb_buf(cli->inbuf);
203 p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE);
204 p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE);
205 p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE);
207 if (strstr(cli->server_type, "Samba")) {
208 cli->is_samba = True;
211 fstrcpy(cli->user_name, "");
213 return NT_STATUS_OK;
216 /****************************************************************************
217 Do a NT1 plaintext session setup.
218 ****************************************************************************/
220 static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli,
221 const char *user, const char *pass,
222 const char *workgroup)
224 uint32 capabilities = cli_session_setup_capabilities(cli);
225 char *p;
226 fstring lanman;
228 fstr_sprintf( lanman, "Samba %s", SAMBA_VERSION_STRING);
230 memset(cli->outbuf, '\0', smb_size);
231 cli_set_message(cli->outbuf,13,0,True);
232 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
233 cli_setup_packet(cli);
235 SCVAL(cli->outbuf,smb_vwv0,0xFF);
236 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
237 SSVAL(cli->outbuf,smb_vwv3,2);
238 SSVAL(cli->outbuf,smb_vwv4,cli->pid);
239 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
240 SSVAL(cli->outbuf,smb_vwv8,0);
241 SIVAL(cli->outbuf,smb_vwv11,capabilities);
242 p = smb_buf(cli->outbuf);
244 /* check wether to send the ASCII or UNICODE version of the password */
246 if ( (capabilities & CAP_UNICODE) == 0 ) {
247 p += clistr_push(cli, p, pass, -1, STR_TERMINATE); /* password */
248 SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf)));
250 else {
251 /* For ucs2 passwords clistr_push calls ucs2_align, which causes
252 * the space taken by the unicode password to be one byte too
253 * long (as we're on an odd byte boundary here). Reduce the
254 * count by 1 to cope with this. Fixes smbclient against NetApp
255 * servers which can't cope. Fix from
256 * bryan.kolodziej@allenlund.com in bug #3840.
258 p += clistr_push(cli, p, pass, -1, STR_UNICODE|STR_TERMINATE); /* unicode password */
259 SSVAL(cli->outbuf,smb_vwv8,PTR_DIFF(p, smb_buf(cli->outbuf))-1);
262 p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */
263 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */
264 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
265 p += clistr_push(cli, p, lanman, -1, STR_TERMINATE);
266 cli_setup_bcc(cli, p);
268 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
269 return cli_nt_error(cli);
272 show_msg(cli->inbuf);
274 if (cli_is_error(cli)) {
275 return cli_nt_error(cli);
278 cli->vuid = SVAL(cli->inbuf,smb_uid);
279 p = smb_buf(cli->inbuf);
280 p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE);
281 p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE);
282 p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE);
283 fstrcpy(cli->user_name, user);
285 if (strstr(cli->server_type, "Samba")) {
286 cli->is_samba = True;
289 return NT_STATUS_OK;
292 /****************************************************************************
293 do a NT1 NTLM/LM encrypted session setup - for when extended security
294 is not negotiated.
295 @param cli client state to create do session setup on
296 @param user username
297 @param pass *either* cleartext password (passlen !=24) or LM response.
298 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
299 @param workgroup The user's domain.
300 ****************************************************************************/
302 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
303 const char *pass, size_t passlen,
304 const char *ntpass, size_t ntpasslen,
305 const char *workgroup)
307 uint32 capabilities = cli_session_setup_capabilities(cli);
308 DATA_BLOB lm_response = data_blob_null;
309 DATA_BLOB nt_response = data_blob_null;
310 DATA_BLOB session_key = data_blob_null;
311 NTSTATUS result;
312 char *p;
314 if (passlen == 0) {
315 /* do nothing - guest login */
316 } else if (passlen != 24) {
317 if (lp_client_ntlmv2_auth()) {
318 DATA_BLOB server_chal;
319 DATA_BLOB names_blob;
320 server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8));
322 /* note that the 'workgroup' here is a best guess - we don't know
323 the server's domain at this point. The 'server name' is also
324 dodgy...
326 names_blob = NTLMv2_generate_names_blob(cli->called.name, workgroup);
328 if (!SMBNTLMv2encrypt(user, workgroup, pass, &server_chal,
329 &names_blob,
330 &lm_response, &nt_response, &session_key)) {
331 data_blob_free(&names_blob);
332 data_blob_free(&server_chal);
333 return NT_STATUS_ACCESS_DENIED;
335 data_blob_free(&names_blob);
336 data_blob_free(&server_chal);
338 } else {
339 uchar nt_hash[16];
340 E_md4hash(pass, nt_hash);
342 #ifdef LANMAN_ONLY
343 nt_response = data_blob_null;
344 #else
345 nt_response = data_blob(NULL, 24);
346 SMBNTencrypt(pass,cli->secblob.data,nt_response.data);
347 #endif
348 /* non encrypted password supplied. Ignore ntpass. */
349 if (lp_client_lanman_auth()) {
350 lm_response = data_blob(NULL, 24);
351 if (!SMBencrypt(pass,cli->secblob.data, lm_response.data)) {
352 /* Oops, the LM response is invalid, just put
353 the NT response there instead */
354 data_blob_free(&lm_response);
355 lm_response = data_blob(nt_response.data, nt_response.length);
357 } else {
358 /* LM disabled, place NT# in LM field instead */
359 lm_response = data_blob(nt_response.data, nt_response.length);
362 session_key = data_blob(NULL, 16);
363 #ifdef LANMAN_ONLY
364 E_deshash(pass, session_key.data);
365 memset(&session_key.data[8], '\0', 8);
366 #else
367 SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
368 #endif
370 #ifdef LANMAN_ONLY
371 cli_simple_set_signing(cli, session_key, lm_response);
372 #else
373 cli_simple_set_signing(cli, session_key, nt_response);
374 #endif
375 } else {
376 /* pre-encrypted password supplied. Only used for
377 security=server, can't do
378 signing because we don't have original key */
380 lm_response = data_blob(pass, passlen);
381 nt_response = data_blob(ntpass, ntpasslen);
384 /* send a session setup command */
385 memset(cli->outbuf,'\0',smb_size);
387 cli_set_message(cli->outbuf,13,0,True);
388 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
389 cli_setup_packet(cli);
391 SCVAL(cli->outbuf,smb_vwv0,0xFF);
392 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
393 SSVAL(cli->outbuf,smb_vwv3,2);
394 SSVAL(cli->outbuf,smb_vwv4,cli->pid);
395 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
396 SSVAL(cli->outbuf,smb_vwv7,lm_response.length);
397 SSVAL(cli->outbuf,smb_vwv8,nt_response.length);
398 SIVAL(cli->outbuf,smb_vwv11,capabilities);
399 p = smb_buf(cli->outbuf);
400 if (lm_response.length) {
401 memcpy(p,lm_response.data, lm_response.length); p += lm_response.length;
403 if (nt_response.length) {
404 memcpy(p,nt_response.data, nt_response.length); p += nt_response.length;
406 p += clistr_push(cli, p, user, -1, STR_TERMINATE);
408 /* Upper case here might help some NTLMv2 implementations */
409 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER);
410 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
411 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
412 cli_setup_bcc(cli, p);
414 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
415 result = cli_nt_error(cli);
416 goto end;
419 /* show_msg(cli->inbuf); */
421 if (cli_is_error(cli)) {
422 result = cli_nt_error(cli);
423 goto end;
426 /* use the returned vuid from now on */
427 cli->vuid = SVAL(cli->inbuf,smb_uid);
429 p = smb_buf(cli->inbuf);
430 p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE);
431 p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE);
432 p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE);
434 if (strstr(cli->server_type, "Samba")) {
435 cli->is_samba = True;
438 fstrcpy(cli->user_name, user);
440 if (session_key.data) {
441 /* Have plaintext orginal */
442 cli_set_session_key(cli, session_key);
445 result = NT_STATUS_OK;
446 end:
447 data_blob_free(&lm_response);
448 data_blob_free(&nt_response);
449 data_blob_free(&session_key);
450 return result;
453 /****************************************************************************
454 Send a extended security session setup blob
455 ****************************************************************************/
457 static bool cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob)
459 uint32 capabilities = cli_session_setup_capabilities(cli);
460 char *p;
462 capabilities |= CAP_EXTENDED_SECURITY;
464 /* send a session setup command */
465 memset(cli->outbuf,'\0',smb_size);
467 cli_set_message(cli->outbuf,12,0,True);
468 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
470 cli_setup_packet(cli);
472 SCVAL(cli->outbuf,smb_vwv0,0xFF);
473 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
474 SSVAL(cli->outbuf,smb_vwv3,2);
475 SSVAL(cli->outbuf,smb_vwv4,1);
476 SIVAL(cli->outbuf,smb_vwv5,0);
477 SSVAL(cli->outbuf,smb_vwv7,blob.length);
478 SIVAL(cli->outbuf,smb_vwv10,capabilities);
479 p = smb_buf(cli->outbuf);
480 memcpy(p, blob.data, blob.length);
481 p += blob.length;
482 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
483 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
484 cli_setup_bcc(cli, p);
485 return cli_send_smb(cli);
488 /****************************************************************************
489 Send a extended security session setup blob, returning a reply blob.
490 ****************************************************************************/
492 static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli)
494 DATA_BLOB blob2 = data_blob_null;
495 char *p;
496 size_t len;
498 if (!cli_receive_smb(cli))
499 return blob2;
501 show_msg(cli->inbuf);
503 if (cli_is_error(cli) && !NT_STATUS_EQUAL(cli_nt_error(cli),
504 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
505 return blob2;
508 /* use the returned vuid from now on */
509 cli->vuid = SVAL(cli->inbuf,smb_uid);
511 p = smb_buf(cli->inbuf);
513 blob2 = data_blob(p, SVAL(cli->inbuf, smb_vwv3));
515 p += blob2.length;
516 p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE);
518 /* w2k with kerberos doesn't properly null terminate this field */
519 len = smb_buflen(cli->inbuf) - PTR_DIFF(p, smb_buf(cli->inbuf));
520 p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), len, 0);
522 return blob2;
525 #ifdef HAVE_KRB5
526 /****************************************************************************
527 Send a extended security session setup blob, returning a reply blob.
528 ****************************************************************************/
530 /* The following is calculated from :
531 * (smb_size-4) = 35
532 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
533 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
534 * end of packet.
537 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
539 static bool cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob)
541 int32 remaining = blob.length;
542 int32 cur = 0;
543 DATA_BLOB send_blob = data_blob_null;
544 int32 max_blob_size = 0;
545 DATA_BLOB receive_blob = data_blob_null;
547 if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) {
548 DEBUG(0,("cli_session_setup_blob: cli->max_xmit too small "
549 "(was %u, need minimum %u)\n",
550 (unsigned int)cli->max_xmit,
551 BASE_SESSSETUP_BLOB_PACKET_SIZE));
552 cli_set_nt_error(cli, NT_STATUS_INVALID_PARAMETER);
553 return False;
556 max_blob_size = cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE;
558 while ( remaining > 0) {
559 if (remaining >= max_blob_size) {
560 send_blob.length = max_blob_size;
561 remaining -= max_blob_size;
562 } else {
563 send_blob.length = remaining;
564 remaining = 0;
567 send_blob.data = &blob.data[cur];
568 cur += send_blob.length;
570 DEBUG(10, ("cli_session_setup_blob: Remaining (%u) sending (%u) current (%u)\n",
571 (unsigned int)remaining,
572 (unsigned int)send_blob.length,
573 (unsigned int)cur ));
575 if (!cli_session_setup_blob_send(cli, send_blob)) {
576 DEBUG(0, ("cli_session_setup_blob: send failed\n"));
577 return False;
580 receive_blob = cli_session_setup_blob_receive(cli);
581 data_blob_free(&receive_blob);
583 if (cli_is_error(cli) &&
584 !NT_STATUS_EQUAL( cli_get_nt_error(cli),
585 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
586 DEBUG(0, ("cli_session_setup_blob: receive failed "
587 "(%s)\n", nt_errstr(cli_get_nt_error(cli))));
588 cli->vuid = 0;
589 return False;
593 return True;
596 /****************************************************************************
597 Use in-memory credentials cache
598 ****************************************************************************/
600 static void use_in_memory_ccache(void) {
601 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
604 /****************************************************************************
605 Do a spnego/kerberos encrypted session setup.
606 ****************************************************************************/
608 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup)
610 DATA_BLOB negTokenTarg;
611 DATA_BLOB session_key_krb5;
612 NTSTATUS nt_status;
613 int rc;
615 cli_temp_set_signing(cli);
617 DEBUG(2,("Doing kerberos session setup\n"));
619 /* generate the encapsulated kerberos5 ticket */
620 rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5, 0, NULL);
622 if (rc) {
623 DEBUG(1, ("cli_session_setup_kerberos: spnego_gen_negTokenTarg failed: %s\n",
624 error_message(rc)));
625 return ADS_ERROR_KRB5(rc);
628 #if 0
629 file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length);
630 #endif
632 if (!cli_session_setup_blob(cli, negTokenTarg)) {
633 nt_status = cli_nt_error(cli);
634 goto nt_error;
637 if (cli_is_error(cli)) {
638 nt_status = cli_nt_error(cli);
639 if (NT_STATUS_IS_OK(nt_status)) {
640 nt_status = NT_STATUS_UNSUCCESSFUL;
642 goto nt_error;
645 cli_set_session_key(cli, session_key_krb5);
647 if (cli_simple_set_signing(
648 cli, session_key_krb5, data_blob_null)) {
650 /* 'resign' the last message, so we get the right sequence numbers
651 for checking the first reply from the server */
652 cli_calculate_sign_mac(cli, cli->outbuf);
654 if (!cli_check_sign_mac(cli, cli->inbuf)) {
655 nt_status = NT_STATUS_ACCESS_DENIED;
656 goto nt_error;
660 data_blob_free(&negTokenTarg);
661 data_blob_free(&session_key_krb5);
663 return ADS_ERROR_NT(NT_STATUS_OK);
665 nt_error:
666 data_blob_free(&negTokenTarg);
667 data_blob_free(&session_key_krb5);
668 cli->vuid = 0;
669 return ADS_ERROR_NT(nt_status);
671 #endif /* HAVE_KRB5 */
674 /****************************************************************************
675 Do a spnego/NTLMSSP encrypted session setup.
676 ****************************************************************************/
678 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
679 const char *pass, const char *domain)
681 struct ntlmssp_state *ntlmssp_state;
682 NTSTATUS nt_status;
683 int turn = 1;
684 DATA_BLOB msg1;
685 DATA_BLOB blob = data_blob_null;
686 DATA_BLOB blob_in = data_blob_null;
687 DATA_BLOB blob_out = data_blob_null;
689 cli_temp_set_signing(cli);
691 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) {
692 return nt_status;
694 ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
696 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
697 return nt_status;
699 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
700 return nt_status;
702 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) {
703 return nt_status;
706 do {
707 nt_status = ntlmssp_update(ntlmssp_state,
708 blob_in, &blob_out);
709 data_blob_free(&blob_in);
710 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(nt_status)) {
711 if (turn == 1) {
712 /* and wrap it in a SPNEGO wrapper */
713 msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out);
714 } else {
715 /* wrap it in SPNEGO */
716 msg1 = spnego_gen_auth(blob_out);
719 /* now send that blob on its way */
720 if (!cli_session_setup_blob_send(cli, msg1)) {
721 DEBUG(3, ("Failed to send NTLMSSP/SPNEGO blob to server!\n"));
722 nt_status = NT_STATUS_UNSUCCESSFUL;
723 } else {
724 blob = cli_session_setup_blob_receive(cli);
726 nt_status = cli_nt_error(cli);
727 if (cli_is_error(cli) && NT_STATUS_IS_OK(nt_status)) {
728 if (cli->smb_rw_error == SMB_READ_BAD_SIG) {
729 nt_status = NT_STATUS_ACCESS_DENIED;
730 } else {
731 nt_status = NT_STATUS_UNSUCCESSFUL;
735 data_blob_free(&msg1);
738 if (!blob.length) {
739 if (NT_STATUS_IS_OK(nt_status)) {
740 nt_status = NT_STATUS_UNSUCCESSFUL;
742 } else if ((turn == 1) &&
743 NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
744 DATA_BLOB tmp_blob = data_blob_null;
745 /* the server might give us back two challenges */
746 if (!spnego_parse_challenge(blob, &blob_in,
747 &tmp_blob)) {
748 DEBUG(3,("Failed to parse challenges\n"));
749 nt_status = NT_STATUS_INVALID_PARAMETER;
751 data_blob_free(&tmp_blob);
752 } else {
753 if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP,
754 &blob_in)) {
755 DEBUG(3,("Failed to parse auth response\n"));
756 if (NT_STATUS_IS_OK(nt_status)
757 || NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED))
758 nt_status = NT_STATUS_INVALID_PARAMETER;
761 data_blob_free(&blob);
762 data_blob_free(&blob_out);
763 turn++;
764 } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED));
766 data_blob_free(&blob_in);
768 if (NT_STATUS_IS_OK(nt_status)) {
770 DATA_BLOB key = data_blob(ntlmssp_state->session_key.data,
771 ntlmssp_state->session_key.length);
772 DATA_BLOB null_blob = data_blob_null;
773 bool res;
775 fstrcpy(cli->server_domain, ntlmssp_state->server_domain);
776 cli_set_session_key(cli, ntlmssp_state->session_key);
778 res = cli_simple_set_signing(cli, key, null_blob);
780 data_blob_free(&key);
782 if (res) {
784 /* 'resign' the last message, so we get the right sequence numbers
785 for checking the first reply from the server */
786 cli_calculate_sign_mac(cli, cli->outbuf);
788 if (!cli_check_sign_mac(cli, cli->inbuf)) {
789 nt_status = NT_STATUS_ACCESS_DENIED;
794 /* we have a reference conter on ntlmssp_state, if we are signing
795 then the state will be kept by the signing engine */
797 ntlmssp_end(&ntlmssp_state);
799 if (!NT_STATUS_IS_OK(nt_status)) {
800 cli->vuid = 0;
802 return nt_status;
805 /****************************************************************************
806 Do a spnego encrypted session setup.
808 user_domain: The shortname of the domain the user/machine is a member of.
809 dest_realm: The realm we're connecting to, if NULL we use our default realm.
810 ****************************************************************************/
812 ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
813 const char *pass, const char *user_domain,
814 const char * dest_realm)
816 char *principal = NULL;
817 char *OIDs[ASN1_MAX_OIDS];
818 int i;
819 DATA_BLOB blob;
820 const char *p = NULL;
821 char *account = NULL;
823 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
825 /* the server might not even do spnego */
826 if (cli->secblob.length <= 16) {
827 DEBUG(3,("server didn't supply a full spnego negprot\n"));
828 goto ntlmssp;
831 #if 0
832 file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
833 #endif
835 /* there is 16 bytes of GUID before the real spnego packet starts */
836 blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);
838 /* The server sent us the first part of the SPNEGO exchange in the
839 * negprot reply. It is WRONG to depend on the principal sent in the
840 * negprot reply, but right now we do it. If we don't receive one,
841 * we try to best guess, then fall back to NTLM. */
842 if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) {
843 data_blob_free(&blob);
844 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
846 data_blob_free(&blob);
848 /* make sure the server understands kerberos */
849 for (i=0;OIDs[i];i++) {
850 DEBUG(3,("got OID=%s\n", OIDs[i]));
851 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
852 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
853 cli->got_kerberos_mechanism = True;
855 free(OIDs[i]);
858 DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
860 fstrcpy(cli->user_name, user);
862 #ifdef HAVE_KRB5
863 /* If password is set we reauthenticate to kerberos server
864 * and do not store results */
866 if (cli->got_kerberos_mechanism && cli->use_kerberos) {
867 ADS_STATUS rc;
869 if (pass && *pass) {
870 int ret;
872 use_in_memory_ccache();
873 ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
875 if (ret){
876 SAFE_FREE(principal);
877 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
878 if (cli->fallback_after_kerberos)
879 goto ntlmssp;
880 return ADS_ERROR_KRB5(ret);
884 /* If we get a bad principal, try to guess it if
885 we have a valid host NetBIOS name.
887 if (strequal(principal, ADS_IGNORE_PRINCIPAL)) {
888 SAFE_FREE(principal);
891 if (principal == NULL &&
892 !is_ipaddress(cli->desthost) &&
893 !strequal(star_smbserver_name,
894 cli->desthost)) {
895 char *realm = NULL;
896 char *machine = NULL;
897 char *host = NULL;
898 DEBUG(3,("cli_session_setup_spnego: got a "
899 "bad server principal, trying to guess ...\n"));
901 host = strchr_m(cli->desthost, '.');
902 if (host) {
903 machine = SMB_STRNDUP(cli->desthost,
904 host - cli->desthost);
905 } else {
906 machine = SMB_STRDUP(cli->desthost);
908 if (machine == NULL) {
909 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
912 if (dest_realm) {
913 realm = SMB_STRDUP(dest_realm);
914 strupper_m(realm);
915 } else {
916 realm = kerberos_get_default_realm_from_ccache();
918 if (realm && *realm) {
919 if (asprintf(&principal, "%s$@%s",
920 machine, realm) < 0) {
921 SAFE_FREE(machine);
922 SAFE_FREE(realm);
923 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
925 DEBUG(3,("cli_session_setup_spnego: guessed "
926 "server principal=%s\n",
927 principal ? principal : "<null>"));
929 SAFE_FREE(machine);
930 SAFE_FREE(realm);
933 if (principal) {
934 rc = cli_session_setup_kerberos(cli, principal,
935 dest_realm);
936 if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
937 SAFE_FREE(principal);
938 return rc;
942 #endif
944 SAFE_FREE(principal);
946 ntlmssp:
948 account = talloc_strdup(talloc_tos(), user);
949 if (!account) {
950 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
953 /* when falling back to ntlmssp while authenticating with a machine
954 * account strip off the realm - gd */
956 if ((p = strchr_m(user, '@')) != NULL) {
957 account[PTR_DIFF(p,user)] = '\0';
960 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
963 /****************************************************************************
964 Send a session setup. The username and workgroup is in UNIX character
965 format and must be converted to DOS codepage format before sending. If the
966 password is in plaintext, the same should be done.
967 ****************************************************************************/
969 NTSTATUS cli_session_setup(struct cli_state *cli,
970 const char *user,
971 const char *pass, int passlen,
972 const char *ntpass, int ntpasslen,
973 const char *workgroup)
975 char *p;
976 fstring user2;
978 if (user) {
979 fstrcpy(user2, user);
980 } else {
981 user2[0] ='\0';
984 if (!workgroup) {
985 workgroup = "";
988 /* allow for workgroups as part of the username */
989 if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
990 (p=strchr_m(user2,*lp_winbind_separator()))) {
991 *p = 0;
992 user = p+1;
993 workgroup = user2;
996 if (cli->protocol < PROTOCOL_LANMAN1) {
997 return NT_STATUS_OK;
1000 /* now work out what sort of session setup we are going to
1001 do. I have split this into separate functions to make the
1002 flow a bit easier to understand (tridge) */
1004 /* if its an older server then we have to use the older request format */
1006 if (cli->protocol < PROTOCOL_NT1) {
1007 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
1008 DEBUG(1, ("Server requested LM password but 'client lanman auth'"
1009 " is disabled\n"));
1010 return NT_STATUS_ACCESS_DENIED;
1013 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
1014 !lp_client_plaintext_auth() && (*pass)) {
1015 DEBUG(1, ("Server requested plaintext password but "
1016 "'client plaintext auth' is disabled\n"));
1017 return NT_STATUS_ACCESS_DENIED;
1020 return cli_session_setup_lanman2(cli, user, pass, passlen,
1021 workgroup);
1024 /* if no user is supplied then we have to do an anonymous connection.
1025 passwords are ignored */
1027 if (!user || !*user)
1028 return cli_session_setup_guest(cli);
1030 /* if the server is share level then send a plaintext null
1031 password at this point. The password is sent in the tree
1032 connect */
1034 if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
1035 return cli_session_setup_plaintext(cli, user, "", workgroup);
1037 /* if the server doesn't support encryption then we have to use
1038 plaintext. The second password is ignored */
1040 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1041 if (!lp_client_plaintext_auth() && (*pass)) {
1042 DEBUG(1, ("Server requested plaintext password but "
1043 "'client plaintext auth' is disabled\n"));
1044 return NT_STATUS_ACCESS_DENIED;
1046 return cli_session_setup_plaintext(cli, user, pass, workgroup);
1049 /* if the server supports extended security then use SPNEGO */
1051 if (cli->capabilities & CAP_EXTENDED_SECURITY) {
1052 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
1053 workgroup, NULL);
1054 if (!ADS_ERR_OK(status)) {
1055 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1056 return ads_ntstatus(status);
1058 } else {
1059 NTSTATUS status;
1061 /* otherwise do a NT1 style session setup */
1062 status = cli_session_setup_nt1(cli, user, pass, passlen,
1063 ntpass, ntpasslen, workgroup);
1064 if (!NT_STATUS_IS_OK(status)) {
1065 DEBUG(3,("cli_session_setup: NT1 session setup "
1066 "failed: %s\n", nt_errstr(status)));
1067 return status;
1071 if (strstr(cli->server_type, "Samba")) {
1072 cli->is_samba = True;
1075 return NT_STATUS_OK;
1078 /****************************************************************************
1079 Send a uloggoff.
1080 *****************************************************************************/
1082 bool cli_ulogoff(struct cli_state *cli)
1084 memset(cli->outbuf,'\0',smb_size);
1085 cli_set_message(cli->outbuf,2,0,True);
1086 SCVAL(cli->outbuf,smb_com,SMBulogoffX);
1087 cli_setup_packet(cli);
1088 SSVAL(cli->outbuf,smb_vwv0,0xFF);
1089 SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */
1091 cli_send_smb(cli);
1092 if (!cli_receive_smb(cli))
1093 return False;
1095 if (cli_is_error(cli)) {
1096 return False;
1099 cli->vuid = -1;
1100 return True;
1103 /****************************************************************************
1104 Send a tconX.
1105 ****************************************************************************/
1107 bool cli_send_tconX(struct cli_state *cli,
1108 const char *share, const char *dev, const char *pass, int passlen)
1110 fstring fullshare, pword;
1111 char *p;
1112 memset(cli->outbuf,'\0',smb_size);
1113 memset(cli->inbuf,'\0',smb_size);
1115 fstrcpy(cli->share, share);
1117 /* in user level security don't send a password now */
1118 if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
1119 passlen = 1;
1120 pass = "";
1121 } else if (!pass) {
1122 DEBUG(1, ("Server not using user level security and no password supplied.\n"));
1123 return False;
1126 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
1127 *pass && passlen != 24) {
1128 if (!lp_client_lanman_auth()) {
1129 DEBUG(1, ("Server requested LANMAN password "
1130 "(share-level security) but "
1131 "'client lanman auth' is disabled\n"));
1132 return False;
1136 * Non-encrypted passwords - convert to DOS codepage before encryption.
1138 passlen = 24;
1139 SMBencrypt(pass,cli->secblob.data,(uchar *)pword);
1140 } else {
1141 if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL|NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) {
1142 if (!lp_client_plaintext_auth() && (*pass)) {
1143 DEBUG(1, ("Server requested plaintext "
1144 "password but 'client plaintext "
1145 "auth' is disabled\n"));
1146 return False;
1150 * Non-encrypted passwords - convert to DOS codepage before using.
1152 passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
1154 } else {
1155 if (passlen) {
1156 memcpy(pword, pass, passlen);
1161 slprintf(fullshare, sizeof(fullshare)-1,
1162 "\\\\%s\\%s", cli->desthost, share);
1164 cli_set_message(cli->outbuf,4, 0, True);
1165 SCVAL(cli->outbuf,smb_com,SMBtconX);
1166 cli_setup_packet(cli);
1168 SSVAL(cli->outbuf,smb_vwv0,0xFF);
1169 SSVAL(cli->outbuf,smb_vwv2,TCONX_FLAG_EXTENDED_RESPONSE);
1170 SSVAL(cli->outbuf,smb_vwv3,passlen);
1172 p = smb_buf(cli->outbuf);
1173 if (passlen) {
1174 memcpy(p,pword,passlen);
1176 p += passlen;
1177 p += clistr_push(cli, p, fullshare, -1, STR_TERMINATE |STR_UPPER);
1178 p += clistr_push(cli, p, dev, -1, STR_TERMINATE |STR_UPPER | STR_ASCII);
1180 cli_setup_bcc(cli, p);
1182 cli_send_smb(cli);
1183 if (!cli_receive_smb(cli))
1184 return False;
1186 if (cli_is_error(cli))
1187 return False;
1189 clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE|STR_ASCII);
1191 if (cli->protocol >= PROTOCOL_NT1 &&
1192 smb_buflen(cli->inbuf) == 3) {
1193 /* almost certainly win95 - enable bug fixes */
1194 cli->win95 = True;
1197 /* Make sure that we have the optional support 16-bit field. WCT > 2 */
1198 /* Avoids issues when connecting to Win9x boxes sharing files */
1200 cli->dfsroot = False;
1201 if ( (CVAL(cli->inbuf, smb_wct))>2 && cli->protocol >= PROTOCOL_LANMAN2 )
1202 cli->dfsroot = (SVAL( cli->inbuf, smb_vwv2 ) & SMB_SHARE_IN_DFS) ? True : False;
1204 cli->cnum = SVAL(cli->inbuf,smb_tid);
1205 return True;
1208 /****************************************************************************
1209 Send a tree disconnect.
1210 ****************************************************************************/
1212 bool cli_tdis(struct cli_state *cli)
1214 memset(cli->outbuf,'\0',smb_size);
1215 cli_set_message(cli->outbuf,0,0,True);
1216 SCVAL(cli->outbuf,smb_com,SMBtdis);
1217 SSVAL(cli->outbuf,smb_tid,cli->cnum);
1218 cli_setup_packet(cli);
1220 cli_send_smb(cli);
1221 if (!cli_receive_smb(cli))
1222 return False;
1224 if (cli_is_error(cli)) {
1225 return False;
1228 cli->cnum = -1;
1229 return True;
1232 /****************************************************************************
1233 Send a negprot command.
1234 ****************************************************************************/
1236 void cli_negprot_send(struct cli_state *cli)
1238 char *p;
1239 int numprots;
1241 if (cli->protocol < PROTOCOL_NT1)
1242 cli->use_spnego = False;
1244 memset(cli->outbuf,'\0',smb_size);
1246 /* setup the protocol strings */
1247 cli_set_message(cli->outbuf,0,0,True);
1249 p = smb_buf(cli->outbuf);
1250 for (numprots=0;
1251 prots[numprots].name && prots[numprots].prot<=cli->protocol;
1252 numprots++) {
1253 *p++ = 2;
1254 p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE);
1257 SCVAL(cli->outbuf,smb_com,SMBnegprot);
1258 cli_setup_bcc(cli, p);
1259 cli_setup_packet(cli);
1261 SCVAL(smb_buf(cli->outbuf),0,2);
1263 cli_send_smb(cli);
1266 /****************************************************************************
1267 Send a negprot command.
1268 ****************************************************************************/
1270 bool cli_negprot(struct cli_state *cli)
1272 char *p;
1273 int numprots;
1274 int plength;
1276 if (cli->protocol < PROTOCOL_NT1)
1277 cli->use_spnego = False;
1279 memset(cli->outbuf,'\0',smb_size);
1281 /* setup the protocol strings */
1282 for (plength=0,numprots=0;
1283 prots[numprots].name && prots[numprots].prot<=cli->protocol;
1284 numprots++)
1285 plength += strlen(prots[numprots].name)+2;
1287 cli_set_message(cli->outbuf,0,plength,True);
1289 p = smb_buf(cli->outbuf);
1290 for (numprots=0;
1291 prots[numprots].name && prots[numprots].prot<=cli->protocol;
1292 numprots++) {
1293 *p++ = 2;
1294 p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE);
1297 SCVAL(cli->outbuf,smb_com,SMBnegprot);
1298 cli_setup_packet(cli);
1300 SCVAL(smb_buf(cli->outbuf),0,2);
1302 cli_send_smb(cli);
1303 if (!cli_receive_smb(cli))
1304 return False;
1306 show_msg(cli->inbuf);
1308 if (cli_is_error(cli) ||
1309 ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) {
1310 return(False);
1313 cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot;
1315 if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) {
1316 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
1317 return False;
1320 if (cli->protocol >= PROTOCOL_NT1) {
1321 struct timespec ts;
1322 /* NT protocol */
1323 cli->sec_mode = CVAL(cli->inbuf,smb_vwv1);
1324 cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1);
1325 cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1);
1326 cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1);
1327 cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1);
1328 cli->serverzone *= 60;
1329 /* this time arrives in real GMT */
1330 ts = interpret_long_date(cli->inbuf+smb_vwv11+1);
1331 cli->servertime = ts.tv_sec;
1332 cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf));
1333 cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1);
1334 if (cli->capabilities & CAP_RAW_MODE) {
1335 cli->readbraw_supported = True;
1336 cli->writebraw_supported = True;
1338 /* work out if they sent us a workgroup */
1339 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
1340 smb_buflen(cli->inbuf) > 8) {
1341 clistr_pull(cli, cli->server_domain,
1342 smb_buf(cli->inbuf)+8, sizeof(cli->server_domain),
1343 smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN);
1347 * As signing is slow we only turn it on if either the client or
1348 * the server require it. JRA.
1351 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
1352 /* Fail if server says signing is mandatory and we don't want to support it. */
1353 if (!cli->sign_info.allow_smb_signing) {
1354 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
1355 return False;
1357 cli->sign_info.negotiated_smb_signing = True;
1358 cli->sign_info.mandatory_signing = True;
1359 } else if (cli->sign_info.mandatory_signing && cli->sign_info.allow_smb_signing) {
1360 /* Fail if client says signing is mandatory and the server doesn't support it. */
1361 if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
1362 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
1363 return False;
1365 cli->sign_info.negotiated_smb_signing = True;
1366 cli->sign_info.mandatory_signing = True;
1367 } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
1368 cli->sign_info.negotiated_smb_signing = True;
1371 if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
1372 SAFE_FREE(cli->outbuf);
1373 SAFE_FREE(cli->inbuf);
1374 cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1375 cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1376 cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE;
1379 } else if (cli->protocol >= PROTOCOL_LANMAN1) {
1380 cli->use_spnego = False;
1381 cli->sec_mode = SVAL(cli->inbuf,smb_vwv1);
1382 cli->max_xmit = SVAL(cli->inbuf,smb_vwv2);
1383 cli->max_mux = SVAL(cli->inbuf, smb_vwv3);
1384 cli->sesskey = IVAL(cli->inbuf,smb_vwv6);
1385 cli->serverzone = SVALS(cli->inbuf,smb_vwv10);
1386 cli->serverzone *= 60;
1387 /* this time is converted to GMT by make_unix_date */
1388 cli->servertime = cli_make_unix_date(cli,cli->inbuf+smb_vwv8);
1389 cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0);
1390 cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0);
1391 cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf));
1392 } else {
1393 /* the old core protocol */
1394 cli->use_spnego = False;
1395 cli->sec_mode = 0;
1396 cli->serverzone = get_time_zone(time(NULL));
1399 cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
1401 /* a way to force ascii SMB */
1402 if (getenv("CLI_FORCE_ASCII"))
1403 cli->capabilities &= ~CAP_UNICODE;
1405 return True;
1408 /****************************************************************************
1409 Send a session request. See rfc1002.txt 4.3 and 4.3.2.
1410 ****************************************************************************/
1412 bool cli_session_request(struct cli_state *cli,
1413 struct nmb_name *calling, struct nmb_name *called)
1415 char *p;
1416 int len = 4;
1418 memcpy(&(cli->calling), calling, sizeof(*calling));
1419 memcpy(&(cli->called ), called , sizeof(*called ));
1421 /* put in the destination name */
1422 p = cli->outbuf+len;
1423 name_mangle(cli->called .name, p, cli->called .name_type);
1424 len += name_len(p);
1426 /* and my name */
1427 p = cli->outbuf+len;
1428 name_mangle(cli->calling.name, p, cli->calling.name_type);
1429 len += name_len(p);
1431 /* 445 doesn't have session request */
1432 if (cli->port == 445)
1433 return True;
1435 /* send a session request (RFC 1002) */
1436 /* setup the packet length
1437 * Remove four bytes from the length count, since the length
1438 * field in the NBT Session Service header counts the number
1439 * of bytes which follow. The cli_send_smb() function knows
1440 * about this and accounts for those four bytes.
1441 * CRH.
1443 len -= 4;
1444 _smb_setlen(cli->outbuf,len);
1445 SCVAL(cli->outbuf,0,0x81);
1447 cli_send_smb(cli);
1448 DEBUG(5,("Sent session request\n"));
1450 if (!cli_receive_smb(cli))
1451 return False;
1453 if (CVAL(cli->inbuf,0) == 0x84) {
1454 /* C. Hoch 9/14/95 Start */
1455 /* For information, here is the response structure.
1456 * We do the byte-twiddling to for portability.
1457 struct RetargetResponse{
1458 unsigned char type;
1459 unsigned char flags;
1460 int16 length;
1461 int32 ip_addr;
1462 int16 port;
1465 uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
1466 struct in_addr dest_ip;
1468 /* SESSION RETARGET */
1469 putip((char *)&dest_ip,cli->inbuf+4);
1470 in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
1472 cli->fd = open_socket_out(SOCK_STREAM,
1473 &cli->dest_ss,
1474 port,
1475 LONG_CONNECT_TIMEOUT);
1476 if (cli->fd == -1)
1477 return False;
1479 DEBUG(3,("Retargeted\n"));
1481 set_socket_options(cli->fd, lp_socket_options());
1483 /* Try again */
1485 static int depth;
1486 bool ret;
1487 if (depth > 4) {
1488 DEBUG(0,("Retarget recursion - failing\n"));
1489 return False;
1491 depth++;
1492 ret = cli_session_request(cli, calling, called);
1493 depth--;
1494 return ret;
1496 } /* C. Hoch 9/14/95 End */
1498 if (CVAL(cli->inbuf,0) != 0x82) {
1499 /* This is the wrong place to put the error... JRA. */
1500 cli->rap_error = CVAL(cli->inbuf,4);
1501 return False;
1503 return(True);
1506 /****************************************************************************
1507 Open the client sockets.
1508 ****************************************************************************/
1510 NTSTATUS cli_connect(struct cli_state *cli,
1511 const char *host,
1512 struct sockaddr_storage *dest_ss)
1515 int name_type = 0x20;
1516 TALLOC_CTX *frame = talloc_stackframe();
1517 unsigned int num_addrs = 0;
1518 unsigned int i = 0;
1519 struct sockaddr_storage *ss_arr = NULL;
1520 char *p = NULL;
1522 /* reasonable default hostname */
1523 if (!host) {
1524 host = star_smbserver_name;
1527 fstrcpy(cli->desthost, host);
1528 fstr_sprintf(cli->srv_name_slash, "\\\\%s", cli->desthost);
1529 strupper_m(cli->srv_name_slash);
1531 /* allow hostnames of the form NAME#xx and do a netbios lookup */
1532 if ((p = strchr(cli->desthost, '#'))) {
1533 name_type = strtol(p+1, NULL, 16);
1534 *p = 0;
1537 if (!dest_ss || is_zero_addr(dest_ss)) {
1538 NTSTATUS status =resolve_name_list(frame,
1539 cli->desthost,
1540 name_type,
1541 &ss_arr,
1542 &num_addrs);
1543 if (!NT_STATUS_IS_OK(status)) {
1544 TALLOC_FREE(frame);
1545 return NT_STATUS_BAD_NETWORK_NAME;
1547 } else {
1548 num_addrs = 1;
1549 ss_arr = TALLOC_P(frame, struct sockaddr_storage);
1550 if (!ss_arr) {
1551 TALLOC_FREE(frame);
1552 return NT_STATUS_NO_MEMORY;
1554 *ss_arr = *dest_ss;
1557 for (i = 0; i < num_addrs; i++) {
1558 cli->dest_ss = ss_arr[i];
1559 if (getenv("LIBSMB_PROG")) {
1560 cli->fd = sock_exec(getenv("LIBSMB_PROG"));
1561 } else {
1562 /* try 445 first, then 139 */
1563 uint16_t port = cli->port?cli->port:445;
1564 cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
1565 port, cli->timeout);
1566 if (cli->fd == -1 && cli->port == 0) {
1567 port = 139;
1568 cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
1569 port, cli->timeout);
1571 if (cli->fd != -1) {
1572 cli->port = port;
1575 if (cli->fd == -1) {
1576 char addr[INET6_ADDRSTRLEN];
1577 print_sockaddr(addr, sizeof(addr), &ss_arr[i]);
1578 DEBUG(2,("Error connecting to %s (%s)\n",
1579 dest_ss?addr:host,strerror(errno)));
1580 } else {
1581 /* Exit from loop on first connection. */
1582 break;
1586 if (cli->fd == -1) {
1587 TALLOC_FREE(frame);
1588 return map_nt_error_from_unix(errno);
1591 if (dest_ss) {
1592 *dest_ss = cli->dest_ss;
1595 set_socket_options(cli->fd, lp_socket_options());
1597 TALLOC_FREE(frame);
1598 return NT_STATUS_OK;
1602 establishes a connection to after the negprot.
1603 @param output_cli A fully initialised cli structure, non-null only on success
1604 @param dest_host The netbios name of the remote host
1605 @param dest_ss (optional) The the destination IP, NULL for name based lookup
1606 @param port (optional) The destination port (0 for default)
1607 @param retry bool. Did this connection fail with a retryable error ?
1610 NTSTATUS cli_start_connection(struct cli_state **output_cli,
1611 const char *my_name,
1612 const char *dest_host,
1613 struct sockaddr_storage *dest_ss, int port,
1614 int signing_state, int flags,
1615 bool *retry)
1617 NTSTATUS nt_status;
1618 struct nmb_name calling;
1619 struct nmb_name called;
1620 struct cli_state *cli;
1621 struct sockaddr_storage ss;
1623 if (retry)
1624 *retry = False;
1626 if (!my_name)
1627 my_name = global_myname();
1629 if (!(cli = cli_initialise())) {
1630 return NT_STATUS_NO_MEMORY;
1633 make_nmb_name(&calling, my_name, 0x0);
1634 make_nmb_name(&called , dest_host, 0x20);
1636 if (cli_set_port(cli, port) != port) {
1637 cli_shutdown(cli);
1638 return NT_STATUS_UNSUCCESSFUL;
1641 cli_set_timeout(cli, 10000); /* 10 seconds. */
1643 if (dest_ss) {
1644 ss = *dest_ss;
1645 } else {
1646 zero_sockaddr(&ss);
1649 again:
1651 DEBUG(3,("Connecting to host=%s\n", dest_host));
1653 nt_status = cli_connect(cli, dest_host, &ss);
1654 if (!NT_STATUS_IS_OK(nt_status)) {
1655 char addr[INET6_ADDRSTRLEN];
1656 print_sockaddr(addr, sizeof(addr), &ss);
1657 DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
1658 nmb_namestr(&called), addr, nt_errstr(nt_status) ));
1659 cli_shutdown(cli);
1660 return nt_status;
1663 if (retry)
1664 *retry = True;
1666 if (!cli_session_request(cli, &calling, &called)) {
1667 char *p;
1668 DEBUG(1,("session request to %s failed (%s)\n",
1669 called.name, cli_errstr(cli)));
1670 if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
1671 *p = 0;
1672 goto again;
1674 if (strcmp(called.name, star_smbserver_name)) {
1675 make_nmb_name(&called , star_smbserver_name, 0x20);
1676 goto again;
1678 return NT_STATUS_BAD_NETWORK_NAME;
1681 cli_setup_signing_state(cli, signing_state);
1683 if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
1684 cli->use_spnego = False;
1685 else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
1686 cli->use_kerberos = True;
1688 if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) &&
1689 cli->use_kerberos) {
1690 cli->fallback_after_kerberos = true;
1693 if (!cli_negprot(cli)) {
1694 DEBUG(1,("failed negprot\n"));
1695 nt_status = cli_nt_error(cli);
1696 if (NT_STATUS_IS_OK(nt_status)) {
1697 nt_status = NT_STATUS_UNSUCCESSFUL;
1699 cli_shutdown(cli);
1700 return nt_status;
1703 *output_cli = cli;
1704 return NT_STATUS_OK;
1709 establishes a connection right up to doing tconX, password specified.
1710 @param output_cli A fully initialised cli structure, non-null only on success
1711 @param dest_host The netbios name of the remote host
1712 @param dest_ip (optional) The the destination IP, NULL for name based lookup
1713 @param port (optional) The destination port (0 for default)
1714 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
1715 @param service_type The 'type' of serivice.
1716 @param user Username, unix string
1717 @param domain User's domain
1718 @param password User's password, unencrypted unix string.
1719 @param retry bool. Did this connection fail with a retryable error ?
1722 NTSTATUS cli_full_connection(struct cli_state **output_cli,
1723 const char *my_name,
1724 const char *dest_host,
1725 struct sockaddr_storage *dest_ss, int port,
1726 const char *service, const char *service_type,
1727 const char *user, const char *domain,
1728 const char *password, int flags,
1729 int signing_state,
1730 bool *retry)
1732 NTSTATUS nt_status;
1733 struct cli_state *cli = NULL;
1734 int pw_len = password ? strlen(password)+1 : 0;
1736 *output_cli = NULL;
1738 if (password == NULL) {
1739 password = "";
1742 nt_status = cli_start_connection(&cli, my_name, dest_host,
1743 dest_ss, port, signing_state,
1744 flags, retry);
1746 if (!NT_STATUS_IS_OK(nt_status)) {
1747 return nt_status;
1750 nt_status = cli_session_setup(cli, user, password, pw_len, password,
1751 pw_len, domain);
1752 if (!NT_STATUS_IS_OK(nt_status)) {
1754 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
1755 DEBUG(1,("failed session setup with %s\n",
1756 nt_errstr(nt_status)));
1757 cli_shutdown(cli);
1758 return nt_status;
1761 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
1762 if (!NT_STATUS_IS_OK(nt_status)) {
1763 DEBUG(1,("anonymous failed session setup with %s\n",
1764 nt_errstr(nt_status)));
1765 cli_shutdown(cli);
1766 return nt_status;
1770 if (service) {
1771 if (!cli_send_tconX(cli, service, service_type, password, pw_len)) {
1772 nt_status = cli_nt_error(cli);
1773 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
1774 cli_shutdown(cli);
1775 if (NT_STATUS_IS_OK(nt_status)) {
1776 nt_status = NT_STATUS_UNSUCCESSFUL;
1778 return nt_status;
1782 cli_init_creds(cli, user, domain, password);
1784 *output_cli = cli;
1785 return NT_STATUS_OK;
1788 /****************************************************************************
1789 Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
1790 ****************************************************************************/
1792 bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
1793 struct sockaddr_storage *pdest_ss)
1795 struct nmb_name calling, called;
1797 make_nmb_name(&calling, srchost, 0x0);
1800 * If the called name is an IP address
1801 * then use *SMBSERVER immediately.
1804 if(is_ipaddress(desthost)) {
1805 make_nmb_name(&called, star_smbserver_name, 0x20);
1806 } else {
1807 make_nmb_name(&called, desthost, 0x20);
1810 if (!cli_session_request(*ppcli, &calling, &called)) {
1811 NTSTATUS status;
1812 struct nmb_name smbservername;
1814 make_nmb_name(&smbservername, star_smbserver_name, 0x20);
1817 * If the name wasn't *SMBSERVER then
1818 * try with *SMBSERVER if the first name fails.
1821 if (nmb_name_equal(&called, &smbservername)) {
1824 * The name used was *SMBSERVER, don't bother with another name.
1827 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
1828 with error %s.\n", desthost, cli_errstr(*ppcli) ));
1829 return False;
1832 /* Try again... */
1833 cli_shutdown(*ppcli);
1835 *ppcli = cli_initialise();
1836 if (!*ppcli) {
1837 /* Out of memory... */
1838 return False;
1841 status = cli_connect(*ppcli, desthost, pdest_ss);
1842 if (!NT_STATUS_IS_OK(status) ||
1843 !cli_session_request(*ppcli, &calling, &smbservername)) {
1844 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
1845 name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
1846 return False;
1850 return True;
1853 /****************************************************************************
1854 Send an old style tcon.
1855 ****************************************************************************/
1856 NTSTATUS cli_raw_tcon(struct cli_state *cli,
1857 const char *service, const char *pass, const char *dev,
1858 uint16 *max_xmit, uint16 *tid)
1860 char *p;
1862 if (!lp_client_plaintext_auth() && (*pass)) {
1863 DEBUG(1, ("Server requested plaintext password but 'client "
1864 "plaintext auth' is disabled\n"));
1865 return NT_STATUS_ACCESS_DENIED;
1868 memset(cli->outbuf,'\0',smb_size);
1869 memset(cli->inbuf,'\0',smb_size);
1871 cli_set_message(cli->outbuf, 0, 0, True);
1872 SCVAL(cli->outbuf,smb_com,SMBtcon);
1873 cli_setup_packet(cli);
1875 p = smb_buf(cli->outbuf);
1876 *p++ = 4; p += clistr_push(cli, p, service, -1, STR_TERMINATE | STR_NOALIGN);
1877 *p++ = 4; p += clistr_push(cli, p, pass, -1, STR_TERMINATE | STR_NOALIGN);
1878 *p++ = 4; p += clistr_push(cli, p, dev, -1, STR_TERMINATE | STR_NOALIGN);
1880 cli_setup_bcc(cli, p);
1882 cli_send_smb(cli);
1883 if (!cli_receive_smb(cli)) {
1884 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
1887 if (cli_is_error(cli)) {
1888 return cli_nt_error(cli);
1891 *max_xmit = SVAL(cli->inbuf, smb_vwv0);
1892 *tid = SVAL(cli->inbuf, smb_vwv1);
1894 return NT_STATUS_OK;
1897 /* Return a cli_state pointing at the IPC$ share for the given server */
1899 struct cli_state *get_ipc_connect(char *server,
1900 struct sockaddr_storage *server_ss,
1901 const struct user_auth_info *user_info)
1903 struct cli_state *cli;
1904 NTSTATUS nt_status;
1905 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
1907 if (user_info->use_kerberos) {
1908 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
1911 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
1912 user_info->username ? user_info->username : "",
1913 lp_workgroup(),
1914 user_info->password ? user_info->password : "",
1915 flags,
1916 Undefined, NULL);
1918 if (NT_STATUS_IS_OK(nt_status)) {
1919 return cli;
1920 } else if (is_ipaddress(server)) {
1921 /* windows 9* needs a correct NMB name for connections */
1922 fstring remote_name;
1924 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
1925 cli = get_ipc_connect(remote_name, server_ss, user_info);
1926 if (cli)
1927 return cli;
1930 return NULL;
1934 * Given the IP address of a master browser on the network, return its
1935 * workgroup and connect to it.
1937 * This function is provided to allow additional processing beyond what
1938 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
1939 * browsers and obtain each master browsers' list of domains (in case the
1940 * first master browser is recently on the network and has not yet
1941 * synchronized with other master browsers and therefore does not yet have the
1942 * entire network browse list)
1945 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
1946 struct ip_service *mb_ip,
1947 const struct user_auth_info *user_info,
1948 char **pp_workgroup_out)
1950 char addr[INET6_ADDRSTRLEN];
1951 fstring name;
1952 struct cli_state *cli;
1953 struct sockaddr_storage server_ss;
1955 *pp_workgroup_out = NULL;
1957 print_sockaddr(addr, sizeof(addr), &mb_ip->ss);
1958 DEBUG(99, ("Looking up name of master browser %s\n",
1959 addr));
1962 * Do a name status query to find out the name of the master browser.
1963 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
1964 * master browser will not respond to a wildcard query (or, at least,
1965 * an NT4 server acting as the domain master browser will not).
1967 * We might be able to use ONLY the query on MSBROWSE, but that's not
1968 * yet been tested with all Windows versions, so until it is, leave
1969 * the original wildcard query as the first choice and fall back to
1970 * MSBROWSE if the wildcard query fails.
1972 if (!name_status_find("*", 0, 0x1d, &mb_ip->ss, name) &&
1973 !name_status_find(MSBROWSE, 1, 0x1d, &mb_ip->ss, name)) {
1975 DEBUG(99, ("Could not retrieve name status for %s\n",
1976 addr));
1977 return NULL;
1980 if (!find_master_ip(name, &server_ss)) {
1981 DEBUG(99, ("Could not find master ip for %s\n", name));
1982 return NULL;
1985 *pp_workgroup_out = talloc_strdup(ctx, name);
1987 DEBUG(4, ("found master browser %s, %s\n", name, addr));
1989 print_sockaddr(addr, sizeof(addr), &server_ss);
1990 cli = get_ipc_connect(addr, &server_ss, user_info);
1992 return cli;
1996 * Return the IP address and workgroup of a master browser on the network, and
1997 * connect to it.
2000 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
2001 const struct user_auth_info *user_info,
2002 char **pp_workgroup_out)
2004 struct ip_service *ip_list;
2005 struct cli_state *cli;
2006 int i, count;
2008 *pp_workgroup_out = NULL;
2010 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
2012 /* Go looking for workgroups by broadcasting on the local network */
2014 if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
2015 &count))) {
2016 DEBUG(99, ("No master browsers responded\n"));
2017 return False;
2020 for (i = 0; i < count; i++) {
2021 char addr[INET6_ADDRSTRLEN];
2022 print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
2023 DEBUG(99, ("Found master browser %s\n", addr));
2025 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
2026 user_info, pp_workgroup_out);
2027 if (cli)
2028 return(cli);
2031 return NULL;