s3: Fix some nonempty blank lines and some typos
[Samba.git] / source3 / winbindd / winbindd_samr.c
blobd33a3097d61a646a5581d0fee660ac0bf8dd4914
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"
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, result;
89 struct policy_handle samr_connect_hnd;
90 struct dcerpc_binding_handle *b;
92 status = open_internal_samr_pipe(mem_ctx, samr_pipe);
93 if (!NT_STATUS_IS_OK(status)) {
94 return status;
97 b = (*samr_pipe)->binding_handle;
99 status = dcerpc_samr_Connect2(b, mem_ctx,
100 (*samr_pipe)->desthost,
101 SEC_FLAG_MAXIMUM_ALLOWED,
102 &samr_connect_hnd,
103 &result);
104 if (!NT_STATUS_IS_OK(status)) {
105 return status;
107 if (!NT_STATUS_IS_OK(result)) {
108 return result;
111 status = dcerpc_samr_OpenDomain(b, mem_ctx,
112 &samr_connect_hnd,
113 SEC_FLAG_MAXIMUM_ALLOWED,
114 &domain->sid,
115 samr_domain_hnd,
116 &result);
117 if (!NT_STATUS_IS_OK(status)) {
118 return status;
121 return result;
124 static NTSTATUS open_internal_lsa_pipe(TALLOC_CTX *mem_ctx,
125 struct rpc_pipe_client **lsa_pipe)
127 struct rpc_pipe_client *cli = NULL;
128 struct auth_serversupplied_info *server_info = NULL;
129 NTSTATUS status;
131 if (cli != NULL) {
132 goto done;
135 if (server_info == NULL) {
136 status = make_server_info_system(mem_ctx, &server_info);
137 if (!NT_STATUS_IS_OK(status)) {
138 DEBUG(0, ("open_lsa_pipe: Could not create auth_serversupplied_info: %s\n",
139 nt_errstr(status)));
140 return status;
144 /* create a lsa connection */
145 status = rpc_pipe_open_interface(mem_ctx,
146 &ndr_table_lsarpc.syntax_id,
147 server_info,
148 NULL,
149 winbind_messaging_context(),
150 &cli);
151 if (!NT_STATUS_IS_OK(status)) {
152 DEBUG(0, ("open_lsa_pipe: Could not connect to lsa_pipe: %s\n",
153 nt_errstr(status)));
154 return status;
157 done:
158 if (lsa_pipe) {
159 *lsa_pipe = cli;
162 return NT_STATUS_OK;
165 static NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
166 struct rpc_pipe_client **lsa_pipe,
167 struct policy_handle *lsa_hnd)
169 NTSTATUS status;
171 status = open_internal_lsa_pipe(mem_ctx, lsa_pipe);
172 if (!NT_STATUS_IS_OK(status)) {
173 return status;
176 status = rpccli_lsa_open_policy((*lsa_pipe),
177 mem_ctx,
178 true,
179 SEC_FLAG_MAXIMUM_ALLOWED,
180 lsa_hnd);
182 return status;
185 /*********************************************************************
186 SAM specific functions.
187 *********************************************************************/
189 /* List all domain groups */
190 static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
191 TALLOC_CTX *mem_ctx,
192 uint32_t *pnum_info,
193 struct acct_info **pinfo)
195 struct rpc_pipe_client *samr_pipe;
196 struct policy_handle dom_pol;
197 struct acct_info *info = NULL;
198 uint32_t num_info = 0;
199 TALLOC_CTX *tmp_ctx;
200 NTSTATUS status, result;
201 struct dcerpc_binding_handle *b = NULL;
203 DEBUG(3,("sam_enum_dom_groups\n"));
205 ZERO_STRUCT(dom_pol);
207 if (pnum_info) {
208 *pnum_info = 0;
211 tmp_ctx = talloc_stackframe();
212 if (tmp_ctx == NULL) {
213 return NT_STATUS_NO_MEMORY;
216 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
217 if (!NT_STATUS_IS_OK(status)) {
218 goto error;
221 b = samr_pipe->binding_handle;
223 status = rpc_enum_dom_groups(tmp_ctx,
224 samr_pipe,
225 &dom_pol,
226 &num_info,
227 &info);
228 if (!NT_STATUS_IS_OK(status)) {
229 goto error;
232 if (pnum_info) {
233 *pnum_info = num_info;
236 if (pinfo) {
237 *pinfo = talloc_move(mem_ctx, &info);
240 error:
241 if (b && is_valid_policy_hnd(&dom_pol)) {
242 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
244 TALLOC_FREE(tmp_ctx);
245 return status;
248 /* Query display info for a domain */
249 static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
250 TALLOC_CTX *mem_ctx,
251 uint32_t *pnum_info,
252 struct wbint_userinfo **pinfo)
254 struct rpc_pipe_client *samr_pipe = NULL;
255 struct policy_handle dom_pol;
256 struct wbint_userinfo *info = NULL;
257 uint32_t num_info = 0;
258 TALLOC_CTX *tmp_ctx;
259 NTSTATUS status, result;
260 struct dcerpc_binding_handle *b = NULL;
262 DEBUG(3,("samr_query_user_list\n"));
264 ZERO_STRUCT(dom_pol);
266 if (pnum_info) {
267 *pnum_info = 0;
270 tmp_ctx = talloc_stackframe();
271 if (tmp_ctx == NULL) {
272 return NT_STATUS_NO_MEMORY;
275 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
276 if (!NT_STATUS_IS_OK(status)) {
277 goto done;
280 b = samr_pipe->binding_handle;
282 status = rpc_query_user_list(tmp_ctx,
283 samr_pipe,
284 &dom_pol,
285 &domain->sid,
286 &num_info,
287 &info);
288 if (!NT_STATUS_IS_OK(status)) {
289 goto done;
292 if (pnum_info) {
293 *pnum_info = num_info;
296 if (pinfo) {
297 *pinfo = talloc_move(mem_ctx, &info);
300 done:
301 if (b && is_valid_policy_hnd(&dom_pol)) {
302 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
305 TALLOC_FREE(tmp_ctx);
306 return status;
309 /* Lookup user information from a rid or username. */
310 static NTSTATUS sam_query_user(struct winbindd_domain *domain,
311 TALLOC_CTX *mem_ctx,
312 const struct dom_sid *user_sid,
313 struct wbint_userinfo *user_info)
315 struct rpc_pipe_client *samr_pipe;
316 struct policy_handle dom_pol;
317 TALLOC_CTX *tmp_ctx;
318 NTSTATUS status, result;
319 struct dcerpc_binding_handle *b = NULL;
321 DEBUG(3,("sam_query_user\n"));
323 ZERO_STRUCT(dom_pol);
325 /* Paranoia check */
326 if (!sid_check_is_in_our_domain(user_sid)) {
327 return NT_STATUS_NO_SUCH_USER;
330 if (user_info) {
331 user_info->homedir = NULL;
332 user_info->shell = NULL;
333 user_info->primary_gid = (gid_t) -1;
336 tmp_ctx = talloc_stackframe();
337 if (tmp_ctx == NULL) {
338 return NT_STATUS_NO_MEMORY;
341 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
342 if (!NT_STATUS_IS_OK(status)) {
343 goto done;
346 b = samr_pipe->binding_handle;
348 status = rpc_query_user(tmp_ctx,
349 samr_pipe,
350 &dom_pol,
351 &domain->sid,
352 user_sid,
353 user_info);
355 done:
356 if (b && is_valid_policy_hnd(&dom_pol)) {
357 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
360 TALLOC_FREE(tmp_ctx);
361 return status;
364 /* get a list of trusted domains - builtin domain */
365 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
366 TALLOC_CTX *mem_ctx,
367 struct netr_DomainTrustList *ptrust_list)
369 struct rpc_pipe_client *lsa_pipe;
370 struct policy_handle lsa_policy;
371 struct netr_DomainTrust *trusts = NULL;
372 uint32_t num_trusts = 0;
373 TALLOC_CTX *tmp_ctx;
374 NTSTATUS status, result;
375 struct dcerpc_binding_handle *b = NULL;
377 DEBUG(3,("samr: trusted domains\n"));
379 ZERO_STRUCT(lsa_policy);
381 if (ptrust_list) {
382 ZERO_STRUCTP(ptrust_list);
385 tmp_ctx = talloc_stackframe();
386 if (tmp_ctx == NULL) {
387 return NT_STATUS_NO_MEMORY;
390 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
391 if (!NT_STATUS_IS_OK(status)) {
392 goto done;
395 b = lsa_pipe->binding_handle;
397 status = rpc_trusted_domains(tmp_ctx,
398 lsa_pipe,
399 &lsa_policy,
400 &num_trusts,
401 &trusts);
402 if (!NT_STATUS_IS_OK(status)) {
403 goto done;
406 if (ptrust_list) {
407 ptrust_list->count = num_trusts;
408 ptrust_list->array = talloc_move(mem_ctx, &trusts);
411 done:
412 if (b && is_valid_policy_hnd(&lsa_policy)) {
413 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
416 TALLOC_FREE(tmp_ctx);
417 return status;
420 /* Lookup group membership given a rid. */
421 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
422 TALLOC_CTX *mem_ctx,
423 const struct dom_sid *group_sid,
424 enum lsa_SidType type,
425 uint32_t *pnum_names,
426 struct dom_sid **psid_mem,
427 char ***pnames,
428 uint32_t **pname_types)
430 struct rpc_pipe_client *samr_pipe;
431 struct policy_handle dom_pol;
433 uint32_t num_names = 0;
434 struct dom_sid *sid_mem = NULL;
435 char **names = NULL;
436 uint32_t *name_types = NULL;
438 TALLOC_CTX *tmp_ctx;
439 NTSTATUS status, result;
440 struct dcerpc_binding_handle *b = NULL;
442 DEBUG(3,("sam_lookup_groupmem\n"));
444 ZERO_STRUCT(dom_pol);
446 /* Paranoia check */
447 if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
448 /* There's no groups, only aliases in BUILTIN */
449 return NT_STATUS_NO_SUCH_GROUP;
452 if (pnum_names) {
453 pnum_names = 0;
456 tmp_ctx = talloc_stackframe();
457 if (tmp_ctx == NULL) {
458 return NT_STATUS_NO_MEMORY;
461 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
462 if (!NT_STATUS_IS_OK(status)) {
463 goto done;
466 b = samr_pipe->binding_handle;
468 status = rpc_lookup_groupmem(tmp_ctx,
469 samr_pipe,
470 &dom_pol,
471 domain->name,
472 &domain->sid,
473 group_sid,
474 type,
475 &num_names,
476 &sid_mem,
477 &names,
478 &name_types);
480 if (pnum_names) {
481 *pnum_names = num_names;
484 if (pnames) {
485 *pnames = talloc_move(mem_ctx, &names);
488 if (pname_types) {
489 *pname_types = talloc_move(mem_ctx, &name_types);
492 if (psid_mem) {
493 *psid_mem = talloc_move(mem_ctx, &sid_mem);
496 done:
497 if (b && is_valid_policy_hnd(&dom_pol)) {
498 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
501 TALLOC_FREE(tmp_ctx);
502 return status;
505 /*********************************************************************
506 BUILTIN specific functions.
507 *********************************************************************/
509 /* List all domain groups */
510 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
511 TALLOC_CTX *mem_ctx,
512 uint32 *num_entries,
513 struct acct_info **info)
515 /* BUILTIN doesn't have domain groups */
516 *num_entries = 0;
517 *info = NULL;
518 return NT_STATUS_OK;
521 /* Query display info for a domain */
522 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
523 TALLOC_CTX *mem_ctx,
524 uint32 *num_entries,
525 struct wbint_userinfo **info)
527 /* We don't have users */
528 *num_entries = 0;
529 *info = NULL;
530 return NT_STATUS_OK;
533 /* Lookup user information from a rid or username. */
534 static NTSTATUS builtin_query_user(struct winbindd_domain *domain,
535 TALLOC_CTX *mem_ctx,
536 const struct dom_sid *user_sid,
537 struct wbint_userinfo *user_info)
539 return NT_STATUS_NO_SUCH_USER;
542 /* get a list of trusted domains - builtin domain */
543 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
544 TALLOC_CTX *mem_ctx,
545 struct netr_DomainTrustList *trusts)
547 ZERO_STRUCTP(trusts);
548 return NT_STATUS_OK;
551 /*********************************************************************
552 COMMON functions.
553 *********************************************************************/
555 /* List all local groups (aliases) */
556 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
557 TALLOC_CTX *mem_ctx,
558 uint32_t *pnum_info,
559 struct acct_info **pinfo)
561 struct rpc_pipe_client *samr_pipe;
562 struct policy_handle dom_pol;
563 struct acct_info *info = NULL;
564 uint32_t num_info = 0;
565 TALLOC_CTX *tmp_ctx;
566 NTSTATUS status, result;
567 struct dcerpc_binding_handle *b = NULL;
569 DEBUG(3,("samr: enum local groups\n"));
571 ZERO_STRUCT(dom_pol);
573 if (pnum_info) {
574 *pnum_info = 0;
577 tmp_ctx = talloc_stackframe();
578 if (tmp_ctx == NULL) {
579 return NT_STATUS_NO_MEMORY;
582 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
583 if (!NT_STATUS_IS_OK(status)) {
584 goto done;
587 b = samr_pipe->binding_handle;
589 status = rpc_enum_local_groups(mem_ctx,
590 samr_pipe,
591 &dom_pol,
592 &num_info,
593 &info);
594 if (!NT_STATUS_IS_OK(status)) {
595 goto done;
598 if (pnum_info) {
599 *pnum_info = num_info;
602 if (pinfo) {
603 *pinfo = talloc_move(mem_ctx, &info);
606 done:
607 if (b && is_valid_policy_hnd(&dom_pol)) {
608 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
611 TALLOC_FREE(tmp_ctx);
612 return status;
615 /* convert a single name to a sid in a domain */
616 static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
617 TALLOC_CTX *mem_ctx,
618 const char *domain_name,
619 const char *name,
620 uint32_t flags,
621 struct dom_sid *psid,
622 enum lsa_SidType *ptype)
624 struct rpc_pipe_client *lsa_pipe;
625 struct policy_handle lsa_policy;
626 struct dom_sid sid;
627 enum lsa_SidType type;
628 TALLOC_CTX *tmp_ctx;
629 NTSTATUS status, result;
630 struct dcerpc_binding_handle *b = NULL;
632 DEBUG(3,("sam_name_to_sid\n"));
634 ZERO_STRUCT(lsa_policy);
636 tmp_ctx = talloc_stackframe();
637 if (tmp_ctx == NULL) {
638 return NT_STATUS_NO_MEMORY;
641 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
642 if (!NT_STATUS_IS_OK(status)) {
643 goto done;
646 b = lsa_pipe->binding_handle;
648 status = rpc_name_to_sid(tmp_ctx,
649 lsa_pipe,
650 &lsa_policy,
651 domain_name,
652 name,
653 flags,
654 &sid,
655 &type);
656 if (!NT_STATUS_IS_OK(status)) {
657 goto done;
660 if (psid) {
661 sid_copy(psid, &sid);
663 if (ptype) {
664 *ptype = type;
667 done:
668 if (b && is_valid_policy_hnd(&lsa_policy)) {
669 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
672 TALLOC_FREE(tmp_ctx);
673 return status;
676 /* convert a domain SID to a user or group name */
677 static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
678 TALLOC_CTX *mem_ctx,
679 const struct dom_sid *sid,
680 char **pdomain_name,
681 char **pname,
682 enum lsa_SidType *ptype)
684 struct rpc_pipe_client *lsa_pipe;
685 struct policy_handle lsa_policy;
686 char *domain_name = NULL;
687 char *name = NULL;
688 enum lsa_SidType type;
689 TALLOC_CTX *tmp_ctx;
690 NTSTATUS status, result;
691 struct dcerpc_binding_handle *b = NULL;
693 DEBUG(3,("sam_sid_to_name\n"));
695 ZERO_STRUCT(lsa_policy);
697 /* Paranoia check */
698 if (!sid_check_is_in_builtin(sid) &&
699 !sid_check_is_in_our_domain(sid) &&
700 !sid_check_is_in_unix_users(sid) &&
701 !sid_check_is_unix_users(sid) &&
702 !sid_check_is_in_unix_groups(sid) &&
703 !sid_check_is_unix_groups(sid) &&
704 !sid_check_is_in_wellknown_domain(sid)) {
705 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
706 "lookup SID %s\n", sid_string_dbg(sid)));
707 return NT_STATUS_NONE_MAPPED;
710 tmp_ctx = talloc_stackframe();
711 if (tmp_ctx == NULL) {
712 return NT_STATUS_NO_MEMORY;
715 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
716 if (!NT_STATUS_IS_OK(status)) {
717 goto done;
720 b = lsa_pipe->binding_handle;
722 status = rpc_sid_to_name(tmp_ctx,
723 lsa_pipe,
724 &lsa_policy,
725 domain,
726 sid,
727 &domain_name,
728 &name,
729 &type);
731 if (ptype) {
732 *ptype = type;
735 if (pname) {
736 *pname = talloc_move(mem_ctx, &name);
739 if (pdomain_name) {
740 *pdomain_name = talloc_move(mem_ctx, &domain_name);
743 done:
744 if (b && is_valid_policy_hnd(&lsa_policy)) {
745 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
748 TALLOC_FREE(tmp_ctx);
749 return status;
752 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
753 TALLOC_CTX *mem_ctx,
754 const struct dom_sid *sid,
755 uint32 *rids,
756 size_t num_rids,
757 char **pdomain_name,
758 char ***pnames,
759 enum lsa_SidType **ptypes)
761 struct rpc_pipe_client *lsa_pipe;
762 struct policy_handle lsa_policy;
763 enum lsa_SidType *types = NULL;
764 char *domain_name = NULL;
765 char **names = NULL;
766 TALLOC_CTX *tmp_ctx;
767 NTSTATUS status, result;
768 struct dcerpc_binding_handle *b = NULL;
770 DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
772 ZERO_STRUCT(lsa_policy);
774 /* Paranoia check */
775 if (!sid_check_is_in_builtin(sid) &&
776 !sid_check_is_in_our_domain(sid) &&
777 !sid_check_is_in_unix_users(sid) &&
778 !sid_check_is_unix_users(sid) &&
779 !sid_check_is_in_unix_groups(sid) &&
780 !sid_check_is_unix_groups(sid) &&
781 !sid_check_is_in_wellknown_domain(sid)) {
782 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
783 "lookup SID %s\n", sid_string_dbg(sid)));
784 return NT_STATUS_NONE_MAPPED;
787 tmp_ctx = talloc_stackframe();
788 if (tmp_ctx == NULL) {
789 return NT_STATUS_NO_MEMORY;
792 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
793 if (!NT_STATUS_IS_OK(status)) {
794 goto done;
797 b = lsa_pipe->binding_handle;
799 status = rpc_rids_to_names(tmp_ctx,
800 lsa_pipe,
801 &lsa_policy,
802 domain,
803 sid,
804 rids,
805 num_rids,
806 &domain_name,
807 &names,
808 &types);
809 if (!NT_STATUS_IS_OK(status)) {
810 goto done;
813 if (pdomain_name) {
814 *pdomain_name = talloc_move(mem_ctx, &domain_name);
817 if (ptypes) {
818 *ptypes = talloc_move(mem_ctx, &types);
821 if (pnames) {
822 *pnames = talloc_move(mem_ctx, &names);
825 done:
826 if (b && is_valid_policy_hnd(&lsa_policy)) {
827 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
830 TALLOC_FREE(tmp_ctx);
831 return status;
834 static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
835 TALLOC_CTX *mem_ctx,
836 struct samr_DomInfo12 *lockout_policy)
838 struct rpc_pipe_client *samr_pipe;
839 struct policy_handle dom_pol;
840 union samr_DomainInfo *info = NULL;
841 TALLOC_CTX *tmp_ctx;
842 NTSTATUS status, result;
843 struct dcerpc_binding_handle *b = NULL;
845 DEBUG(3,("sam_lockout_policy\n"));
847 ZERO_STRUCT(dom_pol);
849 tmp_ctx = talloc_stackframe();
850 if (tmp_ctx == NULL) {
851 return NT_STATUS_NO_MEMORY;
854 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
855 if (!NT_STATUS_IS_OK(status)) {
856 goto error;
859 b = samr_pipe->binding_handle;
861 status = dcerpc_samr_QueryDomainInfo(b,
862 mem_ctx,
863 &dom_pol,
865 &info,
866 &result);
867 if (!NT_STATUS_IS_OK(status)) {
868 goto error;
870 if (!NT_STATUS_IS_OK(result)) {
871 status = result;
872 goto error;
875 *lockout_policy = info->info12;
877 error:
878 if (b && is_valid_policy_hnd(&dom_pol)) {
879 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
882 TALLOC_FREE(tmp_ctx);
883 return status;
886 static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
887 TALLOC_CTX *mem_ctx,
888 struct samr_DomInfo1 *passwd_policy)
890 struct rpc_pipe_client *samr_pipe;
891 struct policy_handle dom_pol;
892 union samr_DomainInfo *info = NULL;
893 TALLOC_CTX *tmp_ctx;
894 NTSTATUS status, result;
895 struct dcerpc_binding_handle *b = NULL;
897 DEBUG(3,("sam_password_policy\n"));
899 ZERO_STRUCT(dom_pol);
901 tmp_ctx = talloc_stackframe();
902 if (tmp_ctx == NULL) {
903 return NT_STATUS_NO_MEMORY;
906 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
907 if (!NT_STATUS_IS_OK(status)) {
908 goto error;
911 b = samr_pipe->binding_handle;
913 status = dcerpc_samr_QueryDomainInfo(b,
914 mem_ctx,
915 &dom_pol,
917 &info,
918 &result);
919 if (!NT_STATUS_IS_OK(status)) {
920 goto error;
922 if (!NT_STATUS_IS_OK(result)) {
923 status = result;
924 goto error;
927 *passwd_policy = info->info1;
929 error:
930 if (b && is_valid_policy_hnd(&dom_pol)) {
931 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
934 TALLOC_FREE(tmp_ctx);
935 return status;
938 /* Lookup groups a user is a member of. */
939 static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
940 TALLOC_CTX *mem_ctx,
941 const struct dom_sid *user_sid,
942 uint32_t *pnum_groups,
943 struct dom_sid **puser_grpsids)
945 struct rpc_pipe_client *samr_pipe;
946 struct policy_handle dom_pol;
947 struct dom_sid *user_grpsids = NULL;
948 uint32_t num_groups = 0;
949 TALLOC_CTX *tmp_ctx;
950 NTSTATUS status, result;
951 struct dcerpc_binding_handle *b = NULL;
953 DEBUG(3,("sam_lookup_usergroups\n"));
955 ZERO_STRUCT(dom_pol);
957 if (pnum_groups) {
958 *pnum_groups = 0;
961 tmp_ctx = talloc_stackframe();
962 if (tmp_ctx == NULL) {
963 return NT_STATUS_NO_MEMORY;
966 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
967 if (!NT_STATUS_IS_OK(status)) {
968 goto done;
971 b = samr_pipe->binding_handle;
973 status = rpc_lookup_usergroups(tmp_ctx,
974 samr_pipe,
975 &dom_pol,
976 &domain->sid,
977 user_sid,
978 &num_groups,
979 &user_grpsids);
980 if (!NT_STATUS_IS_OK(status)) {
981 goto done;
984 if (pnum_groups) {
985 *pnum_groups = num_groups;
988 if (puser_grpsids) {
989 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
992 done:
993 if (b && is_valid_policy_hnd(&dom_pol)) {
994 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
997 TALLOC_FREE(tmp_ctx);
998 return status;
1001 static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
1002 TALLOC_CTX *mem_ctx,
1003 uint32_t num_sids,
1004 const struct dom_sid *sids,
1005 uint32_t *pnum_aliases,
1006 uint32_t **palias_rids)
1008 struct rpc_pipe_client *samr_pipe;
1009 struct policy_handle dom_pol;
1010 uint32_t num_aliases = 0;
1011 uint32_t *alias_rids = NULL;
1012 TALLOC_CTX *tmp_ctx;
1013 NTSTATUS status, result;
1014 struct dcerpc_binding_handle *b = NULL;
1016 DEBUG(3,("sam_lookup_useraliases\n"));
1018 ZERO_STRUCT(dom_pol);
1020 if (pnum_aliases) {
1021 *pnum_aliases = 0;
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 b = samr_pipe->binding_handle;
1036 status = rpc_lookup_useraliases(tmp_ctx,
1037 samr_pipe,
1038 &dom_pol,
1039 num_sids,
1040 sids,
1041 &num_aliases,
1042 &alias_rids);
1043 if (!NT_STATUS_IS_OK(status)) {
1044 goto done;
1047 if (pnum_aliases) {
1048 *pnum_aliases = num_aliases;
1051 if (palias_rids) {
1052 *palias_rids = talloc_move(mem_ctx, &alias_rids);
1055 done:
1056 if (b && is_valid_policy_hnd(&dom_pol)) {
1057 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
1060 TALLOC_FREE(tmp_ctx);
1061 return status;
1064 /* find the sequence number for a domain */
1065 static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
1066 uint32_t *pseq)
1068 struct rpc_pipe_client *samr_pipe;
1069 struct policy_handle dom_pol;
1070 uint32_t seq;
1071 TALLOC_CTX *tmp_ctx;
1072 NTSTATUS status, result;
1073 struct dcerpc_binding_handle *b = NULL;
1075 DEBUG(3,("samr: sequence number\n"));
1077 ZERO_STRUCT(dom_pol);
1079 if (pseq) {
1080 *pseq = DOM_SEQUENCE_NONE;
1083 tmp_ctx = talloc_stackframe();
1084 if (tmp_ctx == NULL) {
1085 return NT_STATUS_NO_MEMORY;
1088 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
1089 if (!NT_STATUS_IS_OK(status)) {
1090 goto done;
1093 b = samr_pipe->binding_handle;
1095 status = rpc_sequence_number(tmp_ctx,
1096 samr_pipe,
1097 &dom_pol,
1098 domain->name,
1099 &seq);
1100 if (!NT_STATUS_IS_OK(status)) {
1101 goto done;
1104 if (pseq) {
1105 *pseq = seq;
1107 done:
1108 if (b && is_valid_policy_hnd(&dom_pol)) {
1109 dcerpc_samr_Close(b, tmp_ctx, &dom_pol, &result);
1112 TALLOC_FREE(tmp_ctx);
1113 return status;
1116 /* the rpc backend methods are exposed via this structure */
1117 struct winbindd_methods builtin_passdb_methods = {
1118 .consistent = false,
1120 .query_user_list = builtin_query_user_list,
1121 .enum_dom_groups = builtin_enum_dom_groups,
1122 .enum_local_groups = sam_enum_local_groups,
1123 .name_to_sid = sam_name_to_sid,
1124 .sid_to_name = sam_sid_to_name,
1125 .rids_to_names = sam_rids_to_names,
1126 .query_user = builtin_query_user,
1127 .lookup_usergroups = sam_lookup_usergroups,
1128 .lookup_useraliases = sam_lookup_useraliases,
1129 .lookup_groupmem = sam_lookup_groupmem,
1130 .sequence_number = sam_sequence_number,
1131 .lockout_policy = sam_lockout_policy,
1132 .password_policy = sam_password_policy,
1133 .trusted_domains = builtin_trusted_domains
1136 /* the rpc backend methods are exposed via this structure */
1137 struct winbindd_methods sam_passdb_methods = {
1138 .consistent = false,
1140 .query_user_list = sam_query_user_list,
1141 .enum_dom_groups = sam_enum_dom_groups,
1142 .enum_local_groups = sam_enum_local_groups,
1143 .name_to_sid = sam_name_to_sid,
1144 .sid_to_name = sam_sid_to_name,
1145 .rids_to_names = sam_rids_to_names,
1146 .query_user = sam_query_user,
1147 .lookup_usergroups = sam_lookup_usergroups,
1148 .lookup_useraliases = sam_lookup_useraliases,
1149 .lookup_groupmem = sam_lookup_groupmem,
1150 .sequence_number = sam_sequence_number,
1151 .lockout_policy = sam_lockout_policy,
1152 .password_policy = sam_password_policy,
1153 .trusted_domains = sam_trusted_domains