s3-passdb: use passdb headers where needed.
[Samba.git] / source3 / winbindd / winbindd_samr.c
blob68e6a5a338910c1f1db090f6e183dca83567ea13
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/ndr_samr_c.h"
31 #include "rpc_client/cli_samr.h"
32 #include "../librpc/gen_ndr/srv_samr.h"
33 #include "../librpc/gen_ndr/ndr_lsa_c.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"
38 #include "passdb/machine_sid.h"
40 #undef DBGC_CLASS
41 #define DBGC_CLASS DBGC_WINBIND
43 static NTSTATUS open_internal_samr_pipe(TALLOC_CTX *mem_ctx,
44 struct rpc_pipe_client **samr_pipe)
46 struct rpc_pipe_client *cli = NULL;
47 struct auth_serversupplied_info *session_info = NULL;
48 NTSTATUS status;
50 if (session_info == NULL) {
51 status = make_session_info_system(mem_ctx, &session_info);
52 if (!NT_STATUS_IS_OK(status)) {
53 DEBUG(0, ("open_samr_pipe: Could not create auth_serversupplied_info: %s\n",
54 nt_errstr(status)));
55 return status;
59 /* create a samr connection */
60 status = rpc_pipe_open_interface(mem_ctx,
61 &ndr_table_samr.syntax_id,
62 session_info,
63 NULL,
64 winbind_messaging_context(),
65 &cli);
66 if (!NT_STATUS_IS_OK(status)) {
67 DEBUG(0, ("open_samr_pipe: Could not connect to samr_pipe: %s\n",
68 nt_errstr(status)));
69 return status;
72 if (samr_pipe) {
73 *samr_pipe = cli;
76 return NT_STATUS_OK;
79 NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
80 struct winbindd_domain *domain,
81 struct rpc_pipe_client **samr_pipe,
82 struct policy_handle *samr_domain_hnd)
84 NTSTATUS status, result;
85 struct policy_handle samr_connect_hnd;
86 struct dcerpc_binding_handle *b;
88 status = open_internal_samr_pipe(mem_ctx, samr_pipe);
89 if (!NT_STATUS_IS_OK(status)) {
90 return status;
93 b = (*samr_pipe)->binding_handle;
95 status = dcerpc_samr_Connect2(b, mem_ctx,
96 (*samr_pipe)->desthost,
97 SEC_FLAG_MAXIMUM_ALLOWED,
98 &samr_connect_hnd,
99 &result);
100 if (!NT_STATUS_IS_OK(status)) {
101 return status;
103 if (!NT_STATUS_IS_OK(result)) {
104 return result;
107 status = dcerpc_samr_OpenDomain(b, mem_ctx,
108 &samr_connect_hnd,
109 SEC_FLAG_MAXIMUM_ALLOWED,
110 &domain->sid,
111 samr_domain_hnd,
112 &result);
113 if (!NT_STATUS_IS_OK(status)) {
114 return status;
117 return result;
120 static NTSTATUS open_internal_lsa_pipe(TALLOC_CTX *mem_ctx,
121 struct rpc_pipe_client **lsa_pipe)
123 struct rpc_pipe_client *cli = NULL;
124 struct auth_serversupplied_info *session_info = NULL;
125 NTSTATUS status;
127 if (session_info == NULL) {
128 status = make_session_info_system(mem_ctx, &session_info);
129 if (!NT_STATUS_IS_OK(status)) {
130 DEBUG(0, ("open_lsa_pipe: Could not create auth_serversupplied_info: %s\n",
131 nt_errstr(status)));
132 return status;
136 /* create a lsa connection */
137 status = rpc_pipe_open_interface(mem_ctx,
138 &ndr_table_lsarpc.syntax_id,
139 session_info,
140 NULL,
141 winbind_messaging_context(),
142 &cli);
143 if (!NT_STATUS_IS_OK(status)) {
144 DEBUG(0, ("open_lsa_pipe: Could not connect to lsa_pipe: %s\n",
145 nt_errstr(status)));
146 return status;
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 wb_acct_info **pinfo)
186 struct rpc_pipe_client *samr_pipe;
187 struct policy_handle dom_pol;
188 struct wb_acct_info *info = NULL;
189 uint32_t num_info = 0;
190 TALLOC_CTX *tmp_ctx;
191 NTSTATUS status, result;
192 struct dcerpc_binding_handle *b = NULL;
194 DEBUG(3,("sam_enum_dom_groups\n"));
196 ZERO_STRUCT(dom_pol);
198 if (pnum_info) {
199 *pnum_info = 0;
202 tmp_ctx = talloc_stackframe();
203 if (tmp_ctx == NULL) {
204 return NT_STATUS_NO_MEMORY;
207 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
208 if (!NT_STATUS_IS_OK(status)) {
209 goto error;
212 b = samr_pipe->binding_handle;
214 status = rpc_enum_dom_groups(tmp_ctx,
215 samr_pipe,
216 &dom_pol,
217 &num_info,
218 &info);
219 if (!NT_STATUS_IS_OK(status)) {
220 goto error;
223 if (pnum_info) {
224 *pnum_info = num_info;
227 if (pinfo) {
228 *pinfo = talloc_move(mem_ctx, &info);
231 error:
232 if (b && is_valid_policy_hnd(&dom_pol)) {
233 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
235 TALLOC_FREE(tmp_ctx);
236 return status;
239 /* Query display info for a domain */
240 static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
241 TALLOC_CTX *mem_ctx,
242 uint32_t *pnum_info,
243 struct wbint_userinfo **pinfo)
245 struct rpc_pipe_client *samr_pipe = NULL;
246 struct policy_handle dom_pol;
247 struct wbint_userinfo *info = NULL;
248 uint32_t num_info = 0;
249 TALLOC_CTX *tmp_ctx;
250 NTSTATUS status, result;
251 struct dcerpc_binding_handle *b = NULL;
253 DEBUG(3,("samr_query_user_list\n"));
255 ZERO_STRUCT(dom_pol);
257 if (pnum_info) {
258 *pnum_info = 0;
261 tmp_ctx = talloc_stackframe();
262 if (tmp_ctx == NULL) {
263 return NT_STATUS_NO_MEMORY;
266 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
267 if (!NT_STATUS_IS_OK(status)) {
268 goto done;
271 b = samr_pipe->binding_handle;
273 status = rpc_query_user_list(tmp_ctx,
274 samr_pipe,
275 &dom_pol,
276 &domain->sid,
277 &num_info,
278 &info);
279 if (!NT_STATUS_IS_OK(status)) {
280 goto done;
283 if (pnum_info) {
284 *pnum_info = num_info;
287 if (pinfo) {
288 *pinfo = talloc_move(mem_ctx, &info);
291 done:
292 if (b && is_valid_policy_hnd(&dom_pol)) {
293 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
296 TALLOC_FREE(tmp_ctx);
297 return status;
300 /* Lookup user information from a rid or username. */
301 static NTSTATUS sam_query_user(struct winbindd_domain *domain,
302 TALLOC_CTX *mem_ctx,
303 const struct dom_sid *user_sid,
304 struct wbint_userinfo *user_info)
306 struct rpc_pipe_client *samr_pipe;
307 struct policy_handle dom_pol;
308 TALLOC_CTX *tmp_ctx;
309 NTSTATUS status, result;
310 struct dcerpc_binding_handle *b = NULL;
312 DEBUG(3,("sam_query_user\n"));
314 ZERO_STRUCT(dom_pol);
316 /* Paranoia check */
317 if (!sid_check_is_in_our_domain(user_sid)) {
318 return NT_STATUS_NO_SUCH_USER;
321 if (user_info) {
322 user_info->homedir = NULL;
323 user_info->shell = NULL;
324 user_info->primary_gid = (gid_t) -1;
327 tmp_ctx = talloc_stackframe();
328 if (tmp_ctx == NULL) {
329 return NT_STATUS_NO_MEMORY;
332 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
333 if (!NT_STATUS_IS_OK(status)) {
334 goto done;
337 b = samr_pipe->binding_handle;
339 status = rpc_query_user(tmp_ctx,
340 samr_pipe,
341 &dom_pol,
342 &domain->sid,
343 user_sid,
344 user_info);
346 done:
347 if (b && is_valid_policy_hnd(&dom_pol)) {
348 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
351 TALLOC_FREE(tmp_ctx);
352 return status;
355 /* get a list of trusted domains - builtin domain */
356 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
357 TALLOC_CTX *mem_ctx,
358 struct netr_DomainTrustList *ptrust_list)
360 struct rpc_pipe_client *lsa_pipe;
361 struct policy_handle lsa_policy;
362 struct netr_DomainTrust *trusts = NULL;
363 uint32_t num_trusts = 0;
364 TALLOC_CTX *tmp_ctx;
365 NTSTATUS status, result;
366 struct dcerpc_binding_handle *b = NULL;
368 DEBUG(3,("samr: trusted domains\n"));
370 ZERO_STRUCT(lsa_policy);
372 if (ptrust_list) {
373 ZERO_STRUCTP(ptrust_list);
376 tmp_ctx = talloc_stackframe();
377 if (tmp_ctx == NULL) {
378 return NT_STATUS_NO_MEMORY;
381 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
382 if (!NT_STATUS_IS_OK(status)) {
383 goto done;
386 b = lsa_pipe->binding_handle;
388 status = rpc_trusted_domains(tmp_ctx,
389 lsa_pipe,
390 &lsa_policy,
391 &num_trusts,
392 &trusts);
393 if (!NT_STATUS_IS_OK(status)) {
394 goto done;
397 if (ptrust_list) {
398 ptrust_list->count = num_trusts;
399 ptrust_list->array = talloc_move(mem_ctx, &trusts);
402 done:
403 if (b && is_valid_policy_hnd(&lsa_policy)) {
404 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
407 TALLOC_FREE(tmp_ctx);
408 return status;
411 /* Lookup group membership given a rid. */
412 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
413 TALLOC_CTX *mem_ctx,
414 const struct dom_sid *group_sid,
415 enum lsa_SidType type,
416 uint32_t *pnum_names,
417 struct dom_sid **psid_mem,
418 char ***pnames,
419 uint32_t **pname_types)
421 struct rpc_pipe_client *samr_pipe;
422 struct policy_handle dom_pol;
424 uint32_t num_names = 0;
425 struct dom_sid *sid_mem = NULL;
426 char **names = NULL;
427 uint32_t *name_types = NULL;
429 TALLOC_CTX *tmp_ctx;
430 NTSTATUS status, result;
431 struct dcerpc_binding_handle *b = NULL;
433 DEBUG(3,("sam_lookup_groupmem\n"));
435 ZERO_STRUCT(dom_pol);
437 /* Paranoia check */
438 if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
439 /* There's no groups, only aliases in BUILTIN */
440 return NT_STATUS_NO_SUCH_GROUP;
443 if (pnum_names) {
444 pnum_names = 0;
447 tmp_ctx = talloc_stackframe();
448 if (tmp_ctx == NULL) {
449 return NT_STATUS_NO_MEMORY;
452 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
453 if (!NT_STATUS_IS_OK(status)) {
454 goto done;
457 b = samr_pipe->binding_handle;
459 status = rpc_lookup_groupmem(tmp_ctx,
460 samr_pipe,
461 &dom_pol,
462 domain->name,
463 &domain->sid,
464 group_sid,
465 type,
466 &num_names,
467 &sid_mem,
468 &names,
469 &name_types);
471 if (pnum_names) {
472 *pnum_names = num_names;
475 if (pnames) {
476 *pnames = talloc_move(mem_ctx, &names);
479 if (pname_types) {
480 *pname_types = talloc_move(mem_ctx, &name_types);
483 if (psid_mem) {
484 *psid_mem = talloc_move(mem_ctx, &sid_mem);
487 done:
488 if (b && is_valid_policy_hnd(&dom_pol)) {
489 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
492 TALLOC_FREE(tmp_ctx);
493 return status;
496 /*********************************************************************
497 BUILTIN specific functions.
498 *********************************************************************/
500 /* List all domain groups */
501 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
502 TALLOC_CTX *mem_ctx,
503 uint32 *num_entries,
504 struct wb_acct_info **info)
506 /* BUILTIN doesn't have domain groups */
507 *num_entries = 0;
508 *info = NULL;
509 return NT_STATUS_OK;
512 /* Query display info for a domain */
513 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
514 TALLOC_CTX *mem_ctx,
515 uint32 *num_entries,
516 struct wbint_userinfo **info)
518 /* We don't have users */
519 *num_entries = 0;
520 *info = NULL;
521 return NT_STATUS_OK;
524 /* Lookup user information from a rid or username. */
525 static NTSTATUS builtin_query_user(struct winbindd_domain *domain,
526 TALLOC_CTX *mem_ctx,
527 const struct dom_sid *user_sid,
528 struct wbint_userinfo *user_info)
530 return NT_STATUS_NO_SUCH_USER;
533 /* get a list of trusted domains - builtin domain */
534 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
535 TALLOC_CTX *mem_ctx,
536 struct netr_DomainTrustList *trusts)
538 ZERO_STRUCTP(trusts);
539 return NT_STATUS_OK;
542 /*********************************************************************
543 COMMON functions.
544 *********************************************************************/
546 /* List all local groups (aliases) */
547 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
548 TALLOC_CTX *mem_ctx,
549 uint32_t *pnum_info,
550 struct wb_acct_info **pinfo)
552 struct rpc_pipe_client *samr_pipe;
553 struct policy_handle dom_pol;
554 struct wb_acct_info *info = NULL;
555 uint32_t num_info = 0;
556 TALLOC_CTX *tmp_ctx;
557 NTSTATUS status, result;
558 struct dcerpc_binding_handle *b = NULL;
560 DEBUG(3,("samr: enum local groups\n"));
562 ZERO_STRUCT(dom_pol);
564 if (pnum_info) {
565 *pnum_info = 0;
568 tmp_ctx = talloc_stackframe();
569 if (tmp_ctx == NULL) {
570 return NT_STATUS_NO_MEMORY;
573 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
574 if (!NT_STATUS_IS_OK(status)) {
575 goto done;
578 b = samr_pipe->binding_handle;
580 status = rpc_enum_local_groups(mem_ctx,
581 samr_pipe,
582 &dom_pol,
583 &num_info,
584 &info);
585 if (!NT_STATUS_IS_OK(status)) {
586 goto done;
589 if (pnum_info) {
590 *pnum_info = num_info;
593 if (pinfo) {
594 *pinfo = talloc_move(mem_ctx, &info);
597 done:
598 if (b && is_valid_policy_hnd(&dom_pol)) {
599 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
602 TALLOC_FREE(tmp_ctx);
603 return status;
606 /* convert a single name to a sid in a domain */
607 static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
608 TALLOC_CTX *mem_ctx,
609 const char *domain_name,
610 const char *name,
611 uint32_t flags,
612 struct dom_sid *psid,
613 enum lsa_SidType *ptype)
615 struct rpc_pipe_client *lsa_pipe;
616 struct policy_handle lsa_policy;
617 struct dom_sid sid;
618 enum lsa_SidType type;
619 TALLOC_CTX *tmp_ctx;
620 NTSTATUS status, result;
621 struct dcerpc_binding_handle *b = NULL;
623 DEBUG(3,("sam_name_to_sid\n"));
625 ZERO_STRUCT(lsa_policy);
627 tmp_ctx = talloc_stackframe();
628 if (tmp_ctx == NULL) {
629 return NT_STATUS_NO_MEMORY;
632 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
633 if (!NT_STATUS_IS_OK(status)) {
634 goto done;
637 b = lsa_pipe->binding_handle;
639 status = rpc_name_to_sid(tmp_ctx,
640 lsa_pipe,
641 &lsa_policy,
642 domain_name,
643 name,
644 flags,
645 &sid,
646 &type);
647 if (!NT_STATUS_IS_OK(status)) {
648 goto done;
651 if (psid) {
652 sid_copy(psid, &sid);
654 if (ptype) {
655 *ptype = type;
658 done:
659 if (b && is_valid_policy_hnd(&lsa_policy)) {
660 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
663 TALLOC_FREE(tmp_ctx);
664 return status;
667 /* convert a domain SID to a user or group name */
668 static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
669 TALLOC_CTX *mem_ctx,
670 const struct dom_sid *sid,
671 char **pdomain_name,
672 char **pname,
673 enum lsa_SidType *ptype)
675 struct rpc_pipe_client *lsa_pipe;
676 struct policy_handle lsa_policy;
677 char *domain_name = NULL;
678 char *name = NULL;
679 enum lsa_SidType type;
680 TALLOC_CTX *tmp_ctx;
681 NTSTATUS status, result;
682 struct dcerpc_binding_handle *b = NULL;
684 DEBUG(3,("sam_sid_to_name\n"));
686 ZERO_STRUCT(lsa_policy);
688 /* Paranoia check */
689 if (!sid_check_is_in_builtin(sid) &&
690 !sid_check_is_in_our_domain(sid) &&
691 !sid_check_is_in_unix_users(sid) &&
692 !sid_check_is_unix_users(sid) &&
693 !sid_check_is_in_unix_groups(sid) &&
694 !sid_check_is_unix_groups(sid) &&
695 !sid_check_is_in_wellknown_domain(sid)) {
696 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
697 "lookup SID %s\n", sid_string_dbg(sid)));
698 return NT_STATUS_NONE_MAPPED;
701 tmp_ctx = talloc_stackframe();
702 if (tmp_ctx == NULL) {
703 return NT_STATUS_NO_MEMORY;
706 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
707 if (!NT_STATUS_IS_OK(status)) {
708 goto done;
711 b = lsa_pipe->binding_handle;
713 status = rpc_sid_to_name(tmp_ctx,
714 lsa_pipe,
715 &lsa_policy,
716 domain,
717 sid,
718 &domain_name,
719 &name,
720 &type);
722 if (ptype) {
723 *ptype = type;
726 if (pname) {
727 *pname = talloc_move(mem_ctx, &name);
730 if (pdomain_name) {
731 *pdomain_name = talloc_move(mem_ctx, &domain_name);
734 done:
735 if (b && is_valid_policy_hnd(&lsa_policy)) {
736 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
739 TALLOC_FREE(tmp_ctx);
740 return status;
743 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
744 TALLOC_CTX *mem_ctx,
745 const struct dom_sid *domain_sid,
746 uint32 *rids,
747 size_t num_rids,
748 char **pdomain_name,
749 char ***pnames,
750 enum lsa_SidType **ptypes)
752 struct rpc_pipe_client *lsa_pipe;
753 struct policy_handle lsa_policy;
754 enum lsa_SidType *types = NULL;
755 char *domain_name = NULL;
756 char **names = NULL;
757 TALLOC_CTX *tmp_ctx;
758 NTSTATUS status, result;
759 struct dcerpc_binding_handle *b = NULL;
761 DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
763 ZERO_STRUCT(lsa_policy);
765 /* Paranoia check */
766 if (!sid_check_is_builtin(domain_sid) &&
767 !sid_check_is_domain(domain_sid) &&
768 !sid_check_is_unix_users(domain_sid) &&
769 !sid_check_is_unix_groups(domain_sid) &&
770 !sid_check_is_in_wellknown_domain(domain_sid)) {
771 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
772 "lookup SID %s\n", sid_string_dbg(domain_sid)));
773 return NT_STATUS_NONE_MAPPED;
776 tmp_ctx = talloc_stackframe();
777 if (tmp_ctx == NULL) {
778 return NT_STATUS_NO_MEMORY;
781 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
782 if (!NT_STATUS_IS_OK(status)) {
783 goto done;
786 b = lsa_pipe->binding_handle;
788 status = rpc_rids_to_names(tmp_ctx,
789 lsa_pipe,
790 &lsa_policy,
791 domain,
792 domain_sid,
793 rids,
794 num_rids,
795 &domain_name,
796 &names,
797 &types);
798 if (!NT_STATUS_IS_OK(status)) {
799 goto done;
802 if (pdomain_name) {
803 *pdomain_name = talloc_move(mem_ctx, &domain_name);
806 if (ptypes) {
807 *ptypes = talloc_move(mem_ctx, &types);
810 if (pnames) {
811 *pnames = talloc_move(mem_ctx, &names);
814 done:
815 if (b && is_valid_policy_hnd(&lsa_policy)) {
816 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
819 TALLOC_FREE(tmp_ctx);
820 return status;
823 static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
824 TALLOC_CTX *mem_ctx,
825 struct samr_DomInfo12 *lockout_policy)
827 struct rpc_pipe_client *samr_pipe;
828 struct policy_handle dom_pol;
829 union samr_DomainInfo *info = NULL;
830 TALLOC_CTX *tmp_ctx;
831 NTSTATUS status, result;
832 struct dcerpc_binding_handle *b = NULL;
834 DEBUG(3,("sam_lockout_policy\n"));
836 ZERO_STRUCT(dom_pol);
838 tmp_ctx = talloc_stackframe();
839 if (tmp_ctx == NULL) {
840 return NT_STATUS_NO_MEMORY;
843 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
844 if (!NT_STATUS_IS_OK(status)) {
845 goto error;
848 b = samr_pipe->binding_handle;
850 status = dcerpc_samr_QueryDomainInfo(b,
851 mem_ctx,
852 &dom_pol,
854 &info,
855 &result);
856 if (!NT_STATUS_IS_OK(status)) {
857 goto error;
859 if (!NT_STATUS_IS_OK(result)) {
860 status = result;
861 goto error;
864 *lockout_policy = info->info12;
866 error:
867 if (b && is_valid_policy_hnd(&dom_pol)) {
868 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
871 TALLOC_FREE(tmp_ctx);
872 return status;
875 static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
876 TALLOC_CTX *mem_ctx,
877 struct samr_DomInfo1 *passwd_policy)
879 struct rpc_pipe_client *samr_pipe;
880 struct policy_handle dom_pol;
881 union samr_DomainInfo *info = NULL;
882 TALLOC_CTX *tmp_ctx;
883 NTSTATUS status, result;
884 struct dcerpc_binding_handle *b = NULL;
886 DEBUG(3,("sam_password_policy\n"));
888 ZERO_STRUCT(dom_pol);
890 tmp_ctx = talloc_stackframe();
891 if (tmp_ctx == NULL) {
892 return NT_STATUS_NO_MEMORY;
895 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
896 if (!NT_STATUS_IS_OK(status)) {
897 goto error;
900 b = samr_pipe->binding_handle;
902 status = dcerpc_samr_QueryDomainInfo(b,
903 mem_ctx,
904 &dom_pol,
906 &info,
907 &result);
908 if (!NT_STATUS_IS_OK(status)) {
909 goto error;
911 if (!NT_STATUS_IS_OK(result)) {
912 status = result;
913 goto error;
916 *passwd_policy = info->info1;
918 error:
919 if (b && is_valid_policy_hnd(&dom_pol)) {
920 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
923 TALLOC_FREE(tmp_ctx);
924 return status;
927 /* Lookup groups a user is a member of. */
928 static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
929 TALLOC_CTX *mem_ctx,
930 const struct dom_sid *user_sid,
931 uint32_t *pnum_groups,
932 struct dom_sid **puser_grpsids)
934 struct rpc_pipe_client *samr_pipe;
935 struct policy_handle dom_pol;
936 struct dom_sid *user_grpsids = NULL;
937 uint32_t num_groups = 0;
938 TALLOC_CTX *tmp_ctx;
939 NTSTATUS status, result;
940 struct dcerpc_binding_handle *b = NULL;
942 DEBUG(3,("sam_lookup_usergroups\n"));
944 ZERO_STRUCT(dom_pol);
946 if (pnum_groups) {
947 *pnum_groups = 0;
950 tmp_ctx = talloc_stackframe();
951 if (tmp_ctx == NULL) {
952 return NT_STATUS_NO_MEMORY;
955 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
956 if (!NT_STATUS_IS_OK(status)) {
957 goto done;
960 b = samr_pipe->binding_handle;
962 status = rpc_lookup_usergroups(tmp_ctx,
963 samr_pipe,
964 &dom_pol,
965 &domain->sid,
966 user_sid,
967 &num_groups,
968 &user_grpsids);
969 if (!NT_STATUS_IS_OK(status)) {
970 goto done;
973 if (pnum_groups) {
974 *pnum_groups = num_groups;
977 if (puser_grpsids) {
978 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
981 done:
982 if (b && is_valid_policy_hnd(&dom_pol)) {
983 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
986 TALLOC_FREE(tmp_ctx);
987 return status;
990 static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
991 TALLOC_CTX *mem_ctx,
992 uint32_t num_sids,
993 const struct dom_sid *sids,
994 uint32_t *pnum_aliases,
995 uint32_t **palias_rids)
997 struct rpc_pipe_client *samr_pipe;
998 struct policy_handle dom_pol;
999 uint32_t num_aliases = 0;
1000 uint32_t *alias_rids = NULL;
1001 TALLOC_CTX *tmp_ctx;
1002 NTSTATUS status, result;
1003 struct dcerpc_binding_handle *b = NULL;
1005 DEBUG(3,("sam_lookup_useraliases\n"));
1007 ZERO_STRUCT(dom_pol);
1009 if (pnum_aliases) {
1010 *pnum_aliases = 0;
1013 tmp_ctx = talloc_stackframe();
1014 if (tmp_ctx == NULL) {
1015 return NT_STATUS_NO_MEMORY;
1018 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
1019 if (!NT_STATUS_IS_OK(status)) {
1020 goto done;
1023 b = samr_pipe->binding_handle;
1025 status = rpc_lookup_useraliases(tmp_ctx,
1026 samr_pipe,
1027 &dom_pol,
1028 num_sids,
1029 sids,
1030 &num_aliases,
1031 &alias_rids);
1032 if (!NT_STATUS_IS_OK(status)) {
1033 goto done;
1036 if (pnum_aliases) {
1037 *pnum_aliases = num_aliases;
1040 if (palias_rids) {
1041 *palias_rids = talloc_move(mem_ctx, &alias_rids);
1044 done:
1045 if (b && is_valid_policy_hnd(&dom_pol)) {
1046 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
1049 TALLOC_FREE(tmp_ctx);
1050 return status;
1053 /* find the sequence number for a domain */
1054 static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
1055 uint32_t *pseq)
1057 struct rpc_pipe_client *samr_pipe;
1058 struct policy_handle dom_pol;
1059 uint32_t seq;
1060 TALLOC_CTX *tmp_ctx;
1061 NTSTATUS status, result;
1062 struct dcerpc_binding_handle *b = NULL;
1064 DEBUG(3,("samr: sequence number\n"));
1066 ZERO_STRUCT(dom_pol);
1068 if (pseq) {
1069 *pseq = DOM_SEQUENCE_NONE;
1072 tmp_ctx = talloc_stackframe();
1073 if (tmp_ctx == NULL) {
1074 return NT_STATUS_NO_MEMORY;
1077 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
1078 if (!NT_STATUS_IS_OK(status)) {
1079 goto done;
1082 b = samr_pipe->binding_handle;
1084 status = rpc_sequence_number(tmp_ctx,
1085 samr_pipe,
1086 &dom_pol,
1087 domain->name,
1088 &seq);
1089 if (!NT_STATUS_IS_OK(status)) {
1090 goto done;
1093 if (pseq) {
1094 *pseq = seq;
1096 done:
1097 if (b && is_valid_policy_hnd(&dom_pol)) {
1098 dcerpc_samr_Close(b, tmp_ctx, &dom_pol, &result);
1101 TALLOC_FREE(tmp_ctx);
1102 return status;
1105 /* the rpc backend methods are exposed via this structure */
1106 struct winbindd_methods builtin_passdb_methods = {
1107 .consistent = false,
1109 .query_user_list = builtin_query_user_list,
1110 .enum_dom_groups = builtin_enum_dom_groups,
1111 .enum_local_groups = sam_enum_local_groups,
1112 .name_to_sid = sam_name_to_sid,
1113 .sid_to_name = sam_sid_to_name,
1114 .rids_to_names = sam_rids_to_names,
1115 .query_user = builtin_query_user,
1116 .lookup_usergroups = sam_lookup_usergroups,
1117 .lookup_useraliases = sam_lookup_useraliases,
1118 .lookup_groupmem = sam_lookup_groupmem,
1119 .sequence_number = sam_sequence_number,
1120 .lockout_policy = sam_lockout_policy,
1121 .password_policy = sam_password_policy,
1122 .trusted_domains = builtin_trusted_domains
1125 /* the rpc backend methods are exposed via this structure */
1126 struct winbindd_methods sam_passdb_methods = {
1127 .consistent = false,
1129 .query_user_list = sam_query_user_list,
1130 .enum_dom_groups = sam_enum_dom_groups,
1131 .enum_local_groups = sam_enum_local_groups,
1132 .name_to_sid = sam_name_to_sid,
1133 .sid_to_name = sam_sid_to_name,
1134 .rids_to_names = sam_rids_to_names,
1135 .query_user = sam_query_user,
1136 .lookup_usergroups = sam_lookup_usergroups,
1137 .lookup_useraliases = sam_lookup_useraliases,
1138 .lookup_groupmem = sam_lookup_groupmem,
1139 .sequence_number = sam_sequence_number,
1140 .lockout_policy = sam_lockout_policy,
1141 .password_policy = sam_password_policy,
1142 .trusted_domains = sam_trusted_domains