s3: Add "client_id" to pipes_struct
[Samba/wip.git] / source3 / winbindd / winbindd_samr.c
blobf4d84fb1323e436f9578618361e70f9494e2c970
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"
37 #undef DBGC_CLASS
38 #define DBGC_CLASS DBGC_WINBIND
40 static NTSTATUS open_internal_samr_pipe(TALLOC_CTX *mem_ctx,
41 struct rpc_pipe_client **samr_pipe)
43 struct rpc_pipe_client *cli = NULL;
44 struct auth_serversupplied_info *server_info = NULL;
45 NTSTATUS status;
47 if (cli != NULL) {
48 goto done;
51 if (server_info == NULL) {
52 status = make_server_info_system(mem_ctx, &server_info);
53 if (!NT_STATUS_IS_OK(status)) {
54 DEBUG(0, ("open_samr_pipe: Could not create auth_serversupplied_info: %s\n",
55 nt_errstr(status)));
56 return status;
60 /* create a samr connection */
61 status = rpc_pipe_open_internal(mem_ctx,
62 &ndr_table_samr.syntax_id,
63 server_info,
64 NULL,
65 winbind_messaging_context(),
66 &cli);
67 if (!NT_STATUS_IS_OK(status)) {
68 DEBUG(0, ("open_samr_pipe: Could not connect to samr_pipe: %s\n",
69 nt_errstr(status)));
70 return status;
73 done:
74 if (samr_pipe) {
75 *samr_pipe = cli;
78 return NT_STATUS_OK;
81 NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
82 struct winbindd_domain *domain,
83 struct rpc_pipe_client **samr_pipe,
84 struct policy_handle *samr_domain_hnd)
86 NTSTATUS status;
87 struct policy_handle samr_connect_hnd;
89 status = open_internal_samr_pipe(mem_ctx, samr_pipe);
90 if (!NT_STATUS_IS_OK(status)) {
91 return status;
94 status = rpccli_samr_Connect2((*samr_pipe),
95 mem_ctx,
96 (*samr_pipe)->desthost,
97 SEC_FLAG_MAXIMUM_ALLOWED,
98 &samr_connect_hnd);
99 if (!NT_STATUS_IS_OK(status)) {
100 return status;
103 status = rpccli_samr_OpenDomain((*samr_pipe),
104 mem_ctx,
105 &samr_connect_hnd,
106 SEC_FLAG_MAXIMUM_ALLOWED,
107 &domain->sid,
108 samr_domain_hnd);
110 return status;
113 static NTSTATUS open_internal_lsa_pipe(TALLOC_CTX *mem_ctx,
114 struct rpc_pipe_client **lsa_pipe)
116 struct rpc_pipe_client *cli = NULL;
117 struct auth_serversupplied_info *server_info = NULL;
118 NTSTATUS status;
120 if (cli != NULL) {
121 goto done;
124 if (server_info == NULL) {
125 status = make_server_info_system(mem_ctx, &server_info);
126 if (!NT_STATUS_IS_OK(status)) {
127 DEBUG(0, ("open_lsa_pipe: Could not create auth_serversupplied_info: %s\n",
128 nt_errstr(status)));
129 return status;
133 /* create a samr connection */
134 status = rpc_pipe_open_internal(mem_ctx,
135 &ndr_table_lsarpc.syntax_id,
136 server_info,
137 NULL,
138 winbind_messaging_context(),
139 &cli);
140 if (!NT_STATUS_IS_OK(status)) {
141 DEBUG(0, ("open_lsa_pipe: Could not connect to lsa_pipe: %s\n",
142 nt_errstr(status)));
143 return status;
146 done:
147 if (lsa_pipe) {
148 *lsa_pipe = cli;
151 return NT_STATUS_OK;
154 static NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
155 struct rpc_pipe_client **lsa_pipe,
156 struct policy_handle *lsa_hnd)
158 NTSTATUS status;
160 status = open_internal_lsa_pipe(mem_ctx, lsa_pipe);
161 if (!NT_STATUS_IS_OK(status)) {
162 return status;
165 status = rpccli_lsa_open_policy((*lsa_pipe),
166 mem_ctx,
167 true,
168 SEC_FLAG_MAXIMUM_ALLOWED,
169 lsa_hnd);
171 return status;
174 /*********************************************************************
175 SAM specific functions.
176 *********************************************************************/
178 /* List all domain groups */
179 static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
180 TALLOC_CTX *mem_ctx,
181 uint32_t *pnum_info,
182 struct acct_info **pinfo)
184 struct rpc_pipe_client *samr_pipe;
185 struct policy_handle dom_pol;
186 struct acct_info *info = NULL;
187 uint32_t num_info = 0;
188 TALLOC_CTX *tmp_ctx;
189 NTSTATUS status;
191 DEBUG(3,("sam_enum_dom_groups\n"));
193 ZERO_STRUCT(dom_pol);
195 if (pnum_info) {
196 *pnum_info = 0;
199 tmp_ctx = talloc_stackframe();
200 if (tmp_ctx == NULL) {
201 return NT_STATUS_NO_MEMORY;
204 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
205 if (!NT_STATUS_IS_OK(status)) {
206 goto error;
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 (is_valid_policy_hnd(&dom_pol)) {
228 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
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;
247 DEBUG(3,("samr_query_user_list\n"));
249 ZERO_STRUCT(dom_pol);
251 if (pnum_info) {
252 *pnum_info = 0;
255 tmp_ctx = talloc_stackframe();
256 if (tmp_ctx == NULL) {
257 return NT_STATUS_NO_MEMORY;
260 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
261 if (!NT_STATUS_IS_OK(status)) {
262 goto done;
265 status = rpc_query_user_list(tmp_ctx,
266 samr_pipe,
267 &dom_pol,
268 &domain->sid,
269 &num_info,
270 &info);
271 if (!NT_STATUS_IS_OK(status)) {
272 goto done;
275 if (pnum_info) {
276 *pnum_info = num_info;
279 if (pinfo) {
280 *pinfo = talloc_move(mem_ctx, &info);
283 done:
284 if (is_valid_policy_hnd(&dom_pol)) {
285 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
288 TALLOC_FREE(tmp_ctx);
289 return status;
292 /* Lookup user information from a rid or username. */
293 static NTSTATUS sam_query_user(struct winbindd_domain *domain,
294 TALLOC_CTX *mem_ctx,
295 const struct dom_sid *user_sid,
296 struct wbint_userinfo *user_info)
298 struct rpc_pipe_client *samr_pipe;
299 struct policy_handle dom_pol;
300 TALLOC_CTX *tmp_ctx;
301 NTSTATUS status;
303 DEBUG(3,("sam_query_user\n"));
305 ZERO_STRUCT(dom_pol);
307 /* Paranoia check */
308 if (!sid_check_is_in_our_domain(user_sid)) {
309 return NT_STATUS_NO_SUCH_USER;
312 if (user_info) {
313 user_info->homedir = NULL;
314 user_info->shell = NULL;
315 user_info->primary_gid = (gid_t) -1;
318 tmp_ctx = talloc_stackframe();
319 if (tmp_ctx == NULL) {
320 return NT_STATUS_NO_MEMORY;
323 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
324 if (!NT_STATUS_IS_OK(status)) {
325 goto done;
328 status = rpc_query_user(tmp_ctx,
329 samr_pipe,
330 &dom_pol,
331 &domain->sid,
332 user_sid,
333 user_info);
335 done:
336 if (is_valid_policy_hnd(&dom_pol)) {
337 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
340 TALLOC_FREE(tmp_ctx);
341 return status;
344 /* get a list of trusted domains - builtin domain */
345 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
346 TALLOC_CTX *mem_ctx,
347 struct netr_DomainTrustList *ptrust_list)
349 struct rpc_pipe_client *lsa_pipe;
350 struct policy_handle lsa_policy;
351 struct netr_DomainTrust *trusts = NULL;
352 uint32_t num_trusts = 0;
353 TALLOC_CTX *tmp_ctx;
354 NTSTATUS status;
356 DEBUG(3,("samr: trusted domains\n"));
358 ZERO_STRUCT(lsa_policy);
360 if (ptrust_list) {
361 ZERO_STRUCTP(ptrust_list);
364 tmp_ctx = talloc_stackframe();
365 if (tmp_ctx == NULL) {
366 return NT_STATUS_NO_MEMORY;
369 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
370 if (!NT_STATUS_IS_OK(status)) {
371 goto done;
374 status = rpc_trusted_domains(tmp_ctx,
375 lsa_pipe,
376 &lsa_policy,
377 &num_trusts,
378 &trusts);
379 if (!NT_STATUS_IS_OK(status)) {
380 goto done;
383 if (ptrust_list) {
384 ptrust_list->count = num_trusts;
385 ptrust_list->array = talloc_move(mem_ctx, &trusts);
388 done:
389 if (is_valid_policy_hnd(&lsa_policy)) {
390 rpccli_lsa_Close(lsa_pipe, mem_ctx, &lsa_policy);
393 TALLOC_FREE(tmp_ctx);
394 return status;
397 /* Lookup group membership given a rid. */
398 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
399 TALLOC_CTX *mem_ctx,
400 const struct dom_sid *group_sid,
401 enum lsa_SidType type,
402 uint32_t *pnum_names,
403 struct dom_sid **psid_mem,
404 char ***pnames,
405 uint32_t **pname_types)
407 struct rpc_pipe_client *samr_pipe;
408 struct policy_handle dom_pol;
410 uint32_t num_names = 0;
411 struct dom_sid *sid_mem = NULL;
412 char **names = NULL;
413 uint32_t *name_types = NULL;
415 TALLOC_CTX *tmp_ctx;
416 NTSTATUS status;
418 DEBUG(3,("sam_lookup_groupmem\n"));
420 ZERO_STRUCT(dom_pol);
422 /* Paranoia check */
423 if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
424 /* There's no groups, only aliases in BUILTIN */
425 return NT_STATUS_NO_SUCH_GROUP;
428 if (pnum_names) {
429 pnum_names = 0;
432 tmp_ctx = talloc_stackframe();
433 if (tmp_ctx == NULL) {
434 return NT_STATUS_NO_MEMORY;
437 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
438 if (!NT_STATUS_IS_OK(status)) {
439 goto done;
442 status = rpc_lookup_groupmem(tmp_ctx,
443 samr_pipe,
444 &dom_pol,
445 domain->name,
446 &domain->sid,
447 group_sid,
448 type,
449 &num_names,
450 &sid_mem,
451 &names,
452 &name_types);
454 if (pnum_names) {
455 *pnum_names = num_names;
458 if (pnames) {
459 *pnames = talloc_move(mem_ctx, &names);
462 if (pname_types) {
463 *pname_types = talloc_move(mem_ctx, &name_types);
466 if (psid_mem) {
467 *psid_mem = talloc_move(mem_ctx, &sid_mem);
470 done:
471 if (is_valid_policy_hnd(&dom_pol)) {
472 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
475 TALLOC_FREE(tmp_ctx);
476 return status;
479 /*********************************************************************
480 BUILTIN specific functions.
481 *********************************************************************/
483 /* List all domain groups */
484 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
485 TALLOC_CTX *mem_ctx,
486 uint32 *num_entries,
487 struct acct_info **info)
489 /* BUILTIN doesn't have domain groups */
490 *num_entries = 0;
491 *info = NULL;
492 return NT_STATUS_OK;
495 /* Query display info for a domain */
496 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
497 TALLOC_CTX *mem_ctx,
498 uint32 *num_entries,
499 struct wbint_userinfo **info)
501 /* We don't have users */
502 *num_entries = 0;
503 *info = NULL;
504 return NT_STATUS_OK;
507 /* Lookup user information from a rid or username. */
508 static NTSTATUS builtin_query_user(struct winbindd_domain *domain,
509 TALLOC_CTX *mem_ctx,
510 const struct dom_sid *user_sid,
511 struct wbint_userinfo *user_info)
513 return NT_STATUS_NO_SUCH_USER;
516 /* get a list of trusted domains - builtin domain */
517 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
518 TALLOC_CTX *mem_ctx,
519 struct netr_DomainTrustList *trusts)
521 ZERO_STRUCTP(trusts);
522 return NT_STATUS_OK;
525 /*********************************************************************
526 COMMON functions.
527 *********************************************************************/
529 /* List all local groups (aliases) */
530 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
531 TALLOC_CTX *mem_ctx,
532 uint32_t *pnum_info,
533 struct acct_info **pinfo)
535 struct rpc_pipe_client *samr_pipe;
536 struct policy_handle dom_pol;
537 struct acct_info *info = NULL;
538 uint32_t num_info = 0;
539 TALLOC_CTX *tmp_ctx;
540 NTSTATUS status;
542 DEBUG(3,("samr: enum local groups\n"));
544 ZERO_STRUCT(dom_pol);
546 if (pnum_info) {
547 *pnum_info = 0;
550 tmp_ctx = talloc_stackframe();
551 if (tmp_ctx == NULL) {
552 return NT_STATUS_NO_MEMORY;
555 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
556 if (!NT_STATUS_IS_OK(status)) {
557 goto done;
560 status = rpc_enum_local_groups(mem_ctx,
561 samr_pipe,
562 &dom_pol,
563 &num_info,
564 &info);
565 if (!NT_STATUS_IS_OK(status)) {
566 goto done;
569 if (pnum_info) {
570 *pnum_info = num_info;
573 if (pinfo) {
574 *pinfo = talloc_move(mem_ctx, &info);
577 done:
578 if (is_valid_policy_hnd(&dom_pol)) {
579 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
582 TALLOC_FREE(tmp_ctx);
583 return status;
586 /* convert a single name to a sid in a domain */
587 static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
588 TALLOC_CTX *mem_ctx,
589 const char *domain_name,
590 const char *name,
591 uint32_t flags,
592 struct dom_sid *psid,
593 enum lsa_SidType *ptype)
595 struct rpc_pipe_client *lsa_pipe;
596 struct policy_handle lsa_policy;
597 struct dom_sid sid;
598 enum lsa_SidType type;
599 TALLOC_CTX *tmp_ctx;
600 NTSTATUS status;
602 DEBUG(3,("sam_name_to_sid\n"));
604 ZERO_STRUCT(lsa_policy);
606 tmp_ctx = talloc_stackframe();
607 if (tmp_ctx == NULL) {
608 return NT_STATUS_NO_MEMORY;
611 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
612 if (!NT_STATUS_IS_OK(status)) {
613 goto done;
616 status = rpc_name_to_sid(tmp_ctx,
617 lsa_pipe,
618 &lsa_policy,
619 domain_name,
620 name,
621 flags,
622 &sid,
623 &type);
624 if (!NT_STATUS_IS_OK(status)) {
625 goto done;
628 if (psid) {
629 sid_copy(psid, &sid);
631 if (ptype) {
632 *ptype = type;
635 done:
636 if (is_valid_policy_hnd(&lsa_policy)) {
637 rpccli_lsa_Close(lsa_pipe, mem_ctx, &lsa_policy);
640 TALLOC_FREE(tmp_ctx);
641 return status;
644 /* convert a domain SID to a user or group name */
645 static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
646 TALLOC_CTX *mem_ctx,
647 const struct dom_sid *sid,
648 char **pdomain_name,
649 char **pname,
650 enum lsa_SidType *ptype)
652 struct rpc_pipe_client *lsa_pipe;
653 struct policy_handle lsa_policy;
654 char *domain_name = NULL;
655 char *name = NULL;
656 enum lsa_SidType type;
657 TALLOC_CTX *tmp_ctx;
658 NTSTATUS status;
660 DEBUG(3,("sam_sid_to_name\n"));
662 ZERO_STRUCT(lsa_policy);
664 /* Paranoia check */
665 if (!sid_check_is_in_builtin(sid) &&
666 !sid_check_is_in_our_domain(sid) &&
667 !sid_check_is_in_unix_users(sid) &&
668 !sid_check_is_unix_users(sid) &&
669 !sid_check_is_in_unix_groups(sid) &&
670 !sid_check_is_unix_groups(sid) &&
671 !sid_check_is_in_wellknown_domain(sid)) {
672 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
673 "lookup SID %s\n", sid_string_dbg(sid)));
674 return NT_STATUS_NONE_MAPPED;
677 tmp_ctx = talloc_stackframe();
678 if (tmp_ctx == NULL) {
679 return NT_STATUS_NO_MEMORY;
682 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
683 if (!NT_STATUS_IS_OK(status)) {
684 goto done;
687 status = rpc_sid_to_name(tmp_ctx,
688 lsa_pipe,
689 &lsa_policy,
690 domain,
691 sid,
692 &domain_name,
693 &name,
694 &type);
696 if (ptype) {
697 *ptype = type;
700 if (pname) {
701 *pname = talloc_move(mem_ctx, &name);
704 if (pdomain_name) {
705 *pdomain_name = talloc_move(mem_ctx, &domain_name);
708 done:
709 if (is_valid_policy_hnd(&lsa_policy)) {
710 rpccli_lsa_Close(lsa_pipe, mem_ctx, &lsa_policy);
713 TALLOC_FREE(tmp_ctx);
714 return status;
717 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
718 TALLOC_CTX *mem_ctx,
719 const struct dom_sid *sid,
720 uint32 *rids,
721 size_t num_rids,
722 char **pdomain_name,
723 char ***pnames,
724 enum lsa_SidType **ptypes)
726 struct rpc_pipe_client *lsa_pipe;
727 struct policy_handle lsa_policy;
728 enum lsa_SidType *types = NULL;
729 char *domain_name = NULL;
730 char **names = NULL;
731 TALLOC_CTX *tmp_ctx;
732 NTSTATUS status;
734 DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
736 ZERO_STRUCT(lsa_policy);
738 /* Paranoia check */
739 if (!sid_check_is_in_builtin(sid) &&
740 !sid_check_is_in_our_domain(sid) &&
741 !sid_check_is_in_unix_users(sid) &&
742 !sid_check_is_unix_users(sid) &&
743 !sid_check_is_in_unix_groups(sid) &&
744 !sid_check_is_unix_groups(sid) &&
745 !sid_check_is_in_wellknown_domain(sid)) {
746 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
747 "lookup SID %s\n", sid_string_dbg(sid)));
748 return NT_STATUS_NONE_MAPPED;
751 tmp_ctx = talloc_stackframe();
752 if (tmp_ctx == NULL) {
753 return NT_STATUS_NO_MEMORY;
756 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
757 if (!NT_STATUS_IS_OK(status)) {
758 goto done;
761 status = rpc_rids_to_names(tmp_ctx,
762 lsa_pipe,
763 &lsa_policy,
764 domain,
765 sid,
766 rids,
767 num_rids,
768 &domain_name,
769 &names,
770 &types);
771 if (!NT_STATUS_IS_OK(status)) {
772 goto done;
775 if (pdomain_name) {
776 *pdomain_name = talloc_move(mem_ctx, &domain_name);
779 if (ptypes) {
780 *ptypes = talloc_move(mem_ctx, &types);
783 if (pnames) {
784 *pnames = talloc_move(mem_ctx, &names);
787 done:
788 if (is_valid_policy_hnd(&lsa_policy)) {
789 rpccli_lsa_Close(lsa_pipe, mem_ctx, &lsa_policy);
792 TALLOC_FREE(tmp_ctx);
793 return status;
796 static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
797 TALLOC_CTX *mem_ctx,
798 struct samr_DomInfo12 *lockout_policy)
800 struct rpc_pipe_client *samr_pipe;
801 struct policy_handle dom_pol;
802 union samr_DomainInfo *info = NULL;
803 TALLOC_CTX *tmp_ctx;
804 NTSTATUS status;
806 DEBUG(3,("sam_lockout_policy\n"));
808 ZERO_STRUCT(dom_pol);
810 tmp_ctx = talloc_stackframe();
811 if (tmp_ctx == NULL) {
812 return NT_STATUS_NO_MEMORY;
815 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
816 if (!NT_STATUS_IS_OK(status)) {
817 goto error;
820 status = rpccli_samr_QueryDomainInfo(samr_pipe,
821 mem_ctx,
822 &dom_pol,
824 &info);
825 if (!NT_STATUS_IS_OK(status)) {
826 goto error;
829 *lockout_policy = info->info12;
831 error:
832 if (is_valid_policy_hnd(&dom_pol)) {
833 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
836 TALLOC_FREE(tmp_ctx);
837 return status;
840 static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
841 TALLOC_CTX *mem_ctx,
842 struct samr_DomInfo1 *passwd_policy)
844 struct rpc_pipe_client *samr_pipe;
845 struct policy_handle dom_pol;
846 union samr_DomainInfo *info = NULL;
847 TALLOC_CTX *tmp_ctx;
848 NTSTATUS status;
850 DEBUG(3,("sam_password_policy\n"));
852 ZERO_STRUCT(dom_pol);
854 tmp_ctx = talloc_stackframe();
855 if (tmp_ctx == NULL) {
856 return NT_STATUS_NO_MEMORY;
859 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
860 if (!NT_STATUS_IS_OK(status)) {
861 goto error;
864 status = rpccli_samr_QueryDomainInfo(samr_pipe,
865 mem_ctx,
866 &dom_pol,
868 &info);
869 if (!NT_STATUS_IS_OK(status)) {
870 goto error;
873 *passwd_policy = info->info1;
875 error:
876 if (is_valid_policy_hnd(&dom_pol)) {
877 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
880 TALLOC_FREE(tmp_ctx);
881 return status;
884 /* Lookup groups a user is a member of. */
885 static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
886 TALLOC_CTX *mem_ctx,
887 const struct dom_sid *user_sid,
888 uint32_t *pnum_groups,
889 struct dom_sid **puser_grpsids)
891 struct rpc_pipe_client *samr_pipe;
892 struct policy_handle dom_pol;
893 struct dom_sid *user_grpsids = NULL;
894 uint32_t num_groups = 0;
895 TALLOC_CTX *tmp_ctx;
896 NTSTATUS status;
898 DEBUG(3,("sam_lookup_usergroups\n"));
900 ZERO_STRUCT(dom_pol);
902 if (pnum_groups) {
903 *pnum_groups = 0;
906 tmp_ctx = talloc_stackframe();
907 if (tmp_ctx == NULL) {
908 return NT_STATUS_NO_MEMORY;
911 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
912 if (!NT_STATUS_IS_OK(status)) {
913 goto done;
916 status = rpc_lookup_usergroups(tmp_ctx,
917 samr_pipe,
918 &dom_pol,
919 &domain->sid,
920 user_sid,
921 &num_groups,
922 &user_grpsids);
923 if (!NT_STATUS_IS_OK(status)) {
924 goto done;
927 if (pnum_groups) {
928 *pnum_groups = num_groups;
931 if (puser_grpsids) {
932 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
935 done:
936 if (is_valid_policy_hnd(&dom_pol)) {
937 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
940 TALLOC_FREE(tmp_ctx);
941 return status;
944 static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
945 TALLOC_CTX *mem_ctx,
946 uint32_t num_sids,
947 const struct dom_sid *sids,
948 uint32_t *pnum_aliases,
949 uint32_t **palias_rids)
951 struct rpc_pipe_client *samr_pipe;
952 struct policy_handle dom_pol;
953 uint32_t num_aliases = 0;
954 uint32_t *alias_rids = NULL;
955 TALLOC_CTX *tmp_ctx;
956 NTSTATUS status;
958 DEBUG(3,("sam_lookup_useraliases\n"));
960 ZERO_STRUCT(dom_pol);
962 if (pnum_aliases) {
963 *pnum_aliases = 0;
966 tmp_ctx = talloc_stackframe();
967 if (tmp_ctx == NULL) {
968 return NT_STATUS_NO_MEMORY;
971 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
972 if (!NT_STATUS_IS_OK(status)) {
973 goto done;
976 status = rpc_lookup_useraliases(tmp_ctx,
977 samr_pipe,
978 &dom_pol,
979 num_sids,
980 sids,
981 &num_aliases,
982 &alias_rids);
983 if (!NT_STATUS_IS_OK(status)) {
984 goto done;
987 if (pnum_aliases) {
988 *pnum_aliases = num_aliases;
991 if (palias_rids) {
992 *palias_rids = talloc_move(mem_ctx, &alias_rids);
995 done:
996 if (is_valid_policy_hnd(&dom_pol)) {
997 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
1000 TALLOC_FREE(tmp_ctx);
1001 return status;
1004 /* find the sequence number for a domain */
1005 static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
1006 uint32_t *pseq)
1008 struct rpc_pipe_client *samr_pipe;
1009 struct policy_handle dom_pol;
1010 uint32_t seq;
1011 TALLOC_CTX *tmp_ctx;
1012 NTSTATUS status;
1014 DEBUG(3,("samr: sequence number\n"));
1016 ZERO_STRUCT(dom_pol);
1018 if (pseq) {
1019 *pseq = DOM_SEQUENCE_NONE;
1022 tmp_ctx = talloc_stackframe();
1023 if (tmp_ctx == NULL) {
1024 return NT_STATUS_NO_MEMORY;
1027 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
1028 if (!NT_STATUS_IS_OK(status)) {
1029 goto done;
1032 status = rpc_sequence_number(tmp_ctx,
1033 samr_pipe,
1034 &dom_pol,
1035 domain->name,
1036 &seq);
1037 if (!NT_STATUS_IS_OK(status)) {
1038 goto done;
1041 if (pseq) {
1042 *pseq = seq;
1044 done:
1045 if (is_valid_policy_hnd(&dom_pol)) {
1046 rpccli_samr_Close(samr_pipe, tmp_ctx, &dom_pol);
1049 TALLOC_FREE(tmp_ctx);
1050 return status;
1053 /* the rpc backend methods are exposed via this structure */
1054 struct winbindd_methods builtin_passdb_methods = {
1055 .consistent = false,
1057 .query_user_list = builtin_query_user_list,
1058 .enum_dom_groups = builtin_enum_dom_groups,
1059 .enum_local_groups = sam_enum_local_groups,
1060 .name_to_sid = sam_name_to_sid,
1061 .sid_to_name = sam_sid_to_name,
1062 .rids_to_names = sam_rids_to_names,
1063 .query_user = builtin_query_user,
1064 .lookup_usergroups = sam_lookup_usergroups,
1065 .lookup_useraliases = sam_lookup_useraliases,
1066 .lookup_groupmem = sam_lookup_groupmem,
1067 .sequence_number = sam_sequence_number,
1068 .lockout_policy = sam_lockout_policy,
1069 .password_policy = sam_password_policy,
1070 .trusted_domains = builtin_trusted_domains
1073 /* the rpc backend methods are exposed via this structure */
1074 struct winbindd_methods sam_passdb_methods = {
1075 .consistent = false,
1077 .query_user_list = sam_query_user_list,
1078 .enum_dom_groups = sam_enum_dom_groups,
1079 .enum_local_groups = sam_enum_local_groups,
1080 .name_to_sid = sam_name_to_sid,
1081 .sid_to_name = sam_sid_to_name,
1082 .rids_to_names = sam_rids_to_names,
1083 .query_user = sam_query_user,
1084 .lookup_usergroups = sam_lookup_usergroups,
1085 .lookup_useraliases = sam_lookup_useraliases,
1086 .lookup_groupmem = sam_lookup_groupmem,
1087 .sequence_number = sam_sequence_number,
1088 .lockout_policy = sam_lockout_policy,
1089 .password_policy = sam_password_policy,
1090 .trusted_domains = sam_trusted_domains