s3: Fix Coverity ID 2143: DEADCODE
[Samba.git] / source3 / winbindd / winbindd_samr.c
blob3d9636186607022a5603a948c55efa497a9b3726
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 *session_info = NULL;
47 NTSTATUS status;
49 if (cli != NULL) {
50 goto done;
53 if (session_info == NULL) {
54 status = make_session_info_system(mem_ctx, &session_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 session_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 *session_info = NULL;
129 NTSTATUS status;
131 if (session_info == NULL) {
132 status = make_session_info_system(mem_ctx, &session_info);
133 if (!NT_STATUS_IS_OK(status)) {
134 DEBUG(0, ("open_lsa_pipe: Could not create auth_serversupplied_info: %s\n",
135 nt_errstr(status)));
136 return status;
140 /* create a lsa connection */
141 status = rpc_pipe_open_interface(mem_ctx,
142 &ndr_table_lsarpc.syntax_id,
143 session_info,
144 NULL,
145 winbind_messaging_context(),
146 &cli);
147 if (!NT_STATUS_IS_OK(status)) {
148 DEBUG(0, ("open_lsa_pipe: Could not connect to lsa_pipe: %s\n",
149 nt_errstr(status)));
150 return status;
153 done:
154 if (lsa_pipe) {
155 *lsa_pipe = cli;
158 return NT_STATUS_OK;
161 static NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
162 struct rpc_pipe_client **lsa_pipe,
163 struct policy_handle *lsa_hnd)
165 NTSTATUS status;
167 status = open_internal_lsa_pipe(mem_ctx, lsa_pipe);
168 if (!NT_STATUS_IS_OK(status)) {
169 return status;
172 status = rpccli_lsa_open_policy((*lsa_pipe),
173 mem_ctx,
174 true,
175 SEC_FLAG_MAXIMUM_ALLOWED,
176 lsa_hnd);
178 return status;
181 /*********************************************************************
182 SAM specific functions.
183 *********************************************************************/
185 /* List all domain groups */
186 static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
187 TALLOC_CTX *mem_ctx,
188 uint32_t *pnum_info,
189 struct acct_info **pinfo)
191 struct rpc_pipe_client *samr_pipe;
192 struct policy_handle dom_pol;
193 struct acct_info *info = NULL;
194 uint32_t num_info = 0;
195 TALLOC_CTX *tmp_ctx;
196 NTSTATUS status, result;
197 struct dcerpc_binding_handle *b = NULL;
199 DEBUG(3,("sam_enum_dom_groups\n"));
201 ZERO_STRUCT(dom_pol);
203 if (pnum_info) {
204 *pnum_info = 0;
207 tmp_ctx = talloc_stackframe();
208 if (tmp_ctx == NULL) {
209 return NT_STATUS_NO_MEMORY;
212 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
213 if (!NT_STATUS_IS_OK(status)) {
214 goto error;
217 b = samr_pipe->binding_handle;
219 status = rpc_enum_dom_groups(tmp_ctx,
220 samr_pipe,
221 &dom_pol,
222 &num_info,
223 &info);
224 if (!NT_STATUS_IS_OK(status)) {
225 goto error;
228 if (pnum_info) {
229 *pnum_info = num_info;
232 if (pinfo) {
233 *pinfo = talloc_move(mem_ctx, &info);
236 error:
237 if (b && is_valid_policy_hnd(&dom_pol)) {
238 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
240 TALLOC_FREE(tmp_ctx);
241 return status;
244 /* Query display info for a domain */
245 static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
246 TALLOC_CTX *mem_ctx,
247 uint32_t *pnum_info,
248 struct wbint_userinfo **pinfo)
250 struct rpc_pipe_client *samr_pipe = NULL;
251 struct policy_handle dom_pol;
252 struct wbint_userinfo *info = NULL;
253 uint32_t num_info = 0;
254 TALLOC_CTX *tmp_ctx;
255 NTSTATUS status, result;
256 struct dcerpc_binding_handle *b = NULL;
258 DEBUG(3,("samr_query_user_list\n"));
260 ZERO_STRUCT(dom_pol);
262 if (pnum_info) {
263 *pnum_info = 0;
266 tmp_ctx = talloc_stackframe();
267 if (tmp_ctx == NULL) {
268 return NT_STATUS_NO_MEMORY;
271 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
272 if (!NT_STATUS_IS_OK(status)) {
273 goto done;
276 b = samr_pipe->binding_handle;
278 status = rpc_query_user_list(tmp_ctx,
279 samr_pipe,
280 &dom_pol,
281 &domain->sid,
282 &num_info,
283 &info);
284 if (!NT_STATUS_IS_OK(status)) {
285 goto done;
288 if (pnum_info) {
289 *pnum_info = num_info;
292 if (pinfo) {
293 *pinfo = talloc_move(mem_ctx, &info);
296 done:
297 if (b && is_valid_policy_hnd(&dom_pol)) {
298 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
301 TALLOC_FREE(tmp_ctx);
302 return status;
305 /* Lookup user information from a rid or username. */
306 static NTSTATUS sam_query_user(struct winbindd_domain *domain,
307 TALLOC_CTX *mem_ctx,
308 const struct dom_sid *user_sid,
309 struct wbint_userinfo *user_info)
311 struct rpc_pipe_client *samr_pipe;
312 struct policy_handle dom_pol;
313 TALLOC_CTX *tmp_ctx;
314 NTSTATUS status, result;
315 struct dcerpc_binding_handle *b = NULL;
317 DEBUG(3,("sam_query_user\n"));
319 ZERO_STRUCT(dom_pol);
321 /* Paranoia check */
322 if (!sid_check_is_in_our_domain(user_sid)) {
323 return NT_STATUS_NO_SUCH_USER;
326 if (user_info) {
327 user_info->homedir = NULL;
328 user_info->shell = NULL;
329 user_info->primary_gid = (gid_t) -1;
332 tmp_ctx = talloc_stackframe();
333 if (tmp_ctx == NULL) {
334 return NT_STATUS_NO_MEMORY;
337 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
338 if (!NT_STATUS_IS_OK(status)) {
339 goto done;
342 b = samr_pipe->binding_handle;
344 status = rpc_query_user(tmp_ctx,
345 samr_pipe,
346 &dom_pol,
347 &domain->sid,
348 user_sid,
349 user_info);
351 done:
352 if (b && is_valid_policy_hnd(&dom_pol)) {
353 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
356 TALLOC_FREE(tmp_ctx);
357 return status;
360 /* get a list of trusted domains - builtin domain */
361 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
362 TALLOC_CTX *mem_ctx,
363 struct netr_DomainTrustList *ptrust_list)
365 struct rpc_pipe_client *lsa_pipe;
366 struct policy_handle lsa_policy;
367 struct netr_DomainTrust *trusts = NULL;
368 uint32_t num_trusts = 0;
369 TALLOC_CTX *tmp_ctx;
370 NTSTATUS status, result;
371 struct dcerpc_binding_handle *b = NULL;
373 DEBUG(3,("samr: trusted domains\n"));
375 ZERO_STRUCT(lsa_policy);
377 if (ptrust_list) {
378 ZERO_STRUCTP(ptrust_list);
381 tmp_ctx = talloc_stackframe();
382 if (tmp_ctx == NULL) {
383 return NT_STATUS_NO_MEMORY;
386 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
387 if (!NT_STATUS_IS_OK(status)) {
388 goto done;
391 b = lsa_pipe->binding_handle;
393 status = rpc_trusted_domains(tmp_ctx,
394 lsa_pipe,
395 &lsa_policy,
396 &num_trusts,
397 &trusts);
398 if (!NT_STATUS_IS_OK(status)) {
399 goto done;
402 if (ptrust_list) {
403 ptrust_list->count = num_trusts;
404 ptrust_list->array = talloc_move(mem_ctx, &trusts);
407 done:
408 if (b && is_valid_policy_hnd(&lsa_policy)) {
409 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
412 TALLOC_FREE(tmp_ctx);
413 return status;
416 /* Lookup group membership given a rid. */
417 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
418 TALLOC_CTX *mem_ctx,
419 const struct dom_sid *group_sid,
420 enum lsa_SidType type,
421 uint32_t *pnum_names,
422 struct dom_sid **psid_mem,
423 char ***pnames,
424 uint32_t **pname_types)
426 struct rpc_pipe_client *samr_pipe;
427 struct policy_handle dom_pol;
429 uint32_t num_names = 0;
430 struct dom_sid *sid_mem = NULL;
431 char **names = NULL;
432 uint32_t *name_types = NULL;
434 TALLOC_CTX *tmp_ctx;
435 NTSTATUS status, result;
436 struct dcerpc_binding_handle *b = NULL;
438 DEBUG(3,("sam_lookup_groupmem\n"));
440 ZERO_STRUCT(dom_pol);
442 /* Paranoia check */
443 if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
444 /* There's no groups, only aliases in BUILTIN */
445 return NT_STATUS_NO_SUCH_GROUP;
448 if (pnum_names) {
449 pnum_names = 0;
452 tmp_ctx = talloc_stackframe();
453 if (tmp_ctx == NULL) {
454 return NT_STATUS_NO_MEMORY;
457 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
458 if (!NT_STATUS_IS_OK(status)) {
459 goto done;
462 b = samr_pipe->binding_handle;
464 status = rpc_lookup_groupmem(tmp_ctx,
465 samr_pipe,
466 &dom_pol,
467 domain->name,
468 &domain->sid,
469 group_sid,
470 type,
471 &num_names,
472 &sid_mem,
473 &names,
474 &name_types);
476 if (pnum_names) {
477 *pnum_names = num_names;
480 if (pnames) {
481 *pnames = talloc_move(mem_ctx, &names);
484 if (pname_types) {
485 *pname_types = talloc_move(mem_ctx, &name_types);
488 if (psid_mem) {
489 *psid_mem = talloc_move(mem_ctx, &sid_mem);
492 done:
493 if (b && is_valid_policy_hnd(&dom_pol)) {
494 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
497 TALLOC_FREE(tmp_ctx);
498 return status;
501 /*********************************************************************
502 BUILTIN specific functions.
503 *********************************************************************/
505 /* List all domain groups */
506 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
507 TALLOC_CTX *mem_ctx,
508 uint32 *num_entries,
509 struct acct_info **info)
511 /* BUILTIN doesn't have domain groups */
512 *num_entries = 0;
513 *info = NULL;
514 return NT_STATUS_OK;
517 /* Query display info for a domain */
518 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
519 TALLOC_CTX *mem_ctx,
520 uint32 *num_entries,
521 struct wbint_userinfo **info)
523 /* We don't have users */
524 *num_entries = 0;
525 *info = NULL;
526 return NT_STATUS_OK;
529 /* Lookup user information from a rid or username. */
530 static NTSTATUS builtin_query_user(struct winbindd_domain *domain,
531 TALLOC_CTX *mem_ctx,
532 const struct dom_sid *user_sid,
533 struct wbint_userinfo *user_info)
535 return NT_STATUS_NO_SUCH_USER;
538 /* get a list of trusted domains - builtin domain */
539 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
540 TALLOC_CTX *mem_ctx,
541 struct netr_DomainTrustList *trusts)
543 ZERO_STRUCTP(trusts);
544 return NT_STATUS_OK;
547 /*********************************************************************
548 COMMON functions.
549 *********************************************************************/
551 /* List all local groups (aliases) */
552 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
553 TALLOC_CTX *mem_ctx,
554 uint32_t *pnum_info,
555 struct acct_info **pinfo)
557 struct rpc_pipe_client *samr_pipe;
558 struct policy_handle dom_pol;
559 struct acct_info *info = NULL;
560 uint32_t num_info = 0;
561 TALLOC_CTX *tmp_ctx;
562 NTSTATUS status, result;
563 struct dcerpc_binding_handle *b = NULL;
565 DEBUG(3,("samr: enum local groups\n"));
567 ZERO_STRUCT(dom_pol);
569 if (pnum_info) {
570 *pnum_info = 0;
573 tmp_ctx = talloc_stackframe();
574 if (tmp_ctx == NULL) {
575 return NT_STATUS_NO_MEMORY;
578 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
579 if (!NT_STATUS_IS_OK(status)) {
580 goto done;
583 b = samr_pipe->binding_handle;
585 status = rpc_enum_local_groups(mem_ctx,
586 samr_pipe,
587 &dom_pol,
588 &num_info,
589 &info);
590 if (!NT_STATUS_IS_OK(status)) {
591 goto done;
594 if (pnum_info) {
595 *pnum_info = num_info;
598 if (pinfo) {
599 *pinfo = talloc_move(mem_ctx, &info);
602 done:
603 if (b && is_valid_policy_hnd(&dom_pol)) {
604 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
607 TALLOC_FREE(tmp_ctx);
608 return status;
611 /* convert a single name to a sid in a domain */
612 static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
613 TALLOC_CTX *mem_ctx,
614 const char *domain_name,
615 const char *name,
616 uint32_t flags,
617 struct dom_sid *psid,
618 enum lsa_SidType *ptype)
620 struct rpc_pipe_client *lsa_pipe;
621 struct policy_handle lsa_policy;
622 struct dom_sid sid;
623 enum lsa_SidType type;
624 TALLOC_CTX *tmp_ctx;
625 NTSTATUS status, result;
626 struct dcerpc_binding_handle *b = NULL;
628 DEBUG(3,("sam_name_to_sid\n"));
630 ZERO_STRUCT(lsa_policy);
632 tmp_ctx = talloc_stackframe();
633 if (tmp_ctx == NULL) {
634 return NT_STATUS_NO_MEMORY;
637 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
638 if (!NT_STATUS_IS_OK(status)) {
639 goto done;
642 b = lsa_pipe->binding_handle;
644 status = rpc_name_to_sid(tmp_ctx,
645 lsa_pipe,
646 &lsa_policy,
647 domain_name,
648 name,
649 flags,
650 &sid,
651 &type);
652 if (!NT_STATUS_IS_OK(status)) {
653 goto done;
656 if (psid) {
657 sid_copy(psid, &sid);
659 if (ptype) {
660 *ptype = type;
663 done:
664 if (b && is_valid_policy_hnd(&lsa_policy)) {
665 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
668 TALLOC_FREE(tmp_ctx);
669 return status;
672 /* convert a domain SID to a user or group name */
673 static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
674 TALLOC_CTX *mem_ctx,
675 const struct dom_sid *sid,
676 char **pdomain_name,
677 char **pname,
678 enum lsa_SidType *ptype)
680 struct rpc_pipe_client *lsa_pipe;
681 struct policy_handle lsa_policy;
682 char *domain_name = NULL;
683 char *name = NULL;
684 enum lsa_SidType type;
685 TALLOC_CTX *tmp_ctx;
686 NTSTATUS status, result;
687 struct dcerpc_binding_handle *b = NULL;
689 DEBUG(3,("sam_sid_to_name\n"));
691 ZERO_STRUCT(lsa_policy);
693 /* Paranoia check */
694 if (!sid_check_is_in_builtin(sid) &&
695 !sid_check_is_in_our_domain(sid) &&
696 !sid_check_is_in_unix_users(sid) &&
697 !sid_check_is_unix_users(sid) &&
698 !sid_check_is_in_unix_groups(sid) &&
699 !sid_check_is_unix_groups(sid) &&
700 !sid_check_is_in_wellknown_domain(sid)) {
701 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
702 "lookup SID %s\n", sid_string_dbg(sid)));
703 return NT_STATUS_NONE_MAPPED;
706 tmp_ctx = talloc_stackframe();
707 if (tmp_ctx == NULL) {
708 return NT_STATUS_NO_MEMORY;
711 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
712 if (!NT_STATUS_IS_OK(status)) {
713 goto done;
716 b = lsa_pipe->binding_handle;
718 status = rpc_sid_to_name(tmp_ctx,
719 lsa_pipe,
720 &lsa_policy,
721 domain,
722 sid,
723 &domain_name,
724 &name,
725 &type);
727 if (ptype) {
728 *ptype = type;
731 if (pname) {
732 *pname = talloc_move(mem_ctx, &name);
735 if (pdomain_name) {
736 *pdomain_name = talloc_move(mem_ctx, &domain_name);
739 done:
740 if (b && is_valid_policy_hnd(&lsa_policy)) {
741 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
744 TALLOC_FREE(tmp_ctx);
745 return status;
748 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
749 TALLOC_CTX *mem_ctx,
750 const struct dom_sid *domain_sid,
751 uint32 *rids,
752 size_t num_rids,
753 char **pdomain_name,
754 char ***pnames,
755 enum lsa_SidType **ptypes)
757 struct rpc_pipe_client *lsa_pipe;
758 struct policy_handle lsa_policy;
759 enum lsa_SidType *types = NULL;
760 char *domain_name = NULL;
761 char **names = NULL;
762 TALLOC_CTX *tmp_ctx;
763 NTSTATUS status, result;
764 struct dcerpc_binding_handle *b = NULL;
766 DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
768 ZERO_STRUCT(lsa_policy);
770 /* Paranoia check */
771 if (!sid_check_is_builtin(domain_sid) &&
772 !sid_check_is_domain(domain_sid) &&
773 !sid_check_is_unix_users(domain_sid) &&
774 !sid_check_is_unix_groups(domain_sid) &&
775 !sid_check_is_in_wellknown_domain(domain_sid)) {
776 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
777 "lookup SID %s\n", sid_string_dbg(domain_sid)));
778 return NT_STATUS_NONE_MAPPED;
781 tmp_ctx = talloc_stackframe();
782 if (tmp_ctx == NULL) {
783 return NT_STATUS_NO_MEMORY;
786 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
787 if (!NT_STATUS_IS_OK(status)) {
788 goto done;
791 b = lsa_pipe->binding_handle;
793 status = rpc_rids_to_names(tmp_ctx,
794 lsa_pipe,
795 &lsa_policy,
796 domain,
797 domain_sid,
798 rids,
799 num_rids,
800 &domain_name,
801 &names,
802 &types);
803 if (!NT_STATUS_IS_OK(status)) {
804 goto done;
807 if (pdomain_name) {
808 *pdomain_name = talloc_move(mem_ctx, &domain_name);
811 if (ptypes) {
812 *ptypes = talloc_move(mem_ctx, &types);
815 if (pnames) {
816 *pnames = talloc_move(mem_ctx, &names);
819 done:
820 if (b && is_valid_policy_hnd(&lsa_policy)) {
821 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
824 TALLOC_FREE(tmp_ctx);
825 return status;
828 static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
829 TALLOC_CTX *mem_ctx,
830 struct samr_DomInfo12 *lockout_policy)
832 struct rpc_pipe_client *samr_pipe;
833 struct policy_handle dom_pol;
834 union samr_DomainInfo *info = NULL;
835 TALLOC_CTX *tmp_ctx;
836 NTSTATUS status, result;
837 struct dcerpc_binding_handle *b = NULL;
839 DEBUG(3,("sam_lockout_policy\n"));
841 ZERO_STRUCT(dom_pol);
843 tmp_ctx = talloc_stackframe();
844 if (tmp_ctx == NULL) {
845 return NT_STATUS_NO_MEMORY;
848 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
849 if (!NT_STATUS_IS_OK(status)) {
850 goto error;
853 b = samr_pipe->binding_handle;
855 status = dcerpc_samr_QueryDomainInfo(b,
856 mem_ctx,
857 &dom_pol,
859 &info,
860 &result);
861 if (!NT_STATUS_IS_OK(status)) {
862 goto error;
864 if (!NT_STATUS_IS_OK(result)) {
865 status = result;
866 goto error;
869 *lockout_policy = info->info12;
871 error:
872 if (b && is_valid_policy_hnd(&dom_pol)) {
873 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
876 TALLOC_FREE(tmp_ctx);
877 return status;
880 static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
881 TALLOC_CTX *mem_ctx,
882 struct samr_DomInfo1 *passwd_policy)
884 struct rpc_pipe_client *samr_pipe;
885 struct policy_handle dom_pol;
886 union samr_DomainInfo *info = NULL;
887 TALLOC_CTX *tmp_ctx;
888 NTSTATUS status, result;
889 struct dcerpc_binding_handle *b = NULL;
891 DEBUG(3,("sam_password_policy\n"));
893 ZERO_STRUCT(dom_pol);
895 tmp_ctx = talloc_stackframe();
896 if (tmp_ctx == NULL) {
897 return NT_STATUS_NO_MEMORY;
900 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
901 if (!NT_STATUS_IS_OK(status)) {
902 goto error;
905 b = samr_pipe->binding_handle;
907 status = dcerpc_samr_QueryDomainInfo(b,
908 mem_ctx,
909 &dom_pol,
911 &info,
912 &result);
913 if (!NT_STATUS_IS_OK(status)) {
914 goto error;
916 if (!NT_STATUS_IS_OK(result)) {
917 status = result;
918 goto error;
921 *passwd_policy = info->info1;
923 error:
924 if (b && is_valid_policy_hnd(&dom_pol)) {
925 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
928 TALLOC_FREE(tmp_ctx);
929 return status;
932 /* Lookup groups a user is a member of. */
933 static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
934 TALLOC_CTX *mem_ctx,
935 const struct dom_sid *user_sid,
936 uint32_t *pnum_groups,
937 struct dom_sid **puser_grpsids)
939 struct rpc_pipe_client *samr_pipe;
940 struct policy_handle dom_pol;
941 struct dom_sid *user_grpsids = NULL;
942 uint32_t num_groups = 0;
943 TALLOC_CTX *tmp_ctx;
944 NTSTATUS status, result;
945 struct dcerpc_binding_handle *b = NULL;
947 DEBUG(3,("sam_lookup_usergroups\n"));
949 ZERO_STRUCT(dom_pol);
951 if (pnum_groups) {
952 *pnum_groups = 0;
955 tmp_ctx = talloc_stackframe();
956 if (tmp_ctx == NULL) {
957 return NT_STATUS_NO_MEMORY;
960 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
961 if (!NT_STATUS_IS_OK(status)) {
962 goto done;
965 b = samr_pipe->binding_handle;
967 status = rpc_lookup_usergroups(tmp_ctx,
968 samr_pipe,
969 &dom_pol,
970 &domain->sid,
971 user_sid,
972 &num_groups,
973 &user_grpsids);
974 if (!NT_STATUS_IS_OK(status)) {
975 goto done;
978 if (pnum_groups) {
979 *pnum_groups = num_groups;
982 if (puser_grpsids) {
983 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
986 done:
987 if (b && is_valid_policy_hnd(&dom_pol)) {
988 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
991 TALLOC_FREE(tmp_ctx);
992 return status;
995 static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
996 TALLOC_CTX *mem_ctx,
997 uint32_t num_sids,
998 const struct dom_sid *sids,
999 uint32_t *pnum_aliases,
1000 uint32_t **palias_rids)
1002 struct rpc_pipe_client *samr_pipe;
1003 struct policy_handle dom_pol;
1004 uint32_t num_aliases = 0;
1005 uint32_t *alias_rids = NULL;
1006 TALLOC_CTX *tmp_ctx;
1007 NTSTATUS status, result;
1008 struct dcerpc_binding_handle *b = NULL;
1010 DEBUG(3,("sam_lookup_useraliases\n"));
1012 ZERO_STRUCT(dom_pol);
1014 if (pnum_aliases) {
1015 *pnum_aliases = 0;
1018 tmp_ctx = talloc_stackframe();
1019 if (tmp_ctx == NULL) {
1020 return NT_STATUS_NO_MEMORY;
1023 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
1024 if (!NT_STATUS_IS_OK(status)) {
1025 goto done;
1028 b = samr_pipe->binding_handle;
1030 status = rpc_lookup_useraliases(tmp_ctx,
1031 samr_pipe,
1032 &dom_pol,
1033 num_sids,
1034 sids,
1035 &num_aliases,
1036 &alias_rids);
1037 if (!NT_STATUS_IS_OK(status)) {
1038 goto done;
1041 if (pnum_aliases) {
1042 *pnum_aliases = num_aliases;
1045 if (palias_rids) {
1046 *palias_rids = talloc_move(mem_ctx, &alias_rids);
1049 done:
1050 if (b && is_valid_policy_hnd(&dom_pol)) {
1051 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
1054 TALLOC_FREE(tmp_ctx);
1055 return status;
1058 /* find the sequence number for a domain */
1059 static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
1060 uint32_t *pseq)
1062 struct rpc_pipe_client *samr_pipe;
1063 struct policy_handle dom_pol;
1064 uint32_t seq;
1065 TALLOC_CTX *tmp_ctx;
1066 NTSTATUS status, result;
1067 struct dcerpc_binding_handle *b = NULL;
1069 DEBUG(3,("samr: sequence number\n"));
1071 ZERO_STRUCT(dom_pol);
1073 if (pseq) {
1074 *pseq = DOM_SEQUENCE_NONE;
1077 tmp_ctx = talloc_stackframe();
1078 if (tmp_ctx == NULL) {
1079 return NT_STATUS_NO_MEMORY;
1082 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
1083 if (!NT_STATUS_IS_OK(status)) {
1084 goto done;
1087 b = samr_pipe->binding_handle;
1089 status = rpc_sequence_number(tmp_ctx,
1090 samr_pipe,
1091 &dom_pol,
1092 domain->name,
1093 &seq);
1094 if (!NT_STATUS_IS_OK(status)) {
1095 goto done;
1098 if (pseq) {
1099 *pseq = seq;
1101 done:
1102 if (b && is_valid_policy_hnd(&dom_pol)) {
1103 dcerpc_samr_Close(b, tmp_ctx, &dom_pol, &result);
1106 TALLOC_FREE(tmp_ctx);
1107 return status;
1110 /* the rpc backend methods are exposed via this structure */
1111 struct winbindd_methods builtin_passdb_methods = {
1112 .consistent = false,
1114 .query_user_list = builtin_query_user_list,
1115 .enum_dom_groups = builtin_enum_dom_groups,
1116 .enum_local_groups = sam_enum_local_groups,
1117 .name_to_sid = sam_name_to_sid,
1118 .sid_to_name = sam_sid_to_name,
1119 .rids_to_names = sam_rids_to_names,
1120 .query_user = builtin_query_user,
1121 .lookup_usergroups = sam_lookup_usergroups,
1122 .lookup_useraliases = sam_lookup_useraliases,
1123 .lookup_groupmem = sam_lookup_groupmem,
1124 .sequence_number = sam_sequence_number,
1125 .lockout_policy = sam_lockout_policy,
1126 .password_policy = sam_password_policy,
1127 .trusted_domains = builtin_trusted_domains
1130 /* the rpc backend methods are exposed via this structure */
1131 struct winbindd_methods sam_passdb_methods = {
1132 .consistent = false,
1134 .query_user_list = sam_query_user_list,
1135 .enum_dom_groups = sam_enum_dom_groups,
1136 .enum_local_groups = sam_enum_local_groups,
1137 .name_to_sid = sam_name_to_sid,
1138 .sid_to_name = sam_sid_to_name,
1139 .rids_to_names = sam_rids_to_names,
1140 .query_user = sam_query_user,
1141 .lookup_usergroups = sam_lookup_usergroups,
1142 .lookup_useraliases = sam_lookup_useraliases,
1143 .lookup_groupmem = sam_lookup_groupmem,
1144 .sequence_number = sam_sequence_number,
1145 .lockout_policy = sam_lockout_policy,
1146 .password_policy = sam_password_policy,
1147 .trusted_domains = sam_trusted_domains