whitespace: auth_log.py python conventions
[Samba.git] / source3 / winbindd / winbindd_samr.c
blobaedb77bdee9b425e222860ae1e8a4c212200b49b
1 /*
2 * Unix SMB/CIFS implementation.
4 * Winbind rpc backend functions
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>
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.
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.
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/>.
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 "../librpc/gen_ndr/ndr_samr_c.h"
32 #include "rpc_client/cli_samr.h"
33 #include "../librpc/gen_ndr/ndr_lsa_c.h"
34 #include "rpc_client/cli_lsarpc.h"
35 #include "rpc_server/rpc_ncacn_np.h"
36 #include "../libcli/security/security.h"
37 #include "passdb/machine_sid.h"
38 #include "auth.h"
40 #undef DBGC_CLASS
41 #define DBGC_CLASS DBGC_WINBIND
43 NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
44 struct winbindd_domain *domain,
45 struct rpc_pipe_client **samr_pipe,
46 struct policy_handle *samr_domain_hnd)
48 NTSTATUS status, result;
49 struct policy_handle samr_connect_hnd;
50 struct dcerpc_binding_handle *b;
52 status = wb_open_internal_pipe(mem_ctx, &ndr_table_samr, samr_pipe);
53 if (!NT_STATUS_IS_OK(status)) {
54 return status;
57 b = (*samr_pipe)->binding_handle;
59 status = dcerpc_samr_Connect2(b, mem_ctx,
60 (*samr_pipe)->desthost,
61 SEC_FLAG_MAXIMUM_ALLOWED,
62 &samr_connect_hnd,
63 &result);
64 if (!NT_STATUS_IS_OK(status)) {
65 return status;
67 if (!NT_STATUS_IS_OK(result)) {
68 return result;
71 status = dcerpc_samr_OpenDomain(b, mem_ctx,
72 &samr_connect_hnd,
73 SEC_FLAG_MAXIMUM_ALLOWED,
74 &domain->sid,
75 samr_domain_hnd,
76 &result);
77 if (!NT_STATUS_IS_OK(status)) {
78 return status;
81 return result;
84 NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
85 struct rpc_pipe_client **lsa_pipe,
86 struct policy_handle *lsa_hnd)
88 NTSTATUS status;
90 status = wb_open_internal_pipe(mem_ctx, &ndr_table_lsarpc, lsa_pipe);
91 if (!NT_STATUS_IS_OK(status)) {
92 return status;
95 status = rpccli_lsa_open_policy((*lsa_pipe),
96 mem_ctx,
97 true,
98 SEC_FLAG_MAXIMUM_ALLOWED,
99 lsa_hnd);
101 return status;
104 /*********************************************************************
105 SAM specific functions.
106 *********************************************************************/
108 /* List all domain groups */
109 static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
110 TALLOC_CTX *mem_ctx,
111 uint32_t *pnum_info,
112 struct wb_acct_info **pinfo)
114 struct rpc_pipe_client *samr_pipe;
115 struct policy_handle dom_pol = { 0 };
116 struct wb_acct_info *info = NULL;
117 uint32_t num_info = 0;
118 TALLOC_CTX *tmp_ctx;
119 NTSTATUS status, result;
120 struct dcerpc_binding_handle *b = NULL;
122 DEBUG(3,("sam_enum_dom_groups\n"));
124 if (pnum_info) {
125 *pnum_info = 0;
128 tmp_ctx = talloc_stackframe();
129 if (tmp_ctx == NULL) {
130 return NT_STATUS_NO_MEMORY;
133 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
134 if (!NT_STATUS_IS_OK(status)) {
135 goto error;
138 b = samr_pipe->binding_handle;
140 status = rpc_enum_dom_groups(tmp_ctx,
141 samr_pipe,
142 &dom_pol,
143 &num_info,
144 &info);
145 if (!NT_STATUS_IS_OK(status)) {
146 goto error;
149 if (pnum_info) {
150 *pnum_info = num_info;
153 if (pinfo) {
154 *pinfo = talloc_move(mem_ctx, &info);
157 error:
158 if (b && is_valid_policy_hnd(&dom_pol)) {
159 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
161 TALLOC_FREE(tmp_ctx);
162 return status;
165 /* Query display info for a domain */
166 static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
167 TALLOC_CTX *mem_ctx,
168 uint32_t **prids)
170 struct rpc_pipe_client *samr_pipe = NULL;
171 struct policy_handle dom_pol = { 0 };
172 uint32_t *rids = NULL;
173 TALLOC_CTX *tmp_ctx;
174 NTSTATUS status, result;
175 struct dcerpc_binding_handle *b = NULL;
177 DEBUG(3,("samr_query_user_list\n"));
179 tmp_ctx = talloc_stackframe();
180 if (tmp_ctx == NULL) {
181 return NT_STATUS_NO_MEMORY;
184 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
185 if (!NT_STATUS_IS_OK(status)) {
186 goto done;
189 b = samr_pipe->binding_handle;
191 status = rpc_query_user_list(tmp_ctx,
192 samr_pipe,
193 &dom_pol,
194 &domain->sid,
195 &rids);
196 if (!NT_STATUS_IS_OK(status)) {
197 goto done;
200 if (prids != NULL) {
201 *prids = talloc_move(mem_ctx, &rids);
204 done:
205 if (b && is_valid_policy_hnd(&dom_pol)) {
206 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
209 TALLOC_FREE(rids);
210 TALLOC_FREE(tmp_ctx);
211 return status;
214 /* get a list of trusted domains - builtin domain */
215 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
216 TALLOC_CTX *mem_ctx,
217 struct netr_DomainTrustList *ptrust_list)
219 struct rpc_pipe_client *lsa_pipe;
220 struct policy_handle lsa_policy = { 0 };
221 struct netr_DomainTrust *trusts = NULL;
222 uint32_t num_trusts = 0;
223 TALLOC_CTX *tmp_ctx;
224 NTSTATUS status, result;
225 struct dcerpc_binding_handle *b = NULL;
227 DEBUG(3,("samr: trusted domains\n"));
229 if (ptrust_list) {
230 ZERO_STRUCTP(ptrust_list);
233 tmp_ctx = talloc_stackframe();
234 if (tmp_ctx == NULL) {
235 return NT_STATUS_NO_MEMORY;
238 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
239 if (!NT_STATUS_IS_OK(status)) {
240 goto done;
243 b = lsa_pipe->binding_handle;
245 status = rpc_trusted_domains(tmp_ctx,
246 lsa_pipe,
247 &lsa_policy,
248 &num_trusts,
249 &trusts);
250 if (!NT_STATUS_IS_OK(status)) {
251 goto done;
254 if (ptrust_list) {
255 ptrust_list->count = num_trusts;
256 ptrust_list->array = talloc_move(mem_ctx, &trusts);
259 done:
260 if (b && is_valid_policy_hnd(&lsa_policy)) {
261 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
264 TALLOC_FREE(tmp_ctx);
265 return status;
268 /* Lookup group membership given a rid. */
269 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
270 TALLOC_CTX *mem_ctx,
271 const struct dom_sid *group_sid,
272 enum lsa_SidType type,
273 uint32_t *pnum_names,
274 struct dom_sid **psid_mem,
275 char ***pnames,
276 uint32_t **pname_types)
278 struct rpc_pipe_client *samr_pipe;
279 struct policy_handle dom_pol = { 0 };
281 uint32_t num_names = 0;
282 struct dom_sid *sid_mem = NULL;
283 char **names = NULL;
284 uint32_t *name_types = NULL;
286 TALLOC_CTX *tmp_ctx;
287 NTSTATUS status, result;
288 struct dcerpc_binding_handle *b = NULL;
290 DEBUG(3,("sam_lookup_groupmem\n"));
292 /* Paranoia check */
293 if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
294 /* There's no groups, only aliases in BUILTIN */
295 return NT_STATUS_NO_SUCH_GROUP;
298 if (pnum_names) {
299 *pnum_names = 0;
302 tmp_ctx = talloc_stackframe();
303 if (tmp_ctx == NULL) {
304 return NT_STATUS_NO_MEMORY;
307 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
308 if (!NT_STATUS_IS_OK(status)) {
309 goto done;
312 b = samr_pipe->binding_handle;
314 status = rpc_lookup_groupmem(tmp_ctx,
315 samr_pipe,
316 &dom_pol,
317 domain->name,
318 &domain->sid,
319 group_sid,
320 type,
321 &num_names,
322 &sid_mem,
323 &names,
324 &name_types);
326 if (pnum_names) {
327 *pnum_names = num_names;
330 if (pnames) {
331 *pnames = talloc_move(mem_ctx, &names);
334 if (pname_types) {
335 *pname_types = talloc_move(mem_ctx, &name_types);
338 if (psid_mem) {
339 *psid_mem = talloc_move(mem_ctx, &sid_mem);
342 done:
343 if (b && is_valid_policy_hnd(&dom_pol)) {
344 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
347 TALLOC_FREE(tmp_ctx);
348 return status;
351 /*********************************************************************
352 BUILTIN specific functions.
353 *********************************************************************/
355 /* List all domain groups */
356 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
357 TALLOC_CTX *mem_ctx,
358 uint32_t *num_entries,
359 struct wb_acct_info **info)
361 /* BUILTIN doesn't have domain groups */
362 *num_entries = 0;
363 *info = NULL;
364 return NT_STATUS_OK;
367 /* Query display info for a domain */
368 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
369 TALLOC_CTX *mem_ctx,
370 uint32_t **rids)
372 /* We don't have users */
373 *rids = NULL;
374 return NT_STATUS_OK;
377 /* get a list of trusted domains - builtin domain */
378 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
379 TALLOC_CTX *mem_ctx,
380 struct netr_DomainTrustList *trusts)
382 ZERO_STRUCTP(trusts);
383 return NT_STATUS_OK;
386 /*********************************************************************
387 COMMON functions.
388 *********************************************************************/
390 /* List all local groups (aliases) */
391 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
392 TALLOC_CTX *mem_ctx,
393 uint32_t *pnum_info,
394 struct wb_acct_info **pinfo)
396 struct rpc_pipe_client *samr_pipe;
397 struct policy_handle dom_pol = { 0 };
398 struct wb_acct_info *info = NULL;
399 uint32_t num_info = 0;
400 TALLOC_CTX *tmp_ctx;
401 NTSTATUS status, result;
402 struct dcerpc_binding_handle *b = NULL;
404 DEBUG(3,("samr: enum local groups\n"));
406 if (pnum_info) {
407 *pnum_info = 0;
410 tmp_ctx = talloc_stackframe();
411 if (tmp_ctx == NULL) {
412 return NT_STATUS_NO_MEMORY;
415 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
416 if (!NT_STATUS_IS_OK(status)) {
417 goto done;
420 b = samr_pipe->binding_handle;
422 status = rpc_enum_local_groups(mem_ctx,
423 samr_pipe,
424 &dom_pol,
425 &num_info,
426 &info);
427 if (!NT_STATUS_IS_OK(status)) {
428 goto done;
431 if (pnum_info) {
432 *pnum_info = num_info;
435 if (pinfo) {
436 *pinfo = talloc_move(mem_ctx, &info);
439 done:
440 if (b && is_valid_policy_hnd(&dom_pol)) {
441 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
444 TALLOC_FREE(tmp_ctx);
445 return status;
448 /* convert a single name to a sid in a domain */
449 static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
450 TALLOC_CTX *mem_ctx,
451 const char *domain_name,
452 const char *name,
453 uint32_t flags,
454 struct dom_sid *psid,
455 enum lsa_SidType *ptype)
457 struct rpc_pipe_client *lsa_pipe;
458 struct policy_handle lsa_policy = { 0 };
459 struct dom_sid sid;
460 enum lsa_SidType type;
461 TALLOC_CTX *tmp_ctx;
462 NTSTATUS status, result;
463 struct dcerpc_binding_handle *b = NULL;
465 DEBUG(3,("sam_name_to_sid\n"));
467 tmp_ctx = talloc_stackframe();
468 if (tmp_ctx == NULL) {
469 return NT_STATUS_NO_MEMORY;
472 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
473 if (!NT_STATUS_IS_OK(status)) {
474 goto done;
477 b = lsa_pipe->binding_handle;
479 status = rpc_name_to_sid(tmp_ctx,
480 lsa_pipe,
481 &lsa_policy,
482 domain_name,
483 name,
484 flags,
485 &sid,
486 &type);
487 if (!NT_STATUS_IS_OK(status)) {
488 goto done;
491 if (psid) {
492 sid_copy(psid, &sid);
494 if (ptype) {
495 *ptype = type;
498 done:
499 if (b && is_valid_policy_hnd(&lsa_policy)) {
500 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
503 TALLOC_FREE(tmp_ctx);
504 return status;
507 /* convert a domain SID to a user or group name */
508 static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
509 TALLOC_CTX *mem_ctx,
510 const struct dom_sid *sid,
511 char **pdomain_name,
512 char **pname,
513 enum lsa_SidType *ptype)
515 struct rpc_pipe_client *lsa_pipe;
516 struct policy_handle lsa_policy = { 0 };
517 char *domain_name = NULL;
518 char *name = NULL;
519 enum lsa_SidType type;
520 TALLOC_CTX *tmp_ctx;
521 NTSTATUS status, result;
522 struct dcerpc_binding_handle *b = NULL;
524 DEBUG(3,("sam_sid_to_name\n"));
526 /* Paranoia check */
527 if (!sid_check_is_in_builtin(sid) &&
528 !sid_check_is_builtin(sid) &&
529 !sid_check_is_in_our_sam(sid) &&
530 !sid_check_is_our_sam(sid) &&
531 !sid_check_is_in_unix_users(sid) &&
532 !sid_check_is_unix_users(sid) &&
533 !sid_check_is_in_unix_groups(sid) &&
534 !sid_check_is_unix_groups(sid) &&
535 !sid_check_is_in_wellknown_domain(sid)) {
536 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
537 "lookup SID %s\n", sid_string_dbg(sid)));
538 return NT_STATUS_NONE_MAPPED;
541 tmp_ctx = talloc_stackframe();
542 if (tmp_ctx == NULL) {
543 return NT_STATUS_NO_MEMORY;
546 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
547 if (!NT_STATUS_IS_OK(status)) {
548 goto done;
551 b = lsa_pipe->binding_handle;
553 status = rpc_sid_to_name(tmp_ctx,
554 lsa_pipe,
555 &lsa_policy,
556 domain,
557 sid,
558 &domain_name,
559 &name,
560 &type);
562 if (ptype) {
563 *ptype = type;
566 if (pname) {
567 *pname = talloc_move(mem_ctx, &name);
570 if (pdomain_name) {
571 *pdomain_name = talloc_move(mem_ctx, &domain_name);
574 done:
575 if (b && is_valid_policy_hnd(&lsa_policy)) {
576 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
579 TALLOC_FREE(tmp_ctx);
580 return status;
583 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
584 TALLOC_CTX *mem_ctx,
585 const struct dom_sid *domain_sid,
586 uint32_t *rids,
587 size_t num_rids,
588 char **pdomain_name,
589 char ***pnames,
590 enum lsa_SidType **ptypes)
592 struct rpc_pipe_client *lsa_pipe;
593 struct policy_handle lsa_policy = { 0 };
594 enum lsa_SidType *types = NULL;
595 char *domain_name = NULL;
596 char **names = NULL;
597 TALLOC_CTX *tmp_ctx;
598 NTSTATUS status, result;
599 struct dcerpc_binding_handle *b = NULL;
601 DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
603 /* Paranoia check */
604 if (!sid_check_is_builtin(domain_sid) &&
605 !sid_check_is_our_sam(domain_sid) &&
606 !sid_check_is_unix_users(domain_sid) &&
607 !sid_check_is_unix_groups(domain_sid) &&
608 !sid_check_is_in_wellknown_domain(domain_sid)) {
609 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
610 "lookup SID %s\n", sid_string_dbg(domain_sid)));
611 return NT_STATUS_NONE_MAPPED;
614 tmp_ctx = talloc_stackframe();
615 if (tmp_ctx == NULL) {
616 return NT_STATUS_NO_MEMORY;
619 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
620 if (!NT_STATUS_IS_OK(status)) {
621 goto done;
624 b = lsa_pipe->binding_handle;
626 status = rpc_rids_to_names(tmp_ctx,
627 lsa_pipe,
628 &lsa_policy,
629 domain,
630 domain_sid,
631 rids,
632 num_rids,
633 &domain_name,
634 &names,
635 &types);
636 if (!NT_STATUS_IS_OK(status)) {
637 goto done;
640 if (pdomain_name) {
641 *pdomain_name = talloc_move(mem_ctx, &domain_name);
644 if (ptypes) {
645 *ptypes = talloc_move(mem_ctx, &types);
648 if (pnames) {
649 *pnames = talloc_move(mem_ctx, &names);
652 done:
653 if (b && is_valid_policy_hnd(&lsa_policy)) {
654 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
657 TALLOC_FREE(tmp_ctx);
658 return status;
661 static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
662 TALLOC_CTX *mem_ctx,
663 struct samr_DomInfo12 *lockout_policy)
665 struct rpc_pipe_client *samr_pipe;
666 struct policy_handle dom_pol = { 0 };
667 union samr_DomainInfo *info = NULL;
668 TALLOC_CTX *tmp_ctx;
669 NTSTATUS status, result;
670 struct dcerpc_binding_handle *b = NULL;
672 DEBUG(3,("sam_lockout_policy\n"));
674 tmp_ctx = talloc_stackframe();
675 if (tmp_ctx == NULL) {
676 return NT_STATUS_NO_MEMORY;
679 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
680 if (!NT_STATUS_IS_OK(status)) {
681 goto error;
684 b = samr_pipe->binding_handle;
686 status = dcerpc_samr_QueryDomainInfo(b,
687 mem_ctx,
688 &dom_pol,
689 DomainLockoutInformation,
690 &info,
691 &result);
692 if (!NT_STATUS_IS_OK(status)) {
693 goto error;
695 if (!NT_STATUS_IS_OK(result)) {
696 status = result;
697 goto error;
700 *lockout_policy = info->info12;
702 error:
703 if (b && is_valid_policy_hnd(&dom_pol)) {
704 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
707 TALLOC_FREE(tmp_ctx);
708 return status;
711 static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
712 TALLOC_CTX *mem_ctx,
713 struct samr_DomInfo1 *passwd_policy)
715 struct rpc_pipe_client *samr_pipe;
716 struct policy_handle dom_pol = { 0 };
717 union samr_DomainInfo *info = NULL;
718 TALLOC_CTX *tmp_ctx;
719 NTSTATUS status, result;
720 struct dcerpc_binding_handle *b = NULL;
722 DEBUG(3,("sam_password_policy\n"));
724 tmp_ctx = talloc_stackframe();
725 if (tmp_ctx == NULL) {
726 return NT_STATUS_NO_MEMORY;
729 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
730 if (!NT_STATUS_IS_OK(status)) {
731 goto error;
734 b = samr_pipe->binding_handle;
736 status = dcerpc_samr_QueryDomainInfo(b,
737 mem_ctx,
738 &dom_pol,
739 DomainPasswordInformation,
740 &info,
741 &result);
742 if (!NT_STATUS_IS_OK(status)) {
743 goto error;
745 if (!NT_STATUS_IS_OK(result)) {
746 status = result;
747 goto error;
750 *passwd_policy = info->info1;
752 error:
753 if (b && is_valid_policy_hnd(&dom_pol)) {
754 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
757 TALLOC_FREE(tmp_ctx);
758 return status;
761 /* Lookup groups a user is a member of. */
762 static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
763 TALLOC_CTX *mem_ctx,
764 const struct dom_sid *user_sid,
765 uint32_t *pnum_groups,
766 struct dom_sid **puser_grpsids)
768 struct rpc_pipe_client *samr_pipe;
769 struct policy_handle dom_pol;
770 struct dom_sid *user_grpsids = NULL;
771 uint32_t num_groups = 0;
772 TALLOC_CTX *tmp_ctx;
773 NTSTATUS status, result;
774 struct dcerpc_binding_handle *b = NULL;
776 DEBUG(3,("sam_lookup_usergroups\n"));
778 ZERO_STRUCT(dom_pol);
780 if (pnum_groups) {
781 *pnum_groups = 0;
784 tmp_ctx = talloc_stackframe();
785 if (tmp_ctx == NULL) {
786 return NT_STATUS_NO_MEMORY;
789 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
790 if (!NT_STATUS_IS_OK(status)) {
791 goto done;
794 b = samr_pipe->binding_handle;
796 status = rpc_lookup_usergroups(tmp_ctx,
797 samr_pipe,
798 &dom_pol,
799 &domain->sid,
800 user_sid,
801 &num_groups,
802 &user_grpsids);
803 if (!NT_STATUS_IS_OK(status)) {
804 goto done;
807 if (pnum_groups) {
808 *pnum_groups = num_groups;
811 if (puser_grpsids) {
812 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
815 done:
816 if (b && is_valid_policy_hnd(&dom_pol)) {
817 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
820 TALLOC_FREE(tmp_ctx);
821 return status;
824 static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
825 TALLOC_CTX *mem_ctx,
826 uint32_t num_sids,
827 const struct dom_sid *sids,
828 uint32_t *pnum_aliases,
829 uint32_t **palias_rids)
831 struct rpc_pipe_client *samr_pipe;
832 struct policy_handle dom_pol = { 0 };
833 uint32_t num_aliases = 0;
834 uint32_t *alias_rids = NULL;
835 TALLOC_CTX *tmp_ctx;
836 NTSTATUS status, result;
837 struct dcerpc_binding_handle *b = NULL;
839 DEBUG(3,("sam_lookup_useraliases\n"));
841 if (pnum_aliases) {
842 *pnum_aliases = 0;
845 tmp_ctx = talloc_stackframe();
846 if (tmp_ctx == NULL) {
847 return NT_STATUS_NO_MEMORY;
850 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
851 if (!NT_STATUS_IS_OK(status)) {
852 goto done;
855 b = samr_pipe->binding_handle;
857 status = rpc_lookup_useraliases(tmp_ctx,
858 samr_pipe,
859 &dom_pol,
860 num_sids,
861 sids,
862 &num_aliases,
863 &alias_rids);
864 if (!NT_STATUS_IS_OK(status)) {
865 goto done;
868 if (pnum_aliases) {
869 *pnum_aliases = num_aliases;
872 if (palias_rids) {
873 *palias_rids = talloc_move(mem_ctx, &alias_rids);
876 done:
877 if (b && is_valid_policy_hnd(&dom_pol)) {
878 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
881 TALLOC_FREE(tmp_ctx);
882 return status;
885 /* find the sequence number for a domain */
886 static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
887 uint32_t *pseq)
889 struct rpc_pipe_client *samr_pipe;
890 struct policy_handle dom_pol = { 0 };
891 uint32_t seq = DOM_SEQUENCE_NONE;
892 TALLOC_CTX *tmp_ctx;
893 NTSTATUS status, result;
894 struct dcerpc_binding_handle *b = NULL;
896 DEBUG(3,("samr: sequence number\n"));
898 if (pseq) {
899 *pseq = DOM_SEQUENCE_NONE;
902 tmp_ctx = talloc_stackframe();
903 if (tmp_ctx == NULL) {
904 return NT_STATUS_NO_MEMORY;
907 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
908 if (!NT_STATUS_IS_OK(status)) {
909 goto done;
912 b = samr_pipe->binding_handle;
914 status = rpc_sequence_number(tmp_ctx,
915 samr_pipe,
916 &dom_pol,
917 domain->name,
918 &seq);
919 if (!NT_STATUS_IS_OK(status)) {
920 goto done;
923 if (pseq) {
924 *pseq = seq;
926 done:
927 if (b && is_valid_policy_hnd(&dom_pol)) {
928 dcerpc_samr_Close(b, tmp_ctx, &dom_pol, &result);
931 TALLOC_FREE(tmp_ctx);
932 return status;
935 /* the rpc backend methods are exposed via this structure */
936 struct winbindd_methods builtin_passdb_methods = {
937 .consistent = false,
939 .query_user_list = builtin_query_user_list,
940 .enum_dom_groups = builtin_enum_dom_groups,
941 .enum_local_groups = sam_enum_local_groups,
942 .name_to_sid = sam_name_to_sid,
943 .sid_to_name = sam_sid_to_name,
944 .rids_to_names = sam_rids_to_names,
945 .lookup_usergroups = sam_lookup_usergroups,
946 .lookup_useraliases = sam_lookup_useraliases,
947 .lookup_groupmem = sam_lookup_groupmem,
948 .sequence_number = sam_sequence_number,
949 .lockout_policy = sam_lockout_policy,
950 .password_policy = sam_password_policy,
951 .trusted_domains = builtin_trusted_domains
954 /* the rpc backend methods are exposed via this structure */
955 struct winbindd_methods sam_passdb_methods = {
956 .consistent = false,
958 .query_user_list = sam_query_user_list,
959 .enum_dom_groups = sam_enum_dom_groups,
960 .enum_local_groups = sam_enum_local_groups,
961 .name_to_sid = sam_name_to_sid,
962 .sid_to_name = sam_sid_to_name,
963 .rids_to_names = sam_rids_to_names,
964 .lookup_usergroups = sam_lookup_usergroups,
965 .lookup_useraliases = sam_lookup_useraliases,
966 .lookup_groupmem = sam_lookup_groupmem,
967 .sequence_number = sam_sequence_number,
968 .lockout_policy = sam_lockout_policy,
969 .password_policy = sam_password_policy,
970 .trusted_domains = sam_trusted_domains