s3: Remove smbd_server_conn from smb1 receive_unlock_msg
[Samba.git] / source3 / winbindd / winbindd_samr.c
blob455d4941d7fd0e61284e77bbe818a5e294848f05
1 /*
2 * Unix SMB/CIFS implementation.
4 * Winbind rpc backend functions
6 * Copyright (c) 2000-2003 Tim Potter
7 * Copyright (c) 2001 Andrew Tridgell
8 * Copyright (c) 2005 Volker Lendecke
9 * Copyright (c) 2008 Guenther Deschner (pidl conversion)
10 * Copyright (c) 2010 Andreas Schneider <asn@samba.org>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "includes.h"
27 #include "winbindd.h"
28 #include "winbindd_rpc.h"
30 #include "../librpc/gen_ndr/cli_samr.h"
31 #include "rpc_client/cli_samr.h"
32 #include "../librpc/gen_ndr/srv_samr.h"
33 #include "../librpc/gen_ndr/cli_lsa.h"
34 #include "rpc_client/cli_lsarpc.h"
35 #include "../librpc/gen_ndr/srv_lsa.h"
36 #include "rpc_server/rpc_ncacn_np.h"
38 #undef DBGC_CLASS
39 #define DBGC_CLASS DBGC_WINBIND
41 static NTSTATUS open_internal_samr_pipe(TALLOC_CTX *mem_ctx,
42 struct rpc_pipe_client **samr_pipe)
44 struct rpc_pipe_client *cli = NULL;
45 struct auth_serversupplied_info *server_info = NULL;
46 NTSTATUS status;
48 if (cli != NULL) {
49 goto done;
52 if (server_info == NULL) {
53 status = make_server_info_system(mem_ctx, &server_info);
54 if (!NT_STATUS_IS_OK(status)) {
55 DEBUG(0, ("open_samr_pipe: Could not create auth_serversupplied_info: %s\n",
56 nt_errstr(status)));
57 return status;
61 /* create a samr connection */
62 status = rpc_pipe_open_interface(mem_ctx,
63 &ndr_table_samr.syntax_id,
64 server_info,
65 NULL,
66 winbind_messaging_context(),
67 &cli);
68 if (!NT_STATUS_IS_OK(status)) {
69 DEBUG(0, ("open_samr_pipe: Could not connect to samr_pipe: %s\n",
70 nt_errstr(status)));
71 return status;
74 done:
75 if (samr_pipe) {
76 *samr_pipe = cli;
79 return NT_STATUS_OK;
82 NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
83 struct winbindd_domain *domain,
84 struct rpc_pipe_client **samr_pipe,
85 struct policy_handle *samr_domain_hnd)
87 NTSTATUS status;
88 struct policy_handle samr_connect_hnd;
90 status = open_internal_samr_pipe(mem_ctx, samr_pipe);
91 if (!NT_STATUS_IS_OK(status)) {
92 return status;
95 status = rpccli_samr_Connect2((*samr_pipe),
96 mem_ctx,
97 (*samr_pipe)->desthost,
98 SEC_FLAG_MAXIMUM_ALLOWED,
99 &samr_connect_hnd);
100 if (!NT_STATUS_IS_OK(status)) {
101 return status;
104 status = rpccli_samr_OpenDomain((*samr_pipe),
105 mem_ctx,
106 &samr_connect_hnd,
107 SEC_FLAG_MAXIMUM_ALLOWED,
108 &domain->sid,
109 samr_domain_hnd);
111 return status;
114 static NTSTATUS open_internal_lsa_pipe(TALLOC_CTX *mem_ctx,
115 struct rpc_pipe_client **lsa_pipe)
117 struct rpc_pipe_client *cli = NULL;
118 struct auth_serversupplied_info *server_info = NULL;
119 NTSTATUS status;
121 if (cli != NULL) {
122 goto done;
125 if (server_info == NULL) {
126 status = make_server_info_system(mem_ctx, &server_info);
127 if (!NT_STATUS_IS_OK(status)) {
128 DEBUG(0, ("open_lsa_pipe: Could not create auth_serversupplied_info: %s\n",
129 nt_errstr(status)));
130 return status;
134 /* create a samr connection */
135 status = rpc_pipe_open_interface(mem_ctx,
136 &ndr_table_lsarpc.syntax_id,
137 server_info,
138 NULL,
139 winbind_messaging_context(),
140 &cli);
141 if (!NT_STATUS_IS_OK(status)) {
142 DEBUG(0, ("open_lsa_pipe: Could not connect to lsa_pipe: %s\n",
143 nt_errstr(status)));
144 return status;
147 done:
148 if (lsa_pipe) {
149 *lsa_pipe = cli;
152 return NT_STATUS_OK;
155 static NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
156 struct rpc_pipe_client **lsa_pipe,
157 struct policy_handle *lsa_hnd)
159 NTSTATUS status;
161 status = open_internal_lsa_pipe(mem_ctx, lsa_pipe);
162 if (!NT_STATUS_IS_OK(status)) {
163 return status;
166 status = rpccli_lsa_open_policy((*lsa_pipe),
167 mem_ctx,
168 true,
169 SEC_FLAG_MAXIMUM_ALLOWED,
170 lsa_hnd);
172 return status;
175 /*********************************************************************
176 SAM specific functions.
177 *********************************************************************/
179 /* List all domain groups */
180 static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
181 TALLOC_CTX *mem_ctx,
182 uint32_t *pnum_info,
183 struct acct_info **pinfo)
185 struct rpc_pipe_client *samr_pipe;
186 struct policy_handle dom_pol;
187 struct acct_info *info = NULL;
188 uint32_t num_info = 0;
189 TALLOC_CTX *tmp_ctx;
190 NTSTATUS status;
192 DEBUG(3,("sam_enum_dom_groups\n"));
194 ZERO_STRUCT(dom_pol);
196 if (pnum_info) {
197 *pnum_info = 0;
200 tmp_ctx = talloc_stackframe();
201 if (tmp_ctx == NULL) {
202 return NT_STATUS_NO_MEMORY;
205 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
206 if (!NT_STATUS_IS_OK(status)) {
207 goto error;
210 status = rpc_enum_dom_groups(tmp_ctx,
211 samr_pipe,
212 &dom_pol,
213 &num_info,
214 &info);
215 if (!NT_STATUS_IS_OK(status)) {
216 goto error;
219 if (pnum_info) {
220 *pnum_info = num_info;
223 if (pinfo) {
224 *pinfo = talloc_move(mem_ctx, &info);
227 error:
228 if (is_valid_policy_hnd(&dom_pol)) {
229 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
231 TALLOC_FREE(tmp_ctx);
232 return status;
235 /* Query display info for a domain */
236 static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
237 TALLOC_CTX *mem_ctx,
238 uint32_t *pnum_info,
239 struct wbint_userinfo **pinfo)
241 struct rpc_pipe_client *samr_pipe = NULL;
242 struct policy_handle dom_pol;
243 struct wbint_userinfo *info = NULL;
244 uint32_t num_info = 0;
245 TALLOC_CTX *tmp_ctx;
246 NTSTATUS status;
248 DEBUG(3,("samr_query_user_list\n"));
250 ZERO_STRUCT(dom_pol);
252 if (pnum_info) {
253 *pnum_info = 0;
256 tmp_ctx = talloc_stackframe();
257 if (tmp_ctx == NULL) {
258 return NT_STATUS_NO_MEMORY;
261 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
262 if (!NT_STATUS_IS_OK(status)) {
263 goto done;
266 status = rpc_query_user_list(tmp_ctx,
267 samr_pipe,
268 &dom_pol,
269 &domain->sid,
270 &num_info,
271 &info);
272 if (!NT_STATUS_IS_OK(status)) {
273 goto done;
276 if (pnum_info) {
277 *pnum_info = num_info;
280 if (pinfo) {
281 *pinfo = talloc_move(mem_ctx, &info);
284 done:
285 if (is_valid_policy_hnd(&dom_pol)) {
286 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
289 TALLOC_FREE(tmp_ctx);
290 return status;
293 /* Lookup user information from a rid or username. */
294 static NTSTATUS sam_query_user(struct winbindd_domain *domain,
295 TALLOC_CTX *mem_ctx,
296 const struct dom_sid *user_sid,
297 struct wbint_userinfo *user_info)
299 struct rpc_pipe_client *samr_pipe;
300 struct policy_handle dom_pol;
301 TALLOC_CTX *tmp_ctx;
302 NTSTATUS status;
304 DEBUG(3,("sam_query_user\n"));
306 ZERO_STRUCT(dom_pol);
308 /* Paranoia check */
309 if (!sid_check_is_in_our_domain(user_sid)) {
310 return NT_STATUS_NO_SUCH_USER;
313 if (user_info) {
314 user_info->homedir = NULL;
315 user_info->shell = NULL;
316 user_info->primary_gid = (gid_t) -1;
319 tmp_ctx = talloc_stackframe();
320 if (tmp_ctx == NULL) {
321 return NT_STATUS_NO_MEMORY;
324 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
325 if (!NT_STATUS_IS_OK(status)) {
326 goto done;
329 status = rpc_query_user(tmp_ctx,
330 samr_pipe,
331 &dom_pol,
332 &domain->sid,
333 user_sid,
334 user_info);
336 done:
337 if (is_valid_policy_hnd(&dom_pol)) {
338 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
341 TALLOC_FREE(tmp_ctx);
342 return status;
345 /* get a list of trusted domains - builtin domain */
346 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
347 TALLOC_CTX *mem_ctx,
348 struct netr_DomainTrustList *ptrust_list)
350 struct rpc_pipe_client *lsa_pipe;
351 struct policy_handle lsa_policy;
352 struct netr_DomainTrust *trusts = NULL;
353 uint32_t num_trusts = 0;
354 TALLOC_CTX *tmp_ctx;
355 NTSTATUS status;
357 DEBUG(3,("samr: trusted domains\n"));
359 ZERO_STRUCT(lsa_policy);
361 if (ptrust_list) {
362 ZERO_STRUCTP(ptrust_list);
365 tmp_ctx = talloc_stackframe();
366 if (tmp_ctx == NULL) {
367 return NT_STATUS_NO_MEMORY;
370 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
371 if (!NT_STATUS_IS_OK(status)) {
372 goto done;
375 status = rpc_trusted_domains(tmp_ctx,
376 lsa_pipe,
377 &lsa_policy,
378 &num_trusts,
379 &trusts);
380 if (!NT_STATUS_IS_OK(status)) {
381 goto done;
384 if (ptrust_list) {
385 ptrust_list->count = num_trusts;
386 ptrust_list->array = talloc_move(mem_ctx, &trusts);
389 done:
390 if (is_valid_policy_hnd(&lsa_policy)) {
391 rpccli_lsa_Close(lsa_pipe, mem_ctx, &lsa_policy);
394 TALLOC_FREE(tmp_ctx);
395 return status;
398 /* Lookup group membership given a rid. */
399 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
400 TALLOC_CTX *mem_ctx,
401 const struct dom_sid *group_sid,
402 enum lsa_SidType type,
403 uint32_t *pnum_names,
404 struct dom_sid **psid_mem,
405 char ***pnames,
406 uint32_t **pname_types)
408 struct rpc_pipe_client *samr_pipe;
409 struct policy_handle dom_pol;
411 uint32_t num_names = 0;
412 struct dom_sid *sid_mem = NULL;
413 char **names = NULL;
414 uint32_t *name_types = NULL;
416 TALLOC_CTX *tmp_ctx;
417 NTSTATUS status;
419 DEBUG(3,("sam_lookup_groupmem\n"));
421 ZERO_STRUCT(dom_pol);
423 /* Paranoia check */
424 if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
425 /* There's no groups, only aliases in BUILTIN */
426 return NT_STATUS_NO_SUCH_GROUP;
429 if (pnum_names) {
430 pnum_names = 0;
433 tmp_ctx = talloc_stackframe();
434 if (tmp_ctx == NULL) {
435 return NT_STATUS_NO_MEMORY;
438 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
439 if (!NT_STATUS_IS_OK(status)) {
440 goto done;
443 status = rpc_lookup_groupmem(tmp_ctx,
444 samr_pipe,
445 &dom_pol,
446 domain->name,
447 &domain->sid,
448 group_sid,
449 type,
450 &num_names,
451 &sid_mem,
452 &names,
453 &name_types);
455 if (pnum_names) {
456 *pnum_names = num_names;
459 if (pnames) {
460 *pnames = talloc_move(mem_ctx, &names);
463 if (pname_types) {
464 *pname_types = talloc_move(mem_ctx, &name_types);
467 if (psid_mem) {
468 *psid_mem = talloc_move(mem_ctx, &sid_mem);
471 done:
472 if (is_valid_policy_hnd(&dom_pol)) {
473 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
476 TALLOC_FREE(tmp_ctx);
477 return status;
480 /*********************************************************************
481 BUILTIN specific functions.
482 *********************************************************************/
484 /* List all domain groups */
485 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
486 TALLOC_CTX *mem_ctx,
487 uint32 *num_entries,
488 struct acct_info **info)
490 /* BUILTIN doesn't have domain groups */
491 *num_entries = 0;
492 *info = NULL;
493 return NT_STATUS_OK;
496 /* Query display info for a domain */
497 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
498 TALLOC_CTX *mem_ctx,
499 uint32 *num_entries,
500 struct wbint_userinfo **info)
502 /* We don't have users */
503 *num_entries = 0;
504 *info = NULL;
505 return NT_STATUS_OK;
508 /* Lookup user information from a rid or username. */
509 static NTSTATUS builtin_query_user(struct winbindd_domain *domain,
510 TALLOC_CTX *mem_ctx,
511 const struct dom_sid *user_sid,
512 struct wbint_userinfo *user_info)
514 return NT_STATUS_NO_SUCH_USER;
517 /* get a list of trusted domains - builtin domain */
518 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
519 TALLOC_CTX *mem_ctx,
520 struct netr_DomainTrustList *trusts)
522 ZERO_STRUCTP(trusts);
523 return NT_STATUS_OK;
526 /*********************************************************************
527 COMMON functions.
528 *********************************************************************/
530 /* List all local groups (aliases) */
531 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
532 TALLOC_CTX *mem_ctx,
533 uint32_t *pnum_info,
534 struct acct_info **pinfo)
536 struct rpc_pipe_client *samr_pipe;
537 struct policy_handle dom_pol;
538 struct acct_info *info = NULL;
539 uint32_t num_info = 0;
540 TALLOC_CTX *tmp_ctx;
541 NTSTATUS status;
543 DEBUG(3,("samr: enum local groups\n"));
545 ZERO_STRUCT(dom_pol);
547 if (pnum_info) {
548 *pnum_info = 0;
551 tmp_ctx = talloc_stackframe();
552 if (tmp_ctx == NULL) {
553 return NT_STATUS_NO_MEMORY;
556 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
557 if (!NT_STATUS_IS_OK(status)) {
558 goto done;
561 status = rpc_enum_local_groups(mem_ctx,
562 samr_pipe,
563 &dom_pol,
564 &num_info,
565 &info);
566 if (!NT_STATUS_IS_OK(status)) {
567 goto done;
570 if (pnum_info) {
571 *pnum_info = num_info;
574 if (pinfo) {
575 *pinfo = talloc_move(mem_ctx, &info);
578 done:
579 if (is_valid_policy_hnd(&dom_pol)) {
580 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
583 TALLOC_FREE(tmp_ctx);
584 return status;
587 /* convert a single name to a sid in a domain */
588 static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
589 TALLOC_CTX *mem_ctx,
590 const char *domain_name,
591 const char *name,
592 uint32_t flags,
593 struct dom_sid *psid,
594 enum lsa_SidType *ptype)
596 struct rpc_pipe_client *lsa_pipe;
597 struct policy_handle lsa_policy;
598 struct dom_sid sid;
599 enum lsa_SidType type;
600 TALLOC_CTX *tmp_ctx;
601 NTSTATUS status;
603 DEBUG(3,("sam_name_to_sid\n"));
605 ZERO_STRUCT(lsa_policy);
607 tmp_ctx = talloc_stackframe();
608 if (tmp_ctx == NULL) {
609 return NT_STATUS_NO_MEMORY;
612 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
613 if (!NT_STATUS_IS_OK(status)) {
614 goto done;
617 status = rpc_name_to_sid(tmp_ctx,
618 lsa_pipe,
619 &lsa_policy,
620 domain_name,
621 name,
622 flags,
623 &sid,
624 &type);
625 if (!NT_STATUS_IS_OK(status)) {
626 goto done;
629 if (psid) {
630 sid_copy(psid, &sid);
632 if (ptype) {
633 *ptype = type;
636 done:
637 if (is_valid_policy_hnd(&lsa_policy)) {
638 rpccli_lsa_Close(lsa_pipe, mem_ctx, &lsa_policy);
641 TALLOC_FREE(tmp_ctx);
642 return status;
645 /* convert a domain SID to a user or group name */
646 static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
647 TALLOC_CTX *mem_ctx,
648 const struct dom_sid *sid,
649 char **pdomain_name,
650 char **pname,
651 enum lsa_SidType *ptype)
653 struct rpc_pipe_client *lsa_pipe;
654 struct policy_handle lsa_policy;
655 char *domain_name = NULL;
656 char *name = NULL;
657 enum lsa_SidType type;
658 TALLOC_CTX *tmp_ctx;
659 NTSTATUS status;
661 DEBUG(3,("sam_sid_to_name\n"));
663 ZERO_STRUCT(lsa_policy);
665 /* Paranoia check */
666 if (!sid_check_is_in_builtin(sid) &&
667 !sid_check_is_in_our_domain(sid) &&
668 !sid_check_is_in_unix_users(sid) &&
669 !sid_check_is_unix_users(sid) &&
670 !sid_check_is_in_unix_groups(sid) &&
671 !sid_check_is_unix_groups(sid) &&
672 !sid_check_is_in_wellknown_domain(sid)) {
673 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
674 "lookup SID %s\n", sid_string_dbg(sid)));
675 return NT_STATUS_NONE_MAPPED;
678 tmp_ctx = talloc_stackframe();
679 if (tmp_ctx == NULL) {
680 return NT_STATUS_NO_MEMORY;
683 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
684 if (!NT_STATUS_IS_OK(status)) {
685 goto done;
688 status = rpc_sid_to_name(tmp_ctx,
689 lsa_pipe,
690 &lsa_policy,
691 domain,
692 sid,
693 &domain_name,
694 &name,
695 &type);
697 if (ptype) {
698 *ptype = type;
701 if (pname) {
702 *pname = talloc_move(mem_ctx, &name);
705 if (pdomain_name) {
706 *pdomain_name = talloc_move(mem_ctx, &domain_name);
709 done:
710 if (is_valid_policy_hnd(&lsa_policy)) {
711 rpccli_lsa_Close(lsa_pipe, mem_ctx, &lsa_policy);
714 TALLOC_FREE(tmp_ctx);
715 return status;
718 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
719 TALLOC_CTX *mem_ctx,
720 const struct dom_sid *sid,
721 uint32 *rids,
722 size_t num_rids,
723 char **pdomain_name,
724 char ***pnames,
725 enum lsa_SidType **ptypes)
727 struct rpc_pipe_client *lsa_pipe;
728 struct policy_handle lsa_policy;
729 enum lsa_SidType *types = NULL;
730 char *domain_name = NULL;
731 char **names = NULL;
732 TALLOC_CTX *tmp_ctx;
733 NTSTATUS status;
735 DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
737 ZERO_STRUCT(lsa_policy);
739 /* Paranoia check */
740 if (!sid_check_is_in_builtin(sid) &&
741 !sid_check_is_in_our_domain(sid) &&
742 !sid_check_is_in_unix_users(sid) &&
743 !sid_check_is_unix_users(sid) &&
744 !sid_check_is_in_unix_groups(sid) &&
745 !sid_check_is_unix_groups(sid) &&
746 !sid_check_is_in_wellknown_domain(sid)) {
747 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
748 "lookup SID %s\n", sid_string_dbg(sid)));
749 return NT_STATUS_NONE_MAPPED;
752 tmp_ctx = talloc_stackframe();
753 if (tmp_ctx == NULL) {
754 return NT_STATUS_NO_MEMORY;
757 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
758 if (!NT_STATUS_IS_OK(status)) {
759 goto done;
762 status = rpc_rids_to_names(tmp_ctx,
763 lsa_pipe,
764 &lsa_policy,
765 domain,
766 sid,
767 rids,
768 num_rids,
769 &domain_name,
770 &names,
771 &types);
772 if (!NT_STATUS_IS_OK(status)) {
773 goto done;
776 if (pdomain_name) {
777 *pdomain_name = talloc_move(mem_ctx, &domain_name);
780 if (ptypes) {
781 *ptypes = talloc_move(mem_ctx, &types);
784 if (pnames) {
785 *pnames = talloc_move(mem_ctx, &names);
788 done:
789 if (is_valid_policy_hnd(&lsa_policy)) {
790 rpccli_lsa_Close(lsa_pipe, mem_ctx, &lsa_policy);
793 TALLOC_FREE(tmp_ctx);
794 return status;
797 static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
798 TALLOC_CTX *mem_ctx,
799 struct samr_DomInfo12 *lockout_policy)
801 struct rpc_pipe_client *samr_pipe;
802 struct policy_handle dom_pol;
803 union samr_DomainInfo *info = NULL;
804 TALLOC_CTX *tmp_ctx;
805 NTSTATUS status;
807 DEBUG(3,("sam_lockout_policy\n"));
809 ZERO_STRUCT(dom_pol);
811 tmp_ctx = talloc_stackframe();
812 if (tmp_ctx == NULL) {
813 return NT_STATUS_NO_MEMORY;
816 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
817 if (!NT_STATUS_IS_OK(status)) {
818 goto error;
821 status = rpccli_samr_QueryDomainInfo(samr_pipe,
822 mem_ctx,
823 &dom_pol,
825 &info);
826 if (!NT_STATUS_IS_OK(status)) {
827 goto error;
830 *lockout_policy = info->info12;
832 error:
833 if (is_valid_policy_hnd(&dom_pol)) {
834 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
837 TALLOC_FREE(tmp_ctx);
838 return status;
841 static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
842 TALLOC_CTX *mem_ctx,
843 struct samr_DomInfo1 *passwd_policy)
845 struct rpc_pipe_client *samr_pipe;
846 struct policy_handle dom_pol;
847 union samr_DomainInfo *info = NULL;
848 TALLOC_CTX *tmp_ctx;
849 NTSTATUS status;
851 DEBUG(3,("sam_password_policy\n"));
853 ZERO_STRUCT(dom_pol);
855 tmp_ctx = talloc_stackframe();
856 if (tmp_ctx == NULL) {
857 return NT_STATUS_NO_MEMORY;
860 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
861 if (!NT_STATUS_IS_OK(status)) {
862 goto error;
865 status = rpccli_samr_QueryDomainInfo(samr_pipe,
866 mem_ctx,
867 &dom_pol,
869 &info);
870 if (!NT_STATUS_IS_OK(status)) {
871 goto error;
874 *passwd_policy = info->info1;
876 error:
877 if (is_valid_policy_hnd(&dom_pol)) {
878 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
881 TALLOC_FREE(tmp_ctx);
882 return status;
885 /* Lookup groups a user is a member of. */
886 static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
887 TALLOC_CTX *mem_ctx,
888 const struct dom_sid *user_sid,
889 uint32_t *pnum_groups,
890 struct dom_sid **puser_grpsids)
892 struct rpc_pipe_client *samr_pipe;
893 struct policy_handle dom_pol;
894 struct dom_sid *user_grpsids = NULL;
895 uint32_t num_groups = 0;
896 TALLOC_CTX *tmp_ctx;
897 NTSTATUS status;
899 DEBUG(3,("sam_lookup_usergroups\n"));
901 ZERO_STRUCT(dom_pol);
903 if (pnum_groups) {
904 *pnum_groups = 0;
907 tmp_ctx = talloc_stackframe();
908 if (tmp_ctx == NULL) {
909 return NT_STATUS_NO_MEMORY;
912 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
913 if (!NT_STATUS_IS_OK(status)) {
914 goto done;
917 status = rpc_lookup_usergroups(tmp_ctx,
918 samr_pipe,
919 &dom_pol,
920 &domain->sid,
921 user_sid,
922 &num_groups,
923 &user_grpsids);
924 if (!NT_STATUS_IS_OK(status)) {
925 goto done;
928 if (pnum_groups) {
929 *pnum_groups = num_groups;
932 if (puser_grpsids) {
933 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
936 done:
937 if (is_valid_policy_hnd(&dom_pol)) {
938 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
941 TALLOC_FREE(tmp_ctx);
942 return status;
945 static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
946 TALLOC_CTX *mem_ctx,
947 uint32_t num_sids,
948 const struct dom_sid *sids,
949 uint32_t *pnum_aliases,
950 uint32_t **palias_rids)
952 struct rpc_pipe_client *samr_pipe;
953 struct policy_handle dom_pol;
954 uint32_t num_aliases = 0;
955 uint32_t *alias_rids = NULL;
956 TALLOC_CTX *tmp_ctx;
957 NTSTATUS status;
959 DEBUG(3,("sam_lookup_useraliases\n"));
961 ZERO_STRUCT(dom_pol);
963 if (pnum_aliases) {
964 *pnum_aliases = 0;
967 tmp_ctx = talloc_stackframe();
968 if (tmp_ctx == NULL) {
969 return NT_STATUS_NO_MEMORY;
972 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
973 if (!NT_STATUS_IS_OK(status)) {
974 goto done;
977 status = rpc_lookup_useraliases(tmp_ctx,
978 samr_pipe,
979 &dom_pol,
980 num_sids,
981 sids,
982 &num_aliases,
983 &alias_rids);
984 if (!NT_STATUS_IS_OK(status)) {
985 goto done;
988 if (pnum_aliases) {
989 *pnum_aliases = num_aliases;
992 if (palias_rids) {
993 *palias_rids = talloc_move(mem_ctx, &alias_rids);
996 done:
997 if (is_valid_policy_hnd(&dom_pol)) {
998 rpccli_samr_Close(samr_pipe, mem_ctx, &dom_pol);
1001 TALLOC_FREE(tmp_ctx);
1002 return status;
1005 /* find the sequence number for a domain */
1006 static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
1007 uint32_t *pseq)
1009 struct rpc_pipe_client *samr_pipe;
1010 struct policy_handle dom_pol;
1011 uint32_t seq;
1012 TALLOC_CTX *tmp_ctx;
1013 NTSTATUS status;
1015 DEBUG(3,("samr: sequence number\n"));
1017 ZERO_STRUCT(dom_pol);
1019 if (pseq) {
1020 *pseq = DOM_SEQUENCE_NONE;
1023 tmp_ctx = talloc_stackframe();
1024 if (tmp_ctx == NULL) {
1025 return NT_STATUS_NO_MEMORY;
1028 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
1029 if (!NT_STATUS_IS_OK(status)) {
1030 goto done;
1033 status = rpc_sequence_number(tmp_ctx,
1034 samr_pipe,
1035 &dom_pol,
1036 domain->name,
1037 &seq);
1038 if (!NT_STATUS_IS_OK(status)) {
1039 goto done;
1042 if (pseq) {
1043 *pseq = seq;
1045 done:
1046 if (is_valid_policy_hnd(&dom_pol)) {
1047 rpccli_samr_Close(samr_pipe, tmp_ctx, &dom_pol);
1050 TALLOC_FREE(tmp_ctx);
1051 return status;
1054 /* the rpc backend methods are exposed via this structure */
1055 struct winbindd_methods builtin_passdb_methods = {
1056 .consistent = false,
1058 .query_user_list = builtin_query_user_list,
1059 .enum_dom_groups = builtin_enum_dom_groups,
1060 .enum_local_groups = sam_enum_local_groups,
1061 .name_to_sid = sam_name_to_sid,
1062 .sid_to_name = sam_sid_to_name,
1063 .rids_to_names = sam_rids_to_names,
1064 .query_user = builtin_query_user,
1065 .lookup_usergroups = sam_lookup_usergroups,
1066 .lookup_useraliases = sam_lookup_useraliases,
1067 .lookup_groupmem = sam_lookup_groupmem,
1068 .sequence_number = sam_sequence_number,
1069 .lockout_policy = sam_lockout_policy,
1070 .password_policy = sam_password_policy,
1071 .trusted_domains = builtin_trusted_domains
1074 /* the rpc backend methods are exposed via this structure */
1075 struct winbindd_methods sam_passdb_methods = {
1076 .consistent = false,
1078 .query_user_list = sam_query_user_list,
1079 .enum_dom_groups = sam_enum_dom_groups,
1080 .enum_local_groups = sam_enum_local_groups,
1081 .name_to_sid = sam_name_to_sid,
1082 .sid_to_name = sam_sid_to_name,
1083 .rids_to_names = sam_rids_to_names,
1084 .query_user = sam_query_user,
1085 .lookup_usergroups = sam_lookup_usergroups,
1086 .lookup_useraliases = sam_lookup_useraliases,
1087 .lookup_groupmem = sam_lookup_groupmem,
1088 .sequence_number = sam_sequence_number,
1089 .lockout_policy = sam_lockout_policy,
1090 .password_policy = sam_password_policy,
1091 .trusted_domains = sam_trusted_domains