s3:vfs:gpfs convert sharemodes/leases parameter
[Samba.git] / source3 / winbindd / winbindd_samr.c
blobc7528d1c66f8064b76830dd23bd416b68bd8adf7
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"
30 #include "../librpc/gen_ndr/cli_samr.h"
31 #include "rpc_client/cli_samr.h"
32 #include "../librpc/gen_ndr/srv_samr.h"
33 #include "../librpc/gen_ndr/cli_lsa.h"
34 #include "rpc_client/cli_lsarpc.h"
35 #include "../librpc/gen_ndr/srv_lsa.h"
36 #include "rpc_server/rpc_ncacn_np.h"
37 #include "../libcli/security/security.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_serversupplied_info *server_info = NULL;
47 NTSTATUS status;
49 if (cli != NULL) {
50 goto done;
53 if (server_info == NULL) {
54 status = make_server_info_system(mem_ctx, &server_info);
55 if (!NT_STATUS_IS_OK(status)) {
56 DEBUG(0, ("open_samr_pipe: Could not create auth_serversupplied_info: %s\n",
57 nt_errstr(status)));
58 return status;
62 /* create a samr connection */
63 status = rpc_pipe_open_interface(mem_ctx,
64 &ndr_table_samr.syntax_id,
65 server_info,
66 NULL,
67 winbind_messaging_context(),
68 &cli);
69 if (!NT_STATUS_IS_OK(status)) {
70 DEBUG(0, ("open_samr_pipe: Could not connect to samr_pipe: %s\n",
71 nt_errstr(status)));
72 return status;
75 done:
76 if (samr_pipe) {
77 *samr_pipe = cli;
80 return NT_STATUS_OK;
83 NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
84 struct winbindd_domain *domain,
85 struct rpc_pipe_client **samr_pipe,
86 struct policy_handle *samr_domain_hnd)
88 NTSTATUS status;
89 struct policy_handle samr_connect_hnd;
91 status = open_internal_samr_pipe(mem_ctx, samr_pipe);
92 if (!NT_STATUS_IS_OK(status)) {
93 return status;
96 status = rpccli_samr_Connect2((*samr_pipe),
97 mem_ctx,
98 (*samr_pipe)->desthost,
99 SEC_FLAG_MAXIMUM_ALLOWED,
100 &samr_connect_hnd);
101 if (!NT_STATUS_IS_OK(status)) {
102 return status;
105 status = rpccli_samr_OpenDomain((*samr_pipe),
106 mem_ctx,
107 &samr_connect_hnd,
108 SEC_FLAG_MAXIMUM_ALLOWED,
109 &domain->sid,
110 samr_domain_hnd);
112 return status;
115 static NTSTATUS open_internal_lsa_pipe(TALLOC_CTX *mem_ctx,
116 struct rpc_pipe_client **lsa_pipe)
118 struct rpc_pipe_client *cli = NULL;
119 struct auth_serversupplied_info *server_info = NULL;
120 NTSTATUS status;
122 if (cli != NULL) {
123 goto done;
126 if (server_info == NULL) {
127 status = make_server_info_system(mem_ctx, &server_info);
128 if (!NT_STATUS_IS_OK(status)) {
129 DEBUG(0, ("open_lsa_pipe: Could not create auth_serversupplied_info: %s\n",
130 nt_errstr(status)));
131 return status;
135 /* create a samr connection */
136 status = rpc_pipe_open_interface(mem_ctx,
137 &ndr_table_lsarpc.syntax_id,
138 server_info,
139 NULL,
140 winbind_messaging_context(),
141 &cli);
142 if (!NT_STATUS_IS_OK(status)) {
143 DEBUG(0, ("open_lsa_pipe: Could not connect to lsa_pipe: %s\n",
144 nt_errstr(status)));
145 return status;
148 done:
149 if (lsa_pipe) {
150 *lsa_pipe = cli;
153 return NT_STATUS_OK;
156 static NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
157 struct rpc_pipe_client **lsa_pipe,
158 struct policy_handle *lsa_hnd)
160 NTSTATUS status;
162 status = open_internal_lsa_pipe(mem_ctx, lsa_pipe);
163 if (!NT_STATUS_IS_OK(status)) {
164 return status;
167 status = rpccli_lsa_open_policy((*lsa_pipe),
168 mem_ctx,
169 true,
170 SEC_FLAG_MAXIMUM_ALLOWED,
171 lsa_hnd);
173 return status;
176 /*********************************************************************
177 SAM specific functions.
178 *********************************************************************/
180 /* List all domain groups */
181 static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
182 TALLOC_CTX *mem_ctx,
183 uint32_t *pnum_info,
184 struct acct_info **pinfo)
186 struct rpc_pipe_client *samr_pipe;
187 struct policy_handle dom_pol;
188 struct acct_info *info = NULL;
189 uint32_t num_info = 0;
190 TALLOC_CTX *tmp_ctx;
191 NTSTATUS status;
193 DEBUG(3,("sam_enum_dom_groups\n"));
195 ZERO_STRUCT(dom_pol);
197 if (pnum_info) {
198 *pnum_info = 0;
201 tmp_ctx = talloc_stackframe();
202 if (tmp_ctx == NULL) {
203 return NT_STATUS_NO_MEMORY;
206 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
207 if (!NT_STATUS_IS_OK(status)) {
208 goto error;
211 status = rpc_enum_dom_groups(tmp_ctx,
212 samr_pipe,
213 &dom_pol,
214 &num_info,
215 &info);
216 if (!NT_STATUS_IS_OK(status)) {
217 goto error;
220 if (pnum_info) {
221 *pnum_info = num_info;
224 if (pinfo) {
225 *pinfo = talloc_move(mem_ctx, &info);
228 error:
229 if (is_valid_policy_hnd(&dom_pol)) {
230 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
232 TALLOC_FREE(tmp_ctx);
233 return status;
236 /* Query display info for a domain */
237 static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
238 TALLOC_CTX *mem_ctx,
239 uint32_t *pnum_info,
240 struct wbint_userinfo **pinfo)
242 struct rpc_pipe_client *samr_pipe = NULL;
243 struct policy_handle dom_pol;
244 struct wbint_userinfo *info = NULL;
245 uint32_t num_info = 0;
246 TALLOC_CTX *tmp_ctx;
247 NTSTATUS status;
249 DEBUG(3,("samr_query_user_list\n"));
251 ZERO_STRUCT(dom_pol);
253 if (pnum_info) {
254 *pnum_info = 0;
257 tmp_ctx = talloc_stackframe();
258 if (tmp_ctx == NULL) {
259 return NT_STATUS_NO_MEMORY;
262 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
263 if (!NT_STATUS_IS_OK(status)) {
264 goto done;
267 status = rpc_query_user_list(tmp_ctx,
268 samr_pipe,
269 &dom_pol,
270 &domain->sid,
271 &num_info,
272 &info);
273 if (!NT_STATUS_IS_OK(status)) {
274 goto done;
277 if (pnum_info) {
278 *pnum_info = num_info;
281 if (pinfo) {
282 *pinfo = talloc_move(mem_ctx, &info);
285 done:
286 if (is_valid_policy_hnd(&dom_pol)) {
287 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
290 TALLOC_FREE(tmp_ctx);
291 return status;
294 /* Lookup user information from a rid or username. */
295 static NTSTATUS sam_query_user(struct winbindd_domain *domain,
296 TALLOC_CTX *mem_ctx,
297 const struct dom_sid *user_sid,
298 struct wbint_userinfo *user_info)
300 struct rpc_pipe_client *samr_pipe;
301 struct policy_handle dom_pol;
302 TALLOC_CTX *tmp_ctx;
303 NTSTATUS status;
305 DEBUG(3,("sam_query_user\n"));
307 ZERO_STRUCT(dom_pol);
309 /* Paranoia check */
310 if (!sid_check_is_in_our_domain(user_sid)) {
311 return NT_STATUS_NO_SUCH_USER;
314 if (user_info) {
315 user_info->homedir = NULL;
316 user_info->shell = NULL;
317 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 status = rpc_query_user(tmp_ctx,
331 samr_pipe,
332 &dom_pol,
333 &domain->sid,
334 user_sid,
335 user_info);
337 done:
338 if (is_valid_policy_hnd(&dom_pol)) {
339 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
342 TALLOC_FREE(tmp_ctx);
343 return status;
346 /* get a list of trusted domains - builtin domain */
347 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
348 TALLOC_CTX *mem_ctx,
349 struct netr_DomainTrustList *ptrust_list)
351 struct rpc_pipe_client *lsa_pipe;
352 struct policy_handle lsa_policy;
353 struct netr_DomainTrust *trusts = NULL;
354 uint32_t num_trusts = 0;
355 TALLOC_CTX *tmp_ctx;
356 NTSTATUS status;
358 DEBUG(3,("samr: trusted domains\n"));
360 ZERO_STRUCT(lsa_policy);
362 if (ptrust_list) {
363 ZERO_STRUCTP(ptrust_list);
366 tmp_ctx = talloc_stackframe();
367 if (tmp_ctx == NULL) {
368 return NT_STATUS_NO_MEMORY;
371 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
372 if (!NT_STATUS_IS_OK(status)) {
373 goto done;
376 status = rpc_trusted_domains(tmp_ctx,
377 lsa_pipe,
378 &lsa_policy,
379 &num_trusts,
380 &trusts);
381 if (!NT_STATUS_IS_OK(status)) {
382 goto done;
385 if (ptrust_list) {
386 ptrust_list->count = num_trusts;
387 ptrust_list->array = talloc_move(mem_ctx, &trusts);
390 done:
391 if (is_valid_policy_hnd(&lsa_policy)) {
392 rpccli_lsa_Close(lsa_pipe, mem_ctx, &lsa_policy);
395 TALLOC_FREE(tmp_ctx);
396 return status;
399 /* Lookup group membership given a rid. */
400 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
401 TALLOC_CTX *mem_ctx,
402 const struct dom_sid *group_sid,
403 enum lsa_SidType type,
404 uint32_t *pnum_names,
405 struct dom_sid **psid_mem,
406 char ***pnames,
407 uint32_t **pname_types)
409 struct rpc_pipe_client *samr_pipe;
410 struct policy_handle dom_pol;
412 uint32_t num_names = 0;
413 struct dom_sid *sid_mem = NULL;
414 char **names = NULL;
415 uint32_t *name_types = NULL;
417 TALLOC_CTX *tmp_ctx;
418 NTSTATUS status;
420 DEBUG(3,("sam_lookup_groupmem\n"));
422 ZERO_STRUCT(dom_pol);
424 /* Paranoia check */
425 if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
426 /* There's no groups, only aliases in BUILTIN */
427 return NT_STATUS_NO_SUCH_GROUP;
430 if (pnum_names) {
431 pnum_names = 0;
434 tmp_ctx = talloc_stackframe();
435 if (tmp_ctx == NULL) {
436 return NT_STATUS_NO_MEMORY;
439 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
440 if (!NT_STATUS_IS_OK(status)) {
441 goto done;
444 status = rpc_lookup_groupmem(tmp_ctx,
445 samr_pipe,
446 &dom_pol,
447 domain->name,
448 &domain->sid,
449 group_sid,
450 type,
451 &num_names,
452 &sid_mem,
453 &names,
454 &name_types);
456 if (pnum_names) {
457 *pnum_names = num_names;
460 if (pnames) {
461 *pnames = talloc_move(mem_ctx, &names);
464 if (pname_types) {
465 *pname_types = talloc_move(mem_ctx, &name_types);
468 if (psid_mem) {
469 *psid_mem = talloc_move(mem_ctx, &sid_mem);
472 done:
473 if (is_valid_policy_hnd(&dom_pol)) {
474 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
477 TALLOC_FREE(tmp_ctx);
478 return status;
481 /*********************************************************************
482 BUILTIN specific functions.
483 *********************************************************************/
485 /* List all domain groups */
486 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
487 TALLOC_CTX *mem_ctx,
488 uint32 *num_entries,
489 struct acct_info **info)
491 /* BUILTIN doesn't have domain groups */
492 *num_entries = 0;
493 *info = NULL;
494 return NT_STATUS_OK;
497 /* Query display info for a domain */
498 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
499 TALLOC_CTX *mem_ctx,
500 uint32 *num_entries,
501 struct wbint_userinfo **info)
503 /* We don't have users */
504 *num_entries = 0;
505 *info = NULL;
506 return NT_STATUS_OK;
509 /* Lookup user information from a rid or username. */
510 static NTSTATUS builtin_query_user(struct winbindd_domain *domain,
511 TALLOC_CTX *mem_ctx,
512 const struct dom_sid *user_sid,
513 struct wbint_userinfo *user_info)
515 return NT_STATUS_NO_SUCH_USER;
518 /* get a list of trusted domains - builtin domain */
519 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
520 TALLOC_CTX *mem_ctx,
521 struct netr_DomainTrustList *trusts)
523 ZERO_STRUCTP(trusts);
524 return NT_STATUS_OK;
527 /*********************************************************************
528 COMMON functions.
529 *********************************************************************/
531 /* List all local groups (aliases) */
532 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
533 TALLOC_CTX *mem_ctx,
534 uint32_t *pnum_info,
535 struct acct_info **pinfo)
537 struct rpc_pipe_client *samr_pipe;
538 struct policy_handle dom_pol;
539 struct acct_info *info = NULL;
540 uint32_t num_info = 0;
541 TALLOC_CTX *tmp_ctx;
542 NTSTATUS status;
544 DEBUG(3,("samr: enum local groups\n"));
546 ZERO_STRUCT(dom_pol);
548 if (pnum_info) {
549 *pnum_info = 0;
552 tmp_ctx = talloc_stackframe();
553 if (tmp_ctx == NULL) {
554 return NT_STATUS_NO_MEMORY;
557 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
558 if (!NT_STATUS_IS_OK(status)) {
559 goto done;
562 status = rpc_enum_local_groups(mem_ctx,
563 samr_pipe,
564 &dom_pol,
565 &num_info,
566 &info);
567 if (!NT_STATUS_IS_OK(status)) {
568 goto done;
571 if (pnum_info) {
572 *pnum_info = num_info;
575 if (pinfo) {
576 *pinfo = talloc_move(mem_ctx, &info);
579 done:
580 if (is_valid_policy_hnd(&dom_pol)) {
581 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
584 TALLOC_FREE(tmp_ctx);
585 return status;
588 /* convert a single name to a sid in a domain */
589 static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
590 TALLOC_CTX *mem_ctx,
591 const char *domain_name,
592 const char *name,
593 uint32_t flags,
594 struct dom_sid *psid,
595 enum lsa_SidType *ptype)
597 struct rpc_pipe_client *lsa_pipe;
598 struct policy_handle lsa_policy;
599 struct dom_sid sid;
600 enum lsa_SidType type;
601 TALLOC_CTX *tmp_ctx;
602 NTSTATUS status;
604 DEBUG(3,("sam_name_to_sid\n"));
606 ZERO_STRUCT(lsa_policy);
608 tmp_ctx = talloc_stackframe();
609 if (tmp_ctx == NULL) {
610 return NT_STATUS_NO_MEMORY;
613 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
614 if (!NT_STATUS_IS_OK(status)) {
615 goto done;
618 status = rpc_name_to_sid(tmp_ctx,
619 lsa_pipe,
620 &lsa_policy,
621 domain_name,
622 name,
623 flags,
624 &sid,
625 &type);
626 if (!NT_STATUS_IS_OK(status)) {
627 goto done;
630 if (psid) {
631 sid_copy(psid, &sid);
633 if (ptype) {
634 *ptype = type;
637 done:
638 if (is_valid_policy_hnd(&lsa_policy)) {
639 rpccli_lsa_Close(lsa_pipe, mem_ctx, &lsa_policy);
642 TALLOC_FREE(tmp_ctx);
643 return status;
646 /* convert a domain SID to a user or group name */
647 static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
648 TALLOC_CTX *mem_ctx,
649 const struct dom_sid *sid,
650 char **pdomain_name,
651 char **pname,
652 enum lsa_SidType *ptype)
654 struct rpc_pipe_client *lsa_pipe;
655 struct policy_handle lsa_policy;
656 char *domain_name = NULL;
657 char *name = NULL;
658 enum lsa_SidType type;
659 TALLOC_CTX *tmp_ctx;
660 NTSTATUS status;
662 DEBUG(3,("sam_sid_to_name\n"));
664 ZERO_STRUCT(lsa_policy);
666 /* Paranoia check */
667 if (!sid_check_is_in_builtin(sid) &&
668 !sid_check_is_in_our_domain(sid) &&
669 !sid_check_is_in_unix_users(sid) &&
670 !sid_check_is_unix_users(sid) &&
671 !sid_check_is_in_unix_groups(sid) &&
672 !sid_check_is_unix_groups(sid) &&
673 !sid_check_is_in_wellknown_domain(sid)) {
674 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
675 "lookup SID %s\n", sid_string_dbg(sid)));
676 return NT_STATUS_NONE_MAPPED;
679 tmp_ctx = talloc_stackframe();
680 if (tmp_ctx == NULL) {
681 return NT_STATUS_NO_MEMORY;
684 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
685 if (!NT_STATUS_IS_OK(status)) {
686 goto done;
689 status = rpc_sid_to_name(tmp_ctx,
690 lsa_pipe,
691 &lsa_policy,
692 domain,
693 sid,
694 &domain_name,
695 &name,
696 &type);
698 if (ptype) {
699 *ptype = type;
702 if (pname) {
703 *pname = talloc_move(mem_ctx, &name);
706 if (pdomain_name) {
707 *pdomain_name = talloc_move(mem_ctx, &domain_name);
710 done:
711 if (is_valid_policy_hnd(&lsa_policy)) {
712 rpccli_lsa_Close(lsa_pipe, mem_ctx, &lsa_policy);
715 TALLOC_FREE(tmp_ctx);
716 return status;
719 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
720 TALLOC_CTX *mem_ctx,
721 const struct dom_sid *sid,
722 uint32 *rids,
723 size_t num_rids,
724 char **pdomain_name,
725 char ***pnames,
726 enum lsa_SidType **ptypes)
728 struct rpc_pipe_client *lsa_pipe;
729 struct policy_handle lsa_policy;
730 enum lsa_SidType *types = NULL;
731 char *domain_name = NULL;
732 char **names = NULL;
733 TALLOC_CTX *tmp_ctx;
734 NTSTATUS status;
736 DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
738 ZERO_STRUCT(lsa_policy);
740 /* Paranoia check */
741 if (!sid_check_is_in_builtin(sid) &&
742 !sid_check_is_in_our_domain(sid) &&
743 !sid_check_is_in_unix_users(sid) &&
744 !sid_check_is_unix_users(sid) &&
745 !sid_check_is_in_unix_groups(sid) &&
746 !sid_check_is_unix_groups(sid) &&
747 !sid_check_is_in_wellknown_domain(sid)) {
748 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
749 "lookup SID %s\n", sid_string_dbg(sid)));
750 return NT_STATUS_NONE_MAPPED;
753 tmp_ctx = talloc_stackframe();
754 if (tmp_ctx == NULL) {
755 return NT_STATUS_NO_MEMORY;
758 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
759 if (!NT_STATUS_IS_OK(status)) {
760 goto done;
763 status = rpc_rids_to_names(tmp_ctx,
764 lsa_pipe,
765 &lsa_policy,
766 domain,
767 sid,
768 rids,
769 num_rids,
770 &domain_name,
771 &names,
772 &types);
773 if (!NT_STATUS_IS_OK(status)) {
774 goto done;
777 if (pdomain_name) {
778 *pdomain_name = talloc_move(mem_ctx, &domain_name);
781 if (ptypes) {
782 *ptypes = talloc_move(mem_ctx, &types);
785 if (pnames) {
786 *pnames = talloc_move(mem_ctx, &names);
789 done:
790 if (is_valid_policy_hnd(&lsa_policy)) {
791 rpccli_lsa_Close(lsa_pipe, mem_ctx, &lsa_policy);
794 TALLOC_FREE(tmp_ctx);
795 return status;
798 static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
799 TALLOC_CTX *mem_ctx,
800 struct samr_DomInfo12 *lockout_policy)
802 struct rpc_pipe_client *samr_pipe;
803 struct policy_handle dom_pol;
804 union samr_DomainInfo *info = NULL;
805 TALLOC_CTX *tmp_ctx;
806 NTSTATUS status;
808 DEBUG(3,("sam_lockout_policy\n"));
810 ZERO_STRUCT(dom_pol);
812 tmp_ctx = talloc_stackframe();
813 if (tmp_ctx == NULL) {
814 return NT_STATUS_NO_MEMORY;
817 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
818 if (!NT_STATUS_IS_OK(status)) {
819 goto error;
822 status = rpccli_samr_QueryDomainInfo(samr_pipe,
823 mem_ctx,
824 &dom_pol,
826 &info);
827 if (!NT_STATUS_IS_OK(status)) {
828 goto error;
831 *lockout_policy = info->info12;
833 error:
834 if (is_valid_policy_hnd(&dom_pol)) {
835 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
838 TALLOC_FREE(tmp_ctx);
839 return status;
842 static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
843 TALLOC_CTX *mem_ctx,
844 struct samr_DomInfo1 *passwd_policy)
846 struct rpc_pipe_client *samr_pipe;
847 struct policy_handle dom_pol;
848 union samr_DomainInfo *info = NULL;
849 TALLOC_CTX *tmp_ctx;
850 NTSTATUS status;
852 DEBUG(3,("sam_password_policy\n"));
854 ZERO_STRUCT(dom_pol);
856 tmp_ctx = talloc_stackframe();
857 if (tmp_ctx == NULL) {
858 return NT_STATUS_NO_MEMORY;
861 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
862 if (!NT_STATUS_IS_OK(status)) {
863 goto error;
866 status = rpccli_samr_QueryDomainInfo(samr_pipe,
867 mem_ctx,
868 &dom_pol,
870 &info);
871 if (!NT_STATUS_IS_OK(status)) {
872 goto error;
875 *passwd_policy = info->info1;
877 error:
878 if (is_valid_policy_hnd(&dom_pol)) {
879 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
882 TALLOC_FREE(tmp_ctx);
883 return status;
886 /* Lookup groups a user is a member of. */
887 static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
888 TALLOC_CTX *mem_ctx,
889 const struct dom_sid *user_sid,
890 uint32_t *pnum_groups,
891 struct dom_sid **puser_grpsids)
893 struct rpc_pipe_client *samr_pipe;
894 struct policy_handle dom_pol;
895 struct dom_sid *user_grpsids = NULL;
896 uint32_t num_groups = 0;
897 TALLOC_CTX *tmp_ctx;
898 NTSTATUS status;
900 DEBUG(3,("sam_lookup_usergroups\n"));
902 ZERO_STRUCT(dom_pol);
904 if (pnum_groups) {
905 *pnum_groups = 0;
908 tmp_ctx = talloc_stackframe();
909 if (tmp_ctx == NULL) {
910 return NT_STATUS_NO_MEMORY;
913 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
914 if (!NT_STATUS_IS_OK(status)) {
915 goto done;
918 status = rpc_lookup_usergroups(tmp_ctx,
919 samr_pipe,
920 &dom_pol,
921 &domain->sid,
922 user_sid,
923 &num_groups,
924 &user_grpsids);
925 if (!NT_STATUS_IS_OK(status)) {
926 goto done;
929 if (pnum_groups) {
930 *pnum_groups = num_groups;
933 if (puser_grpsids) {
934 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
937 done:
938 if (is_valid_policy_hnd(&dom_pol)) {
939 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
942 TALLOC_FREE(tmp_ctx);
943 return status;
946 static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
947 TALLOC_CTX *mem_ctx,
948 uint32_t num_sids,
949 const struct dom_sid *sids,
950 uint32_t *pnum_aliases,
951 uint32_t **palias_rids)
953 struct rpc_pipe_client *samr_pipe;
954 struct policy_handle dom_pol;
955 uint32_t num_aliases = 0;
956 uint32_t *alias_rids = NULL;
957 TALLOC_CTX *tmp_ctx;
958 NTSTATUS status;
960 DEBUG(3,("sam_lookup_useraliases\n"));
962 ZERO_STRUCT(dom_pol);
964 if (pnum_aliases) {
965 *pnum_aliases = 0;
968 tmp_ctx = talloc_stackframe();
969 if (tmp_ctx == NULL) {
970 return NT_STATUS_NO_MEMORY;
973 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
974 if (!NT_STATUS_IS_OK(status)) {
975 goto done;
978 status = rpc_lookup_useraliases(tmp_ctx,
979 samr_pipe,
980 &dom_pol,
981 num_sids,
982 sids,
983 &num_aliases,
984 &alias_rids);
985 if (!NT_STATUS_IS_OK(status)) {
986 goto done;
989 if (pnum_aliases) {
990 *pnum_aliases = num_aliases;
993 if (palias_rids) {
994 *palias_rids = talloc_move(mem_ctx, &alias_rids);
997 done:
998 if (is_valid_policy_hnd(&dom_pol)) {
999 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
1002 TALLOC_FREE(tmp_ctx);
1003 return status;
1006 /* find the sequence number for a domain */
1007 static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
1008 uint32_t *pseq)
1010 struct rpc_pipe_client *samr_pipe;
1011 struct policy_handle dom_pol;
1012 uint32_t seq;
1013 TALLOC_CTX *tmp_ctx;
1014 NTSTATUS status;
1016 DEBUG(3,("samr: sequence number\n"));
1018 ZERO_STRUCT(dom_pol);
1020 if (pseq) {
1021 *pseq = DOM_SEQUENCE_NONE;
1024 tmp_ctx = talloc_stackframe();
1025 if (tmp_ctx == NULL) {
1026 return NT_STATUS_NO_MEMORY;
1029 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
1030 if (!NT_STATUS_IS_OK(status)) {
1031 goto done;
1034 status = rpc_sequence_number(tmp_ctx,
1035 samr_pipe,
1036 &dom_pol,
1037 domain->name,
1038 &seq);
1039 if (!NT_STATUS_IS_OK(status)) {
1040 goto done;
1043 if (pseq) {
1044 *pseq = seq;
1046 done:
1047 if (is_valid_policy_hnd(&dom_pol)) {
1048 rpccli_samr_Close(samr_pipe, tmp_ctx, &dom_pol);
1051 TALLOC_FREE(tmp_ctx);
1052 return status;
1055 /* the rpc backend methods are exposed via this structure */
1056 struct winbindd_methods builtin_passdb_methods = {
1057 .consistent = false,
1059 .query_user_list = builtin_query_user_list,
1060 .enum_dom_groups = builtin_enum_dom_groups,
1061 .enum_local_groups = sam_enum_local_groups,
1062 .name_to_sid = sam_name_to_sid,
1063 .sid_to_name = sam_sid_to_name,
1064 .rids_to_names = sam_rids_to_names,
1065 .query_user = builtin_query_user,
1066 .lookup_usergroups = sam_lookup_usergroups,
1067 .lookup_useraliases = sam_lookup_useraliases,
1068 .lookup_groupmem = sam_lookup_groupmem,
1069 .sequence_number = sam_sequence_number,
1070 .lockout_policy = sam_lockout_policy,
1071 .password_policy = sam_password_policy,
1072 .trusted_domains = builtin_trusted_domains
1075 /* the rpc backend methods are exposed via this structure */
1076 struct winbindd_methods sam_passdb_methods = {
1077 .consistent = false,
1079 .query_user_list = sam_query_user_list,
1080 .enum_dom_groups = sam_enum_dom_groups,
1081 .enum_local_groups = sam_enum_local_groups,
1082 .name_to_sid = sam_name_to_sid,
1083 .sid_to_name = sam_sid_to_name,
1084 .rids_to_names = sam_rids_to_names,
1085 .query_user = sam_query_user,
1086 .lookup_usergroups = sam_lookup_usergroups,
1087 .lookup_useraliases = sam_lookup_useraliases,
1088 .lookup_groupmem = sam_lookup_groupmem,
1089 .sequence_number = sam_sequence_number,
1090 .lockout_policy = sam_lockout_policy,
1091 .password_policy = sam_password_policy,
1092 .trusted_domains = sam_trusted_domains