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
6    Copyright (C) Volker Lendecke 2011
7    Copyright (C) Jeremy Allison 2011
8 
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22 
23 #include "includes.h"
24 #include "libsmb/libsmb.h"
25 #include "libsmb/namequery.h"
26 #include "auth_info.h"
27 #include "../libcli/auth/libcli_auth.h"
28 #include "../libcli/auth/spnego.h"
29 #include "smb_krb5.h"
30 #include "auth/credentials/credentials.h"
31 #include "auth/gensec/gensec.h"
32 #include "auth/ntlmssp/ntlmssp.h"
33 #include "auth_generic.h"
34 #include "libads/kerberos_proto.h"
35 #include "krb5_env.h"
36 #include "../lib/util/tevent_ntstatus.h"
37 #include "async_smb.h"
38 #include "libsmb/nmblib.h"
39 #include "librpc/ndr/libndr.h"
40 #include "../libcli/smb/smbXcli_base.h"
41 #include "../libcli/smb/smb_seal.h"
42 #include "lib/param/param.h"
43 #include "../libcli/smb/smb2_negotiate_context.h"
44 #include "libads/krb5_errs.h"
45 
46 #define STAR_SMBSERVER "*SMBSERVER"
47 
48 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
49 					   const char *principal);
50 
cli_session_creds_init(TALLOC_CTX * mem_ctx,const char * username,const char * domain,const char * realm,const char * password,bool use_kerberos,bool fallback_after_kerberos,bool use_ccache,bool password_is_nt_hash)51 struct cli_credentials *cli_session_creds_init(TALLOC_CTX *mem_ctx,
52 					       const char *username,
53 					       const char *domain,
54 					       const char *realm,
55 					       const char *password,
56 					       bool use_kerberos,
57 					       bool fallback_after_kerberos,
58 					       bool use_ccache,
59 					       bool password_is_nt_hash)
60 {
61 	struct loadparm_context *lp_ctx = NULL;
62 	struct cli_credentials *creds = NULL;
63 	const char *principal = NULL;
64 	char *tmp = NULL;
65 	char *p = NULL;
66 	bool ok;
67 
68 	creds = cli_credentials_init(mem_ctx);
69 	if (creds == NULL) {
70 		return NULL;
71 	}
72 
73 	lp_ctx = loadparm_init_s3(creds, loadparm_s3_helpers());
74 	if (lp_ctx == NULL) {
75 		goto fail;
76 	}
77 	cli_credentials_set_conf(creds, lp_ctx);
78 
79 	if (username == NULL) {
80 		username = "";
81 	}
82 
83 	if (strlen(username) == 0) {
84 		if (password != NULL && strlen(password) == 0) {
85 			/*
86 			 * some callers pass "" as no password
87 			 *
88 			 * gensec only handles NULL as no password.
89 			 */
90 			password = NULL;
91 		}
92 		if (password == NULL) {
93 			cli_credentials_set_anonymous(creds);
94 			return creds;
95 		}
96 	}
97 
98 	tmp = talloc_strdup(creds, username);
99 	if (tmp == NULL) {
100 		goto fail;
101 	}
102 	username = tmp;
103 
104 	/* allow for workgroups as part of the username */
105 	if ((p = strchr_m(tmp, '\\')) ||
106 	    (p = strchr_m(tmp, '/')) ||
107 	    (p = strchr_m(tmp, *lp_winbind_separator()))) {
108 		*p = 0;
109 		username = p + 1;
110 		domain = tmp;
111 	}
112 
113 	principal = username;
114 	username = cli_session_setup_get_account(creds, principal);
115 	if (username == NULL) {
116 		goto fail;
117 	}
118 	ok = strequal(username, principal);
119 	if (ok) {
120 		/*
121 		 * Ok still the same, so it's not a principal
122 		 */
123 		principal = NULL;
124 	}
125 
126 	if (use_kerberos && fallback_after_kerberos) {
127 		cli_credentials_set_kerberos_state(creds,
128 						   CRED_AUTO_USE_KERBEROS);
129 	} else if (use_kerberos) {
130 		cli_credentials_set_kerberos_state(creds,
131 						   CRED_MUST_USE_KERBEROS);
132 	} else {
133 		cli_credentials_set_kerberos_state(creds,
134 						   CRED_DONT_USE_KERBEROS);
135 	}
136 
137 	if (use_ccache) {
138 		uint32_t features;
139 
140 		features = cli_credentials_get_gensec_features(creds);
141 		features |= GENSEC_FEATURE_NTLM_CCACHE;
142 		cli_credentials_set_gensec_features(creds, features);
143 
144 		if (password != NULL && strlen(password) == 0) {
145 			/*
146 			 * some callers pass "" as no password
147 			 *
148 			 * GENSEC_FEATURE_NTLM_CCACHE only handles
149 			 * NULL as no password.
150 			 */
151 			password = NULL;
152 		}
153 	}
154 
155 	ok = cli_credentials_set_username(creds,
156 					  username,
157 					  CRED_SPECIFIED);
158 	if (!ok) {
159 		goto fail;
160 	}
161 
162 	if (domain != NULL) {
163 		ok = cli_credentials_set_domain(creds,
164 						domain,
165 						CRED_SPECIFIED);
166 		if (!ok) {
167 			goto fail;
168 		}
169 	}
170 
171 	if (principal != NULL) {
172 		ok = cli_credentials_set_principal(creds,
173 						   principal,
174 						   CRED_SPECIFIED);
175 		if (!ok) {
176 			goto fail;
177 		}
178 	}
179 
180 	if (realm != NULL) {
181 		ok = cli_credentials_set_realm(creds,
182 					       realm,
183 					       CRED_SPECIFIED);
184 		if (!ok) {
185 			goto fail;
186 		}
187 	}
188 
189 	if (password != NULL && strlen(password) > 0) {
190 		if (password_is_nt_hash) {
191 			struct samr_Password nt_hash;
192 			size_t converted;
193 
194 			converted = strhex_to_str((char *)nt_hash.hash,
195 						  sizeof(nt_hash.hash),
196 						  password,
197 						  strlen(password));
198 			if (converted != sizeof(nt_hash.hash)) {
199 				goto fail;
200 			}
201 
202 			ok = cli_credentials_set_nt_hash(creds,
203 							 &nt_hash,
204 							 CRED_SPECIFIED);
205 			if (!ok) {
206 				goto fail;
207 			}
208 		} else {
209 			ok = cli_credentials_set_password(creds,
210 							  password,
211 							  CRED_SPECIFIED);
212 			if (!ok) {
213 				goto fail;
214 			}
215 		}
216 	}
217 
218 	return creds;
219 fail:
220 	TALLOC_FREE(creds);
221 	return NULL;
222 }
223 
cli_session_creds_prepare_krb5(struct cli_state * cli,struct cli_credentials * creds)224 NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli,
225 					struct cli_credentials *creds)
226 {
227 	TALLOC_CTX *frame = talloc_stackframe();
228 	const char *user_principal = NULL;
229 	const char *user_account = NULL;
230 	const char *user_domain = NULL;
231 	const char *pass = NULL;
232 	char *canon_principal = NULL;
233 	char *canon_realm = NULL;
234 	const char *target_hostname = NULL;
235 	enum credentials_use_kerberos krb5_state;
236 	bool try_kerberos = false;
237 	bool need_kinit = false;
238 	bool auth_requested = true;
239 	int ret;
240 	bool ok;
241 
242 	target_hostname = smbXcli_conn_remote_name(cli->conn);
243 
244 	auth_requested = cli_credentials_authentication_requested(creds);
245 	if (auth_requested) {
246 		errno = 0;
247 		user_principal = cli_credentials_get_principal(creds, frame);
248 		if (errno != 0) {
249 			TALLOC_FREE(frame);
250 			return NT_STATUS_NO_MEMORY;
251 		}
252 	}
253 	user_account = cli_credentials_get_username(creds);
254 	user_domain = cli_credentials_get_domain(creds);
255 	pass = cli_credentials_get_password(creds);
256 
257 	krb5_state = cli_credentials_get_kerberos_state(creds);
258 
259 	if (krb5_state != CRED_DONT_USE_KERBEROS) {
260 		try_kerberos = true;
261 	}
262 
263 	if (user_principal == NULL) {
264 		try_kerberos = false;
265 	}
266 
267 	if (target_hostname == NULL) {
268 		try_kerberos = false;
269 	} else if (is_ipaddress(target_hostname)) {
270 		try_kerberos = false;
271 	} else if (strequal(target_hostname, "localhost")) {
272 		try_kerberos = false;
273 	} else if (strequal(target_hostname, STAR_SMBSERVER)) {
274 		try_kerberos = false;
275 	} else if (!auth_requested) {
276 		try_kerberos = false;
277 	}
278 
279 	if (krb5_state == CRED_MUST_USE_KERBEROS && !try_kerberos) {
280 		DEBUG(0, ("Kerberos auth with '%s' (%s\\%s) to access "
281 			  "'%s' not possible\n",
282 			  user_principal, user_domain, user_account,
283 			  target_hostname));
284 		TALLOC_FREE(frame);
285 		return NT_STATUS_ACCESS_DENIED;
286 	}
287 
288 	if (pass == NULL || strlen(pass) == 0) {
289 		need_kinit = false;
290 	} else if (krb5_state == CRED_MUST_USE_KERBEROS) {
291 		need_kinit = try_kerberos;
292 	} else {
293 		need_kinit = try_kerberos;
294 	}
295 
296 	if (!need_kinit) {
297 		TALLOC_FREE(frame);
298 		return NT_STATUS_OK;
299 	}
300 
301 	DBG_INFO("Doing kinit for %s to access %s\n",
302 		 user_principal, target_hostname);
303 
304 	/*
305 	 * TODO: This should be done within the gensec layer
306 	 * only if required!
307 	 */
308 	setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
309 	ret = kerberos_kinit_password_ext(user_principal,
310 					  pass,
311 					  0,
312 					  0,
313 					  0,
314 					  NULL,
315 					  false,
316 					  false,
317 					  0,
318 					  frame,
319 					  &canon_principal,
320 					  &canon_realm,
321 					  NULL);
322 	if (ret != 0) {
323 		int dbglvl = DBGLVL_NOTICE;
324 
325 		if (krb5_state == CRED_MUST_USE_KERBEROS) {
326 			dbglvl = DBGLVL_ERR;
327 		}
328 
329 		DEBUG(dbglvl, ("Kinit for %s to access %s failed: %s\n",
330 			       user_principal, target_hostname,
331 			       error_message(ret)));
332 		if (krb5_state == CRED_MUST_USE_KERBEROS) {
333 			TALLOC_FREE(frame);
334 			return krb5_to_nt_status(ret);
335 		}
336 
337 		/*
338 		 * Ignore the error and hope that NTLM will work
339 		 */
340 		TALLOC_FREE(frame);
341 		return NT_STATUS_OK;
342 	}
343 
344 	ok = cli_credentials_set_principal(creds,
345 					   canon_principal,
346 					   CRED_SPECIFIED);
347 	if (!ok) {
348 		TALLOC_FREE(frame);
349 		return NT_STATUS_NO_MEMORY;
350 	}
351 
352 	ok = cli_credentials_set_realm(creds,
353 				       canon_realm,
354 				       CRED_SPECIFIED);
355 	if (!ok) {
356 		TALLOC_FREE(frame);
357 		return NT_STATUS_NO_MEMORY;
358 	}
359 
360 	DBG_DEBUG("Successfully authenticated as %s (%s) to access %s using "
361 		  "Kerberos\n",
362 		  user_principal,
363 		  canon_principal,
364 		  target_hostname);
365 
366 	TALLOC_FREE(frame);
367 	return NT_STATUS_OK;
368 }
369 
cli_state_update_after_sesssetup(struct cli_state * cli,const char * native_os,const char * native_lm,const char * primary_domain)370 static NTSTATUS cli_state_update_after_sesssetup(struct cli_state *cli,
371 						 const char *native_os,
372 						 const char *native_lm,
373 						 const char *primary_domain)
374 {
375 #define _VALID_STR(p) ((p) != NULL && (p)[0] != '\0')
376 
377 	if (!_VALID_STR(cli->server_os) && _VALID_STR(native_os)) {
378 		cli->server_os = talloc_strdup(cli, native_os);
379 		if (cli->server_os == NULL) {
380 			return NT_STATUS_NO_MEMORY;
381 		}
382 	}
383 
384 	if (!_VALID_STR(cli->server_type) && _VALID_STR(native_lm)) {
385 		cli->server_type = talloc_strdup(cli, native_lm);
386 		if (cli->server_type == NULL) {
387 			return NT_STATUS_NO_MEMORY;
388 		}
389 	}
390 
391 	if (!_VALID_STR(cli->server_domain) && _VALID_STR(primary_domain)) {
392 		cli->server_domain = talloc_strdup(cli, primary_domain);
393 		if (cli->server_domain == NULL) {
394 			return NT_STATUS_NO_MEMORY;
395 		}
396 	}
397 
398 #undef _VALID_STRING
399 	return NT_STATUS_OK;
400 }
401 
402 /********************************************************
403  Utility function to ensure we always return at least
404  a valid char * pointer to an empty string for the
405  cli->server_os, cli->server_type and cli->server_domain
406  strings.
407 *******************************************************/
408 
smb_bytes_talloc_string(TALLOC_CTX * mem_ctx,const uint8_t * hdr,char ** dest,uint8_t * src,size_t srclen,ssize_t * destlen)409 static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
410 					const uint8_t *hdr,
411 					char **dest,
412 					uint8_t *src,
413 					size_t srclen,
414 					ssize_t *destlen)
415 {
416 	*destlen = clistr_pull_talloc(mem_ctx,
417 				(const char *)hdr,
418 				SVAL(hdr, HDR_FLG2),
419 				dest,
420 				(char *)src,
421 				srclen,
422 				STR_TERMINATE);
423 	if (*destlen == -1) {
424 		return NT_STATUS_NO_MEMORY;
425 	}
426 
427 	if (*dest == NULL) {
428 		*dest = talloc_strdup(mem_ctx, "");
429 		if (*dest == NULL) {
430 			return NT_STATUS_NO_MEMORY;
431 		}
432 	}
433 	return NT_STATUS_OK;
434 }
435 
436 /****************************************************************************
437  Work out suitable capabilities to offer the server.
438 ****************************************************************************/
439 
cli_session_setup_capabilities(struct cli_state * cli,uint32_t sesssetup_capabilities)440 static uint32_t cli_session_setup_capabilities(struct cli_state *cli,
441 					       uint32_t sesssetup_capabilities)
442 {
443 	uint32_t client_capabilities = smb1cli_conn_capabilities(cli->conn);
444 
445 	/*
446 	 * We only send capabilities based on the mask for:
447 	 * - client only flags
448 	 * - flags used in both directions
449 	 *
450 	 * We do not echo the server only flags, except some legacy flags.
451 	 *
452 	 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
453 	 * CAP_LARGE_WRITEX in order to allow us to do large reads
454 	 * against old Samba releases (<= 3.6.x).
455 	 */
456 	client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_LEGACY_CLIENT_MASK);
457 
458 	/*
459 	 * Session Setup specific flags CAP_DYNAMIC_REAUTH
460 	 * and CAP_EXTENDED_SECURITY are passed by the caller.
461 	 * We need that in order to do guest logins even if
462 	 * CAP_EXTENDED_SECURITY is negotiated.
463 	 */
464 	client_capabilities &= ~(CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
465 	sesssetup_capabilities &= (CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
466 	client_capabilities |= sesssetup_capabilities;
467 
468 	return client_capabilities;
469 }
470 
471 /****************************************************************************
472  Do a NT1 guest session setup.
473 ****************************************************************************/
474 
475 struct cli_session_setup_guest_state {
476 	struct cli_state *cli;
477 	uint16_t vwv[13];
478 	struct iovec bytes;
479 };
480 
481 static void cli_session_setup_guest_done(struct tevent_req *subreq);
482 
cli_session_setup_guest_create(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct cli_state * cli,struct tevent_req ** psmbreq)483 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
484 						  struct tevent_context *ev,
485 						  struct cli_state *cli,
486 						  struct tevent_req **psmbreq)
487 {
488 	struct tevent_req *req, *subreq;
489 	struct cli_session_setup_guest_state *state;
490 	uint16_t *vwv;
491 	uint8_t *bytes;
492 
493 	req = tevent_req_create(mem_ctx, &state,
494 				struct cli_session_setup_guest_state);
495 	if (req == NULL) {
496 		return NULL;
497 	}
498 	state->cli = cli;
499 	vwv = state->vwv;
500 
501 	SCVAL(vwv+0, 0, 0xFF);
502 	SCVAL(vwv+0, 1, 0);
503 	SSVAL(vwv+1, 0, 0);
504 	SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
505 	SSVAL(vwv+3, 0, 2);
506 	SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
507 	SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
508 	SSVAL(vwv+7, 0, 0);
509 	SSVAL(vwv+8, 0, 0);
510 	SSVAL(vwv+9, 0, 0);
511 	SSVAL(vwv+10, 0, 0);
512 	SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
513 
514 	bytes = talloc_array(state, uint8_t, 0);
515 
516 	bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "",  1, /* username */
517 				   NULL);
518 	bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* workgroup */
519 				   NULL);
520 	bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
521 	bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
522 
523 	if (bytes == NULL) {
524 		TALLOC_FREE(req);
525 		return NULL;
526 	}
527 
528 	state->bytes.iov_base = (void *)bytes;
529 	state->bytes.iov_len = talloc_get_size(bytes);
530 
531 	subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 0, 13,
532 			vwv, 1, &state->bytes);
533 	if (subreq == NULL) {
534 		TALLOC_FREE(req);
535 		return NULL;
536 	}
537 	tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
538 	*psmbreq = subreq;
539 	return req;
540 }
541 
cli_session_setup_guest_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct cli_state * cli)542 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
543 						struct tevent_context *ev,
544 						struct cli_state *cli)
545 {
546 	struct tevent_req *req, *subreq;
547 	NTSTATUS status;
548 
549 	req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
550 	if (req == NULL) {
551 		return NULL;
552 	}
553 
554 	status = smb1cli_req_chain_submit(&subreq, 1);
555 	if (!NT_STATUS_IS_OK(status)) {
556 		tevent_req_nterror(req, status);
557 		return tevent_req_post(req, ev);
558 	}
559 	return req;
560 }
561 
cli_session_setup_guest_done(struct tevent_req * subreq)562 static void cli_session_setup_guest_done(struct tevent_req *subreq)
563 {
564 	struct tevent_req *req = tevent_req_callback_data(
565 		subreq, struct tevent_req);
566 	struct cli_session_setup_guest_state *state = tevent_req_data(
567 		req, struct cli_session_setup_guest_state);
568 	struct cli_state *cli = state->cli;
569 	uint32_t num_bytes;
570 	uint8_t *in;
571 	uint8_t *inhdr;
572 	uint8_t *bytes;
573 	uint8_t *p;
574 	NTSTATUS status;
575 	ssize_t ret;
576 	uint8_t wct;
577 	uint16_t *vwv;
578 
579 	status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
580 			      &num_bytes, &bytes);
581 	TALLOC_FREE(subreq);
582 	if (!NT_STATUS_IS_OK(status)) {
583 		tevent_req_nterror(req, status);
584 		return;
585 	}
586 
587 	inhdr = in + NBT_HDR_SIZE;
588 	p = bytes;
589 
590 	cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
591 	smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0));
592 
593 	status = smb_bytes_talloc_string(cli,
594 					inhdr,
595 					&cli->server_os,
596 					p,
597 					bytes+num_bytes-p,
598 					&ret);
599 
600 	if (!NT_STATUS_IS_OK(status)) {
601 		tevent_req_nterror(req, status);
602 		return;
603 	}
604 	p += ret;
605 
606 	status = smb_bytes_talloc_string(cli,
607 					inhdr,
608 					&cli->server_type,
609 					p,
610 					bytes+num_bytes-p,
611 					&ret);
612 
613 	if (!NT_STATUS_IS_OK(status)) {
614 		tevent_req_nterror(req, status);
615 		return;
616 	}
617 	p += ret;
618 
619 	status = smb_bytes_talloc_string(cli,
620 					inhdr,
621 					&cli->server_domain,
622 					p,
623 					bytes+num_bytes-p,
624 					&ret);
625 
626 	if (!NT_STATUS_IS_OK(status)) {
627 		tevent_req_nterror(req, status);
628 		return;
629 	}
630 
631 	tevent_req_done(req);
632 }
633 
cli_session_setup_guest_recv(struct tevent_req * req)634 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
635 {
636 	return tevent_req_simple_recv_ntstatus(req);
637 }
638 
639 /* The following is calculated from :
640  * (smb_size-4) = 35
641  * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
642  * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
643  * end of packet.
644  */
645 
646 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
647 
648 struct cli_sesssetup_blob_state {
649 	struct tevent_context *ev;
650 	struct cli_state *cli;
651 	DATA_BLOB blob;
652 	uint16_t max_blob_size;
653 
654 	DATA_BLOB this_blob;
655 	struct iovec *recv_iov;
656 
657 	NTSTATUS status;
658 	const uint8_t *inbuf;
659 	DATA_BLOB ret_blob;
660 
661 	char *out_native_os;
662 	char *out_native_lm;
663 };
664 
665 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
666 				    struct tevent_req **psubreq);
667 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
668 
cli_sesssetup_blob_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct cli_state * cli,DATA_BLOB blob)669 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
670 						  struct tevent_context *ev,
671 						  struct cli_state *cli,
672 						  DATA_BLOB blob)
673 {
674 	struct tevent_req *req, *subreq;
675 	struct cli_sesssetup_blob_state *state;
676 	uint32_t usable_space;
677 
678 	req = tevent_req_create(mem_ctx, &state,
679 				struct cli_sesssetup_blob_state);
680 	if (req == NULL) {
681 		return NULL;
682 	}
683 	state->ev = ev;
684 	state->blob = blob;
685 	state->cli = cli;
686 
687 	if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
688 		usable_space = UINT16_MAX;
689 	} else {
690 		usable_space = cli_state_available_size(cli,
691 				BASE_SESSSETUP_BLOB_PACKET_SIZE);
692 	}
693 
694 	if (usable_space == 0) {
695 		DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
696 			  "(not possible to send %u bytes)\n",
697 			  BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
698 		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
699 		return tevent_req_post(req, ev);
700 	}
701 	state->max_blob_size = MIN(usable_space, 0xFFFF);
702 
703 	if (!cli_sesssetup_blob_next(state, &subreq)) {
704 		tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
705 		return tevent_req_post(req, ev);
706 	}
707 	tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
708 	return req;
709 }
710 
cli_sesssetup_blob_next(struct cli_sesssetup_blob_state * state,struct tevent_req ** psubreq)711 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
712 				    struct tevent_req **psubreq)
713 {
714 	struct tevent_req *subreq;
715 	uint16_t thistime;
716 
717 	thistime = MIN(state->blob.length, state->max_blob_size);
718 
719 	state->this_blob.data = state->blob.data;
720 	state->this_blob.length = thistime;
721 
722 	state->blob.data += thistime;
723 	state->blob.length -= thistime;
724 
725 	if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
726 		subreq = smb2cli_session_setup_send(state, state->ev,
727 						    state->cli->conn,
728 						    state->cli->timeout,
729 						    state->cli->smb2.session,
730 						    0, /* in_flags */
731 						    SMB2_CAP_DFS, /* in_capabilities */
732 						    0, /* in_channel */
733 						    0, /* in_previous_session_id */
734 						    &state->this_blob);
735 		if (subreq == NULL) {
736 			return false;
737 		}
738 	} else {
739 		uint16_t in_buf_size = 0;
740 		uint16_t in_mpx_max = 0;
741 		uint16_t in_vc_num = 0;
742 		uint32_t in_sess_key = 0;
743 		uint32_t in_capabilities = 0;
744 		const char *in_native_os = NULL;
745 		const char *in_native_lm = NULL;
746 
747 		in_buf_size = CLI_BUFFER_SIZE;
748 		in_mpx_max = smbXcli_conn_max_requests(state->cli->conn);
749 		in_vc_num = cli_state_get_vc_num(state->cli);
750 		in_sess_key = smb1cli_conn_server_session_key(state->cli->conn);
751 		in_capabilities = cli_session_setup_capabilities(state->cli,
752 								CAP_EXTENDED_SECURITY);
753 		in_native_os = "Unix";
754 		in_native_lm = "Samba";
755 
756 		/*
757 		 * For now we keep the same values as before,
758 		 * we may remove these in a separate commit later.
759 		 */
760 		in_mpx_max = 2;
761 		in_vc_num = 1;
762 		in_sess_key = 0;
763 
764 		subreq = smb1cli_session_setup_ext_send(state, state->ev,
765 							state->cli->conn,
766 							state->cli->timeout,
767 							state->cli->smb1.pid,
768 							state->cli->smb1.session,
769 							in_buf_size,
770 							in_mpx_max,
771 							in_vc_num,
772 							in_sess_key,
773 							state->this_blob,
774 							in_capabilities,
775 							in_native_os,
776 							in_native_lm);
777 		if (subreq == NULL) {
778 			return false;
779 		}
780 	}
781 	*psubreq = subreq;
782 	return true;
783 }
784 
cli_sesssetup_blob_done(struct tevent_req * subreq)785 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
786 {
787 	struct tevent_req *req = tevent_req_callback_data(
788 		subreq, struct tevent_req);
789 	struct cli_sesssetup_blob_state *state = tevent_req_data(
790 		req, struct cli_sesssetup_blob_state);
791 	NTSTATUS status;
792 
793 	if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
794 		status = smb2cli_session_setup_recv(subreq, state,
795 						    &state->recv_iov,
796 						    &state->ret_blob);
797 	} else {
798 		status = smb1cli_session_setup_ext_recv(subreq, state,
799 							&state->recv_iov,
800 							&state->inbuf,
801 							&state->ret_blob,
802 							&state->out_native_os,
803 							&state->out_native_lm);
804 	}
805 	TALLOC_FREE(subreq);
806 	if (!NT_STATUS_IS_OK(status)
807 	    && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
808 		tevent_req_nterror(req, status);
809 		return;
810 	}
811 
812 	state->status = status;
813 
814 	status = cli_state_update_after_sesssetup(state->cli,
815 						  state->out_native_os,
816 						  state->out_native_lm,
817 						  NULL);
818 	if (tevent_req_nterror(req, status)) {
819 		return;
820 	}
821 
822 	if (state->blob.length != 0) {
823 		/*
824 		 * More to send
825 		 */
826 		if (!cli_sesssetup_blob_next(state, &subreq)) {
827 			tevent_req_oom(req);
828 			return;
829 		}
830 		tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
831 		return;
832 	}
833 	tevent_req_done(req);
834 }
835 
cli_sesssetup_blob_recv(struct tevent_req * req,TALLOC_CTX * mem_ctx,DATA_BLOB * pblob,const uint8_t ** pinbuf,struct iovec ** precv_iov)836 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
837 					TALLOC_CTX *mem_ctx,
838 					DATA_BLOB *pblob,
839 					const uint8_t **pinbuf,
840 					struct iovec **precv_iov)
841 {
842 	struct cli_sesssetup_blob_state *state = tevent_req_data(
843 		req, struct cli_sesssetup_blob_state);
844 	NTSTATUS status;
845 	struct iovec *recv_iov;
846 
847 	if (tevent_req_is_nterror(req, &status)) {
848 		TALLOC_FREE(state->cli->smb2.session);
849 		cli_state_set_uid(state->cli, UID_FIELD_INVALID);
850 		tevent_req_received(req);
851 		return status;
852 	}
853 
854 	recv_iov = talloc_move(mem_ctx, &state->recv_iov);
855 	if (pblob != NULL) {
856 		*pblob = state->ret_blob;
857 	}
858 	if (pinbuf != NULL) {
859 		*pinbuf = state->inbuf;
860 	}
861 	if (precv_iov != NULL) {
862 		*precv_iov = recv_iov;
863 	}
864         /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
865 	status = state->status;
866 	tevent_req_received(req);
867 	return status;
868 }
869 
870 /****************************************************************************
871  Do a spnego/NTLMSSP encrypted session setup.
872 ****************************************************************************/
873 
874 struct cli_session_setup_gensec_state {
875 	struct tevent_context *ev;
876 	struct cli_state *cli;
877 	struct auth_generic_state *auth_generic;
878 	bool is_anonymous;
879 	DATA_BLOB blob_in;
880 	const uint8_t *inbuf;
881 	struct iovec *recv_iov;
882 	DATA_BLOB blob_out;
883 	bool local_ready;
884 	bool remote_ready;
885 	DATA_BLOB session_key;
886 };
887 
cli_session_setup_gensec_state_destructor(struct cli_session_setup_gensec_state * state)888 static int cli_session_setup_gensec_state_destructor(
889 	struct cli_session_setup_gensec_state *state)
890 {
891 	TALLOC_FREE(state->auth_generic);
892 	data_blob_clear_free(&state->session_key);
893 	return 0;
894 }
895 
896 static void cli_session_setup_gensec_local_next(struct tevent_req *req);
897 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq);
898 static void cli_session_setup_gensec_remote_next(struct tevent_req *req);
899 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq);
900 static void cli_session_setup_gensec_ready(struct tevent_req *req);
901 
cli_session_setup_gensec_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct cli_state * cli,struct cli_credentials * creds,const char * target_service,const char * target_hostname)902 static struct tevent_req *cli_session_setup_gensec_send(
903 	TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
904 	struct cli_credentials *creds,
905 	const char *target_service,
906 	const char *target_hostname)
907 {
908 	struct tevent_req *req;
909 	struct cli_session_setup_gensec_state *state;
910 	NTSTATUS status;
911 	const DATA_BLOB *b = NULL;
912 
913 	req = tevent_req_create(mem_ctx, &state,
914 				struct cli_session_setup_gensec_state);
915 	if (req == NULL) {
916 		return NULL;
917 	}
918 	state->ev = ev;
919 	state->cli = cli;
920 
921 	talloc_set_destructor(
922 		state, cli_session_setup_gensec_state_destructor);
923 
924 	status = auth_generic_client_prepare(state, &state->auth_generic);
925 	if (tevent_req_nterror(req, status)) {
926 		return tevent_req_post(req, ev);
927 	}
928 
929 	status = auth_generic_set_creds(state->auth_generic, creds);
930 	if (tevent_req_nterror(req, status)) {
931 		return tevent_req_post(req, ev);
932 	}
933 
934 	gensec_want_feature(state->auth_generic->gensec_security,
935 			    GENSEC_FEATURE_SESSION_KEY);
936 
937 	if (target_service != NULL) {
938 		status = gensec_set_target_service(
939 				state->auth_generic->gensec_security,
940 				target_service);
941 		if (tevent_req_nterror(req, status)) {
942 			return tevent_req_post(req, ev);
943 		}
944 	}
945 
946 	if (target_hostname != NULL) {
947 		status = gensec_set_target_hostname(
948 				state->auth_generic->gensec_security,
949 				target_hostname);
950 		if (tevent_req_nterror(req, status)) {
951 			return tevent_req_post(req, ev);
952 		}
953 	}
954 
955 	b = smbXcli_conn_server_gss_blob(cli->conn);
956 	if (b != NULL) {
957 		state->blob_in = *b;
958 	}
959 
960 	state->is_anonymous = cli_credentials_is_anonymous(state->auth_generic->credentials);
961 
962 	status = auth_generic_client_start(state->auth_generic,
963 					   GENSEC_OID_SPNEGO);
964 	if (tevent_req_nterror(req, status)) {
965 		return tevent_req_post(req, ev);
966 	}
967 
968 	if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
969 		state->cli->smb2.session = smbXcli_session_create(cli,
970 								  cli->conn);
971 		if (tevent_req_nomem(state->cli->smb2.session, req)) {
972 			return tevent_req_post(req, ev);
973 		}
974 	}
975 
976 	cli_session_setup_gensec_local_next(req);
977 	if (!tevent_req_is_in_progress(req)) {
978 		return tevent_req_post(req, ev);
979 	}
980 
981 	return req;
982 }
983 
cli_session_setup_gensec_local_next(struct tevent_req * req)984 static void cli_session_setup_gensec_local_next(struct tevent_req *req)
985 {
986 	struct cli_session_setup_gensec_state *state =
987 		tevent_req_data(req,
988 		struct cli_session_setup_gensec_state);
989 	struct tevent_req *subreq = NULL;
990 
991 	if (state->local_ready) {
992 		tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
993 		return;
994 	}
995 
996 	subreq = gensec_update_send(state, state->ev,
997 			state->auth_generic->gensec_security,
998 			state->blob_in);
999 	if (tevent_req_nomem(subreq, req)) {
1000 		return;
1001 	}
1002 	tevent_req_set_callback(subreq, cli_session_setup_gensec_local_done, req);
1003 }
1004 
cli_session_setup_gensec_local_done(struct tevent_req * subreq)1005 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq)
1006 {
1007 	struct tevent_req *req =
1008 		tevent_req_callback_data(subreq,
1009 		struct tevent_req);
1010 	struct cli_session_setup_gensec_state *state =
1011 		tevent_req_data(req,
1012 		struct cli_session_setup_gensec_state);
1013 	NTSTATUS status;
1014 
1015 	status = gensec_update_recv(subreq, state, &state->blob_out);
1016 	TALLOC_FREE(subreq);
1017 	state->blob_in = data_blob_null;
1018 	if (!NT_STATUS_IS_OK(status) &&
1019 	    !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1020 	{
1021 		tevent_req_nterror(req, status);
1022 		return;
1023 	}
1024 
1025 	if (NT_STATUS_IS_OK(status)) {
1026 		state->local_ready = true;
1027 	}
1028 
1029 	if (state->local_ready && state->remote_ready) {
1030 		cli_session_setup_gensec_ready(req);
1031 		return;
1032 	}
1033 
1034 	cli_session_setup_gensec_remote_next(req);
1035 }
1036 
cli_session_setup_gensec_remote_next(struct tevent_req * req)1037 static void cli_session_setup_gensec_remote_next(struct tevent_req *req)
1038 {
1039 	struct cli_session_setup_gensec_state *state =
1040 		tevent_req_data(req,
1041 		struct cli_session_setup_gensec_state);
1042 	struct tevent_req *subreq = NULL;
1043 
1044 	if (state->remote_ready) {
1045 		tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1046 		return;
1047 	}
1048 
1049 	subreq = cli_sesssetup_blob_send(state, state->ev,
1050 					 state->cli, state->blob_out);
1051 	if (tevent_req_nomem(subreq, req)) {
1052 		return;
1053 	}
1054 	tevent_req_set_callback(subreq,
1055 				cli_session_setup_gensec_remote_done,
1056 				req);
1057 }
1058 
cli_session_setup_gensec_remote_done(struct tevent_req * subreq)1059 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq)
1060 {
1061 	struct tevent_req *req =
1062 		tevent_req_callback_data(subreq,
1063 		struct tevent_req);
1064 	struct cli_session_setup_gensec_state *state =
1065 		tevent_req_data(req,
1066 		struct cli_session_setup_gensec_state);
1067 	NTSTATUS status;
1068 
1069 	state->inbuf = NULL;
1070 	TALLOC_FREE(state->recv_iov);
1071 
1072 	status = cli_sesssetup_blob_recv(subreq, state, &state->blob_in,
1073 					 &state->inbuf, &state->recv_iov);
1074 	TALLOC_FREE(subreq);
1075 	data_blob_free(&state->blob_out);
1076 	if (!NT_STATUS_IS_OK(status) &&
1077 	    !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1078 	{
1079 		tevent_req_nterror(req, status);
1080 		return;
1081 	}
1082 
1083 	if (NT_STATUS_IS_OK(status)) {
1084 		struct smbXcli_session *session = NULL;
1085 		bool is_guest = false;
1086 
1087 		if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1088 			session = state->cli->smb2.session;
1089 		} else {
1090 			session = state->cli->smb1.session;
1091 		}
1092 
1093 		is_guest = smbXcli_session_is_guest(session);
1094 		if (is_guest) {
1095 			/*
1096 			 * We can't finish the gensec handshake, we don't
1097 			 * have a negotiated session key.
1098 			 *
1099 			 * So just pretend we are completely done,
1100 			 * we need to continue as anonymous from this point,
1101 			 * as we can't get a session key.
1102 			 *
1103 			 * Note that smbXcli_session_is_guest()
1104 			 * always returns false if we require signing.
1105 			 */
1106 			state->blob_in = data_blob_null;
1107 			state->local_ready = true;
1108 			state->is_anonymous = true;
1109 		}
1110 
1111 		state->remote_ready = true;
1112 	}
1113 
1114 	if (state->local_ready && state->remote_ready) {
1115 		cli_session_setup_gensec_ready(req);
1116 		return;
1117 	}
1118 
1119 	cli_session_setup_gensec_local_next(req);
1120 }
1121 
cli_session_dump_keys(TALLOC_CTX * mem_ctx,struct smbXcli_session * session,DATA_BLOB session_key)1122 static void cli_session_dump_keys(TALLOC_CTX *mem_ctx,
1123 				  struct smbXcli_session *session,
1124 				  DATA_BLOB session_key)
1125 {
1126 	NTSTATUS status;
1127 	DATA_BLOB sig = data_blob_null;
1128 	DATA_BLOB app = data_blob_null;
1129 	DATA_BLOB enc = data_blob_null;
1130 	DATA_BLOB dec = data_blob_null;
1131 	uint64_t sid = smb2cli_session_current_id(session);
1132 
1133 	status = smb2cli_session_signing_key(session, mem_ctx, &sig);
1134 	if (!NT_STATUS_IS_OK(status)) {
1135 		goto out;
1136 	}
1137 	status = smbXcli_session_application_key(session, mem_ctx, &app);
1138 	if (!NT_STATUS_IS_OK(status)) {
1139 		goto out;
1140 	}
1141 	status = smb2cli_session_encryption_key(session, mem_ctx, &enc);
1142 	if (!NT_STATUS_IS_OK(status)) {
1143 		goto out;
1144 	}
1145 	status = smb2cli_session_decryption_key(session, mem_ctx, &dec);
1146 	if (!NT_STATUS_IS_OK(status)) {
1147 		goto out;
1148 	}
1149 
1150 	DEBUG(0, ("debug encryption: dumping generated session keys\n"));
1151 	DEBUGADD(0, ("Session Id    "));
1152 	dump_data(0, (uint8_t*)&sid, sizeof(sid));
1153 	DEBUGADD(0, ("Session Key   "));
1154 	dump_data(0, session_key.data, session_key.length);
1155 	DEBUGADD(0, ("Signing Key   "));
1156 	dump_data(0, sig.data, sig.length);
1157 	DEBUGADD(0, ("App Key       "));
1158 	dump_data(0, app.data, app.length);
1159 
1160 	/* In client code, ServerIn is the encryption key */
1161 
1162 	DEBUGADD(0, ("ServerIn Key  "));
1163 	dump_data(0, enc.data, enc.length);
1164 	DEBUGADD(0, ("ServerOut Key "));
1165 	dump_data(0, dec.data, dec.length);
1166 
1167 out:
1168 	data_blob_clear_free(&sig);
1169 	data_blob_clear_free(&app);
1170 	data_blob_clear_free(&enc);
1171 	data_blob_clear_free(&dec);
1172 }
1173 
cli_session_setup_gensec_ready(struct tevent_req * req)1174 static void cli_session_setup_gensec_ready(struct tevent_req *req)
1175 {
1176 	struct cli_session_setup_gensec_state *state =
1177 		tevent_req_data(req,
1178 		struct cli_session_setup_gensec_state);
1179 	const char *server_domain = NULL;
1180 	NTSTATUS status;
1181 
1182 	if (state->blob_in.length != 0) {
1183 		tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1184 		return;
1185 	}
1186 
1187 	if (state->blob_out.length != 0) {
1188 		tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1189 		return;
1190 	}
1191 
1192 	/*
1193 	 * gensec_ntlmssp_server_domain() returns NULL
1194 	 * if NTLMSSP is not used.
1195 	 *
1196 	 * We can remove this later
1197 	 * and leave the server domain empty for SMB2 and above
1198 	 * in future releases.
1199 	 */
1200 	server_domain = gensec_ntlmssp_server_domain(
1201 				state->auth_generic->gensec_security);
1202 
1203 	if (state->cli->server_domain[0] == '\0' && server_domain != NULL) {
1204 		TALLOC_FREE(state->cli->server_domain);
1205 		state->cli->server_domain = talloc_strdup(state->cli,
1206 					server_domain);
1207 		if (state->cli->server_domain == NULL) {
1208 			tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1209 			return;
1210 		}
1211 	}
1212 
1213 	if (state->is_anonymous) {
1214 		/*
1215 		 * Windows server does not set the
1216 		 * SMB2_SESSION_FLAG_IS_NULL flag.
1217 		 *
1218 		 * This fix makes sure we do not try
1219 		 * to verify a signature on the final
1220 		 * session setup response.
1221 		 */
1222 		tevent_req_done(req);
1223 		return;
1224 	}
1225 
1226 	status = gensec_session_key(state->auth_generic->gensec_security,
1227 				    state, &state->session_key);
1228 	if (tevent_req_nterror(req, status)) {
1229 		return;
1230 	}
1231 
1232 	if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1233 		struct smbXcli_session *session = state->cli->smb2.session;
1234 
1235 		status = smb2cli_session_set_session_key(session,
1236 							 state->session_key,
1237 							 state->recv_iov);
1238 		if (tevent_req_nterror(req, status)) {
1239 			return;
1240 		}
1241 		if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB3_00
1242 		    && lp_debug_encryption())
1243 		{
1244 			cli_session_dump_keys(state, session, state->session_key);
1245 		}
1246 	} else {
1247 		struct smbXcli_session *session = state->cli->smb1.session;
1248 		bool active;
1249 
1250 		status = smb1cli_session_set_session_key(session,
1251 							 state->session_key);
1252 		if (tevent_req_nterror(req, status)) {
1253 			return;
1254 		}
1255 
1256 		active = smb1cli_conn_activate_signing(state->cli->conn,
1257 						       state->session_key,
1258 						       data_blob_null);
1259 		if (active) {
1260 			bool ok;
1261 
1262 			ok = smb1cli_conn_check_signing(state->cli->conn,
1263 							state->inbuf, 1);
1264 			if (!ok) {
1265 				tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1266 				return;
1267 			}
1268 		}
1269 	}
1270 
1271 	tevent_req_done(req);
1272 }
1273 
cli_session_setup_gensec_recv(struct tevent_req * req)1274 static NTSTATUS cli_session_setup_gensec_recv(struct tevent_req *req)
1275 {
1276 	struct cli_session_setup_gensec_state *state =
1277 		tevent_req_data(req,
1278 		struct cli_session_setup_gensec_state);
1279 	NTSTATUS status;
1280 
1281 	if (tevent_req_is_nterror(req, &status)) {
1282 		cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1283 		return status;
1284 	}
1285 	return NT_STATUS_OK;
1286 }
1287 
cli_session_setup_get_account(TALLOC_CTX * mem_ctx,const char * principal)1288 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
1289 					   const char *principal)
1290 {
1291 	char *account, *p;
1292 
1293 	account = talloc_strdup(mem_ctx, principal);
1294 	if (account == NULL) {
1295 		return NULL;
1296 	}
1297 	p = strchr_m(account, '@');
1298 	if (p != NULL) {
1299 		*p = '\0';
1300 	}
1301 	return account;
1302 }
1303 
1304 /****************************************************************************
1305  Do a spnego encrypted session setup.
1306 
1307  user_domain: The shortname of the domain the user/machine is a member of.
1308  dest_realm: The realm we're connecting to, if NULL we use our default realm.
1309 ****************************************************************************/
1310 
1311 struct cli_session_setup_spnego_state {
1312 	ADS_STATUS result;
1313 };
1314 
1315 static void cli_session_setup_spnego_done(struct tevent_req *subreq);
1316 
cli_session_setup_spnego_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct cli_state * cli,struct cli_credentials * creds)1317 static struct tevent_req *cli_session_setup_spnego_send(
1318 	TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1319 	struct cli_credentials *creds)
1320 {
1321 	struct tevent_req *req, *subreq;
1322 	struct cli_session_setup_spnego_state *state;
1323 	const char *target_service = NULL;
1324 	const char *target_hostname = NULL;
1325 	NTSTATUS status;
1326 
1327 	req = tevent_req_create(mem_ctx, &state,
1328 				struct cli_session_setup_spnego_state);
1329 	if (req == NULL) {
1330 		return NULL;
1331 	}
1332 
1333 	target_service = "cifs";
1334 	target_hostname = smbXcli_conn_remote_name(cli->conn);
1335 
1336 	status = cli_session_creds_prepare_krb5(cli, creds);
1337 	if (tevent_req_nterror(req, status)) {
1338 		return tevent_req_post(req, ev);
1339 	}
1340 
1341 	DBG_INFO("Connect to %s as %s using SPNEGO\n",
1342 		 target_hostname,
1343 		 cli_credentials_get_principal(creds, talloc_tos()));
1344 
1345 	subreq = cli_session_setup_gensec_send(state, ev, cli, creds,
1346 					       target_service, target_hostname);
1347 	if (tevent_req_nomem(subreq, req)) {
1348 		return tevent_req_post(req, ev);
1349 	}
1350 	tevent_req_set_callback(
1351 		subreq, cli_session_setup_spnego_done, req);
1352 	return req;
1353 }
1354 
cli_session_setup_spnego_done(struct tevent_req * subreq)1355 static void cli_session_setup_spnego_done(struct tevent_req *subreq)
1356 {
1357 	struct tevent_req *req = tevent_req_callback_data(
1358 		subreq, struct tevent_req);
1359 	NTSTATUS status;
1360 
1361 	status = cli_session_setup_gensec_recv(subreq);
1362 	TALLOC_FREE(subreq);
1363 	if (tevent_req_nterror(req, status)) {
1364 		return;
1365 	}
1366 
1367 	tevent_req_done(req);
1368 }
1369 
cli_session_setup_spnego_recv(struct tevent_req * req)1370 static ADS_STATUS cli_session_setup_spnego_recv(struct tevent_req *req)
1371 {
1372 	struct cli_session_setup_spnego_state *state = tevent_req_data(
1373 		req, struct cli_session_setup_spnego_state);
1374 	NTSTATUS status;
1375 
1376 	if (tevent_req_is_nterror(req, &status)) {
1377 		state->result = ADS_ERROR_NT(status);
1378 	}
1379 
1380 	return state->result;
1381 }
1382 
1383 struct cli_session_setup_creds_state {
1384 	struct cli_state *cli;
1385 	DATA_BLOB apassword_blob;
1386 	DATA_BLOB upassword_blob;
1387 	DATA_BLOB lm_session_key;
1388 	DATA_BLOB session_key;
1389 	char *out_native_os;
1390 	char *out_native_lm;
1391 	char *out_primary_domain;
1392 };
1393 
cli_session_setup_creds_cleanup(struct tevent_req * req,enum tevent_req_state req_state)1394 static void cli_session_setup_creds_cleanup(struct tevent_req *req,
1395 					    enum tevent_req_state req_state)
1396 {
1397 	struct cli_session_setup_creds_state *state = tevent_req_data(
1398 		req, struct cli_session_setup_creds_state);
1399 
1400 	if (req_state != TEVENT_REQ_RECEIVED) {
1401 		return;
1402 	}
1403 
1404 	/*
1405 	 * We only call data_blob_clear() as
1406 	 * some of the blobs point to the same memory.
1407 	 *
1408 	 * We let the talloc hierarchy free the memory.
1409 	 */
1410 	data_blob_clear(&state->apassword_blob);
1411 	data_blob_clear(&state->upassword_blob);
1412 	data_blob_clear(&state->lm_session_key);
1413 	data_blob_clear(&state->session_key);
1414 	ZERO_STRUCTP(state);
1415 }
1416 
1417 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq);
1418 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq);
1419 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq);
1420 
1421 /****************************************************************************
1422  Send a session setup. The username and workgroup is in UNIX character
1423  format and must be converted to DOS codepage format before sending. If the
1424  password is in plaintext, the same should be done.
1425 ****************************************************************************/
1426 
cli_session_setup_creds_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct cli_state * cli,struct cli_credentials * creds)1427 struct tevent_req *cli_session_setup_creds_send(TALLOC_CTX *mem_ctx,
1428 					struct tevent_context *ev,
1429 					struct cli_state *cli,
1430 					struct cli_credentials *creds)
1431 {
1432 	struct tevent_req *req, *subreq;
1433 	struct cli_session_setup_creds_state *state;
1434 	uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1435 	bool use_spnego = false;
1436 	int flags = 0;
1437 	enum credentials_use_kerberos krb5_state;
1438 	uint32_t gensec_features;
1439 	const char *username = "";
1440 	const char *domain = "";
1441 	DATA_BLOB target_info = data_blob_null;
1442 	DATA_BLOB challenge = data_blob_null;
1443 	uint16_t in_buf_size = 0;
1444 	uint16_t in_mpx_max = 0;
1445 	uint16_t in_vc_num = 0;
1446 	uint32_t in_sess_key = 0;
1447 	const char *in_native_os = NULL;
1448 	const char *in_native_lm = NULL;
1449 	NTSTATUS status;
1450 
1451 	req = tevent_req_create(mem_ctx, &state,
1452 				struct cli_session_setup_creds_state);
1453 	if (req == NULL) {
1454 		return NULL;
1455 	}
1456 	state->cli = cli;
1457 
1458 	tevent_req_set_cleanup_fn(req, cli_session_setup_creds_cleanup);
1459 
1460 	krb5_state = cli_credentials_get_kerberos_state(creds);
1461 	gensec_features = cli_credentials_get_gensec_features(creds);
1462 
1463 	switch (krb5_state) {
1464 	case CRED_MUST_USE_KERBEROS:
1465 		cli->use_kerberos = true;
1466 		cli->fallback_after_kerberos = false;
1467 		break;
1468 	case CRED_AUTO_USE_KERBEROS:
1469 		cli->use_kerberos = true;
1470 		cli->fallback_after_kerberos = true;
1471 		break;
1472 	case CRED_DONT_USE_KERBEROS:
1473 		cli->use_kerberos = false;
1474 		cli->fallback_after_kerberos = false;
1475 		break;
1476 	}
1477 
1478 	if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
1479 		cli->use_ccache = true;
1480 	} else {
1481 		cli->use_ccache = false;
1482 	}
1483 
1484 	/*
1485 	 * Now work out what sort of session setup we are going to
1486 	 * do. I have split this into separate functions to make the flow a bit
1487 	 * easier to understand (tridge).
1488 	 */
1489 	if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) {
1490 		use_spnego = false;
1491 	} else if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1492 		use_spnego = true;
1493 	} else if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) {
1494 		/*
1495 		 * if the server supports extended security then use SPNEGO
1496 		 * even for anonymous connections.
1497 		 */
1498 		use_spnego = true;
1499 	} else {
1500 		use_spnego = false;
1501 	}
1502 
1503 	if (use_spnego) {
1504 		subreq = cli_session_setup_spnego_send(
1505 			state, ev, cli, creds);
1506 		if (tevent_req_nomem(subreq, req)) {
1507 			return tevent_req_post(req, ev);
1508 		}
1509 		tevent_req_set_callback(subreq, cli_session_setup_creds_done_spnego,
1510 					req);
1511 		return req;
1512 	}
1513 
1514 	if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
1515 		/*
1516 		 * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
1517 		 * this step against older servers.
1518 		 */
1519 		tevent_req_done(req);
1520 		return tevent_req_post(req, ev);
1521 	}
1522 
1523 	if (cli_credentials_is_anonymous(creds)) {
1524 		/*
1525 		 * Do an anonymous session setup
1526 		 */
1527 		goto non_spnego_creds_done;
1528 	}
1529 
1530 	if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) {
1531 		/*
1532 		 * Do an anonymous session setup,
1533 		 * the password is passed via the tree connect.
1534 		 */
1535 		goto non_spnego_creds_done;
1536 	}
1537 
1538 	cli_credentials_get_ntlm_username_domain(creds, state,
1539 						 &username,
1540 						 &domain);
1541 	if (tevent_req_nomem(username, req)) {
1542 		return tevent_req_post(req, ev);
1543 	}
1544 	if (tevent_req_nomem(domain, req)) {
1545 		return tevent_req_post(req, ev);
1546 	}
1547 
1548 	DBG_INFO("Connect to %s as %s using NTLM\n", domain, username);
1549 
1550 	if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1551 		bool use_unicode = smbXcli_conn_use_unicode(cli->conn);
1552 		uint8_t *bytes = NULL;
1553 		size_t bytes_len = 0;
1554 		const char *pw = cli_credentials_get_password(creds);
1555 		size_t pw_len = 0;
1556 
1557 		if (pw == NULL) {
1558 			pw = "";
1559 		}
1560 		pw_len = strlen(pw) + 1;
1561 
1562 		if (!lp_client_plaintext_auth()) {
1563 			DEBUG(1, ("Server requested PLAINTEXT password but "
1564 				  "'client plaintext auth = no'\n"));
1565 			tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1566 			return tevent_req_post(req, ev);
1567 		}
1568 
1569 		bytes = talloc_array(state, uint8_t, 0);
1570 		bytes = trans2_bytes_push_str(bytes, use_unicode,
1571 					      pw, pw_len, &bytes_len);
1572 		if (tevent_req_nomem(bytes, req)) {
1573 			return tevent_req_post(req, ev);
1574 		}
1575 
1576 		if (use_unicode) {
1577 			/*
1578 			 * CAP_UNICODE, can only be negotiated by NT1.
1579 			 */
1580 			state->upassword_blob = data_blob_const(bytes,
1581 								bytes_len);
1582 		} else {
1583 			state->apassword_blob = data_blob_const(bytes,
1584 								bytes_len);
1585 		}
1586 
1587 		goto non_spnego_creds_done;
1588 	}
1589 
1590 	challenge = data_blob_const(smb1cli_conn_server_challenge(cli->conn), 8);
1591 
1592 	if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1593 		if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
1594 			/*
1595 			 * Don't send an NTLMv2 response without NTLMSSP if we
1596 			 * want to use spnego support.
1597 			 */
1598 			DEBUG(1, ("Server does not support EXTENDED_SECURITY "
1599 				  " but 'client use spnego = yes'"
1600 				  " and 'client ntlmv2 auth = yes' is set\n"));
1601 			tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1602 			return tevent_req_post(req, ev);
1603 		}
1604 
1605 		if (lp_client_ntlmv2_auth()) {
1606 			flags |= CLI_CRED_NTLMv2_AUTH;
1607 
1608 			/*
1609 			 * note that the 'domain' here is a best
1610 			 * guess - we don't know the server's domain
1611 			 * at this point. Windows clients also don't
1612 			 * use hostname...
1613 			 */
1614 			target_info = NTLMv2_generate_names_blob(state,
1615 								 NULL,
1616 								 domain);
1617 			if (tevent_req_nomem(target_info.data, req)) {
1618 				return tevent_req_post(req, ev);
1619 			}
1620 		} else {
1621 			flags |= CLI_CRED_NTLM_AUTH;
1622 			if (lp_client_lanman_auth()) {
1623 				flags |= CLI_CRED_LANMAN_AUTH;
1624 			}
1625 		}
1626 	} else {
1627 		if (!lp_client_lanman_auth()) {
1628 			DEBUG(1, ("Server requested user level LM password but "
1629 				  "'client lanman auth = no' is set.\n"));
1630 			tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1631 			return tevent_req_post(req, ev);
1632 		}
1633 
1634 		flags |= CLI_CRED_LANMAN_AUTH;
1635 	}
1636 
1637 	status = cli_credentials_get_ntlm_response(creds, state, &flags,
1638 						   challenge, NULL,
1639 						   target_info,
1640 						   &state->apassword_blob,
1641 						   &state->upassword_blob,
1642 						   &state->lm_session_key,
1643 						   &state->session_key);
1644 	if (tevent_req_nterror(req, status)) {
1645 		return tevent_req_post(req, ev);
1646 	}
1647 
1648 non_spnego_creds_done:
1649 
1650 	in_buf_size = CLI_BUFFER_SIZE;
1651 	in_mpx_max = smbXcli_conn_max_requests(cli->conn);
1652 	in_vc_num = cli_state_get_vc_num(cli);
1653 	in_sess_key = smb1cli_conn_server_session_key(cli->conn);
1654 	in_native_os = "Unix";
1655 	in_native_lm = "Samba";
1656 
1657 	if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1658 		uint32_t in_capabilities = 0;
1659 
1660 		in_capabilities = cli_session_setup_capabilities(cli, 0);
1661 
1662 		/*
1663 		 * For now we keep the same values as before,
1664 		 * we may remove these in a separate commit later.
1665 		 */
1666 		in_mpx_max = 2;
1667 
1668 		subreq = smb1cli_session_setup_nt1_send(state, ev,
1669 							cli->conn,
1670 							cli->timeout,
1671 							cli->smb1.pid,
1672 							cli->smb1.session,
1673 							in_buf_size,
1674 							in_mpx_max,
1675 							in_vc_num,
1676 							in_sess_key,
1677 							username,
1678 							domain,
1679 							state->apassword_blob,
1680 							state->upassword_blob,
1681 							in_capabilities,
1682 							in_native_os,
1683 							in_native_lm);
1684 		if (tevent_req_nomem(subreq, req)) {
1685 			return tevent_req_post(req, ev);
1686 		}
1687 		tevent_req_set_callback(subreq, cli_session_setup_creds_done_nt1,
1688 					req);
1689 		return req;
1690 	}
1691 
1692 	/*
1693 	 * For now we keep the same values as before,
1694 	 * we may remove these in a separate commit later.
1695 	 */
1696 	in_mpx_max = 2;
1697 	in_vc_num = 1;
1698 
1699 	subreq = smb1cli_session_setup_lm21_send(state, ev,
1700 						 cli->conn,
1701 						 cli->timeout,
1702 						 cli->smb1.pid,
1703 						 cli->smb1.session,
1704 						 in_buf_size,
1705 						 in_mpx_max,
1706 						 in_vc_num,
1707 						 in_sess_key,
1708 						 username,
1709 						 domain,
1710 						 state->apassword_blob,
1711 						 in_native_os,
1712 						 in_native_lm);
1713 	if (tevent_req_nomem(subreq, req)) {
1714 		return tevent_req_post(req, ev);
1715 	}
1716 	tevent_req_set_callback(subreq, cli_session_setup_creds_done_lm21,
1717 				req);
1718 	return req;
1719 }
1720 
cli_session_setup_creds_done_spnego(struct tevent_req * subreq)1721 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq)
1722 {
1723 	struct tevent_req *req = tevent_req_callback_data(
1724 		subreq, struct tevent_req);
1725 	ADS_STATUS status;
1726 
1727 	status = cli_session_setup_spnego_recv(subreq);
1728 	TALLOC_FREE(subreq);
1729 	if (!ADS_ERR_OK(status)) {
1730 		DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1731 		tevent_req_nterror(req, ads_ntstatus(status));
1732 		return;
1733 	}
1734 	tevent_req_done(req);
1735 }
1736 
cli_session_setup_creds_done_nt1(struct tevent_req * subreq)1737 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq)
1738 {
1739 	struct tevent_req *req = tevent_req_callback_data(
1740 		subreq, struct tevent_req);
1741 	struct cli_session_setup_creds_state *state = tevent_req_data(
1742 		req, struct cli_session_setup_creds_state);
1743 	struct cli_state *cli = state->cli;
1744 	NTSTATUS status;
1745 	struct iovec *recv_iov = NULL;
1746 	const uint8_t *inbuf = NULL;
1747 	bool ok;
1748 
1749 	status = smb1cli_session_setup_nt1_recv(subreq, state,
1750 						&recv_iov,
1751 						&inbuf,
1752 						&state->out_native_os,
1753 						&state->out_native_lm,
1754 						&state->out_primary_domain);
1755 	TALLOC_FREE(subreq);
1756 	if (!NT_STATUS_IS_OK(status)) {
1757 		DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status)));
1758 		tevent_req_nterror(req, status);
1759 		return;
1760 	}
1761 
1762 	status = cli_state_update_after_sesssetup(state->cli,
1763 						  state->out_native_os,
1764 						  state->out_native_lm,
1765 						  state->out_primary_domain);
1766 	if (tevent_req_nterror(req, status)) {
1767 		return;
1768 	}
1769 
1770 	ok = smb1cli_conn_activate_signing(cli->conn,
1771 					   state->session_key,
1772 					   state->upassword_blob);
1773 	if (ok) {
1774 		ok = smb1cli_conn_check_signing(cli->conn, inbuf, 1);
1775 		if (!ok) {
1776 			tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1777 			return;
1778 		}
1779 	}
1780 
1781 	if (state->session_key.data) {
1782 		struct smbXcli_session *session = cli->smb1.session;
1783 
1784 		status = smb1cli_session_set_session_key(session,
1785 							 state->session_key);
1786 		if (tevent_req_nterror(req, status)) {
1787 			return;
1788 		}
1789 	}
1790 
1791 	tevent_req_done(req);
1792 }
1793 
cli_session_setup_creds_done_lm21(struct tevent_req * subreq)1794 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq)
1795 {
1796 	struct tevent_req *req = tevent_req_callback_data(
1797 		subreq, struct tevent_req);
1798 	struct cli_session_setup_creds_state *state = tevent_req_data(
1799 		req, struct cli_session_setup_creds_state);
1800 	NTSTATUS status;
1801 
1802 	status = smb1cli_session_setup_lm21_recv(subreq, state,
1803 						 &state->out_native_os,
1804 						 &state->out_native_lm);
1805 	TALLOC_FREE(subreq);
1806 	if (!NT_STATUS_IS_OK(status)) {
1807 		DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status)));
1808 		tevent_req_nterror(req, status);
1809 		return;
1810 	}
1811 
1812 	status = cli_state_update_after_sesssetup(state->cli,
1813 						  state->out_native_os,
1814 						  state->out_native_lm,
1815 						  NULL);
1816 	if (tevent_req_nterror(req, status)) {
1817 		return;
1818 	}
1819 
1820 	tevent_req_done(req);
1821 }
1822 
cli_session_setup_creds_recv(struct tevent_req * req)1823 NTSTATUS cli_session_setup_creds_recv(struct tevent_req *req)
1824 {
1825 	return tevent_req_simple_recv_ntstatus(req);
1826 }
1827 
cli_session_setup_creds(struct cli_state * cli,struct cli_credentials * creds)1828 NTSTATUS cli_session_setup_creds(struct cli_state *cli,
1829 				 struct cli_credentials *creds)
1830 {
1831 	struct tevent_context *ev;
1832 	struct tevent_req *req;
1833 	NTSTATUS status = NT_STATUS_NO_MEMORY;
1834 
1835 	if (smbXcli_conn_has_async_calls(cli->conn)) {
1836 		return NT_STATUS_INVALID_PARAMETER;
1837 	}
1838 	ev = samba_tevent_context_init(talloc_tos());
1839 	if (ev == NULL) {
1840 		goto fail;
1841 	}
1842 	req = cli_session_setup_creds_send(ev, ev, cli, creds);
1843 	if (req == NULL) {
1844 		goto fail;
1845 	}
1846 	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1847 		goto fail;
1848 	}
1849 	status = cli_session_setup_creds_recv(req);
1850  fail:
1851 	TALLOC_FREE(ev);
1852 	return status;
1853 }
1854 
cli_session_setup_anon(struct cli_state * cli)1855 NTSTATUS cli_session_setup_anon(struct cli_state *cli)
1856 {
1857 	NTSTATUS status;
1858 	struct cli_credentials *creds = NULL;
1859 
1860 	creds = cli_credentials_init_anon(cli);
1861 	if (creds == NULL) {
1862 		return NT_STATUS_NO_MEMORY;
1863 	}
1864 
1865 	status = cli_session_setup_creds(cli, creds);
1866 	TALLOC_FREE(creds);
1867 	if (!NT_STATUS_IS_OK(status)) {
1868 		return status;
1869 	}
1870 
1871 	return NT_STATUS_OK;
1872 }
1873 
1874 /****************************************************************************
1875  Send a uloggoff.
1876 *****************************************************************************/
1877 
1878 struct cli_ulogoff_state {
1879 	struct cli_state *cli;
1880 	uint16_t vwv[3];
1881 };
1882 
1883 static void cli_ulogoff_done(struct tevent_req *subreq);
1884 
cli_ulogoff_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct cli_state * cli)1885 static struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
1886 				    struct tevent_context *ev,
1887 				    struct cli_state *cli)
1888 {
1889 	struct tevent_req *req, *subreq;
1890 	struct cli_ulogoff_state *state;
1891 
1892 	req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
1893 	if (req == NULL) {
1894 		return NULL;
1895 	}
1896 	state->cli = cli;
1897 
1898 	SCVAL(state->vwv+0, 0, 0xFF);
1899 	SCVAL(state->vwv+1, 0, 0);
1900 	SSVAL(state->vwv+2, 0, 0);
1901 
1902 	subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 0, 2, state->vwv,
1903 			      0, NULL);
1904 	if (tevent_req_nomem(subreq, req)) {
1905 		return tevent_req_post(req, ev);
1906 	}
1907 	tevent_req_set_callback(subreq, cli_ulogoff_done, req);
1908 	return req;
1909 }
1910 
cli_ulogoff_done(struct tevent_req * subreq)1911 static void cli_ulogoff_done(struct tevent_req *subreq)
1912 {
1913 	struct tevent_req *req = tevent_req_callback_data(
1914 		subreq, struct tevent_req);
1915 	struct cli_ulogoff_state *state = tevent_req_data(
1916 		req, struct cli_ulogoff_state);
1917 	NTSTATUS status;
1918 
1919 	status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
1920 	if (!NT_STATUS_IS_OK(status)) {
1921 		tevent_req_nterror(req, status);
1922 		return;
1923 	}
1924 	cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1925 	tevent_req_done(req);
1926 }
1927 
cli_ulogoff_recv(struct tevent_req * req)1928 static NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
1929 {
1930 	return tevent_req_simple_recv_ntstatus(req);
1931 }
1932 
cli_ulogoff(struct cli_state * cli)1933 NTSTATUS cli_ulogoff(struct cli_state *cli)
1934 {
1935 	struct tevent_context *ev;
1936 	struct tevent_req *req;
1937 	NTSTATUS status = NT_STATUS_NO_MEMORY;
1938 
1939 	if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1940 		status = smb2cli_logoff(cli->conn,
1941 					cli->timeout,
1942 					cli->smb2.session);
1943 		if (!NT_STATUS_IS_OK(status)) {
1944 			return status;
1945 		}
1946 		smb2cli_session_set_id_and_flags(cli->smb2.session,
1947 						 UINT64_MAX, 0);
1948 		return NT_STATUS_OK;
1949 	}
1950 
1951 	if (smbXcli_conn_has_async_calls(cli->conn)) {
1952 		return NT_STATUS_INVALID_PARAMETER;
1953 	}
1954 	ev = samba_tevent_context_init(talloc_tos());
1955 	if (ev == NULL) {
1956 		goto fail;
1957 	}
1958 	req = cli_ulogoff_send(ev, ev, cli);
1959 	if (req == NULL) {
1960 		goto fail;
1961 	}
1962 	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1963 		goto fail;
1964 	}
1965 	status = cli_ulogoff_recv(req);
1966 fail:
1967 	TALLOC_FREE(ev);
1968 	return status;
1969 }
1970 
1971 /****************************************************************************
1972  Send a tconX.
1973 ****************************************************************************/
1974 
1975 struct cli_tcon_andx_state {
1976 	struct cli_state *cli;
1977 	uint16_t vwv[4];
1978 	struct iovec bytes;
1979 };
1980 
1981 static void cli_tcon_andx_done(struct tevent_req *subreq);
1982 
cli_tcon_andx_create(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct cli_state * cli,const char * share,const char * dev,const char * pass,int passlen,struct tevent_req ** psmbreq)1983 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
1984 					struct tevent_context *ev,
1985 					struct cli_state *cli,
1986 					const char *share, const char *dev,
1987 					const char *pass, int passlen,
1988 					struct tevent_req **psmbreq)
1989 {
1990 	struct tevent_req *req, *subreq;
1991 	struct cli_tcon_andx_state *state;
1992 	uint8_t p24[24];
1993 	uint16_t *vwv;
1994 	char *tmp = NULL;
1995 	uint8_t *bytes;
1996 	uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1997 	uint16_t tcon_flags = 0;
1998 
1999 	*psmbreq = NULL;
2000 
2001 	req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2002 	if (req == NULL) {
2003 		return NULL;
2004 	}
2005 	state->cli = cli;
2006 	vwv = state->vwv;
2007 
2008 	TALLOC_FREE(cli->smb1.tcon);
2009 	cli->smb1.tcon = smbXcli_tcon_create(cli);
2010 	if (tevent_req_nomem(cli->smb1.tcon, req)) {
2011 		return tevent_req_post(req, ev);
2012 	}
2013 	smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
2014 
2015 	cli->share = talloc_strdup(cli, share);
2016 	if (!cli->share) {
2017 		return NULL;
2018 	}
2019 
2020 	/* in user level security don't send a password now */
2021 	if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2022 		passlen = 1;
2023 		pass = "";
2024 	} else if (pass == NULL) {
2025 		DEBUG(1, ("Server not using user level security and no "
2026 			  "password supplied.\n"));
2027 		goto access_denied;
2028 	}
2029 
2030 	if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2031 	    *pass && passlen != 24) {
2032 		if (!lp_client_lanman_auth()) {
2033 			DEBUG(1, ("Server requested LANMAN password "
2034 				  "(share-level security) but "
2035 				  "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2036 			goto access_denied;
2037 		}
2038 
2039 		/*
2040 		 * Non-encrypted passwords - convert to DOS codepage before
2041 		 * encryption.
2042 		 */
2043 		SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
2044 		passlen = 24;
2045 		pass = (const char *)p24;
2046 	} else {
2047 		if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2048 				     |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2049 		   == 0) {
2050 			uint8_t *tmp_pass;
2051 
2052 			if (!lp_client_plaintext_auth() && (*pass)) {
2053 				DEBUG(1, ("Server requested PLAINTEXT "
2054 					  "password but "
2055 					  "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2056 				goto access_denied;
2057 			}
2058 
2059 			/*
2060 			 * Non-encrypted passwords - convert to DOS codepage
2061 			 * before using.
2062 			 */
2063 			tmp_pass = talloc_array(talloc_tos(), uint8_t, 0);
2064 			if (tevent_req_nomem(tmp_pass, req)) {
2065 				return tevent_req_post(req, ev);
2066 			}
2067 			tmp_pass = trans2_bytes_push_str(tmp_pass,
2068 							 false, /* always DOS */
2069 							 pass,
2070 							 passlen,
2071 							 NULL);
2072 			if (tevent_req_nomem(tmp_pass, req)) {
2073 				return tevent_req_post(req, ev);
2074 			}
2075 			pass = (const char *)tmp_pass;
2076 			passlen = talloc_get_size(tmp_pass);
2077 		}
2078 	}
2079 
2080 	tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE;
2081 	tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
2082 
2083 	SCVAL(vwv+0, 0, 0xFF);
2084 	SCVAL(vwv+0, 1, 0);
2085 	SSVAL(vwv+1, 0, 0);
2086 	SSVAL(vwv+2, 0, tcon_flags);
2087 	SSVAL(vwv+3, 0, passlen);
2088 
2089 	if (passlen && pass) {
2090 		bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2091 	} else {
2092 		bytes = talloc_array(state, uint8_t, 0);
2093 	}
2094 
2095 	/*
2096 	 * Add the sharename
2097 	 */
2098 	tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2099 					 smbXcli_conn_remote_name(cli->conn), share);
2100 	if (tmp == NULL) {
2101 		TALLOC_FREE(req);
2102 		return NULL;
2103 	}
2104 	bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
2105 				   NULL);
2106 	TALLOC_FREE(tmp);
2107 
2108 	/*
2109 	 * Add the devicetype
2110 	 */
2111 	tmp = talloc_strdup_upper(talloc_tos(), dev);
2112 	if (tmp == NULL) {
2113 		TALLOC_FREE(req);
2114 		return NULL;
2115 	}
2116 	bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2117 	TALLOC_FREE(tmp);
2118 
2119 	if (bytes == NULL) {
2120 		TALLOC_FREE(req);
2121 		return NULL;
2122 	}
2123 
2124 	state->bytes.iov_base = (void *)bytes;
2125 	state->bytes.iov_len = talloc_get_size(bytes);
2126 
2127 	subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 0, 4, vwv,
2128 				    1, &state->bytes);
2129 	if (subreq == NULL) {
2130 		TALLOC_FREE(req);
2131 		return NULL;
2132 	}
2133 	tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2134 	*psmbreq = subreq;
2135 	return req;
2136 
2137  access_denied:
2138 	tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2139 	return tevent_req_post(req, ev);
2140 }
2141 
cli_tcon_andx_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct cli_state * cli,const char * share,const char * dev,const char * pass,int passlen)2142 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2143 				      struct tevent_context *ev,
2144 				      struct cli_state *cli,
2145 				      const char *share, const char *dev,
2146 				      const char *pass, int passlen)
2147 {
2148 	struct tevent_req *req, *subreq;
2149 	NTSTATUS status;
2150 
2151 	req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2152 				   &subreq);
2153 	if (req == NULL) {
2154 		return NULL;
2155 	}
2156 	if (subreq == NULL) {
2157 		return req;
2158 	}
2159 	status = smb1cli_req_chain_submit(&subreq, 1);
2160 	if (!NT_STATUS_IS_OK(status)) {
2161 		tevent_req_nterror(req, status);
2162 		return tevent_req_post(req, ev);
2163 	}
2164 	return req;
2165 }
2166 
cli_tcon_andx_done(struct tevent_req * subreq)2167 static void cli_tcon_andx_done(struct tevent_req *subreq)
2168 {
2169 	struct tevent_req *req = tevent_req_callback_data(
2170 		subreq, struct tevent_req);
2171 	struct cli_tcon_andx_state *state = tevent_req_data(
2172 		req, struct cli_tcon_andx_state);
2173 	struct cli_state *cli = state->cli;
2174 	uint8_t *in;
2175 	uint8_t *inhdr;
2176 	uint8_t wct;
2177 	uint16_t *vwv;
2178 	uint32_t num_bytes;
2179 	uint8_t *bytes;
2180 	NTSTATUS status;
2181 	uint16_t optional_support = 0;
2182 
2183 	status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2184 			      &num_bytes, &bytes);
2185 	TALLOC_FREE(subreq);
2186 	if (!NT_STATUS_IS_OK(status)) {
2187 		tevent_req_nterror(req, status);
2188 		return;
2189 	}
2190 
2191 	inhdr = in + NBT_HDR_SIZE;
2192 
2193 	if (num_bytes) {
2194 		if (clistr_pull_talloc(cli,
2195 				(const char *)inhdr,
2196 				SVAL(inhdr, HDR_FLG2),
2197 				&cli->dev,
2198 				bytes,
2199 				num_bytes,
2200 				STR_TERMINATE|STR_ASCII) == -1) {
2201 			tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2202 			return;
2203 		}
2204 	} else {
2205 		cli->dev = talloc_strdup(cli, "");
2206 		if (cli->dev == NULL) {
2207 			tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2208 			return;
2209 		}
2210 	}
2211 
2212 	if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2213 		/* almost certainly win95 - enable bug fixes */
2214 		cli->win95 = True;
2215 	}
2216 
2217 	/*
2218 	 * Make sure that we have the optional support 16-bit field. WCT > 2.
2219 	 * Avoids issues when connecting to Win9x boxes sharing files
2220 	 */
2221 
2222 	if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
2223 		optional_support = SVAL(vwv+2, 0);
2224 	}
2225 
2226 	if (optional_support & SMB_EXTENDED_SIGNATURES) {
2227 		smb1cli_session_protect_session_key(cli->smb1.session);
2228 	}
2229 
2230 	smb1cli_tcon_set_values(state->cli->smb1.tcon,
2231 				SVAL(inhdr, HDR_TID),
2232 				optional_support,
2233 				0, /* maximal_access */
2234 				0, /* guest_maximal_access */
2235 				NULL, /* service */
2236 				NULL); /* fs_type */
2237 
2238 	tevent_req_done(req);
2239 }
2240 
cli_tcon_andx_recv(struct tevent_req * req)2241 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2242 {
2243 	return tevent_req_simple_recv_ntstatus(req);
2244 }
2245 
cli_tcon_andx(struct cli_state * cli,const char * share,const char * dev,const char * pass,int passlen)2246 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2247 		       const char *dev, const char *pass, int passlen)
2248 {
2249 	TALLOC_CTX *frame = talloc_stackframe();
2250 	struct tevent_context *ev;
2251 	struct tevent_req *req;
2252 	NTSTATUS status = NT_STATUS_NO_MEMORY;
2253 
2254 	if (smbXcli_conn_has_async_calls(cli->conn)) {
2255 		/*
2256 		 * Can't use sync call while an async call is in flight
2257 		 */
2258 		status = NT_STATUS_INVALID_PARAMETER;
2259 		goto fail;
2260 	}
2261 
2262 	ev = samba_tevent_context_init(frame);
2263 	if (ev == NULL) {
2264 		goto fail;
2265 	}
2266 
2267 	req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2268 	if (req == NULL) {
2269 		goto fail;
2270 	}
2271 
2272 	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2273 		goto fail;
2274 	}
2275 
2276 	status = cli_tcon_andx_recv(req);
2277  fail:
2278 	TALLOC_FREE(frame);
2279 	return status;
2280 }
2281 
2282 struct cli_tree_connect_state {
2283 	struct cli_state *cli;
2284 };
2285 
2286 static struct tevent_req *cli_raw_tcon_send(
2287 	TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2288 	const char *service, const char *pass, const char *dev);
2289 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
2290 				  uint16_t *max_xmit, uint16_t *tid);
2291 
2292 static void cli_tree_connect_smb2_done(struct tevent_req *subreq);
2293 static void cli_tree_connect_andx_done(struct tevent_req *subreq);
2294 static void cli_tree_connect_raw_done(struct tevent_req *subreq);
2295 
cli_tree_connect_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct cli_state * cli,const char * share,const char * dev,const char * pass)2296 static struct tevent_req *cli_tree_connect_send(
2297 	TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2298 	const char *share, const char *dev, const char *pass)
2299 {
2300 	struct tevent_req *req, *subreq;
2301 	struct cli_tree_connect_state *state;
2302 	int passlen;
2303 
2304 	if (pass == NULL) {
2305 		pass = "";
2306 	}
2307 	passlen = strlen(pass) + 1;
2308 
2309 	req = tevent_req_create(mem_ctx, &state,
2310 				struct cli_tree_connect_state);
2311 	if (req == NULL) {
2312 		return NULL;
2313 	}
2314 	state->cli = cli;
2315 
2316 	cli->share = talloc_strdup(cli, share);
2317 	if (tevent_req_nomem(cli->share, req)) {
2318 		return tevent_req_post(req, ev);
2319 	}
2320 
2321 	if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2322 		char *unc;
2323 
2324 		TALLOC_FREE(cli->smb2.tcon);
2325 		cli->smb2.tcon = smbXcli_tcon_create(cli);
2326 		if (tevent_req_nomem(cli->smb2.tcon, req)) {
2327 			return tevent_req_post(req, ev);
2328 		}
2329 
2330 		unc = talloc_asprintf(state, "\\\\%s\\%s",
2331 				      smbXcli_conn_remote_name(cli->conn),
2332 				      share);
2333 		if (tevent_req_nomem(unc, req)) {
2334 			return tevent_req_post(req, ev);
2335 		}
2336 
2337 		subreq = smb2cli_tcon_send(state, ev, cli->conn, cli->timeout,
2338 					   cli->smb2.session, cli->smb2.tcon,
2339 					   0, /* flags */
2340 					   unc);
2341 		if (tevent_req_nomem(subreq, req)) {
2342 			return tevent_req_post(req, ev);
2343 		}
2344 		tevent_req_set_callback(subreq, cli_tree_connect_smb2_done,
2345 					req);
2346 		return req;
2347 	}
2348 
2349 	if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) {
2350 		subreq = cli_tcon_andx_send(state, ev, cli, share, dev,
2351 					    pass, passlen);
2352 		if (tevent_req_nomem(subreq, req)) {
2353 			return tevent_req_post(req, ev);
2354 		}
2355 		tevent_req_set_callback(subreq, cli_tree_connect_andx_done,
2356 					req);
2357 		return req;
2358 	}
2359 
2360 	subreq = cli_raw_tcon_send(state, ev, cli, share, pass, dev);
2361 	if (tevent_req_nomem(subreq, req)) {
2362 		return tevent_req_post(req, ev);
2363 	}
2364 	tevent_req_set_callback(subreq, cli_tree_connect_raw_done, req);
2365 
2366 	return req;
2367 }
2368 
cli_tree_connect_smb2_done(struct tevent_req * subreq)2369 static void cli_tree_connect_smb2_done(struct tevent_req *subreq)
2370 {
2371 	tevent_req_simple_finish_ntstatus(
2372 		subreq, smb2cli_tcon_recv(subreq));
2373 }
2374 
cli_tree_connect_andx_done(struct tevent_req * subreq)2375 static void cli_tree_connect_andx_done(struct tevent_req *subreq)
2376 {
2377 	tevent_req_simple_finish_ntstatus(
2378 		subreq, cli_tcon_andx_recv(subreq));
2379 }
2380 
cli_tree_connect_raw_done(struct tevent_req * subreq)2381 static void cli_tree_connect_raw_done(struct tevent_req *subreq)
2382 {
2383 	struct tevent_req *req = tevent_req_callback_data(
2384 		subreq, struct tevent_req);
2385 	struct cli_tree_connect_state *state = tevent_req_data(
2386 		req, struct cli_tree_connect_state);
2387 	NTSTATUS status;
2388 	uint16_t max_xmit = 0;
2389 	uint16_t tid = 0;
2390 
2391 	status = cli_raw_tcon_recv(subreq, &max_xmit, &tid);
2392 	if (tevent_req_nterror(req, status)) {
2393 		return;
2394 	}
2395 
2396 	smb1cli_tcon_set_values(state->cli->smb1.tcon,
2397 				tid,
2398 				0, /* optional_support */
2399 				0, /* maximal_access */
2400 				0, /* guest_maximal_access */
2401 				NULL, /* service */
2402 				NULL); /* fs_type */
2403 
2404 	tevent_req_done(req);
2405 }
2406 
cli_tree_connect_recv(struct tevent_req * req)2407 static NTSTATUS cli_tree_connect_recv(struct tevent_req *req)
2408 {
2409 	return tevent_req_simple_recv_ntstatus(req);
2410 }
2411 
cli_tree_connect(struct cli_state * cli,const char * share,const char * dev,const char * pass)2412 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
2413 			  const char *dev, const char *pass)
2414 {
2415 	struct tevent_context *ev;
2416 	struct tevent_req *req;
2417 	NTSTATUS status = NT_STATUS_NO_MEMORY;
2418 
2419 	if (smbXcli_conn_has_async_calls(cli->conn)) {
2420 		return NT_STATUS_INVALID_PARAMETER;
2421 	}
2422 	ev = samba_tevent_context_init(talloc_tos());
2423 	if (ev == NULL) {
2424 		goto fail;
2425 	}
2426 	req = cli_tree_connect_send(ev, ev, cli, share, dev, pass);
2427 	if (req == NULL) {
2428 		goto fail;
2429 	}
2430 	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2431 		goto fail;
2432 	}
2433 	status = cli_tree_connect_recv(req);
2434 fail:
2435 	TALLOC_FREE(ev);
2436 	return status;
2437 }
2438 
cli_tree_connect_creds(struct cli_state * cli,const char * share,const char * dev,struct cli_credentials * creds)2439 NTSTATUS cli_tree_connect_creds(struct cli_state *cli,
2440 				const char *share, const char *dev,
2441 				struct cli_credentials *creds)
2442 {
2443 	const char *pw = NULL;
2444 
2445 	if (creds != NULL) {
2446 		pw = cli_credentials_get_password(creds);
2447 	}
2448 
2449 	return cli_tree_connect(cli, share, dev, pw);
2450 }
2451 
2452 /****************************************************************************
2453  Send a tree disconnect.
2454 ****************************************************************************/
2455 
2456 struct cli_tdis_state {
2457 	struct cli_state *cli;
2458 };
2459 
2460 static void cli_tdis_done(struct tevent_req *subreq);
2461 
cli_tdis_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct cli_state * cli)2462 static struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2463 				 struct tevent_context *ev,
2464 				 struct cli_state *cli)
2465 {
2466 	struct tevent_req *req, *subreq;
2467 	struct cli_tdis_state *state;
2468 
2469 	req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2470 	if (req == NULL) {
2471 		return NULL;
2472 	}
2473 	state->cli = cli;
2474 
2475 	subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, 0, NULL, 0, NULL);
2476 	if (tevent_req_nomem(subreq, req)) {
2477 		return tevent_req_post(req, ev);
2478 	}
2479 	tevent_req_set_callback(subreq, cli_tdis_done, req);
2480 	return req;
2481 }
2482 
cli_tdis_done(struct tevent_req * subreq)2483 static void cli_tdis_done(struct tevent_req *subreq)
2484 {
2485 	struct tevent_req *req = tevent_req_callback_data(
2486 		subreq, struct tevent_req);
2487 	struct cli_tdis_state *state = tevent_req_data(
2488 		req, struct cli_tdis_state);
2489 	NTSTATUS status;
2490 
2491 	status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2492 	TALLOC_FREE(subreq);
2493 	if (!NT_STATUS_IS_OK(status)) {
2494 		tevent_req_nterror(req, status);
2495 		return;
2496 	}
2497 	TALLOC_FREE(state->cli->smb1.tcon);
2498 	tevent_req_done(req);
2499 }
2500 
cli_tdis_recv(struct tevent_req * req)2501 static NTSTATUS cli_tdis_recv(struct tevent_req *req)
2502 {
2503 	return tevent_req_simple_recv_ntstatus(req);
2504 }
2505 
cli_tdis(struct cli_state * cli)2506 NTSTATUS cli_tdis(struct cli_state *cli)
2507 {
2508 	struct tevent_context *ev;
2509 	struct tevent_req *req;
2510 	NTSTATUS status = NT_STATUS_NO_MEMORY;
2511 
2512 	if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2513 		status = smb2cli_tdis(cli->conn,
2514 				    cli->timeout,
2515 				    cli->smb2.session,
2516 				    cli->smb2.tcon);
2517 		if (NT_STATUS_IS_OK(status)) {
2518 			TALLOC_FREE(cli->smb2.tcon);
2519 		}
2520 		return status;
2521 	}
2522 
2523 	if (smbXcli_conn_has_async_calls(cli->conn)) {
2524 		return NT_STATUS_INVALID_PARAMETER;
2525 	}
2526 	ev = samba_tevent_context_init(talloc_tos());
2527 	if (ev == NULL) {
2528 		goto fail;
2529 	}
2530 	req = cli_tdis_send(ev, ev, cli);
2531 	if (req == NULL) {
2532 		goto fail;
2533 	}
2534 	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2535 		goto fail;
2536 	}
2537 	status = cli_tdis_recv(req);
2538 fail:
2539 	TALLOC_FREE(ev);
2540 	return status;
2541 }
2542 
2543 struct cli_connect_sock_state {
2544 	const char **called_names;
2545 	const char **calling_names;
2546 	int *called_types;
2547 	int fd;
2548 	uint16_t port;
2549 };
2550 
2551 static void cli_connect_sock_done(struct tevent_req *subreq);
2552 
2553 /*
2554  * Async only if we don't have to look up the name, i.e. "pss" is set with a
2555  * nonzero address.
2556  */
2557 
cli_connect_sock_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,const char * host,int name_type,const struct sockaddr_storage * pss,const char * myname,uint16_t port)2558 static struct tevent_req *cli_connect_sock_send(
2559 	TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2560 	const char *host, int name_type, const struct sockaddr_storage *pss,
2561 	const char *myname, uint16_t port)
2562 {
2563 	struct tevent_req *req, *subreq;
2564 	struct cli_connect_sock_state *state;
2565 	struct sockaddr_storage *addrs;
2566 	unsigned i, num_addrs;
2567 	NTSTATUS status;
2568 
2569 	req = tevent_req_create(mem_ctx, &state,
2570 				struct cli_connect_sock_state);
2571 	if (req == NULL) {
2572 		return NULL;
2573 	}
2574 
2575 	if ((pss == NULL) || is_zero_addr(pss)) {
2576 
2577 		/*
2578 		 * Here we cheat. resolve_name_list is not async at all. So
2579 		 * this call will only be really async if the name lookup has
2580 		 * been done externally.
2581 		 */
2582 
2583 		status = resolve_name_list(state, host, name_type,
2584 					   &addrs, &num_addrs);
2585 		if (!NT_STATUS_IS_OK(status)) {
2586 			tevent_req_nterror(req, status);
2587 			return tevent_req_post(req, ev);
2588 		}
2589 	} else {
2590 		addrs = talloc_array(state, struct sockaddr_storage, 1);
2591 		if (tevent_req_nomem(addrs, req)) {
2592 			return tevent_req_post(req, ev);
2593 		}
2594 		addrs[0] = *pss;
2595 		num_addrs = 1;
2596 	}
2597 
2598 	state->called_names = talloc_array(state, const char *, num_addrs);
2599 	if (tevent_req_nomem(state->called_names, req)) {
2600 		return tevent_req_post(req, ev);
2601 	}
2602 	state->called_types = talloc_array(state, int, num_addrs);
2603 	if (tevent_req_nomem(state->called_types, req)) {
2604 		return tevent_req_post(req, ev);
2605 	}
2606 	state->calling_names = talloc_array(state, const char *, num_addrs);
2607 	if (tevent_req_nomem(state->calling_names, req)) {
2608 		return tevent_req_post(req, ev);
2609 	}
2610 	for (i=0; i<num_addrs; i++) {
2611 		state->called_names[i] = host;
2612 		state->called_types[i] = name_type;
2613 		state->calling_names[i] = myname;
2614 	}
2615 
2616 	subreq = smbsock_any_connect_send(
2617 		state, ev, addrs, state->called_names, state->called_types,
2618 		state->calling_names, NULL, num_addrs, port);
2619 	if (tevent_req_nomem(subreq, req)) {
2620 		return tevent_req_post(req, ev);
2621 	}
2622 	tevent_req_set_callback(subreq, cli_connect_sock_done, req);
2623 	return req;
2624 }
2625 
cli_connect_sock_done(struct tevent_req * subreq)2626 static void cli_connect_sock_done(struct tevent_req *subreq)
2627 {
2628 	struct tevent_req *req = tevent_req_callback_data(
2629 		subreq, struct tevent_req);
2630 	struct cli_connect_sock_state *state = tevent_req_data(
2631 		req, struct cli_connect_sock_state);
2632 	NTSTATUS status;
2633 
2634 	status = smbsock_any_connect_recv(subreq, &state->fd, NULL,
2635 					  &state->port);
2636 	TALLOC_FREE(subreq);
2637 	if (tevent_req_nterror(req, status)) {
2638 		return;
2639 	}
2640 	set_socket_options(state->fd, lp_socket_options());
2641 	tevent_req_done(req);
2642 }
2643 
cli_connect_sock_recv(struct tevent_req * req,int * pfd,uint16_t * pport)2644 static NTSTATUS cli_connect_sock_recv(struct tevent_req *req,
2645 				      int *pfd, uint16_t *pport)
2646 {
2647 	struct cli_connect_sock_state *state = tevent_req_data(
2648 		req, struct cli_connect_sock_state);
2649 	NTSTATUS status;
2650 
2651 	if (tevent_req_is_nterror(req, &status)) {
2652 		return status;
2653 	}
2654 	*pfd = state->fd;
2655 	*pport = state->port;
2656 	return NT_STATUS_OK;
2657 }
2658 
2659 struct cli_connect_nb_state {
2660 	const char *desthost;
2661 	int signing_state;
2662 	int flags;
2663 	struct cli_state *cli;
2664 };
2665 
2666 static void cli_connect_nb_done(struct tevent_req *subreq);
2667 
cli_connect_nb_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,const char * host,const struct sockaddr_storage * dest_ss,uint16_t port,int name_type,const char * myname,int signing_state,int flags)2668 static struct tevent_req *cli_connect_nb_send(
2669 	TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2670 	const char *host, const struct sockaddr_storage *dest_ss,
2671 	uint16_t port, int name_type, const char *myname,
2672 	int signing_state, int flags)
2673 {
2674 	struct tevent_req *req, *subreq;
2675 	struct cli_connect_nb_state *state;
2676 
2677 	req = tevent_req_create(mem_ctx, &state, struct cli_connect_nb_state);
2678 	if (req == NULL) {
2679 		return NULL;
2680 	}
2681 	state->signing_state = signing_state;
2682 	state->flags = flags;
2683 
2684 	if (host != NULL) {
2685 		char *p = strchr(host, '#');
2686 
2687 		if (p != NULL) {
2688 			name_type = strtol(p+1, NULL, 16);
2689 			host = talloc_strndup(state, host, p - host);
2690 			if (tevent_req_nomem(host, req)) {
2691 				return tevent_req_post(req, ev);
2692 			}
2693 		}
2694 
2695 		state->desthost = host;
2696 	} else if (dest_ss != NULL) {
2697 		state->desthost = print_canonical_sockaddr(state, dest_ss);
2698 		if (tevent_req_nomem(state->desthost, req)) {
2699 			return tevent_req_post(req, ev);
2700 		}
2701 	} else {
2702 		/* No host or dest_ss given. Error out. */
2703 		tevent_req_error(req, EINVAL);
2704 		return tevent_req_post(req, ev);
2705 	}
2706 
2707 	subreq = cli_connect_sock_send(state, ev, host, name_type, dest_ss,
2708 				       myname, port);
2709 	if (tevent_req_nomem(subreq, req)) {
2710 		return tevent_req_post(req, ev);
2711 	}
2712 	tevent_req_set_callback(subreq, cli_connect_nb_done, req);
2713 	return req;
2714 }
2715 
cli_connect_nb_done(struct tevent_req * subreq)2716 static void cli_connect_nb_done(struct tevent_req *subreq)
2717 {
2718 	struct tevent_req *req = tevent_req_callback_data(
2719 		subreq, struct tevent_req);
2720 	struct cli_connect_nb_state *state = tevent_req_data(
2721 		req, struct cli_connect_nb_state);
2722 	NTSTATUS status;
2723 	int fd = 0;
2724 	uint16_t port;
2725 
2726 	status = cli_connect_sock_recv(subreq, &fd, &port);
2727 	TALLOC_FREE(subreq);
2728 	if (tevent_req_nterror(req, status)) {
2729 		return;
2730 	}
2731 
2732 	state->cli = cli_state_create(state, fd, state->desthost,
2733 				      state->signing_state, state->flags);
2734 	if (tevent_req_nomem(state->cli, req)) {
2735 		close(fd);
2736 		return;
2737 	}
2738 	tevent_req_done(req);
2739 }
2740 
cli_connect_nb_recv(struct tevent_req * req,struct cli_state ** pcli)2741 static NTSTATUS cli_connect_nb_recv(struct tevent_req *req,
2742 				    struct cli_state **pcli)
2743 {
2744 	struct cli_connect_nb_state *state = tevent_req_data(
2745 		req, struct cli_connect_nb_state);
2746 	NTSTATUS status;
2747 
2748 	if (tevent_req_is_nterror(req, &status)) {
2749 		return status;
2750 	}
2751 	*pcli = talloc_move(NULL, &state->cli);
2752 	return NT_STATUS_OK;
2753 }
2754 
cli_connect_nb(const char * host,const struct sockaddr_storage * dest_ss,uint16_t port,int name_type,const char * myname,int signing_state,int flags,struct cli_state ** pcli)2755 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2756 			uint16_t port, int name_type, const char *myname,
2757 			int signing_state, int flags, struct cli_state **pcli)
2758 {
2759 	struct tevent_context *ev;
2760 	struct tevent_req *req;
2761 	NTSTATUS status = NT_STATUS_NO_MEMORY;
2762 
2763 	ev = samba_tevent_context_init(talloc_tos());
2764 	if (ev == NULL) {
2765 		goto fail;
2766 	}
2767 	req = cli_connect_nb_send(ev, ev, host, dest_ss, port, name_type,
2768 				  myname, signing_state, flags);
2769 	if (req == NULL) {
2770 		goto fail;
2771 	}
2772 	if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(20, 0))) {
2773 		goto fail;
2774 	}
2775 	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2776 		goto fail;
2777 	}
2778 	status = cli_connect_nb_recv(req, pcli);
2779 fail:
2780 	TALLOC_FREE(ev);
2781 	return status;
2782 }
2783 
2784 struct cli_start_connection_state {
2785 	struct tevent_context *ev;
2786 	struct cli_state *cli;
2787 	int min_protocol;
2788 	int max_protocol;
2789 };
2790 
2791 static void cli_start_connection_connected(struct tevent_req *subreq);
2792 static void cli_start_connection_done(struct tevent_req *subreq);
2793 
2794 /**
2795    establishes a connection to after the negprot.
2796    @param output_cli A fully initialised cli structure, non-null only on success
2797    @param dest_host The netbios name of the remote host
2798    @param dest_ss (optional) The the destination IP, NULL for name based lookup
2799    @param port (optional) The destination port (0 for default)
2800 */
2801 
cli_start_connection_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,const char * my_name,const char * dest_host,const struct sockaddr_storage * dest_ss,int port,int signing_state,int flags)2802 static struct tevent_req *cli_start_connection_send(
2803 	TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2804 	const char *my_name, const char *dest_host,
2805 	const struct sockaddr_storage *dest_ss, int port,
2806 	int signing_state, int flags)
2807 {
2808 	struct tevent_req *req, *subreq;
2809 	struct cli_start_connection_state *state;
2810 
2811 	req = tevent_req_create(mem_ctx, &state,
2812 				struct cli_start_connection_state);
2813 	if (req == NULL) {
2814 		return NULL;
2815 	}
2816 	state->ev = ev;
2817 
2818 	if (signing_state == SMB_SIGNING_IPC_DEFAULT) {
2819 		state->min_protocol = lp_client_ipc_min_protocol();
2820 		state->max_protocol = lp_client_ipc_max_protocol();
2821 	} else {
2822 		state->min_protocol = lp_client_min_protocol();
2823 		state->max_protocol = lp_client_max_protocol();
2824 	}
2825 
2826 	if (flags & CLI_FULL_CONNECTION_FORCE_SMB1) {
2827 		state->max_protocol = MIN(state->max_protocol, PROTOCOL_NT1);
2828 	}
2829 
2830 	if (flags & CLI_FULL_CONNECTION_DISABLE_SMB1) {
2831 		state->min_protocol = MAX(state->max_protocol, PROTOCOL_SMB2_02);
2832 		state->max_protocol = MAX(state->max_protocol, PROTOCOL_LATEST);
2833 	}
2834 
2835 	subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port,
2836 				     0x20, my_name, signing_state, flags);
2837 	if (tevent_req_nomem(subreq, req)) {
2838 		return tevent_req_post(req, ev);
2839 	}
2840 	tevent_req_set_callback(subreq, cli_start_connection_connected, req);
2841 	return req;
2842 }
2843 
cli_start_connection_connected(struct tevent_req * subreq)2844 static void cli_start_connection_connected(struct tevent_req *subreq)
2845 {
2846 	struct tevent_req *req = tevent_req_callback_data(
2847 		subreq, struct tevent_req);
2848 	struct cli_start_connection_state *state = tevent_req_data(
2849 		req, struct cli_start_connection_state);
2850 	NTSTATUS status;
2851 
2852 	status = cli_connect_nb_recv(subreq, &state->cli);
2853 	TALLOC_FREE(subreq);
2854 	if (tevent_req_nterror(req, status)) {
2855 		return;
2856 	}
2857 
2858 	subreq = smbXcli_negprot_send(state, state->ev, state->cli->conn,
2859 				      state->cli->timeout,
2860 				      state->min_protocol,
2861 				      state->max_protocol,
2862 				      WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
2863 	if (tevent_req_nomem(subreq, req)) {
2864 		return;
2865 	}
2866 	tevent_req_set_callback(subreq, cli_start_connection_done, req);
2867 }
2868 
cli_start_connection_done(struct tevent_req * subreq)2869 static void cli_start_connection_done(struct tevent_req *subreq)
2870 {
2871 	struct tevent_req *req = tevent_req_callback_data(
2872 		subreq, struct tevent_req);
2873 	struct cli_start_connection_state *state = tevent_req_data(
2874 		req, struct cli_start_connection_state);
2875 	NTSTATUS status;
2876 
2877 	status = smbXcli_negprot_recv(subreq);
2878 	TALLOC_FREE(subreq);
2879 	if (tevent_req_nterror(req, status)) {
2880 		return;
2881 	}
2882 
2883 	if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
2884 		/* Ensure we ask for some initial credits. */
2885 		smb2cli_conn_set_max_credits(state->cli->conn,
2886 					     DEFAULT_SMB2_MAX_CREDITS);
2887 	}
2888 
2889 	tevent_req_done(req);
2890 }
2891 
cli_start_connection_recv(struct tevent_req * req,struct cli_state ** output_cli)2892 static NTSTATUS cli_start_connection_recv(struct tevent_req *req,
2893 					  struct cli_state **output_cli)
2894 {
2895 	struct cli_start_connection_state *state = tevent_req_data(
2896 		req, struct cli_start_connection_state);
2897 	NTSTATUS status;
2898 
2899 	if (tevent_req_is_nterror(req, &status)) {
2900 		return status;
2901 	}
2902 	*output_cli = state->cli;
2903 
2904 	return NT_STATUS_OK;
2905 }
2906 
cli_start_connection(struct cli_state ** output_cli,const char * my_name,const char * dest_host,const struct sockaddr_storage * dest_ss,int port,int signing_state,int flags)2907 NTSTATUS cli_start_connection(struct cli_state **output_cli,
2908 			      const char *my_name,
2909 			      const char *dest_host,
2910 			      const struct sockaddr_storage *dest_ss, int port,
2911 			      int signing_state, int flags)
2912 {
2913 	struct tevent_context *ev;
2914 	struct tevent_req *req;
2915 	NTSTATUS status = NT_STATUS_NO_MEMORY;
2916 
2917 	ev = samba_tevent_context_init(talloc_tos());
2918 	if (ev == NULL) {
2919 		goto fail;
2920 	}
2921 	req = cli_start_connection_send(ev, ev, my_name, dest_host, dest_ss,
2922 					port, signing_state, flags);
2923 	if (req == NULL) {
2924 		goto fail;
2925 	}
2926 	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2927 		goto fail;
2928 	}
2929 	status = cli_start_connection_recv(req, output_cli);
2930 fail:
2931 	TALLOC_FREE(ev);
2932 	return status;
2933 }
2934 
2935 struct cli_smb1_setup_encryption_blob_state {
2936 	uint16_t setup[1];
2937 	uint8_t param[4];
2938 	NTSTATUS status;
2939 	DATA_BLOB out;
2940 	uint16_t enc_ctx_id;
2941 };
2942 
2943 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq);
2944 
cli_smb1_setup_encryption_blob_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct cli_state * cli,const DATA_BLOB in)2945 static struct tevent_req *cli_smb1_setup_encryption_blob_send(TALLOC_CTX *mem_ctx,
2946 							struct tevent_context *ev,
2947 							struct cli_state *cli,
2948 							const DATA_BLOB in)
2949 {
2950 	struct tevent_req *req = NULL;
2951 	struct cli_smb1_setup_encryption_blob_state *state = NULL;
2952 	struct tevent_req *subreq = NULL;
2953 
2954 	req = tevent_req_create(mem_ctx, &state,
2955 				struct cli_smb1_setup_encryption_blob_state);
2956 	if (req == NULL) {
2957 		return NULL;
2958 	}
2959 
2960 	if (in.length > CLI_BUFFER_SIZE) {
2961 		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
2962 		return tevent_req_post(req, ev);
2963 	}
2964 
2965 	SSVAL(state->setup+0,  0, TRANSACT2_SETFSINFO);
2966 	SSVAL(state->param, 0, 0);
2967 	SSVAL(state->param, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION);
2968 
2969 	subreq = smb1cli_trans_send(state, ev, cli->conn,
2970 				    SMBtrans2,
2971 				    0, 0, /* _flags */
2972 				    0, 0, /* _flags2 */
2973 				    cli->timeout,
2974 				    cli->smb1.pid,
2975 				    cli->smb1.tcon,
2976 				    cli->smb1.session,
2977 				    NULL, /* pipe_name */
2978 				    0, /* fid */
2979 				    0, /* function */
2980 				    0, /* flags */
2981 				    state->setup, 1, 0,
2982 				    state->param, 4, 2,
2983 				    in.data, in.length, CLI_BUFFER_SIZE);
2984 	if (tevent_req_nomem(subreq, req)) {
2985 		return tevent_req_post(req, ev);
2986 	}
2987 	tevent_req_set_callback(subreq,
2988 				cli_smb1_setup_encryption_blob_done,
2989 				req);
2990 
2991 	return req;
2992 }
2993 
cli_smb1_setup_encryption_blob_done(struct tevent_req * subreq)2994 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq)
2995 {
2996 	struct tevent_req *req =
2997 		tevent_req_callback_data(subreq,
2998 				struct tevent_req);
2999 	struct cli_smb1_setup_encryption_blob_state *state =
3000 		tevent_req_data(req,
3001 		struct cli_smb1_setup_encryption_blob_state);
3002 	uint8_t *rparam=NULL, *rdata=NULL;
3003 	uint32_t num_rparam, num_rdata;
3004 	NTSTATUS status;
3005 
3006 	status = smb1cli_trans_recv(subreq, state,
3007 				    NULL, /* recv_flags */
3008 				    NULL, 0, NULL, /* rsetup */
3009 				    &rparam, 0, &num_rparam,
3010 				    &rdata, 0, &num_rdata);
3011 	TALLOC_FREE(subreq);
3012 	state->status = status;
3013 	if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
3014 		status = NT_STATUS_OK;
3015 	}
3016 	if (tevent_req_nterror(req, status)) {
3017 		return;
3018 	}
3019 
3020 	if (num_rparam == 2) {
3021 		state->enc_ctx_id = SVAL(rparam, 0);
3022 	}
3023 	TALLOC_FREE(rparam);
3024 
3025 	state->out = data_blob_const(rdata, num_rdata);
3026 
3027 	tevent_req_done(req);
3028 }
3029 
cli_smb1_setup_encryption_blob_recv(struct tevent_req * req,TALLOC_CTX * mem_ctx,DATA_BLOB * out,uint16_t * enc_ctx_id)3030 static NTSTATUS cli_smb1_setup_encryption_blob_recv(struct tevent_req *req,
3031 						    TALLOC_CTX *mem_ctx,
3032 						    DATA_BLOB *out,
3033 						    uint16_t *enc_ctx_id)
3034 {
3035 	struct cli_smb1_setup_encryption_blob_state *state =
3036 		tevent_req_data(req,
3037 		struct cli_smb1_setup_encryption_blob_state);
3038 	NTSTATUS status;
3039 
3040 	if (tevent_req_is_nterror(req, &status)) {
3041 		tevent_req_received(req);
3042 		return status;
3043 	}
3044 
3045 	status = state->status;
3046 
3047 	*out = state->out;
3048 	talloc_steal(mem_ctx, out->data);
3049 
3050 	*enc_ctx_id = state->enc_ctx_id;
3051 
3052 	tevent_req_received(req);
3053 	return status;
3054 }
3055 
3056 struct cli_smb1_setup_encryption_state {
3057 	struct tevent_context *ev;
3058 	struct cli_state *cli;
3059 	struct smb_trans_enc_state *es;
3060 	DATA_BLOB blob_in;
3061 	DATA_BLOB blob_out;
3062 	bool local_ready;
3063 	bool remote_ready;
3064 };
3065 
3066 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req);
3067 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq);
3068 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req);
3069 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq);
3070 static void cli_smb1_setup_encryption_ready(struct tevent_req *req);
3071 
cli_smb1_setup_encryption_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct cli_state * cli,struct cli_credentials * creds)3072 static struct tevent_req *cli_smb1_setup_encryption_send(TALLOC_CTX *mem_ctx,
3073 						struct tevent_context *ev,
3074 						struct cli_state *cli,
3075 						struct cli_credentials *creds)
3076 {
3077 	struct tevent_req *req = NULL;
3078 	struct cli_smb1_setup_encryption_state *state = NULL;
3079 	struct auth_generic_state *ags = NULL;
3080 	const DATA_BLOB *b = NULL;
3081 	bool auth_requested = false;
3082 	const char *target_service = NULL;
3083 	const char *target_hostname = NULL;
3084 	NTSTATUS status;
3085 
3086 	req = tevent_req_create(mem_ctx, &state,
3087 				struct cli_smb1_setup_encryption_state);
3088 	if (req == NULL) {
3089 		return NULL;
3090 	}
3091 	state->ev = ev;
3092 	state->cli = cli;
3093 
3094 	auth_requested = cli_credentials_authentication_requested(creds);
3095 	if (!auth_requested) {
3096 		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3097 		return tevent_req_post(req, ev);
3098 	}
3099 
3100 	target_service = "cifs";
3101 	target_hostname = smbXcli_conn_remote_name(cli->conn);
3102 
3103 	status = cli_session_creds_prepare_krb5(cli, creds);
3104 	if (tevent_req_nterror(req, status)) {
3105 		return tevent_req_post(req, ev);
3106 	}
3107 
3108 	state->es = talloc_zero(state, struct smb_trans_enc_state);
3109 	if (tevent_req_nomem(state->es, req)) {
3110 		return tevent_req_post(req, ev);
3111 	}
3112 
3113 	status = auth_generic_client_prepare(state->es, &ags);
3114 	if (tevent_req_nterror(req, status)) {
3115 		return tevent_req_post(req, ev);
3116 	}
3117 
3118 	gensec_want_feature(ags->gensec_security,
3119 			    GENSEC_FEATURE_SIGN);
3120 	gensec_want_feature(ags->gensec_security,
3121 			    GENSEC_FEATURE_SEAL);
3122 
3123 	status = auth_generic_set_creds(ags, creds);
3124 	if (tevent_req_nterror(req, status)) {
3125 		return tevent_req_post(req, ev);
3126 	}
3127 
3128 	if (target_service != NULL) {
3129 		status = gensec_set_target_service(ags->gensec_security,
3130 						   target_service);
3131 		if (tevent_req_nterror(req, status)) {
3132 			return tevent_req_post(req, ev);
3133 		}
3134 	}
3135 
3136 	if (target_hostname != NULL) {
3137 		status = gensec_set_target_hostname(ags->gensec_security,
3138 						    target_hostname);
3139 		if (tevent_req_nterror(req, status)) {
3140 			return tevent_req_post(req, ev);
3141 		}
3142 	}
3143 
3144 	gensec_set_max_update_size(ags->gensec_security,
3145 				   CLI_BUFFER_SIZE);
3146 
3147 	b = smbXcli_conn_server_gss_blob(state->cli->conn);
3148 	if (b != NULL) {
3149 		state->blob_in = *b;
3150 	}
3151 
3152 	status = auth_generic_client_start(ags, GENSEC_OID_SPNEGO);
3153 	if (tevent_req_nterror(req, status)) {
3154 		return tevent_req_post(req, ev);
3155 	}
3156 
3157 	/*
3158 	 * We only need the gensec_security part from here.
3159 	 */
3160 	state->es->gensec_security = talloc_move(state->es,
3161 						 &ags->gensec_security);
3162 	TALLOC_FREE(ags);
3163 
3164 	cli_smb1_setup_encryption_local_next(req);
3165 	if (!tevent_req_is_in_progress(req)) {
3166 		return tevent_req_post(req, ev);
3167 	}
3168 
3169 	return req;
3170 }
3171 
cli_smb1_setup_encryption_local_next(struct tevent_req * req)3172 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req)
3173 {
3174 	struct cli_smb1_setup_encryption_state *state =
3175 		tevent_req_data(req,
3176 		struct cli_smb1_setup_encryption_state);
3177 	struct tevent_req *subreq = NULL;
3178 
3179 	if (state->local_ready) {
3180 		tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3181 		return;
3182 	}
3183 
3184 	subreq = gensec_update_send(state, state->ev,
3185 			state->es->gensec_security,
3186 			state->blob_in);
3187 	if (tevent_req_nomem(subreq, req)) {
3188 		return;
3189 	}
3190 	tevent_req_set_callback(subreq, cli_smb1_setup_encryption_local_done, req);
3191 }
3192 
cli_smb1_setup_encryption_local_done(struct tevent_req * subreq)3193 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq)
3194 {
3195 	struct tevent_req *req =
3196 		tevent_req_callback_data(subreq,
3197 		struct tevent_req);
3198 	struct cli_smb1_setup_encryption_state *state =
3199 		tevent_req_data(req,
3200 		struct cli_smb1_setup_encryption_state);
3201 	NTSTATUS status;
3202 
3203 	status = gensec_update_recv(subreq, state, &state->blob_out);
3204 	TALLOC_FREE(subreq);
3205 	state->blob_in = data_blob_null;
3206 	if (!NT_STATUS_IS_OK(status) &&
3207 	    !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3208 	{
3209 		tevent_req_nterror(req, status);
3210 		return;
3211 	}
3212 
3213 	if (NT_STATUS_IS_OK(status)) {
3214 		state->local_ready = true;
3215 	}
3216 
3217 	/*
3218 	 * We always get NT_STATUS_OK from the server even if it is not ready.
3219 	 * So guess the server is ready when we are ready and already sent
3220 	 * our last blob to the server.
3221 	 */
3222 	if (state->local_ready && state->blob_out.length == 0) {
3223 		state->remote_ready = true;
3224 	}
3225 
3226 	if (state->local_ready && state->remote_ready) {
3227 		cli_smb1_setup_encryption_ready(req);
3228 		return;
3229 	}
3230 
3231 	cli_smb1_setup_encryption_remote_next(req);
3232 }
3233 
cli_smb1_setup_encryption_remote_next(struct tevent_req * req)3234 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req)
3235 {
3236 	struct cli_smb1_setup_encryption_state *state =
3237 		tevent_req_data(req,
3238 		struct cli_smb1_setup_encryption_state);
3239 	struct tevent_req *subreq = NULL;
3240 
3241 	if (state->remote_ready) {
3242 		tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3243 		return;
3244 	}
3245 
3246 	subreq = cli_smb1_setup_encryption_blob_send(state, state->ev,
3247 						     state->cli, state->blob_out);
3248 	if (tevent_req_nomem(subreq, req)) {
3249 		return;
3250 	}
3251 	tevent_req_set_callback(subreq,
3252 				cli_smb1_setup_encryption_remote_done,
3253 				req);
3254 }
3255 
cli_smb1_setup_encryption_remote_done(struct tevent_req * subreq)3256 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq)
3257 {
3258 	struct tevent_req *req =
3259 		tevent_req_callback_data(subreq,
3260 		struct tevent_req);
3261 	struct cli_smb1_setup_encryption_state *state =
3262 		tevent_req_data(req,
3263 		struct cli_smb1_setup_encryption_state);
3264 	NTSTATUS status;
3265 
3266 	status = cli_smb1_setup_encryption_blob_recv(subreq, state,
3267 						     &state->blob_in,
3268 						     &state->es->enc_ctx_num);
3269 	TALLOC_FREE(subreq);
3270 	data_blob_free(&state->blob_out);
3271 	if (!NT_STATUS_IS_OK(status) &&
3272 	    !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3273 	{
3274 		tevent_req_nterror(req, status);
3275 		return;
3276 	}
3277 
3278 	/*
3279 	 * We always get NT_STATUS_OK even if the server is not ready.
3280 	 * So guess the server is ready when we are ready and sent
3281 	 * our last blob to the server.
3282 	 */
3283 	if (state->local_ready) {
3284 		state->remote_ready = true;
3285 	}
3286 
3287 	if (state->local_ready && state->remote_ready) {
3288 		cli_smb1_setup_encryption_ready(req);
3289 		return;
3290 	}
3291 
3292 	cli_smb1_setup_encryption_local_next(req);
3293 }
3294 
cli_smb1_setup_encryption_ready(struct tevent_req * req)3295 static void cli_smb1_setup_encryption_ready(struct tevent_req *req)
3296 {
3297 	struct cli_smb1_setup_encryption_state *state =
3298 		tevent_req_data(req,
3299 		struct cli_smb1_setup_encryption_state);
3300 	struct smb_trans_enc_state *es = NULL;
3301 
3302 	if (state->blob_in.length != 0) {
3303 		tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3304 		return;
3305 	}
3306 
3307 	if (state->blob_out.length != 0) {
3308 		tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3309 		return;
3310 	}
3311 
3312 	es = talloc_move(state->cli->conn, &state->es);
3313 	es->enc_on = true;
3314 	smb1cli_conn_set_encryption(state->cli->conn, es);
3315 	es = NULL;
3316 
3317 	tevent_req_done(req);
3318 }
3319 
cli_smb1_setup_encryption_recv(struct tevent_req * req)3320 static NTSTATUS cli_smb1_setup_encryption_recv(struct tevent_req *req)
3321 {
3322 	return tevent_req_simple_recv_ntstatus(req);
3323 }
3324 
cli_smb1_setup_encryption(struct cli_state * cli,struct cli_credentials * creds)3325 NTSTATUS cli_smb1_setup_encryption(struct cli_state *cli,
3326 				   struct cli_credentials *creds)
3327 {
3328 	struct tevent_context *ev = NULL;
3329 	struct tevent_req *req = NULL;
3330 	NTSTATUS status = NT_STATUS_NO_MEMORY;
3331 
3332 	ev = samba_tevent_context_init(talloc_tos());
3333 	if (ev == NULL) {
3334 		goto fail;
3335 	}
3336 	req = cli_smb1_setup_encryption_send(ev, ev, cli, creds);
3337 	if (req == NULL) {
3338 		goto fail;
3339 	}
3340 	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3341 		goto fail;
3342 	}
3343 	status = cli_smb1_setup_encryption_recv(req);
3344  fail:
3345 	TALLOC_FREE(ev);
3346 	return status;
3347 }
3348 
3349 /**
3350    establishes a connection right up to doing tconX, password specified.
3351    @param output_cli A fully initialised cli structure, non-null only on success
3352    @param dest_host The netbios name of the remote host
3353    @param dest_ip (optional) The the destination IP, NULL for name based lookup
3354    @param port (optional) The destination port (0 for default)
3355    @param service (optional) The share to make the connection to.  Should be 'unqualified' in any way.
3356    @param service_type The 'type' of serivice.
3357    @param creds The used user credentials
3358 */
3359 
3360 struct cli_full_connection_creds_state {
3361 	struct tevent_context *ev;
3362 	const char *service;
3363 	const char *service_type;
3364 	struct cli_credentials *creds;
3365 	int flags;
3366 	struct cli_state *cli;
3367 };
3368 
cli_full_connection_creds_state_destructor(struct cli_full_connection_creds_state * s)3369 static int cli_full_connection_creds_state_destructor(
3370 	struct cli_full_connection_creds_state *s)
3371 {
3372 	if (s->cli != NULL) {
3373 		cli_shutdown(s->cli);
3374 		s->cli = NULL;
3375 	}
3376 	return 0;
3377 }
3378 
3379 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq);
3380 static void cli_full_connection_creds_sess_start(struct tevent_req *req);
3381 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq);
3382 static void cli_full_connection_creds_tcon_start(struct tevent_req *req);
3383 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq);
3384 
cli_full_connection_creds_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,const char * my_name,const char * dest_host,const struct sockaddr_storage * dest_ss,int port,const char * service,const char * service_type,struct cli_credentials * creds,int flags,int signing_state)3385 struct tevent_req *cli_full_connection_creds_send(
3386 	TALLOC_CTX *mem_ctx, struct tevent_context *ev,
3387 	const char *my_name, const char *dest_host,
3388 	const struct sockaddr_storage *dest_ss, int port,
3389 	const char *service, const char *service_type,
3390 	struct cli_credentials *creds,
3391 	int flags, int signing_state)
3392 {
3393 	struct tevent_req *req, *subreq;
3394 	struct cli_full_connection_creds_state *state;
3395 	enum credentials_use_kerberos krb5_state;
3396 	uint32_t gensec_features = 0;
3397 
3398 	req = tevent_req_create(mem_ctx, &state,
3399 				struct cli_full_connection_creds_state);
3400 	if (req == NULL) {
3401 		return NULL;
3402 	}
3403 	talloc_set_destructor(state, cli_full_connection_creds_state_destructor);
3404 
3405 	flags &= ~CLI_FULL_CONNECTION_USE_KERBEROS;
3406 	flags &= ~CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3407 	flags &= ~CLI_FULL_CONNECTION_USE_CCACHE;
3408 	flags &= ~CLI_FULL_CONNECTION_USE_NT_HASH;
3409 
3410 	krb5_state = cli_credentials_get_kerberos_state(creds);
3411 	switch (krb5_state) {
3412 	case CRED_MUST_USE_KERBEROS:
3413 		flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3414 		flags &= ~CLI_FULL_CONNECTION_DONT_SPNEGO;
3415 		break;
3416 	case CRED_AUTO_USE_KERBEROS:
3417 		flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3418 		flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3419 		break;
3420 	case CRED_DONT_USE_KERBEROS:
3421 		break;
3422 	}
3423 
3424 	gensec_features = cli_credentials_get_gensec_features(creds);
3425 	if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
3426 		flags |= CLI_FULL_CONNECTION_USE_CCACHE;
3427 	}
3428 
3429 	state->ev = ev;
3430 	state->service = service;
3431 	state->service_type = service_type;
3432 	state->creds = creds;
3433 	state->flags = flags;
3434 
3435 	subreq = cli_start_connection_send(
3436 		state, ev, my_name, dest_host, dest_ss, port,
3437 		signing_state, flags);
3438 	if (tevent_req_nomem(subreq, req)) {
3439 		return tevent_req_post(req, ev);
3440 	}
3441 	tevent_req_set_callback(subreq,
3442 				cli_full_connection_creds_conn_done,
3443 				req);
3444 	return req;
3445 }
3446 
cli_full_connection_creds_conn_done(struct tevent_req * subreq)3447 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq)
3448 {
3449 	struct tevent_req *req = tevent_req_callback_data(
3450 		subreq, struct tevent_req);
3451 	struct cli_full_connection_creds_state *state = tevent_req_data(
3452 		req, struct cli_full_connection_creds_state);
3453 	NTSTATUS status;
3454 
3455 	status = cli_start_connection_recv(subreq, &state->cli);
3456 	TALLOC_FREE(subreq);
3457 	if (tevent_req_nterror(req, status)) {
3458 		return;
3459 	}
3460 
3461 	cli_full_connection_creds_sess_start(req);
3462 }
3463 
cli_full_connection_creds_sess_start(struct tevent_req * req)3464 static void cli_full_connection_creds_sess_start(struct tevent_req *req)
3465 {
3466 	struct cli_full_connection_creds_state *state = tevent_req_data(
3467 		req, struct cli_full_connection_creds_state);
3468 	struct tevent_req *subreq = NULL;
3469 
3470 	subreq = cli_session_setup_creds_send(
3471 		state, state->ev, state->cli, state->creds);
3472 	if (tevent_req_nomem(subreq, req)) {
3473 		return;
3474 	}
3475 	tevent_req_set_callback(subreq,
3476 				cli_full_connection_creds_sess_done,
3477 				req);
3478 }
3479 
cli_full_connection_creds_sess_done(struct tevent_req * subreq)3480 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq)
3481 {
3482 	struct tevent_req *req = tevent_req_callback_data(
3483 		subreq, struct tevent_req);
3484 	struct cli_full_connection_creds_state *state = tevent_req_data(
3485 		req, struct cli_full_connection_creds_state);
3486 	NTSTATUS status;
3487 
3488 	status = cli_session_setup_creds_recv(subreq);
3489 	TALLOC_FREE(subreq);
3490 
3491 	if (!NT_STATUS_IS_OK(status) &&
3492 	    (state->flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3493 
3494 		state->flags &= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3495 
3496 		state->creds = cli_credentials_init_anon(state);
3497 		if (tevent_req_nomem(state->creds, req)) {
3498 			return;
3499 		}
3500 
3501 		cli_full_connection_creds_sess_start(req);
3502 		return;
3503 	}
3504 
3505 	if (tevent_req_nterror(req, status)) {
3506 		return;
3507 	}
3508 
3509 	cli_full_connection_creds_tcon_start(req);
3510 }
3511 
cli_full_connection_creds_tcon_start(struct tevent_req * req)3512 static void cli_full_connection_creds_tcon_start(struct tevent_req *req)
3513 {
3514 	struct cli_full_connection_creds_state *state = tevent_req_data(
3515 		req, struct cli_full_connection_creds_state);
3516 	struct tevent_req *subreq = NULL;
3517 	const char *password = NULL;
3518 
3519 	if (state->service == NULL) {
3520 		tevent_req_done(req);
3521 		return;
3522 	}
3523 
3524 	password = cli_credentials_get_password(state->creds);
3525 
3526 	subreq = cli_tree_connect_send(state, state->ev,
3527 				       state->cli,
3528 				       state->service,
3529 				       state->service_type,
3530 				       password);
3531 	if (tevent_req_nomem(subreq, req)) {
3532 		return;
3533 	}
3534 	tevent_req_set_callback(subreq,
3535 				cli_full_connection_creds_tcon_done,
3536 				req);
3537 }
3538 
cli_full_connection_creds_tcon_done(struct tevent_req * subreq)3539 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq)
3540 {
3541 	struct tevent_req *req = tevent_req_callback_data(
3542 		subreq, struct tevent_req);
3543 	NTSTATUS status;
3544 
3545 	status = cli_tree_connect_recv(subreq);
3546 	TALLOC_FREE(subreq);
3547 	if (tevent_req_nterror(req, status)) {
3548 		return;
3549 	}
3550 
3551 	tevent_req_done(req);
3552 }
3553 
cli_full_connection_creds_recv(struct tevent_req * req,struct cli_state ** output_cli)3554 NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req,
3555 				  struct cli_state **output_cli)
3556 {
3557 	struct cli_full_connection_creds_state *state = tevent_req_data(
3558 		req, struct cli_full_connection_creds_state);
3559 	NTSTATUS status;
3560 
3561 	if (tevent_req_is_nterror(req, &status)) {
3562 		return status;
3563 	}
3564 	*output_cli = state->cli;
3565 	talloc_set_destructor(state, NULL);
3566 	return NT_STATUS_OK;
3567 }
3568 
cli_full_connection_creds(struct cli_state ** output_cli,const char * my_name,const char * dest_host,const struct sockaddr_storage * dest_ss,int port,const char * service,const char * service_type,struct cli_credentials * creds,int flags,int signing_state)3569 NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
3570 				   const char *my_name,
3571 				   const char *dest_host,
3572 				   const struct sockaddr_storage *dest_ss, int port,
3573 				   const char *service, const char *service_type,
3574 				   struct cli_credentials *creds,
3575 				   int flags,
3576 				   int signing_state)
3577 {
3578 	struct tevent_context *ev;
3579 	struct tevent_req *req;
3580 	NTSTATUS status = NT_STATUS_NO_MEMORY;
3581 
3582 	ev = samba_tevent_context_init(talloc_tos());
3583 	if (ev == NULL) {
3584 		goto fail;
3585 	}
3586 	req = cli_full_connection_creds_send(
3587 		ev, ev, my_name, dest_host, dest_ss, port, service,
3588 		service_type, creds, flags, signing_state);
3589 	if (req == NULL) {
3590 		goto fail;
3591 	}
3592 	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3593 		goto fail;
3594 	}
3595 	status = cli_full_connection_creds_recv(req, output_cli);
3596  fail:
3597 	TALLOC_FREE(ev);
3598 	return status;
3599 }
3600 
cli_full_connection(struct cli_state ** output_cli,const char * my_name,const char * dest_host,const struct sockaddr_storage * dest_ss,int port,const char * service,const char * service_type,const char * user,const char * domain,const char * password,int flags,int signing_state)3601 NTSTATUS cli_full_connection(struct cli_state **output_cli,
3602 			     const char *my_name,
3603 			     const char *dest_host,
3604 			     const struct sockaddr_storage *dest_ss, int port,
3605 			     const char *service, const char *service_type,
3606 			     const char *user, const char *domain,
3607 			     const char *password, int flags,
3608 			     int signing_state)
3609 {
3610 	TALLOC_CTX *frame = talloc_stackframe();
3611 	NTSTATUS status;
3612 	bool use_kerberos = false;
3613 	bool fallback_after_kerberos = false;
3614 	bool use_ccache = false;
3615 	bool pw_nt_hash = false;
3616 	struct cli_credentials *creds = NULL;
3617 
3618 	if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) {
3619 		use_kerberos = true;
3620 	}
3621 
3622 	if (flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) {
3623 		fallback_after_kerberos = true;
3624 	}
3625 
3626 	if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
3627 		use_ccache = true;
3628 	}
3629 
3630 	if (flags & CLI_FULL_CONNECTION_USE_NT_HASH) {
3631 		pw_nt_hash = true;
3632 	}
3633 
3634 	creds = cli_session_creds_init(frame,
3635 				       user,
3636 				       domain,
3637 				       NULL, /* realm (use default) */
3638 				       password,
3639 				       use_kerberos,
3640 				       fallback_after_kerberos,
3641 				       use_ccache,
3642 				       pw_nt_hash);
3643 	if (creds == NULL) {
3644 		TALLOC_FREE(frame);
3645 		return NT_STATUS_NO_MEMORY;
3646 	}
3647 
3648 	status = cli_full_connection_creds(output_cli, my_name,
3649 					   dest_host, dest_ss, port,
3650 					   service, service_type,
3651 					   creds, flags, signing_state);
3652 	if (!NT_STATUS_IS_OK(status)) {
3653 		TALLOC_FREE(frame);
3654 		return status;
3655 	}
3656 
3657 	TALLOC_FREE(frame);
3658 	return NT_STATUS_OK;
3659 }
3660 
3661 /****************************************************************************
3662  Send an old style tcon.
3663 ****************************************************************************/
3664 struct cli_raw_tcon_state {
3665 	uint16_t *ret_vwv;
3666 };
3667 
3668 static void cli_raw_tcon_done(struct tevent_req *subreq);
3669 
cli_raw_tcon_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct cli_state * cli,const char * service,const char * pass,const char * dev)3670 static struct tevent_req *cli_raw_tcon_send(
3671 	TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
3672 	const char *service, const char *pass, const char *dev)
3673 {
3674 	struct tevent_req *req, *subreq;
3675 	struct cli_raw_tcon_state *state;
3676 	uint8_t *bytes;
3677 
3678 	req = tevent_req_create(mem_ctx, &state, struct cli_raw_tcon_state);
3679 	if (req == NULL) {
3680 		return NULL;
3681 	}
3682 
3683 	if (!lp_client_plaintext_auth() && (*pass)) {
3684 		DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3685 			  " or 'client ntlmv2 auth = yes'\n"));
3686 		tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3687 		return tevent_req_post(req, ev);
3688 	}
3689 
3690 	TALLOC_FREE(cli->smb1.tcon);
3691 	cli->smb1.tcon = smbXcli_tcon_create(cli);
3692 	if (tevent_req_nomem(cli->smb1.tcon, req)) {
3693 		return tevent_req_post(req, ev);
3694 	}
3695 	smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
3696 
3697 	bytes = talloc_array(state, uint8_t, 0);
3698 	bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3699 	bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3700 				   service, strlen(service)+1, NULL);
3701 	bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3702 	bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3703 				   pass, strlen(pass)+1, NULL);
3704 	bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3705 	bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3706 				   dev, strlen(dev)+1, NULL);
3707 
3708 	if (tevent_req_nomem(bytes, req)) {
3709 		return tevent_req_post(req, ev);
3710 	}
3711 
3712 	subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, 0, NULL,
3713 			      talloc_get_size(bytes), bytes);
3714 	if (tevent_req_nomem(subreq, req)) {
3715 		return tevent_req_post(req, ev);
3716 	}
3717 	tevent_req_set_callback(subreq, cli_raw_tcon_done, req);
3718 	return req;
3719 }
3720 
cli_raw_tcon_done(struct tevent_req * subreq)3721 static void cli_raw_tcon_done(struct tevent_req *subreq)
3722 {
3723 	struct tevent_req *req = tevent_req_callback_data(
3724 		subreq, struct tevent_req);
3725 	struct cli_raw_tcon_state *state = tevent_req_data(
3726 		req, struct cli_raw_tcon_state);
3727 	NTSTATUS status;
3728 
3729 	status = cli_smb_recv(subreq, state, NULL, 2, NULL, &state->ret_vwv,
3730 			      NULL, NULL);
3731 	TALLOC_FREE(subreq);
3732 	if (tevent_req_nterror(req, status)) {
3733 		return;
3734 	}
3735 	tevent_req_done(req);
3736 }
3737 
cli_raw_tcon_recv(struct tevent_req * req,uint16_t * max_xmit,uint16_t * tid)3738 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
3739 				  uint16_t *max_xmit, uint16_t *tid)
3740 {
3741 	struct cli_raw_tcon_state *state = tevent_req_data(
3742 		req, struct cli_raw_tcon_state);
3743 	NTSTATUS status;
3744 
3745 	if (tevent_req_is_nterror(req, &status)) {
3746 		return status;
3747 	}
3748 	*max_xmit = SVAL(state->ret_vwv + 0, 0);
3749 	*tid = SVAL(state->ret_vwv + 1, 0);
3750 	return NT_STATUS_OK;
3751 }
3752 
cli_raw_tcon(struct cli_state * cli,const char * service,const char * pass,const char * dev,uint16_t * max_xmit,uint16_t * tid)3753 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3754 		      const char *service, const char *pass, const char *dev,
3755 		      uint16_t *max_xmit, uint16_t *tid)
3756 {
3757 	struct tevent_context *ev;
3758 	struct tevent_req *req;
3759 	NTSTATUS status = NT_STATUS_NO_MEMORY;
3760 
3761 	ev = samba_tevent_context_init(talloc_tos());
3762 	if (ev == NULL) {
3763 		goto fail;
3764 	}
3765 	req = cli_raw_tcon_send(ev, ev, cli, service, pass, dev);
3766 	if (req == NULL) {
3767 		goto fail;
3768 	}
3769 	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3770 		goto fail;
3771 	}
3772 	status = cli_raw_tcon_recv(req, max_xmit, tid);
3773 fail:
3774 	TALLOC_FREE(ev);
3775 	return status;
3776 }
3777 
3778 /* Return a cli_state pointing at the IPC$ share for the given server */
3779 
get_ipc_connect(char * server,struct sockaddr_storage * server_ss,const struct user_auth_info * user_info)3780 struct cli_state *get_ipc_connect(char *server,
3781 				struct sockaddr_storage *server_ss,
3782 				const struct user_auth_info *user_info)
3783 {
3784         struct cli_state *cli;
3785 	NTSTATUS nt_status;
3786 	uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3787 
3788 	if (get_cmdline_auth_info_use_kerberos(user_info)) {
3789 		flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3790 	}
3791 
3792 	flags |= CLI_FULL_CONNECTION_FORCE_SMB1;
3793 
3794 	nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
3795 					get_cmdline_auth_info_username(user_info),
3796 					lp_workgroup(),
3797 					get_cmdline_auth_info_password(user_info),
3798 					flags,
3799 					SMB_SIGNING_DEFAULT);
3800 
3801 	if (NT_STATUS_IS_OK(nt_status)) {
3802 		return cli;
3803 	} else if (is_ipaddress(server)) {
3804 	    /* windows 9* needs a correct NMB name for connections */
3805 	    fstring remote_name;
3806 
3807 	    if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3808 		cli = get_ipc_connect(remote_name, server_ss, user_info);
3809 		if (cli)
3810 		    return cli;
3811 	    }
3812 	}
3813 	return NULL;
3814 }
3815 
3816 /*
3817  * Given the IP address of a master browser on the network, return its
3818  * workgroup and connect to it.
3819  *
3820  * This function is provided to allow additional processing beyond what
3821  * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3822  * browsers and obtain each master browsers' list of domains (in case the
3823  * first master browser is recently on the network and has not yet
3824  * synchronized with other master browsers and therefore does not yet have the
3825  * entire network browse list)
3826  */
3827 
get_ipc_connect_master_ip(TALLOC_CTX * ctx,struct sockaddr_storage * mb_ip,const struct user_auth_info * user_info,char ** pp_workgroup_out)3828 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3829 				struct sockaddr_storage *mb_ip,
3830 				const struct user_auth_info *user_info,
3831 				char **pp_workgroup_out)
3832 {
3833 	char addr[INET6_ADDRSTRLEN];
3834         fstring name;
3835 	struct cli_state *cli;
3836 	struct sockaddr_storage server_ss;
3837 
3838 	*pp_workgroup_out = NULL;
3839 
3840 	print_sockaddr(addr, sizeof(addr), mb_ip);
3841         DEBUG(99, ("Looking up name of master browser %s\n",
3842                    addr));
3843 
3844         /*
3845          * Do a name status query to find out the name of the master browser.
3846          * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3847          * master browser will not respond to a wildcard query (or, at least,
3848          * an NT4 server acting as the domain master browser will not).
3849          *
3850          * We might be able to use ONLY the query on MSBROWSE, but that's not
3851          * yet been tested with all Windows versions, so until it is, leave
3852          * the original wildcard query as the first choice and fall back to
3853          * MSBROWSE if the wildcard query fails.
3854          */
3855         if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3856             !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3857 
3858                 DEBUG(99, ("Could not retrieve name status for %s\n",
3859                            addr));
3860                 return NULL;
3861         }
3862 
3863         if (!find_master_ip(name, &server_ss)) {
3864                 DEBUG(99, ("Could not find master ip for %s\n", name));
3865                 return NULL;
3866         }
3867 
3868 	*pp_workgroup_out = talloc_strdup(ctx, name);
3869 
3870 	DEBUG(4, ("found master browser %s, %s\n", name, addr));
3871 
3872 	print_sockaddr(addr, sizeof(addr), &server_ss);
3873 	cli = get_ipc_connect(addr, &server_ss, user_info);
3874 
3875 	return cli;
3876 }
3877 
3878 /*
3879  * Return the IP address and workgroup of a master browser on the network, and
3880  * connect to it.
3881  */
3882 
get_ipc_connect_master_ip_bcast(TALLOC_CTX * ctx,const struct user_auth_info * user_info,char ** pp_workgroup_out)3883 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3884 					const struct user_auth_info *user_info,
3885 					char **pp_workgroup_out)
3886 {
3887 	struct sockaddr_storage *ip_list;
3888 	struct cli_state *cli;
3889 	int i, count;
3890 	NTSTATUS status;
3891 
3892 	*pp_workgroup_out = NULL;
3893 
3894         DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3895 
3896         /* Go looking for workgroups by broadcasting on the local network */
3897 
3898 	status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3899 				    &ip_list, &count);
3900         if (!NT_STATUS_IS_OK(status)) {
3901                 DEBUG(99, ("No master browsers responded: %s\n",
3902 			   nt_errstr(status)));
3903                 return NULL;
3904         }
3905 
3906 	for (i = 0; i < count; i++) {
3907 		char addr[INET6_ADDRSTRLEN];
3908 		print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3909 		DEBUG(99, ("Found master browser %s\n", addr));
3910 
3911 		cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3912 				user_info, pp_workgroup_out);
3913 		if (cli)
3914 			return(cli);
3915 	}
3916 
3917 	return NULL;
3918 }
3919