1 /*
2  * Unix SMB/CIFS implementation.
3  *
4  * Winbind rpc backend functions
5  *
6  * Copyright (c) 2000-2003 Tim Potter
7  * Copyright (c) 2001      Andrew Tridgell
8  * Copyright (c) 2005      Volker Lendecke
9  * Copyright (c) 2008      Guenther Deschner (pidl conversion)
10  * Copyright (c) 2010      Andreas Schneider <asn@samba.org>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24  */
25 
26 #include "includes.h"
27 #include "winbindd.h"
28 #include "winbindd_rpc.h"
29 #include "lib/util_unixsids.h"
30 #include "rpc_client/rpc_client.h"
31 #include "rpc_client/cli_pipe.h"
32 #include "../librpc/gen_ndr/ndr_samr_c.h"
33 #include "rpc_client/cli_samr.h"
34 #include "../librpc/gen_ndr/ndr_lsa_c.h"
35 #include "rpc_client/cli_lsarpc.h"
36 #include "rpc_server/rpc_ncacn_np.h"
37 #include "../libcli/security/security.h"
38 #include "passdb/machine_sid.h"
39 #include "auth.h"
40 
41 #undef DBGC_CLASS
42 #define DBGC_CLASS DBGC_WINBIND
43 
44 /*
45  * The other end of this won't go away easily, so we can trust it
46  *
47  * It is either a long-lived process with the same lifetime as
48  * winbindd or a part of this process
49  */
50 struct winbind_internal_pipes {
51 	struct rpc_pipe_client *samr_pipe;
52 	struct policy_handle samr_domain_hnd;
53 	struct rpc_pipe_client *lsa_pipe;
54 	struct policy_handle lsa_hnd;
55 };
56 
57 
open_internal_samr_conn(TALLOC_CTX * mem_ctx,struct winbindd_domain * domain,struct rpc_pipe_client ** samr_pipe,struct policy_handle * samr_domain_hnd)58 NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
59 				 struct winbindd_domain *domain,
60 				 struct rpc_pipe_client **samr_pipe,
61 				 struct policy_handle *samr_domain_hnd)
62 {
63 	NTSTATUS status, result;
64 	struct policy_handle samr_connect_hnd;
65 	struct dcerpc_binding_handle *b;
66 
67 	status = wb_open_internal_pipe(mem_ctx, &ndr_table_samr, samr_pipe);
68 	if (!NT_STATUS_IS_OK(status)) {
69 		return status;
70 	}
71 
72 	b = (*samr_pipe)->binding_handle;
73 
74 	status = dcerpc_samr_Connect2(b, mem_ctx,
75 				      (*samr_pipe)->desthost,
76 				      SEC_FLAG_MAXIMUM_ALLOWED,
77 				      &samr_connect_hnd,
78 				      &result);
79 	if (!NT_STATUS_IS_OK(status)) {
80 		return status;
81 	}
82 	if (!NT_STATUS_IS_OK(result)) {
83 		return result;
84 	}
85 
86 	status = dcerpc_samr_OpenDomain(b, mem_ctx,
87 					&samr_connect_hnd,
88 					SEC_FLAG_MAXIMUM_ALLOWED,
89 					&domain->sid,
90 					samr_domain_hnd,
91 					&result);
92 	if (!NT_STATUS_IS_OK(status)) {
93 		return status;
94 	}
95 
96 	return result;
97 }
98 
open_internal_lsa_conn(TALLOC_CTX * mem_ctx,struct rpc_pipe_client ** lsa_pipe,struct policy_handle * lsa_hnd)99 NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
100 				struct rpc_pipe_client **lsa_pipe,
101 				struct policy_handle *lsa_hnd)
102 {
103 	NTSTATUS status;
104 
105 	status = wb_open_internal_pipe(mem_ctx, &ndr_table_lsarpc, lsa_pipe);
106 	if (!NT_STATUS_IS_OK(status)) {
107 		return status;
108 	}
109 
110 	status = rpccli_lsa_open_policy((*lsa_pipe),
111 					mem_ctx,
112 					true,
113 					SEC_FLAG_MAXIMUM_ALLOWED,
114 					lsa_hnd);
115 
116 	return status;
117 }
118 
119 
open_cached_internal_pipe_conn(struct winbindd_domain * domain,struct rpc_pipe_client ** samr_pipe,struct policy_handle * samr_domain_hnd,struct rpc_pipe_client ** lsa_pipe,struct policy_handle * lsa_hnd)120 static NTSTATUS open_cached_internal_pipe_conn(
121 	struct winbindd_domain *domain,
122 	struct rpc_pipe_client **samr_pipe,
123 	struct policy_handle *samr_domain_hnd,
124 	struct rpc_pipe_client **lsa_pipe,
125 	struct policy_handle *lsa_hnd)
126 {
127 	struct winbind_internal_pipes *internal_pipes = NULL;
128 
129 	if (domain->private_data == NULL) {
130 		TALLOC_CTX *frame = talloc_stackframe();
131 		NTSTATUS status;
132 
133 		internal_pipes = talloc_zero(frame,
134 					     struct winbind_internal_pipes);
135 
136 		status = open_internal_samr_conn(
137 			internal_pipes,
138 			domain,
139 			&internal_pipes->samr_pipe,
140 			&internal_pipes->samr_domain_hnd);
141 		if (!NT_STATUS_IS_OK(status)) {
142 			TALLOC_FREE(frame);
143 			return status;
144 		}
145 
146 		status = open_internal_lsa_conn(internal_pipes,
147 						&internal_pipes->lsa_pipe,
148 						&internal_pipes->lsa_hnd);
149 
150 		if (!NT_STATUS_IS_OK(status)) {
151 			TALLOC_FREE(frame);
152 			return status;
153 		}
154 
155 		domain->private_data = talloc_move(domain, &internal_pipes);
156 
157 		TALLOC_FREE(frame);
158 
159 	}
160 
161 	internal_pipes = talloc_get_type_abort(
162 		domain->private_data, struct winbind_internal_pipes);
163 
164 	if (samr_domain_hnd) {
165 		*samr_domain_hnd = internal_pipes->samr_domain_hnd;
166 	}
167 
168 	if (samr_pipe) {
169 		*samr_pipe = internal_pipes->samr_pipe;
170 	}
171 
172 	if (lsa_hnd) {
173 		*lsa_hnd = internal_pipes->lsa_hnd;
174 	}
175 
176 	if (lsa_pipe) {
177 		*lsa_pipe = internal_pipes->lsa_pipe;
178 	}
179 
180 	return NT_STATUS_OK;
181 }
182 
reset_connection_on_error(struct winbindd_domain * domain,struct rpc_pipe_client * p,NTSTATUS status)183 static bool reset_connection_on_error(struct winbindd_domain *domain,
184 				      struct rpc_pipe_client *p,
185 				      NTSTATUS status)
186 {
187 	struct winbind_internal_pipes *internal_pipes = NULL;
188 
189 	internal_pipes = talloc_get_type_abort(
190 		domain->private_data, struct winbind_internal_pipes);
191 
192 	if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
193 	    NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR))
194 	{
195 		TALLOC_FREE(internal_pipes);
196 		domain->private_data = NULL;
197 		return true;
198 	}
199 
200 	if (!rpccli_is_connected(p)) {
201 		TALLOC_FREE(internal_pipes);
202 		domain->private_data = NULL;
203 		return true;
204 	}
205 
206 	return false;
207 }
208 
209 /*********************************************************************
210  SAM specific functions.
211 *********************************************************************/
212 
213 /* List all domain groups */
sam_enum_dom_groups(struct winbindd_domain * domain,TALLOC_CTX * mem_ctx,uint32_t * pnum_info,struct wb_acct_info ** pinfo)214 static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
215 				    TALLOC_CTX *mem_ctx,
216 				    uint32_t *pnum_info,
217 				    struct wb_acct_info **pinfo)
218 {
219 	struct rpc_pipe_client *samr_pipe;
220 	struct policy_handle dom_pol = { 0 };
221 	struct wb_acct_info *info = NULL;
222 	uint32_t num_info = 0;
223 	TALLOC_CTX *tmp_ctx;
224 	NTSTATUS status;
225 	bool retry = false;
226 
227 	DEBUG(3,("sam_enum_dom_groups\n"));
228 
229 	if (pnum_info) {
230 		*pnum_info = 0;
231 	}
232 
233 	tmp_ctx = talloc_stackframe();
234 	if (tmp_ctx == NULL) {
235 		return NT_STATUS_NO_MEMORY;
236 	}
237 
238 again:
239 	status = open_cached_internal_pipe_conn(domain,
240 						&samr_pipe,
241 						&dom_pol,
242 						NULL,
243 						NULL);
244 	if (!NT_STATUS_IS_OK(status)) {
245 		TALLOC_FREE(tmp_ctx);
246 		return status;
247 	}
248 
249 	status = rpc_enum_dom_groups(tmp_ctx,
250 				     samr_pipe,
251 				     &dom_pol,
252 				     &num_info,
253 				     &info);
254 
255 	if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
256 		retry = true;
257 		goto again;
258 	}
259 
260 	if (!NT_STATUS_IS_OK(status)) {
261 		TALLOC_FREE(tmp_ctx);
262 		return status;
263 	}
264 
265 	if (pnum_info) {
266 		*pnum_info = num_info;
267 	}
268 
269 	if (pinfo) {
270 		*pinfo = talloc_move(mem_ctx, &info);
271 	}
272 
273 	TALLOC_FREE(tmp_ctx);
274 	return status;
275 }
276 
277 /* Query display info for a domain */
sam_query_user_list(struct winbindd_domain * domain,TALLOC_CTX * mem_ctx,uint32_t ** prids)278 static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
279 				    TALLOC_CTX *mem_ctx,
280 				    uint32_t **prids)
281 {
282 	struct rpc_pipe_client *samr_pipe = NULL;
283 	struct policy_handle dom_pol = { 0 };
284 	uint32_t *rids = NULL;
285 	TALLOC_CTX *tmp_ctx;
286 	NTSTATUS status;
287 	bool retry = false;
288 
289 	DEBUG(3,("samr_query_user_list\n"));
290 
291 	tmp_ctx = talloc_stackframe();
292 	if (tmp_ctx == NULL) {
293 		return NT_STATUS_NO_MEMORY;
294 	}
295 
296 again:
297 	status = open_cached_internal_pipe_conn(domain,
298 						&samr_pipe,
299 						&dom_pol,
300 						NULL,
301 						NULL);
302 	if (!NT_STATUS_IS_OK(status)) {
303 		goto done;
304 	}
305 
306 	status = rpc_query_user_list(tmp_ctx,
307 				     samr_pipe,
308 				     &dom_pol,
309 				     &domain->sid,
310 				     &rids);
311 	if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
312 		retry = true;
313 		goto again;
314 	}
315 
316 	if (!NT_STATUS_IS_OK(status)) {
317 		goto done;
318 	}
319 
320 	if (prids != NULL) {
321 		*prids = talloc_move(mem_ctx, &rids);
322 	}
323 
324 done:
325 	TALLOC_FREE(rids);
326 	TALLOC_FREE(tmp_ctx);
327 	return status;
328 }
329 
330 /* get a list of trusted domains - builtin domain */
sam_trusted_domains(struct winbindd_domain * domain,TALLOC_CTX * mem_ctx,struct netr_DomainTrustList * ptrust_list)331 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
332 				    TALLOC_CTX *mem_ctx,
333 				    struct netr_DomainTrustList *ptrust_list)
334 {
335 	struct rpc_pipe_client *lsa_pipe;
336 	struct policy_handle lsa_policy = { 0 };
337 	struct netr_DomainTrust *trusts = NULL;
338 	uint32_t num_trusts = 0;
339 	TALLOC_CTX *tmp_ctx;
340 	NTSTATUS status;
341 	bool retry = false;
342 
343 	DEBUG(3,("samr: trusted domains\n"));
344 
345 	if (ptrust_list) {
346 		ZERO_STRUCTP(ptrust_list);
347 	}
348 
349 	tmp_ctx = talloc_stackframe();
350 	if (tmp_ctx == NULL) {
351 		return NT_STATUS_NO_MEMORY;
352 	}
353 
354 again:
355 	status = open_cached_internal_pipe_conn(domain,
356 						NULL,
357 						NULL,
358 						&lsa_pipe,
359 						&lsa_policy);
360 	if (!NT_STATUS_IS_OK(status)) {
361 		goto done;
362 	}
363 
364 	status = rpc_trusted_domains(tmp_ctx,
365 				     lsa_pipe,
366 				     &lsa_policy,
367 				     &num_trusts,
368 				     &trusts);
369 
370 	if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) {
371 		retry = true;
372 		goto again;
373 	}
374 
375 	if (!NT_STATUS_IS_OK(status)) {
376 		goto done;
377 	}
378 
379 	if (ptrust_list) {
380 		ptrust_list->count = num_trusts;
381 		ptrust_list->array = talloc_move(mem_ctx, &trusts);
382 	}
383 
384 done:
385 	TALLOC_FREE(tmp_ctx);
386 	return status;
387 }
388 
389 /* Lookup group membership given a rid.   */
sam_lookup_groupmem(struct winbindd_domain * domain,TALLOC_CTX * mem_ctx,const struct dom_sid * group_sid,enum lsa_SidType type,uint32_t * pnum_names,struct dom_sid ** psid_mem,char *** pnames,uint32_t ** pname_types)390 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
391 				    TALLOC_CTX *mem_ctx,
392 				    const struct dom_sid *group_sid,
393 				    enum lsa_SidType type,
394 				    uint32_t *pnum_names,
395 				    struct dom_sid **psid_mem,
396 				    char ***pnames,
397 				    uint32_t **pname_types)
398 {
399 	struct rpc_pipe_client *samr_pipe;
400 	struct policy_handle dom_pol = { 0 };
401 
402 	uint32_t num_names = 0;
403 	struct dom_sid *sid_mem = NULL;
404 	char **names = NULL;
405 	uint32_t *name_types = NULL;
406 
407 	TALLOC_CTX *tmp_ctx;
408 	NTSTATUS status;
409 	bool retry = false;
410 
411 	DEBUG(3,("sam_lookup_groupmem\n"));
412 
413 	/* Paranoia check */
414 	if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
415 		/* There's no groups, only aliases in BUILTIN */
416 		return NT_STATUS_NO_SUCH_GROUP;
417 	}
418 
419 	if (pnum_names) {
420 		*pnum_names = 0;
421 	}
422 
423 	tmp_ctx = talloc_stackframe();
424 	if (tmp_ctx == NULL) {
425 		return NT_STATUS_NO_MEMORY;
426 	}
427 
428 again:
429 	status = open_cached_internal_pipe_conn(domain,
430 						&samr_pipe,
431 						&dom_pol,
432 						NULL,
433 						NULL);
434 	if (!NT_STATUS_IS_OK(status)) {
435 		goto done;
436 	}
437 
438 	status = rpc_lookup_groupmem(tmp_ctx,
439 				     samr_pipe,
440 				     &dom_pol,
441 				     domain->name,
442 				     &domain->sid,
443 				     group_sid,
444 				     type,
445 				     &num_names,
446 				     &sid_mem,
447 				     &names,
448 				     &name_types);
449 
450 	if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
451 		retry = true;
452 		goto again;
453 	}
454 
455 	if (pnum_names) {
456 		*pnum_names = num_names;
457 	}
458 
459 	if (pnames) {
460 		*pnames = talloc_move(mem_ctx, &names);
461 	}
462 
463 	if (pname_types) {
464 		*pname_types = talloc_move(mem_ctx, &name_types);
465 	}
466 
467 	if (psid_mem) {
468 		*psid_mem = talloc_move(mem_ctx, &sid_mem);
469 	}
470 
471 done:
472 	TALLOC_FREE(tmp_ctx);
473 	return status;
474 }
475 
476 /*********************************************************************
477  BUILTIN specific functions.
478 *********************************************************************/
479 
480 /* List all domain groups */
builtin_enum_dom_groups(struct winbindd_domain * domain,TALLOC_CTX * mem_ctx,uint32_t * num_entries,struct wb_acct_info ** info)481 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
482 				TALLOC_CTX *mem_ctx,
483 				uint32_t *num_entries,
484 				struct wb_acct_info **info)
485 {
486 	/* BUILTIN doesn't have domain groups */
487 	*num_entries = 0;
488 	*info = NULL;
489 	return NT_STATUS_OK;
490 }
491 
492 /* Query display info for a domain */
builtin_query_user_list(struct winbindd_domain * domain,TALLOC_CTX * mem_ctx,uint32_t ** rids)493 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
494 				TALLOC_CTX *mem_ctx,
495 				uint32_t **rids)
496 {
497 	/* We don't have users */
498 	*rids = NULL;
499 	return NT_STATUS_OK;
500 }
501 
502 /* get a list of trusted domains - builtin domain */
builtin_trusted_domains(struct winbindd_domain * domain,TALLOC_CTX * mem_ctx,struct netr_DomainTrustList * trusts)503 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
504 					TALLOC_CTX *mem_ctx,
505 					struct netr_DomainTrustList *trusts)
506 {
507 	ZERO_STRUCTP(trusts);
508 	return NT_STATUS_OK;
509 }
510 
511 /*********************************************************************
512  COMMON functions.
513 *********************************************************************/
514 
515 /* List all local groups (aliases) */
sam_enum_local_groups(struct winbindd_domain * domain,TALLOC_CTX * mem_ctx,uint32_t * pnum_info,struct wb_acct_info ** pinfo)516 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
517 				      TALLOC_CTX *mem_ctx,
518 				      uint32_t *pnum_info,
519 				      struct wb_acct_info **pinfo)
520 {
521 	struct rpc_pipe_client *samr_pipe;
522 	struct policy_handle dom_pol = { 0 };
523 	struct wb_acct_info *info = NULL;
524 	uint32_t num_info = 0;
525 	TALLOC_CTX *tmp_ctx;
526 	NTSTATUS status;
527 	bool retry = false;
528 
529 	DEBUG(3,("samr: enum local groups\n"));
530 
531 	if (pnum_info) {
532 		*pnum_info = 0;
533 	}
534 
535 	tmp_ctx = talloc_stackframe();
536 	if (tmp_ctx == NULL) {
537 		return NT_STATUS_NO_MEMORY;
538 	}
539 
540 again:
541 	status = open_cached_internal_pipe_conn(domain,
542 						&samr_pipe,
543 						&dom_pol,
544 						NULL,
545 						NULL);
546 	if (!NT_STATUS_IS_OK(status)) {
547 		goto done;
548 	}
549 
550 	status = rpc_enum_local_groups(mem_ctx,
551 				       samr_pipe,
552 				       &dom_pol,
553 				       &num_info,
554 
555 				       &info);
556 	if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
557 		retry = true;
558 		goto again;
559 	}
560 
561 	if (!NT_STATUS_IS_OK(status)) {
562 		goto done;
563 	}
564 
565 	if (pnum_info) {
566 		*pnum_info = num_info;
567 	}
568 
569 	if (pinfo) {
570 		*pinfo = talloc_move(mem_ctx, &info);
571 	}
572 
573 done:
574 	TALLOC_FREE(tmp_ctx);
575 	return status;
576 }
577 
578 /* convert a single name to a sid in a domain */
sam_name_to_sid(struct winbindd_domain * domain,TALLOC_CTX * mem_ctx,const char * domain_name,const char * name,uint32_t flags,const char ** pdom_name,struct dom_sid * psid,enum lsa_SidType * ptype)579 static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
580 				   TALLOC_CTX *mem_ctx,
581 				   const char *domain_name,
582 				   const char *name,
583 				   uint32_t flags,
584 				   const char **pdom_name,
585 				   struct dom_sid *psid,
586 				   enum lsa_SidType *ptype)
587 {
588 	struct rpc_pipe_client *lsa_pipe;
589 	struct policy_handle lsa_policy = { 0 };
590 	struct dom_sid sid;
591 	const char *dom_name;
592 	enum lsa_SidType type;
593 	TALLOC_CTX *tmp_ctx;
594 	NTSTATUS status;
595 	bool retry = false;
596 
597 	DEBUG(3,("sam_name_to_sid\n"));
598 
599 	tmp_ctx = talloc_stackframe();
600 	if (tmp_ctx == NULL) {
601 		return NT_STATUS_NO_MEMORY;
602 	}
603 
604 again:
605 	status = open_cached_internal_pipe_conn(domain,
606 						NULL,
607 						NULL,
608 						&lsa_pipe,
609 						&lsa_policy);
610 	if (!NT_STATUS_IS_OK(status)) {
611 		goto done;
612 	}
613 
614 	status = rpc_name_to_sid(tmp_ctx,
615 				 lsa_pipe,
616 				 &lsa_policy,
617 				 domain_name,
618 				 name,
619 				 flags,
620 				 &dom_name,
621 				 &sid,
622 				 &type);
623 
624 	if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) {
625 		retry = true;
626 		goto again;
627 	}
628 
629 	if (!NT_STATUS_IS_OK(status)) {
630 		goto done;
631 	}
632 
633 	if (pdom_name != NULL) {
634 		*pdom_name = talloc_strdup(mem_ctx, dom_name);
635 		if (*pdom_name == NULL) {
636 			status = NT_STATUS_NO_MEMORY;
637 			goto done;
638 		}
639 	}
640 
641 	if (psid) {
642 		sid_copy(psid, &sid);
643 	}
644 	if (ptype) {
645 		*ptype = type;
646 	}
647 
648 done:
649 	TALLOC_FREE(tmp_ctx);
650 	return status;
651 }
652 
653 /* convert a domain SID to a user or group name */
sam_sid_to_name(struct winbindd_domain * domain,TALLOC_CTX * mem_ctx,const struct dom_sid * sid,char ** pdomain_name,char ** pname,enum lsa_SidType * ptype)654 static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
655 				TALLOC_CTX *mem_ctx,
656 				const struct dom_sid *sid,
657 				char **pdomain_name,
658 				char **pname,
659 				enum lsa_SidType *ptype)
660 {
661 	struct rpc_pipe_client *lsa_pipe;
662 	struct policy_handle lsa_policy = { 0 };
663 	char *domain_name = NULL;
664 	char *name = NULL;
665 	enum lsa_SidType type;
666 	TALLOC_CTX *tmp_ctx;
667 	NTSTATUS status;
668 	bool retry = false;
669 
670 	DEBUG(3,("sam_sid_to_name\n"));
671 
672 	/* Paranoia check */
673 	if (!sid_check_is_in_builtin(sid) &&
674 	    !sid_check_is_builtin(sid) &&
675 	    !sid_check_is_in_our_sam(sid) &&
676 	    !sid_check_is_our_sam(sid) &&
677 	    !sid_check_is_in_unix_users(sid) &&
678 	    !sid_check_is_unix_users(sid) &&
679 	    !sid_check_is_in_unix_groups(sid) &&
680 	    !sid_check_is_unix_groups(sid) &&
681 	    !sid_check_is_in_wellknown_domain(sid)) {
682 		struct dom_sid_buf buf;
683 		DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
684 			  "lookup SID %s\n",
685 			  dom_sid_str_buf(sid, &buf)));
686 		return NT_STATUS_NONE_MAPPED;
687 	}
688 
689 	tmp_ctx = talloc_stackframe();
690 	if (tmp_ctx == NULL) {
691 		return NT_STATUS_NO_MEMORY;
692 	}
693 
694 again:
695 	status = open_cached_internal_pipe_conn(domain,
696 						NULL,
697 						NULL,
698 						&lsa_pipe,
699 						&lsa_policy);
700 	if (!NT_STATUS_IS_OK(status)) {
701 		goto done;
702 	}
703 
704 	status = rpc_sid_to_name(tmp_ctx,
705 				 lsa_pipe,
706 				 &lsa_policy,
707 				 domain,
708 				 sid,
709 				 &domain_name,
710 				 &name,
711 				 &type);
712 
713 	if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) {
714 		retry = true;
715 		goto again;
716 	}
717 
718 	if (ptype) {
719 		*ptype = type;
720 	}
721 
722 	if (pname) {
723 		*pname = talloc_move(mem_ctx, &name);
724 	}
725 
726 	if (pdomain_name) {
727 		*pdomain_name = talloc_move(mem_ctx, &domain_name);
728 	}
729 
730 done:
731 
732 	TALLOC_FREE(tmp_ctx);
733 	return status;
734 }
735 
sam_rids_to_names(struct winbindd_domain * domain,TALLOC_CTX * mem_ctx,const struct dom_sid * domain_sid,uint32_t * rids,size_t num_rids,char ** pdomain_name,char *** pnames,enum lsa_SidType ** ptypes)736 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
737 				  TALLOC_CTX *mem_ctx,
738 				  const struct dom_sid *domain_sid,
739 				  uint32_t *rids,
740 				  size_t num_rids,
741 				  char **pdomain_name,
742 				  char ***pnames,
743 				  enum lsa_SidType **ptypes)
744 {
745 	struct rpc_pipe_client *lsa_pipe;
746 	struct policy_handle lsa_policy = { 0 };
747 	enum lsa_SidType *types = NULL;
748 	char *domain_name = NULL;
749 	char **names = NULL;
750 	TALLOC_CTX *tmp_ctx;
751 	NTSTATUS status;
752 	bool retry = false;
753 
754 	DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
755 
756 	/* Paranoia check */
757 	if (!sid_check_is_builtin(domain_sid) &&
758 	    !sid_check_is_our_sam(domain_sid) &&
759 	    !sid_check_is_unix_users(domain_sid) &&
760 	    !sid_check_is_unix_groups(domain_sid) &&
761 	    !sid_check_is_in_wellknown_domain(domain_sid)) {
762 		struct dom_sid_buf buf;
763 		DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
764 			  "lookup SID %s\n",
765 			  dom_sid_str_buf(domain_sid, &buf)));
766 		return NT_STATUS_NONE_MAPPED;
767 	}
768 
769 	tmp_ctx = talloc_stackframe();
770 	if (tmp_ctx == NULL) {
771 		return NT_STATUS_NO_MEMORY;
772 	}
773 
774 again:
775 	status = open_cached_internal_pipe_conn(domain,
776 						NULL,
777 						NULL,
778 						&lsa_pipe,
779 						&lsa_policy);
780 	if (!NT_STATUS_IS_OK(status)) {
781 		goto done;
782 	}
783 
784 	status = rpc_rids_to_names(tmp_ctx,
785 				   lsa_pipe,
786 				   &lsa_policy,
787 				   domain,
788 				   domain_sid,
789 				   rids,
790 				   num_rids,
791 				   &domain_name,
792 				   &names,
793 				   &types);
794 
795 	if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) {
796 		retry = true;
797 		goto again;
798 	}
799 
800 	if (!NT_STATUS_IS_OK(status)) {
801 		goto done;
802 	}
803 
804 	if (pdomain_name) {
805 		*pdomain_name = talloc_move(mem_ctx, &domain_name);
806 	}
807 
808 	if (ptypes) {
809 		*ptypes = talloc_move(mem_ctx, &types);
810 	}
811 
812 	if (pnames) {
813 		*pnames = talloc_move(mem_ctx, &names);
814 	}
815 
816 done:
817 	TALLOC_FREE(tmp_ctx);
818 	return status;
819 }
820 
sam_lockout_policy(struct winbindd_domain * domain,TALLOC_CTX * mem_ctx,struct samr_DomInfo12 * lockout_policy)821 static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
822 				   TALLOC_CTX *mem_ctx,
823 				   struct samr_DomInfo12 *lockout_policy)
824 {
825 	struct rpc_pipe_client *samr_pipe;
826 	struct policy_handle dom_pol = { 0 };
827 	union samr_DomainInfo *info = NULL;
828 	TALLOC_CTX *tmp_ctx;
829 	NTSTATUS status, result;
830 	struct dcerpc_binding_handle *b = NULL;
831 	bool retry = false;
832 
833 	DEBUG(3,("sam_lockout_policy\n"));
834 
835 	tmp_ctx = talloc_stackframe();
836 	if (tmp_ctx == NULL) {
837 		return NT_STATUS_NO_MEMORY;
838 	}
839 
840 again:
841 	status = open_cached_internal_pipe_conn(domain,
842 						&samr_pipe,
843 						&dom_pol,
844 						NULL,
845 						NULL);
846 	if (!NT_STATUS_IS_OK(status)) {
847 		goto error;
848 	}
849 
850 	b = samr_pipe->binding_handle;
851 
852 	status = dcerpc_samr_QueryDomainInfo(b,
853 					     mem_ctx,
854 					     &dom_pol,
855 					     DomainLockoutInformation,
856 					     &info,
857 					     &result);
858 
859 	if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
860 		retry = true;
861 		goto again;
862 	}
863 
864 	if (!NT_STATUS_IS_OK(status)) {
865 		goto error;
866 	}
867 	if (!NT_STATUS_IS_OK(result)) {
868 		status = result;
869 		goto error;
870 	}
871 
872 	*lockout_policy = info->info12;
873 
874 error:
875 	TALLOC_FREE(tmp_ctx);
876 	return status;
877 }
878 
sam_password_policy(struct winbindd_domain * domain,TALLOC_CTX * mem_ctx,struct samr_DomInfo1 * passwd_policy)879 static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
880 				    TALLOC_CTX *mem_ctx,
881 				    struct samr_DomInfo1 *passwd_policy)
882 {
883 	struct rpc_pipe_client *samr_pipe;
884 	struct policy_handle dom_pol = { 0 };
885 	union samr_DomainInfo *info = NULL;
886 	TALLOC_CTX *tmp_ctx;
887 	NTSTATUS status, result;
888 	struct dcerpc_binding_handle *b = NULL;
889 	bool retry = false;
890 
891 	DEBUG(3,("sam_password_policy\n"));
892 
893 	tmp_ctx = talloc_stackframe();
894 	if (tmp_ctx == NULL) {
895 		return NT_STATUS_NO_MEMORY;
896 	}
897 
898 again:
899 	status = open_cached_internal_pipe_conn(domain,
900 						&samr_pipe,
901 						&dom_pol,
902 						NULL,
903 						NULL);
904 	if (!NT_STATUS_IS_OK(status)) {
905 		goto error;
906 	}
907 
908 	b = samr_pipe->binding_handle;
909 
910 	status = dcerpc_samr_QueryDomainInfo(b,
911 					     mem_ctx,
912 					     &dom_pol,
913 					     DomainPasswordInformation,
914 					     &info,
915 					     &result);
916 
917 	if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
918 		retry = true;
919 		goto again;
920 	}
921 
922 	if (!NT_STATUS_IS_OK(status)) {
923 		goto error;
924 	}
925 	if (!NT_STATUS_IS_OK(result)) {
926 		status = result;
927 		goto error;
928 	}
929 
930 	*passwd_policy = info->info1;
931 
932 error:
933 	TALLOC_FREE(tmp_ctx);
934 	return status;
935 }
936 
937 /* Lookup groups a user is a member of. */
sam_lookup_usergroups(struct winbindd_domain * domain,TALLOC_CTX * mem_ctx,const struct dom_sid * user_sid,uint32_t * pnum_groups,struct dom_sid ** puser_grpsids)938 static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
939 				      TALLOC_CTX *mem_ctx,
940 				      const struct dom_sid *user_sid,
941 				      uint32_t *pnum_groups,
942 				      struct dom_sid **puser_grpsids)
943 {
944 	struct rpc_pipe_client *samr_pipe;
945 	struct policy_handle dom_pol;
946 	struct dom_sid *user_grpsids = NULL;
947 	uint32_t num_groups = 0;
948 	TALLOC_CTX *tmp_ctx;
949 	NTSTATUS status;
950 	bool retry = false;
951 
952 	DEBUG(3,("sam_lookup_usergroups\n"));
953 
954 	ZERO_STRUCT(dom_pol);
955 
956 	if (pnum_groups) {
957 		*pnum_groups = 0;
958 	}
959 
960 	tmp_ctx = talloc_stackframe();
961 	if (tmp_ctx == NULL) {
962 		return NT_STATUS_NO_MEMORY;
963 	}
964 
965 again:
966 	status = open_cached_internal_pipe_conn(domain,
967 						&samr_pipe,
968 						&dom_pol,
969 						NULL,
970 						NULL);
971 	if (!NT_STATUS_IS_OK(status)) {
972 		goto done;
973 	}
974 
975 	status = rpc_lookup_usergroups(tmp_ctx,
976 				       samr_pipe,
977 				       &dom_pol,
978 				       &domain->sid,
979 				       user_sid,
980 				       &num_groups,
981 				       &user_grpsids);
982 
983 	if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
984 		retry = true;
985 		goto again;
986 	}
987 
988 	if (!NT_STATUS_IS_OK(status)) {
989 		goto done;
990 	}
991 
992 	if (pnum_groups) {
993 		*pnum_groups = num_groups;
994 	}
995 
996 	if (puser_grpsids) {
997 		*puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
998 	}
999 
1000 done:
1001 
1002 	TALLOC_FREE(tmp_ctx);
1003 	return status;
1004 }
1005 
sam_lookup_useraliases(struct winbindd_domain * domain,TALLOC_CTX * mem_ctx,uint32_t num_sids,const struct dom_sid * sids,uint32_t * pnum_aliases,uint32_t ** palias_rids)1006 static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
1007 				       TALLOC_CTX *mem_ctx,
1008 				       uint32_t num_sids,
1009 				       const struct dom_sid *sids,
1010 				       uint32_t *pnum_aliases,
1011 				       uint32_t **palias_rids)
1012 {
1013 	struct rpc_pipe_client *samr_pipe;
1014 	struct policy_handle dom_pol = { 0 };
1015 	uint32_t num_aliases = 0;
1016 	uint32_t *alias_rids = NULL;
1017 	TALLOC_CTX *tmp_ctx;
1018 	NTSTATUS status;
1019 	bool retry = false;
1020 
1021 	DEBUG(3,("sam_lookup_useraliases\n"));
1022 
1023 	if (pnum_aliases) {
1024 		*pnum_aliases = 0;
1025 	}
1026 
1027 	tmp_ctx = talloc_stackframe();
1028 	if (tmp_ctx == NULL) {
1029 		return NT_STATUS_NO_MEMORY;
1030 	}
1031 
1032 again:
1033 	status = open_cached_internal_pipe_conn(domain,
1034 						&samr_pipe,
1035 						&dom_pol,
1036 						NULL,
1037 						NULL);
1038 	if (!NT_STATUS_IS_OK(status)) {
1039 		goto done;
1040 	}
1041 
1042 	status = rpc_lookup_useraliases(tmp_ctx,
1043 					samr_pipe,
1044 					&dom_pol,
1045 					num_sids,
1046 					sids,
1047 					&num_aliases,
1048 					&alias_rids);
1049 
1050 	if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
1051 		retry = true;
1052 		goto again;
1053 	}
1054 
1055 	if (!NT_STATUS_IS_OK(status)) {
1056 		goto done;
1057 	}
1058 
1059 	if (pnum_aliases) {
1060 		*pnum_aliases = num_aliases;
1061 	}
1062 
1063 	if (palias_rids) {
1064 		*palias_rids = talloc_move(mem_ctx, &alias_rids);
1065 	}
1066 
1067 done:
1068 
1069 	TALLOC_FREE(tmp_ctx);
1070 	return status;
1071 }
1072 
1073 /* find the sequence number for a domain */
sam_sequence_number(struct winbindd_domain * domain,uint32_t * pseq)1074 static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
1075 				    uint32_t *pseq)
1076 {
1077 	struct rpc_pipe_client *samr_pipe;
1078 	struct policy_handle dom_pol = { 0 };
1079 	uint32_t seq = DOM_SEQUENCE_NONE;
1080 	TALLOC_CTX *tmp_ctx;
1081 	NTSTATUS status;
1082 	bool retry = false;
1083 
1084 	DEBUG(3,("samr: sequence number\n"));
1085 
1086 	if (pseq) {
1087 		*pseq = DOM_SEQUENCE_NONE;
1088 	}
1089 
1090 	tmp_ctx = talloc_stackframe();
1091 	if (tmp_ctx == NULL) {
1092 		return NT_STATUS_NO_MEMORY;
1093 	}
1094 
1095 again:
1096 	status = open_cached_internal_pipe_conn(domain,
1097 						&samr_pipe,
1098 						&dom_pol,
1099 						NULL,
1100 						NULL);
1101 	if (!NT_STATUS_IS_OK(status)) {
1102 		goto done;
1103 	}
1104 
1105 	status = rpc_sequence_number(tmp_ctx,
1106 				     samr_pipe,
1107 				     &dom_pol,
1108 				     domain->name,
1109 				     &seq);
1110 
1111 	if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
1112 		retry = true;
1113 		goto again;
1114 	}
1115 
1116 	if (!NT_STATUS_IS_OK(status)) {
1117 		goto done;
1118 	}
1119 
1120 	if (pseq) {
1121 		*pseq = seq;
1122 	}
1123 
1124 done:
1125 	TALLOC_FREE(tmp_ctx);
1126 	return status;
1127 }
1128 
1129 /* the rpc backend methods are exposed via this structure */
1130 struct winbindd_methods builtin_passdb_methods = {
1131 	.consistent            = false,
1132 
1133 	.query_user_list       = builtin_query_user_list,
1134 	.enum_dom_groups       = builtin_enum_dom_groups,
1135 	.enum_local_groups     = sam_enum_local_groups,
1136 	.name_to_sid           = sam_name_to_sid,
1137 	.sid_to_name           = sam_sid_to_name,
1138 	.rids_to_names         = sam_rids_to_names,
1139 	.lookup_usergroups     = sam_lookup_usergroups,
1140 	.lookup_useraliases    = sam_lookup_useraliases,
1141 	.lookup_groupmem       = sam_lookup_groupmem,
1142 	.sequence_number       = sam_sequence_number,
1143 	.lockout_policy        = sam_lockout_policy,
1144 	.password_policy       = sam_password_policy,
1145 	.trusted_domains       = builtin_trusted_domains
1146 };
1147 
1148 /* the rpc backend methods are exposed via this structure */
1149 struct winbindd_methods sam_passdb_methods = {
1150 	.consistent            = false,
1151 
1152 	.query_user_list       = sam_query_user_list,
1153 	.enum_dom_groups       = sam_enum_dom_groups,
1154 	.enum_local_groups     = sam_enum_local_groups,
1155 	.name_to_sid           = sam_name_to_sid,
1156 	.sid_to_name           = sam_sid_to_name,
1157 	.rids_to_names         = sam_rids_to_names,
1158 	.lookup_usergroups     = sam_lookup_usergroups,
1159 	.lookup_useraliases    = sam_lookup_useraliases,
1160 	.lookup_groupmem       = sam_lookup_groupmem,
1161 	.sequence_number       = sam_sequence_number,
1162 	.lockout_policy        = sam_lockout_policy,
1163 	.password_policy       = sam_password_policy,
1164 	.trusted_domains       = sam_trusted_domains
1165 };
1166