winbindd: Remove pointless if statement
[Samba/wip.git] / source3 / winbindd / winbindd_samr.c
blob78843d62a464ecc8e9954a90e96a9c46c951dea0
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 "rpc_client/rpc_client.h"
30 #include "../librpc/gen_ndr/ndr_samr_c.h"
31 #include "rpc_client/cli_samr.h"
32 #include "../librpc/gen_ndr/ndr_lsa_c.h"
33 #include "rpc_client/cli_lsarpc.h"
34 #include "rpc_server/rpc_ncacn_np.h"
35 #include "../libcli/security/security.h"
36 #include "passdb/machine_sid.h"
37 #include "auth.h"
39 #undef DBGC_CLASS
40 #define DBGC_CLASS DBGC_WINBIND
42 static NTSTATUS open_internal_samr_pipe(TALLOC_CTX *mem_ctx,
43 struct rpc_pipe_client **samr_pipe)
45 struct rpc_pipe_client *cli = NULL;
46 struct auth_session_info *session_info = NULL;
47 NTSTATUS status;
49 status = make_session_info_system(mem_ctx, &session_info);
50 if (!NT_STATUS_IS_OK(status)) {
51 DEBUG(0, ("open_samr_pipe: Could not create auth_session_info: %s\n",
52 nt_errstr(status)));
53 return status;
56 /* create a samr connection */
57 status = rpc_pipe_open_internal(mem_ctx,
58 &ndr_table_samr.syntax_id,
59 session_info,
60 NULL,
61 winbind_messaging_context(),
62 &cli);
63 if (!NT_STATUS_IS_OK(status)) {
64 DEBUG(0, ("open_samr_pipe: Could not connect to samr_pipe: %s\n",
65 nt_errstr(status)));
66 return status;
69 if (samr_pipe) {
70 *samr_pipe = cli;
73 return NT_STATUS_OK;
76 NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
77 struct winbindd_domain *domain,
78 struct rpc_pipe_client **samr_pipe,
79 struct policy_handle *samr_domain_hnd)
81 NTSTATUS status, result;
82 struct policy_handle samr_connect_hnd;
83 struct dcerpc_binding_handle *b;
85 status = open_internal_samr_pipe(mem_ctx, samr_pipe);
86 if (!NT_STATUS_IS_OK(status)) {
87 return status;
90 b = (*samr_pipe)->binding_handle;
92 status = dcerpc_samr_Connect2(b, mem_ctx,
93 (*samr_pipe)->desthost,
94 SEC_FLAG_MAXIMUM_ALLOWED,
95 &samr_connect_hnd,
96 &result);
97 if (!NT_STATUS_IS_OK(status)) {
98 return status;
100 if (!NT_STATUS_IS_OK(result)) {
101 return result;
104 status = dcerpc_samr_OpenDomain(b, mem_ctx,
105 &samr_connect_hnd,
106 SEC_FLAG_MAXIMUM_ALLOWED,
107 &domain->sid,
108 samr_domain_hnd,
109 &result);
110 if (!NT_STATUS_IS_OK(status)) {
111 return status;
114 return result;
117 static NTSTATUS open_internal_lsa_pipe(TALLOC_CTX *mem_ctx,
118 struct rpc_pipe_client **lsa_pipe)
120 struct rpc_pipe_client *cli = NULL;
121 struct auth_session_info *session_info = NULL;
122 NTSTATUS status;
124 status = make_session_info_system(mem_ctx, &session_info);
125 if (!NT_STATUS_IS_OK(status)) {
126 DEBUG(0, ("open_lsa_pipe: Could not create auth_session_info: %s\n",
127 nt_errstr(status)));
128 return status;
131 /* create a lsa connection */
132 status = rpc_pipe_open_internal(mem_ctx,
133 &ndr_table_lsarpc.syntax_id,
134 session_info,
135 NULL,
136 winbind_messaging_context(),
137 &cli);
138 if (!NT_STATUS_IS_OK(status)) {
139 DEBUG(0, ("open_lsa_pipe: Could not connect to lsa_pipe: %s\n",
140 nt_errstr(status)));
141 return status;
144 if (lsa_pipe) {
145 *lsa_pipe = cli;
148 return NT_STATUS_OK;
151 static NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
152 struct rpc_pipe_client **lsa_pipe,
153 struct policy_handle *lsa_hnd)
155 NTSTATUS status;
157 status = open_internal_lsa_pipe(mem_ctx, lsa_pipe);
158 if (!NT_STATUS_IS_OK(status)) {
159 return status;
162 status = rpccli_lsa_open_policy((*lsa_pipe),
163 mem_ctx,
164 true,
165 SEC_FLAG_MAXIMUM_ALLOWED,
166 lsa_hnd);
168 return status;
171 /*********************************************************************
172 SAM specific functions.
173 *********************************************************************/
175 /* List all domain groups */
176 static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
177 TALLOC_CTX *mem_ctx,
178 uint32_t *pnum_info,
179 struct wb_acct_info **pinfo)
181 struct rpc_pipe_client *samr_pipe;
182 struct policy_handle dom_pol;
183 struct wb_acct_info *info = NULL;
184 uint32_t num_info = 0;
185 TALLOC_CTX *tmp_ctx;
186 NTSTATUS status, result;
187 struct dcerpc_binding_handle *b = NULL;
189 DEBUG(3,("sam_enum_dom_groups\n"));
191 ZERO_STRUCT(dom_pol);
193 if (pnum_info) {
194 *pnum_info = 0;
197 tmp_ctx = talloc_stackframe();
198 if (tmp_ctx == NULL) {
199 return NT_STATUS_NO_MEMORY;
202 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
203 if (!NT_STATUS_IS_OK(status)) {
204 goto error;
207 b = samr_pipe->binding_handle;
209 status = rpc_enum_dom_groups(tmp_ctx,
210 samr_pipe,
211 &dom_pol,
212 &num_info,
213 &info);
214 if (!NT_STATUS_IS_OK(status)) {
215 goto error;
218 if (pnum_info) {
219 *pnum_info = num_info;
222 if (pinfo) {
223 *pinfo = talloc_move(mem_ctx, &info);
226 error:
227 if (b && is_valid_policy_hnd(&dom_pol)) {
228 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
230 TALLOC_FREE(tmp_ctx);
231 return status;
234 /* Query display info for a domain */
235 static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
236 TALLOC_CTX *mem_ctx,
237 uint32_t *pnum_info,
238 struct wbint_userinfo **pinfo)
240 struct rpc_pipe_client *samr_pipe = NULL;
241 struct policy_handle dom_pol;
242 struct wbint_userinfo *info = NULL;
243 uint32_t num_info = 0;
244 TALLOC_CTX *tmp_ctx;
245 NTSTATUS status, result;
246 struct dcerpc_binding_handle *b = NULL;
248 DEBUG(3,("samr_query_user_list\n"));
250 ZERO_STRUCT(dom_pol);
252 if (pnum_info) {
253 *pnum_info = 0;
256 tmp_ctx = talloc_stackframe();
257 if (tmp_ctx == NULL) {
258 return NT_STATUS_NO_MEMORY;
261 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
262 if (!NT_STATUS_IS_OK(status)) {
263 goto done;
266 b = samr_pipe->binding_handle;
268 status = rpc_query_user_list(tmp_ctx,
269 samr_pipe,
270 &dom_pol,
271 &domain->sid,
272 &num_info,
273 &info);
274 if (!NT_STATUS_IS_OK(status)) {
275 goto done;
278 if (pnum_info) {
279 *pnum_info = num_info;
282 if (pinfo) {
283 *pinfo = talloc_move(mem_ctx, &info);
286 done:
287 if (b && is_valid_policy_hnd(&dom_pol)) {
288 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
291 TALLOC_FREE(tmp_ctx);
292 return status;
295 /* Lookup user information from a rid or username. */
296 static NTSTATUS sam_query_user(struct winbindd_domain *domain,
297 TALLOC_CTX *mem_ctx,
298 const struct dom_sid *user_sid,
299 struct wbint_userinfo *user_info)
301 struct rpc_pipe_client *samr_pipe;
302 struct policy_handle dom_pol;
303 TALLOC_CTX *tmp_ctx;
304 NTSTATUS status, result;
305 struct dcerpc_binding_handle *b = NULL;
307 DEBUG(3,("sam_query_user\n"));
309 ZERO_STRUCT(dom_pol);
311 /* Paranoia check */
312 if (!sid_check_is_in_our_sam(user_sid)) {
313 return NT_STATUS_NO_SUCH_USER;
316 user_info->homedir = NULL;
317 user_info->shell = NULL;
318 user_info->primary_gid = (gid_t) -1;
320 tmp_ctx = talloc_stackframe();
321 if (tmp_ctx == NULL) {
322 return NT_STATUS_NO_MEMORY;
325 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
326 if (!NT_STATUS_IS_OK(status)) {
327 goto done;
330 b = samr_pipe->binding_handle;
332 status = rpc_query_user(tmp_ctx,
333 samr_pipe,
334 &dom_pol,
335 &domain->sid,
336 user_sid,
337 user_info);
339 done:
340 if (b && is_valid_policy_hnd(&dom_pol)) {
341 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
344 TALLOC_FREE(tmp_ctx);
345 return status;
348 /* get a list of trusted domains - builtin domain */
349 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
350 TALLOC_CTX *mem_ctx,
351 struct netr_DomainTrustList *ptrust_list)
353 struct rpc_pipe_client *lsa_pipe;
354 struct policy_handle lsa_policy;
355 struct netr_DomainTrust *trusts = NULL;
356 uint32_t num_trusts = 0;
357 TALLOC_CTX *tmp_ctx;
358 NTSTATUS status, result;
359 struct dcerpc_binding_handle *b = NULL;
361 DEBUG(3,("samr: trusted domains\n"));
363 ZERO_STRUCT(lsa_policy);
365 if (ptrust_list) {
366 ZERO_STRUCTP(ptrust_list);
369 tmp_ctx = talloc_stackframe();
370 if (tmp_ctx == NULL) {
371 return NT_STATUS_NO_MEMORY;
374 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
375 if (!NT_STATUS_IS_OK(status)) {
376 goto done;
379 b = lsa_pipe->binding_handle;
381 status = rpc_trusted_domains(tmp_ctx,
382 lsa_pipe,
383 &lsa_policy,
384 &num_trusts,
385 &trusts);
386 if (!NT_STATUS_IS_OK(status)) {
387 goto done;
390 if (ptrust_list) {
391 ptrust_list->count = num_trusts;
392 ptrust_list->array = talloc_move(mem_ctx, &trusts);
395 done:
396 if (b && is_valid_policy_hnd(&lsa_policy)) {
397 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
400 TALLOC_FREE(tmp_ctx);
401 return status;
404 /* Lookup group membership given a rid. */
405 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
406 TALLOC_CTX *mem_ctx,
407 const struct dom_sid *group_sid,
408 enum lsa_SidType type,
409 uint32_t *pnum_names,
410 struct dom_sid **psid_mem,
411 char ***pnames,
412 uint32_t **pname_types)
414 struct rpc_pipe_client *samr_pipe;
415 struct policy_handle dom_pol;
417 uint32_t num_names = 0;
418 struct dom_sid *sid_mem = NULL;
419 char **names = NULL;
420 uint32_t *name_types = NULL;
422 TALLOC_CTX *tmp_ctx;
423 NTSTATUS status, result;
424 struct dcerpc_binding_handle *b = NULL;
426 DEBUG(3,("sam_lookup_groupmem\n"));
428 ZERO_STRUCT(dom_pol);
430 /* Paranoia check */
431 if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
432 /* There's no groups, only aliases in BUILTIN */
433 return NT_STATUS_NO_SUCH_GROUP;
436 if (pnum_names) {
437 *pnum_names = 0;
440 tmp_ctx = talloc_stackframe();
441 if (tmp_ctx == NULL) {
442 return NT_STATUS_NO_MEMORY;
445 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
446 if (!NT_STATUS_IS_OK(status)) {
447 goto done;
450 b = samr_pipe->binding_handle;
452 status = rpc_lookup_groupmem(tmp_ctx,
453 samr_pipe,
454 &dom_pol,
455 domain->name,
456 &domain->sid,
457 group_sid,
458 type,
459 &num_names,
460 &sid_mem,
461 &names,
462 &name_types);
464 if (pnum_names) {
465 *pnum_names = num_names;
468 if (pnames) {
469 *pnames = talloc_move(mem_ctx, &names);
472 if (pname_types) {
473 *pname_types = talloc_move(mem_ctx, &name_types);
476 if (psid_mem) {
477 *psid_mem = talloc_move(mem_ctx, &sid_mem);
480 done:
481 if (b && is_valid_policy_hnd(&dom_pol)) {
482 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
485 TALLOC_FREE(tmp_ctx);
486 return status;
489 /*********************************************************************
490 BUILTIN specific functions.
491 *********************************************************************/
493 /* List all domain groups */
494 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
495 TALLOC_CTX *mem_ctx,
496 uint32 *num_entries,
497 struct wb_acct_info **info)
499 /* BUILTIN doesn't have domain groups */
500 *num_entries = 0;
501 *info = NULL;
502 return NT_STATUS_OK;
505 /* Query display info for a domain */
506 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
507 TALLOC_CTX *mem_ctx,
508 uint32 *num_entries,
509 struct wbint_userinfo **info)
511 /* We don't have users */
512 *num_entries = 0;
513 *info = NULL;
514 return NT_STATUS_OK;
517 /* Lookup user information from a rid or username. */
518 static NTSTATUS builtin_query_user(struct winbindd_domain *domain,
519 TALLOC_CTX *mem_ctx,
520 const struct dom_sid *user_sid,
521 struct wbint_userinfo *user_info)
523 return NT_STATUS_NO_SUCH_USER;
526 /* get a list of trusted domains - builtin domain */
527 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
528 TALLOC_CTX *mem_ctx,
529 struct netr_DomainTrustList *trusts)
531 ZERO_STRUCTP(trusts);
532 return NT_STATUS_OK;
535 /*********************************************************************
536 COMMON functions.
537 *********************************************************************/
539 /* List all local groups (aliases) */
540 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
541 TALLOC_CTX *mem_ctx,
542 uint32_t *pnum_info,
543 struct wb_acct_info **pinfo)
545 struct rpc_pipe_client *samr_pipe;
546 struct policy_handle dom_pol;
547 struct wb_acct_info *info = NULL;
548 uint32_t num_info = 0;
549 TALLOC_CTX *tmp_ctx;
550 NTSTATUS status, result;
551 struct dcerpc_binding_handle *b = NULL;
553 DEBUG(3,("samr: enum local groups\n"));
555 ZERO_STRUCT(dom_pol);
557 if (pnum_info) {
558 *pnum_info = 0;
561 tmp_ctx = talloc_stackframe();
562 if (tmp_ctx == NULL) {
563 return NT_STATUS_NO_MEMORY;
566 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
567 if (!NT_STATUS_IS_OK(status)) {
568 goto done;
571 b = samr_pipe->binding_handle;
573 status = rpc_enum_local_groups(mem_ctx,
574 samr_pipe,
575 &dom_pol,
576 &num_info,
577 &info);
578 if (!NT_STATUS_IS_OK(status)) {
579 goto done;
582 if (pnum_info) {
583 *pnum_info = num_info;
586 if (pinfo) {
587 *pinfo = talloc_move(mem_ctx, &info);
590 done:
591 if (b && is_valid_policy_hnd(&dom_pol)) {
592 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
595 TALLOC_FREE(tmp_ctx);
596 return status;
599 /* convert a single name to a sid in a domain */
600 static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
601 TALLOC_CTX *mem_ctx,
602 const char *domain_name,
603 const char *name,
604 uint32_t flags,
605 struct dom_sid *psid,
606 enum lsa_SidType *ptype)
608 struct rpc_pipe_client *lsa_pipe;
609 struct policy_handle lsa_policy;
610 struct dom_sid sid;
611 enum lsa_SidType type;
612 TALLOC_CTX *tmp_ctx;
613 NTSTATUS status, result;
614 struct dcerpc_binding_handle *b = NULL;
616 DEBUG(3,("sam_name_to_sid\n"));
618 ZERO_STRUCT(lsa_policy);
620 tmp_ctx = talloc_stackframe();
621 if (tmp_ctx == NULL) {
622 return NT_STATUS_NO_MEMORY;
625 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
626 if (!NT_STATUS_IS_OK(status)) {
627 goto done;
630 b = lsa_pipe->binding_handle;
632 status = rpc_name_to_sid(tmp_ctx,
633 lsa_pipe,
634 &lsa_policy,
635 domain_name,
636 name,
637 flags,
638 &sid,
639 &type);
640 if (!NT_STATUS_IS_OK(status)) {
641 goto done;
644 if (psid) {
645 sid_copy(psid, &sid);
647 if (ptype) {
648 *ptype = type;
651 done:
652 if (b && is_valid_policy_hnd(&lsa_policy)) {
653 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
656 TALLOC_FREE(tmp_ctx);
657 return status;
660 /* convert a domain SID to a user or group name */
661 static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
662 TALLOC_CTX *mem_ctx,
663 const struct dom_sid *sid,
664 char **pdomain_name,
665 char **pname,
666 enum lsa_SidType *ptype)
668 struct rpc_pipe_client *lsa_pipe;
669 struct policy_handle lsa_policy;
670 char *domain_name = NULL;
671 char *name = NULL;
672 enum lsa_SidType type;
673 TALLOC_CTX *tmp_ctx;
674 NTSTATUS status, result;
675 struct dcerpc_binding_handle *b = NULL;
677 DEBUG(3,("sam_sid_to_name\n"));
679 ZERO_STRUCT(lsa_policy);
681 /* Paranoia check */
682 if (!sid_check_is_in_builtin(sid) &&
683 !sid_check_is_builtin(sid) &&
684 !sid_check_is_in_our_sam(sid) &&
685 !sid_check_is_our_sam(sid) &&
686 !sid_check_is_in_unix_users(sid) &&
687 !sid_check_is_unix_users(sid) &&
688 !sid_check_is_in_unix_groups(sid) &&
689 !sid_check_is_unix_groups(sid) &&
690 !sid_check_is_in_wellknown_domain(sid)) {
691 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
692 "lookup SID %s\n", sid_string_dbg(sid)));
693 return NT_STATUS_NONE_MAPPED;
696 tmp_ctx = talloc_stackframe();
697 if (tmp_ctx == NULL) {
698 return NT_STATUS_NO_MEMORY;
701 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
702 if (!NT_STATUS_IS_OK(status)) {
703 goto done;
706 b = lsa_pipe->binding_handle;
708 status = rpc_sid_to_name(tmp_ctx,
709 lsa_pipe,
710 &lsa_policy,
711 domain,
712 sid,
713 &domain_name,
714 &name,
715 &type);
717 if (ptype) {
718 *ptype = type;
721 if (pname) {
722 *pname = talloc_move(mem_ctx, &name);
725 if (pdomain_name) {
726 *pdomain_name = talloc_move(mem_ctx, &domain_name);
729 done:
730 if (b && is_valid_policy_hnd(&lsa_policy)) {
731 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
734 TALLOC_FREE(tmp_ctx);
735 return status;
738 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
739 TALLOC_CTX *mem_ctx,
740 const struct dom_sid *domain_sid,
741 uint32 *rids,
742 size_t num_rids,
743 char **pdomain_name,
744 char ***pnames,
745 enum lsa_SidType **ptypes)
747 struct rpc_pipe_client *lsa_pipe;
748 struct policy_handle lsa_policy;
749 enum lsa_SidType *types = NULL;
750 char *domain_name = NULL;
751 char **names = NULL;
752 TALLOC_CTX *tmp_ctx;
753 NTSTATUS status, result;
754 struct dcerpc_binding_handle *b = NULL;
756 DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
758 ZERO_STRUCT(lsa_policy);
760 /* Paranoia check */
761 if (!sid_check_is_builtin(domain_sid) &&
762 !sid_check_is_our_sam(domain_sid) &&
763 !sid_check_is_unix_users(domain_sid) &&
764 !sid_check_is_unix_groups(domain_sid) &&
765 !sid_check_is_in_wellknown_domain(domain_sid)) {
766 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
767 "lookup SID %s\n", sid_string_dbg(domain_sid)));
768 return NT_STATUS_NONE_MAPPED;
771 tmp_ctx = talloc_stackframe();
772 if (tmp_ctx == NULL) {
773 return NT_STATUS_NO_MEMORY;
776 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
777 if (!NT_STATUS_IS_OK(status)) {
778 goto done;
781 b = lsa_pipe->binding_handle;
783 status = rpc_rids_to_names(tmp_ctx,
784 lsa_pipe,
785 &lsa_policy,
786 domain,
787 domain_sid,
788 rids,
789 num_rids,
790 &domain_name,
791 &names,
792 &types);
793 if (!NT_STATUS_IS_OK(status)) {
794 goto done;
797 if (pdomain_name) {
798 *pdomain_name = talloc_move(mem_ctx, &domain_name);
801 if (ptypes) {
802 *ptypes = talloc_move(mem_ctx, &types);
805 if (pnames) {
806 *pnames = talloc_move(mem_ctx, &names);
809 done:
810 if (b && is_valid_policy_hnd(&lsa_policy)) {
811 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
814 TALLOC_FREE(tmp_ctx);
815 return status;
818 static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
819 TALLOC_CTX *mem_ctx,
820 struct samr_DomInfo12 *lockout_policy)
822 struct rpc_pipe_client *samr_pipe;
823 struct policy_handle dom_pol;
824 union samr_DomainInfo *info = NULL;
825 TALLOC_CTX *tmp_ctx;
826 NTSTATUS status, result;
827 struct dcerpc_binding_handle *b = NULL;
829 DEBUG(3,("sam_lockout_policy\n"));
831 ZERO_STRUCT(dom_pol);
833 tmp_ctx = talloc_stackframe();
834 if (tmp_ctx == NULL) {
835 return NT_STATUS_NO_MEMORY;
838 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
839 if (!NT_STATUS_IS_OK(status)) {
840 goto error;
843 b = samr_pipe->binding_handle;
845 status = dcerpc_samr_QueryDomainInfo(b,
846 mem_ctx,
847 &dom_pol,
848 DomainLockoutInformation,
849 &info,
850 &result);
851 if (!NT_STATUS_IS_OK(status)) {
852 goto error;
854 if (!NT_STATUS_IS_OK(result)) {
855 status = result;
856 goto error;
859 *lockout_policy = info->info12;
861 error:
862 if (b && is_valid_policy_hnd(&dom_pol)) {
863 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
866 TALLOC_FREE(tmp_ctx);
867 return status;
870 static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
871 TALLOC_CTX *mem_ctx,
872 struct samr_DomInfo1 *passwd_policy)
874 struct rpc_pipe_client *samr_pipe;
875 struct policy_handle dom_pol;
876 union samr_DomainInfo *info = NULL;
877 TALLOC_CTX *tmp_ctx;
878 NTSTATUS status, result;
879 struct dcerpc_binding_handle *b = NULL;
881 DEBUG(3,("sam_password_policy\n"));
883 ZERO_STRUCT(dom_pol);
885 tmp_ctx = talloc_stackframe();
886 if (tmp_ctx == NULL) {
887 return NT_STATUS_NO_MEMORY;
890 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
891 if (!NT_STATUS_IS_OK(status)) {
892 goto error;
895 b = samr_pipe->binding_handle;
897 status = dcerpc_samr_QueryDomainInfo(b,
898 mem_ctx,
899 &dom_pol,
900 DomainPasswordInformation,
901 &info,
902 &result);
903 if (!NT_STATUS_IS_OK(status)) {
904 goto error;
906 if (!NT_STATUS_IS_OK(result)) {
907 status = result;
908 goto error;
911 *passwd_policy = info->info1;
913 error:
914 if (b && is_valid_policy_hnd(&dom_pol)) {
915 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
918 TALLOC_FREE(tmp_ctx);
919 return status;
922 /* Lookup groups a user is a member of. */
923 static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
924 TALLOC_CTX *mem_ctx,
925 const struct dom_sid *user_sid,
926 uint32_t *pnum_groups,
927 struct dom_sid **puser_grpsids)
929 struct rpc_pipe_client *samr_pipe;
930 struct policy_handle dom_pol;
931 struct dom_sid *user_grpsids = NULL;
932 uint32_t num_groups = 0;
933 TALLOC_CTX *tmp_ctx;
934 NTSTATUS status, result;
935 struct dcerpc_binding_handle *b = NULL;
937 DEBUG(3,("sam_lookup_usergroups\n"));
939 ZERO_STRUCT(dom_pol);
941 if (pnum_groups) {
942 *pnum_groups = 0;
945 tmp_ctx = talloc_stackframe();
946 if (tmp_ctx == NULL) {
947 return NT_STATUS_NO_MEMORY;
950 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
951 if (!NT_STATUS_IS_OK(status)) {
952 goto done;
955 b = samr_pipe->binding_handle;
957 status = rpc_lookup_usergroups(tmp_ctx,
958 samr_pipe,
959 &dom_pol,
960 &domain->sid,
961 user_sid,
962 &num_groups,
963 &user_grpsids);
964 if (!NT_STATUS_IS_OK(status)) {
965 goto done;
968 if (pnum_groups) {
969 *pnum_groups = num_groups;
972 if (puser_grpsids) {
973 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
976 done:
977 if (b && is_valid_policy_hnd(&dom_pol)) {
978 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
981 TALLOC_FREE(tmp_ctx);
982 return status;
985 static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
986 TALLOC_CTX *mem_ctx,
987 uint32_t num_sids,
988 const struct dom_sid *sids,
989 uint32_t *pnum_aliases,
990 uint32_t **palias_rids)
992 struct rpc_pipe_client *samr_pipe;
993 struct policy_handle dom_pol;
994 uint32_t num_aliases = 0;
995 uint32_t *alias_rids = NULL;
996 TALLOC_CTX *tmp_ctx;
997 NTSTATUS status, result;
998 struct dcerpc_binding_handle *b = NULL;
1000 DEBUG(3,("sam_lookup_useraliases\n"));
1002 ZERO_STRUCT(dom_pol);
1004 if (pnum_aliases) {
1005 *pnum_aliases = 0;
1008 tmp_ctx = talloc_stackframe();
1009 if (tmp_ctx == NULL) {
1010 return NT_STATUS_NO_MEMORY;
1013 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
1014 if (!NT_STATUS_IS_OK(status)) {
1015 goto done;
1018 b = samr_pipe->binding_handle;
1020 status = rpc_lookup_useraliases(tmp_ctx,
1021 samr_pipe,
1022 &dom_pol,
1023 num_sids,
1024 sids,
1025 &num_aliases,
1026 &alias_rids);
1027 if (!NT_STATUS_IS_OK(status)) {
1028 goto done;
1031 if (pnum_aliases) {
1032 *pnum_aliases = num_aliases;
1035 if (palias_rids) {
1036 *palias_rids = talloc_move(mem_ctx, &alias_rids);
1039 done:
1040 if (b && is_valid_policy_hnd(&dom_pol)) {
1041 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
1044 TALLOC_FREE(tmp_ctx);
1045 return status;
1048 /* find the sequence number for a domain */
1049 static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
1050 uint32_t *pseq)
1052 struct rpc_pipe_client *samr_pipe;
1053 struct policy_handle dom_pol;
1054 uint32_t seq;
1055 TALLOC_CTX *tmp_ctx;
1056 NTSTATUS status, result;
1057 struct dcerpc_binding_handle *b = NULL;
1059 DEBUG(3,("samr: sequence number\n"));
1061 ZERO_STRUCT(dom_pol);
1063 if (pseq) {
1064 *pseq = DOM_SEQUENCE_NONE;
1067 tmp_ctx = talloc_stackframe();
1068 if (tmp_ctx == NULL) {
1069 return NT_STATUS_NO_MEMORY;
1072 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
1073 if (!NT_STATUS_IS_OK(status)) {
1074 goto done;
1077 b = samr_pipe->binding_handle;
1079 status = rpc_sequence_number(tmp_ctx,
1080 samr_pipe,
1081 &dom_pol,
1082 domain->name,
1083 &seq);
1084 if (!NT_STATUS_IS_OK(status)) {
1085 goto done;
1088 if (pseq) {
1089 *pseq = seq;
1091 done:
1092 if (b && is_valid_policy_hnd(&dom_pol)) {
1093 dcerpc_samr_Close(b, tmp_ctx, &dom_pol, &result);
1096 TALLOC_FREE(tmp_ctx);
1097 return status;
1100 /* the rpc backend methods are exposed via this structure */
1101 struct winbindd_methods builtin_passdb_methods = {
1102 .consistent = false,
1104 .query_user_list = builtin_query_user_list,
1105 .enum_dom_groups = builtin_enum_dom_groups,
1106 .enum_local_groups = sam_enum_local_groups,
1107 .name_to_sid = sam_name_to_sid,
1108 .sid_to_name = sam_sid_to_name,
1109 .rids_to_names = sam_rids_to_names,
1110 .query_user = builtin_query_user,
1111 .lookup_usergroups = sam_lookup_usergroups,
1112 .lookup_useraliases = sam_lookup_useraliases,
1113 .lookup_groupmem = sam_lookup_groupmem,
1114 .sequence_number = sam_sequence_number,
1115 .lockout_policy = sam_lockout_policy,
1116 .password_policy = sam_password_policy,
1117 .trusted_domains = builtin_trusted_domains
1120 /* the rpc backend methods are exposed via this structure */
1121 struct winbindd_methods sam_passdb_methods = {
1122 .consistent = false,
1124 .query_user_list = sam_query_user_list,
1125 .enum_dom_groups = sam_enum_dom_groups,
1126 .enum_local_groups = sam_enum_local_groups,
1127 .name_to_sid = sam_name_to_sid,
1128 .sid_to_name = sam_sid_to_name,
1129 .rids_to_names = sam_rids_to_names,
1130 .query_user = sam_query_user,
1131 .lookup_usergroups = sam_lookup_usergroups,
1132 .lookup_useraliases = sam_lookup_useraliases,
1133 .lookup_groupmem = sam_lookup_groupmem,
1134 .sequence_number = sam_sequence_number,
1135 .lockout_policy = sam_lockout_policy,
1136 .password_policy = sam_password_policy,
1137 .trusted_domains = sam_trusted_domains