s3-winbind: Rename common_password_policy to sam_password_policy.
[Samba/gebeck_regimport.git] / source3 / winbindd / winbindd_samr.c
blob12298e1829c9f26115f616c5edbc839beacdbdc0
1 /*
2 * Unix SMB/CIFS implementation.
4 * Winbind rpc backend functions
6 * Copyright (c) 2000-2003 Tim Potter
7 * Copyright (c) 2001 Andrew Tridgell
8 * Copyright (c) 2005 Volker Lendecke
9 * Copyright (c) 2008 Guenther Deschner (pidl conversion)
10 * Copyright (c) 2010 Andreas Schneider <asn@samba.org>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "includes.h"
27 #include "winbindd.h"
28 #include "winbindd_rpc.h"
30 #include "../librpc/gen_ndr/cli_samr.h"
31 #include "rpc_client/cli_samr.h"
32 #include "../librpc/gen_ndr/srv_samr.h"
33 #include "../librpc/gen_ndr/cli_lsa.h"
34 #include "rpc_client/cli_lsarpc.h"
35 #include "../librpc/gen_ndr/srv_lsa.h"
37 #undef DBGC_CLASS
38 #define DBGC_CLASS DBGC_WINBIND
40 static NTSTATUS open_internal_samr_pipe(TALLOC_CTX *mem_ctx,
41 struct rpc_pipe_client **samr_pipe)
43 static struct rpc_pipe_client *cli = NULL;
44 struct auth_serversupplied_info *server_info = NULL;
45 NTSTATUS status;
47 if (cli != NULL) {
48 goto done;
51 if (server_info == NULL) {
52 status = make_server_info_system(mem_ctx, &server_info);
53 if (!NT_STATUS_IS_OK(status)) {
54 DEBUG(0, ("open_samr_pipe: Could not create auth_serversupplied_info: %s\n",
55 nt_errstr(status)));
56 return status;
60 /* create a samr connection */
61 status = rpc_pipe_open_internal(talloc_autofree_context(),
62 &ndr_table_samr.syntax_id,
63 rpc_samr_dispatch,
64 server_info,
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 done:
73 if (samr_pipe) {
74 *samr_pipe = cli;
77 return NT_STATUS_OK;
80 static NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
81 struct winbindd_domain *domain,
82 struct rpc_pipe_client **samr_pipe,
83 struct policy_handle *samr_domain_hnd)
85 NTSTATUS status;
86 struct policy_handle samr_connect_hnd;
88 status = open_internal_samr_pipe(mem_ctx, samr_pipe);
89 if (!NT_STATUS_IS_OK(status)) {
90 return status;
93 status = rpccli_samr_Connect2((*samr_pipe),
94 mem_ctx,
95 (*samr_pipe)->desthost,
96 SEC_FLAG_MAXIMUM_ALLOWED,
97 &samr_connect_hnd);
98 if (!NT_STATUS_IS_OK(status)) {
99 return status;
102 status = rpccli_samr_OpenDomain((*samr_pipe),
103 mem_ctx,
104 &samr_connect_hnd,
105 SEC_FLAG_MAXIMUM_ALLOWED,
106 &domain->sid,
107 samr_domain_hnd);
109 return status;
112 static NTSTATUS open_internal_lsa_pipe(TALLOC_CTX *mem_ctx,
113 struct rpc_pipe_client **lsa_pipe)
115 static struct rpc_pipe_client *cli = NULL;
116 struct auth_serversupplied_info *server_info = NULL;
117 NTSTATUS status;
119 if (cli != NULL) {
120 goto done;
123 if (server_info == NULL) {
124 status = make_server_info_system(mem_ctx, &server_info);
125 if (!NT_STATUS_IS_OK(status)) {
126 DEBUG(0, ("open_samr_pipe: Could not create auth_serversupplied_info: %s\n",
127 nt_errstr(status)));
128 return status;
132 /* create a samr connection */
133 status = rpc_pipe_open_internal(talloc_autofree_context(),
134 &ndr_table_lsarpc.syntax_id,
135 rpc_lsarpc_dispatch,
136 server_info,
137 &cli);
138 if (!NT_STATUS_IS_OK(status)) {
139 DEBUG(0, ("open_samr_pipe: Could not connect to samr_pipe: %s\n",
140 nt_errstr(status)));
141 return status;
144 done:
145 if (lsa_pipe) {
146 *lsa_pipe = cli;
149 return NT_STATUS_OK;
152 static NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
153 struct rpc_pipe_client **lsa_pipe,
154 struct policy_handle *lsa_hnd)
156 NTSTATUS status;
158 status = open_internal_lsa_pipe(mem_ctx, lsa_pipe);
159 if (!NT_STATUS_IS_OK(status)) {
160 return status;
163 status = rpccli_lsa_open_policy((*lsa_pipe),
164 mem_ctx,
165 true,
166 SEC_FLAG_MAXIMUM_ALLOWED,
167 lsa_hnd);
169 return status;
172 /*********************************************************************
173 SAM specific functions.
174 *********************************************************************/
176 /* List all domain groups */
177 static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
178 TALLOC_CTX *mem_ctx,
179 uint32_t *pnum_info,
180 struct acct_info **pinfo)
182 struct rpc_pipe_client *samr_pipe;
183 struct policy_handle dom_pol;
184 struct acct_info *info = NULL;
185 uint32_t num_info = 0;
186 TALLOC_CTX *tmp_ctx;
187 NTSTATUS status;
189 DEBUG(3,("sam_enum_dom_groups\n"));
191 if (pnum_info) {
192 *pnum_info = 0;
195 tmp_ctx = talloc_stackframe();
196 if (tmp_ctx == NULL) {
197 return NT_STATUS_NO_MEMORY;
200 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
201 if (!NT_STATUS_IS_OK(status)) {
202 goto error;
205 status = rpc_enum_dom_groups(tmp_ctx,
206 samr_pipe,
207 &dom_pol,
208 &num_info,
209 &info);
210 if (!NT_STATUS_IS_OK(status)) {
211 goto error;
214 if (pnum_info) {
215 *pnum_info = num_info;
218 if (pinfo) {
219 *pinfo = talloc_move(mem_ctx, &info);
222 error:
223 TALLOC_FREE(tmp_ctx);
224 return status;
227 /* Query display info for a domain */
228 static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
229 TALLOC_CTX *mem_ctx,
230 uint32_t *pnum_info,
231 struct wbint_userinfo **pinfo)
233 struct rpc_pipe_client *samr_pipe = NULL;
234 struct policy_handle dom_pol;
235 struct wbint_userinfo *info = NULL;
236 uint32_t num_info = 0;
237 TALLOC_CTX *tmp_ctx;
238 NTSTATUS status;
240 DEBUG(3,("samr_query_user_list\n"));
242 if (pnum_info) {
243 *pnum_info = 0;
246 tmp_ctx = talloc_stackframe();
247 if (tmp_ctx == NULL) {
248 return NT_STATUS_NO_MEMORY;
251 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
252 if (!NT_STATUS_IS_OK(status)) {
253 goto done;
256 status = rpc_query_user_list(tmp_ctx,
257 samr_pipe,
258 &dom_pol,
259 &domain->sid,
260 &num_info,
261 &info);
262 if (!NT_STATUS_IS_OK(status)) {
263 goto done;
266 if (pnum_info) {
267 *pnum_info = num_info;
270 if (pinfo) {
271 *pinfo = talloc_move(mem_ctx, &info);
274 done:
275 TALLOC_FREE(tmp_ctx);
276 return status;
279 /* Lookup user information from a rid or username. */
280 static NTSTATUS sam_query_user(struct winbindd_domain *domain,
281 TALLOC_CTX *mem_ctx,
282 const struct dom_sid *user_sid,
283 struct wbint_userinfo *user_info)
285 struct rpc_pipe_client *samr_pipe;
286 struct policy_handle dom_pol;
287 TALLOC_CTX *tmp_ctx;
288 NTSTATUS status;
290 DEBUG(3,("sam_query_user\n"));
292 /* Paranoia check */
293 if (!sid_check_is_in_our_domain(user_sid)) {
294 return NT_STATUS_NO_SUCH_USER;
297 if (user_info) {
298 user_info->homedir = NULL;
299 user_info->shell = NULL;
300 user_info->primary_gid = (gid_t) -1;
303 tmp_ctx = talloc_stackframe();
304 if (tmp_ctx == NULL) {
305 return NT_STATUS_NO_MEMORY;
308 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
309 if (!NT_STATUS_IS_OK(status)) {
310 goto done;
313 status = rpc_query_user(tmp_ctx,
314 samr_pipe,
315 &dom_pol,
316 &domain->sid,
317 user_sid,
318 user_info);
320 done:
321 TALLOC_FREE(tmp_ctx);
322 return status;
325 /* get a list of trusted domains - builtin domain */
326 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
327 TALLOC_CTX *mem_ctx,
328 struct netr_DomainTrustList *trusts)
330 struct rpc_pipe_client *lsa_pipe;
331 struct netr_DomainTrust *array = NULL;
332 struct policy_handle lsa_policy;
333 uint32_t enum_ctx = 0;
334 uint32_t count = 0;
335 TALLOC_CTX *tmp_ctx;
336 NTSTATUS status;
338 DEBUG(3,("samr: trusted domains\n"));
340 tmp_ctx = talloc_stackframe();
341 if (tmp_ctx == NULL) {
342 return NT_STATUS_NO_MEMORY;
345 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
346 if (!NT_STATUS_IS_OK(status)) {
347 goto error;
350 do {
351 struct lsa_DomainList dom_list;
352 uint32_t start_idx;
353 uint32_t i;
356 * We don't run into deadlocks here, cause winbind_off() is
357 * called in the main function.
359 status = rpccli_lsa_EnumTrustDom(lsa_pipe,
360 tmp_ctx,
361 &lsa_policy,
362 &enum_ctx,
363 &dom_list,
364 (uint32_t) -1);
365 if (!NT_STATUS_IS_OK(status)) {
366 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
367 goto error;
371 start_idx = trusts->count;
372 count += dom_list.count;
374 array = talloc_realloc(tmp_ctx,
375 array,
376 struct netr_DomainTrust,
377 count);
378 if (array == NULL) {
379 status = NT_STATUS_NO_MEMORY;
380 goto error;
383 for (i = 0; i < dom_list.count; i++) {
384 struct netr_DomainTrust *trust = &array[i];
385 struct dom_sid *sid;
387 ZERO_STRUCTP(trust);
389 trust->netbios_name = talloc_move(array,
390 &dom_list.domains[i].name.string);
391 trust->dns_name = NULL;
393 sid = talloc(array, struct dom_sid);
394 if (sid == NULL) {
395 status = NT_STATUS_NO_MEMORY;
396 goto error;
398 sid_copy(sid, dom_list.domains[i].sid);
399 trust->sid = sid;
401 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
403 if (trusts) {
404 trusts->count = count;
405 trusts->array = talloc_move(mem_ctx, &array);
408 error:
409 TALLOC_FREE(tmp_ctx);
410 return status;
413 /* Lookup group membership given a rid. */
414 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
415 TALLOC_CTX *mem_ctx,
416 const struct dom_sid *group_sid,
417 enum lsa_SidType type,
418 uint32_t *pnum_names,
419 struct dom_sid **psid_mem,
420 char ***pnames,
421 uint32_t **pname_types)
423 struct rpc_pipe_client *samr_pipe;
424 struct policy_handle dom_pol;
426 uint32_t num_names = 0;
427 struct dom_sid *sid_mem = NULL;
428 char **names = NULL;
429 uint32_t *name_types = NULL;
431 TALLOC_CTX *tmp_ctx;
432 NTSTATUS status;
434 DEBUG(3,("sam_lookup_groupmem\n"));
436 /* Paranoia check */
437 if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
438 /* There's no groups, only aliases in BUILTIN */
439 return NT_STATUS_NO_SUCH_GROUP;
442 if (pnum_names) {
443 pnum_names = 0;
446 tmp_ctx = talloc_stackframe();
447 if (tmp_ctx == NULL) {
448 return NT_STATUS_NO_MEMORY;
451 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
452 if (!NT_STATUS_IS_OK(status)) {
453 goto done;
456 status = rpc_lookup_groupmem(tmp_ctx,
457 samr_pipe,
458 &dom_pol,
459 domain->name,
460 &domain->sid,
461 group_sid,
462 type,
463 &num_names,
464 &sid_mem,
465 &names,
466 &name_types);
468 if (pnum_names) {
469 *pnum_names = num_names;
472 if (pnames) {
473 *pnames = talloc_move(mem_ctx, &names);
476 if (pname_types) {
477 *pname_types = talloc_move(mem_ctx, &name_types);
480 if (psid_mem) {
481 *psid_mem = talloc_move(mem_ctx, &sid_mem);
484 done:
485 TALLOC_FREE(tmp_ctx);
486 return status;
489 /*********************************************************************
490 BUILTIN specific functions.
491 *********************************************************************/
493 /* List all domain groups */
494 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
495 TALLOC_CTX *mem_ctx,
496 uint32 *num_entries,
497 struct acct_info **info)
499 /* BUILTIN doesn't have domain groups */
500 *num_entries = 0;
501 *info = NULL;
502 return NT_STATUS_OK;
505 /* Query display info for a domain */
506 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
507 TALLOC_CTX *mem_ctx,
508 uint32 *num_entries,
509 struct wbint_userinfo **info)
511 /* We don't have users */
512 *num_entries = 0;
513 *info = NULL;
514 return NT_STATUS_OK;
517 /* Lookup user information from a rid or username. */
518 static NTSTATUS builtin_query_user(struct winbindd_domain *domain,
519 TALLOC_CTX *mem_ctx,
520 const struct dom_sid *user_sid,
521 struct wbint_userinfo *user_info)
523 return NT_STATUS_NO_SUCH_USER;
526 /* get a list of trusted domains - builtin domain */
527 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
528 TALLOC_CTX *mem_ctx,
529 struct netr_DomainTrustList *trusts)
531 ZERO_STRUCTP(trusts);
532 return NT_STATUS_OK;
535 /*********************************************************************
536 COMMON functions.
537 *********************************************************************/
539 /* List all local groups (aliases) */
540 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
541 TALLOC_CTX *mem_ctx,
542 uint32_t *pnum_info,
543 struct acct_info **pinfo)
545 struct rpc_pipe_client *samr_pipe;
546 struct policy_handle dom_pol;
547 struct acct_info *info = NULL;
548 uint32_t num_info = 0;
549 TALLOC_CTX *tmp_ctx;
550 NTSTATUS status;
552 DEBUG(3,("samr: enum local groups\n"));
554 if (pnum_info) {
555 *pnum_info = 0;
558 tmp_ctx = talloc_stackframe();
559 if (tmp_ctx == NULL) {
560 return NT_STATUS_NO_MEMORY;
563 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
564 if (!NT_STATUS_IS_OK(status)) {
565 goto done;
568 status = rpc_enum_local_groups(mem_ctx,
569 samr_pipe,
570 &dom_pol,
571 &num_info,
572 &info);
573 if (!NT_STATUS_IS_OK(status)) {
574 goto done;
577 if (pnum_info) {
578 *pnum_info = num_info;
581 if (pinfo) {
582 *pinfo = talloc_move(mem_ctx, &info);
585 done:
586 TALLOC_FREE(tmp_ctx);
587 return status;
590 /* convert a single name to a sid in a domain */
591 static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
592 TALLOC_CTX *mem_ctx,
593 const char *domain_name,
594 const char *name,
595 uint32_t flags,
596 struct dom_sid *psid,
597 enum lsa_SidType *ptype)
599 struct rpc_pipe_client *lsa_pipe;
600 struct policy_handle lsa_policy;
601 struct dom_sid sid;
602 enum lsa_SidType type;
603 TALLOC_CTX *tmp_ctx;
604 NTSTATUS status;
606 DEBUG(3,("sam_name_to_sid\n"));
608 tmp_ctx = talloc_stackframe();
609 if (tmp_ctx == NULL) {
610 return NT_STATUS_NO_MEMORY;
613 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
614 if (!NT_STATUS_IS_OK(status)) {
615 goto done;
618 status = rpc_name_to_sid(tmp_ctx,
619 lsa_pipe,
620 &lsa_policy,
621 domain_name,
622 name,
623 flags,
624 &sid,
625 &type);
626 if (!NT_STATUS_IS_OK(status)) {
627 goto done;
630 if (psid) {
631 sid_copy(psid, &sid);
633 if (ptype) {
634 *ptype = type;
637 done:
638 TALLOC_FREE(tmp_ctx);
639 return status;
642 /* convert a domain SID to a user or group name */
643 static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
644 TALLOC_CTX *mem_ctx,
645 const struct dom_sid *sid,
646 char **pdomain_name,
647 char **pname,
648 enum lsa_SidType *ptype)
650 struct rpc_pipe_client *lsa_pipe;
651 struct policy_handle lsa_policy;
652 char *domain_name = NULL;
653 char *name = NULL;
654 enum lsa_SidType type;
655 TALLOC_CTX *tmp_ctx;
656 NTSTATUS status;
658 DEBUG(3,("sam_sid_to_name\n"));
660 /* Paranoia check */
661 if (!sid_check_is_in_builtin(sid) &&
662 !sid_check_is_in_our_domain(sid) &&
663 !sid_check_is_in_unix_users(sid) &&
664 !sid_check_is_unix_users(sid) &&
665 !sid_check_is_in_unix_groups(sid) &&
666 !sid_check_is_unix_groups(sid) &&
667 !sid_check_is_in_wellknown_domain(sid)) {
668 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
669 "lookup SID %s\n", sid_string_dbg(sid)));
670 return NT_STATUS_NONE_MAPPED;
673 tmp_ctx = talloc_stackframe();
674 if (tmp_ctx == NULL) {
675 return NT_STATUS_NO_MEMORY;
678 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
679 if (!NT_STATUS_IS_OK(status)) {
680 goto done;
683 status = rpc_sid_to_name(tmp_ctx,
684 lsa_pipe,
685 &lsa_policy,
686 domain,
687 sid,
688 &domain_name,
689 &name,
690 &type);
692 if (ptype) {
693 *ptype = type;
696 if (pname) {
697 *pname = talloc_move(mem_ctx, &name);
700 if (pdomain_name) {
701 *pdomain_name = talloc_move(mem_ctx, &domain_name);
704 done:
705 TALLOC_FREE(tmp_ctx);
706 return status;
709 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
710 TALLOC_CTX *mem_ctx,
711 const struct dom_sid *sid,
712 uint32 *rids,
713 size_t num_rids,
714 char **pdomain_name,
715 char ***pnames,
716 enum lsa_SidType **ptypes)
718 struct rpc_pipe_client *lsa_pipe;
719 struct policy_handle lsa_policy;
720 enum lsa_SidType *types = NULL;
721 char *domain_name = NULL;
722 char **names = NULL;
723 TALLOC_CTX *tmp_ctx;
724 NTSTATUS status;
726 DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
728 /* Paranoia check */
729 if (!sid_check_is_in_builtin(sid) &&
730 !sid_check_is_in_our_domain(sid) &&
731 !sid_check_is_in_unix_users(sid) &&
732 !sid_check_is_unix_users(sid) &&
733 !sid_check_is_in_unix_groups(sid) &&
734 !sid_check_is_unix_groups(sid) &&
735 !sid_check_is_in_wellknown_domain(sid)) {
736 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
737 "lookup SID %s\n", sid_string_dbg(sid)));
738 return NT_STATUS_NONE_MAPPED;
741 tmp_ctx = talloc_stackframe();
742 if (tmp_ctx == NULL) {
743 return NT_STATUS_NO_MEMORY;
746 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
747 if (!NT_STATUS_IS_OK(status)) {
748 goto done;
751 status = rpc_rids_to_names(tmp_ctx,
752 lsa_pipe,
753 &lsa_policy,
754 domain,
755 sid,
756 rids,
757 num_rids,
758 &domain_name,
759 &names,
760 &types);
761 if (!NT_STATUS_IS_OK(status)) {
762 goto done;
765 if (pdomain_name) {
766 *pdomain_name = talloc_move(mem_ctx, &domain_name);
769 if (ptypes) {
770 *ptypes = talloc_move(mem_ctx, &types);
773 if (pnames) {
774 *pnames = talloc_move(mem_ctx, &names);
777 done:
778 TALLOC_FREE(tmp_ctx);
779 return status;
782 static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
783 TALLOC_CTX *mem_ctx,
784 struct samr_DomInfo12 *lockout_policy)
786 struct rpc_pipe_client *samr_pipe;
787 struct policy_handle dom_pol;
788 union samr_DomainInfo *info = NULL;
789 TALLOC_CTX *tmp_ctx;
790 NTSTATUS status;
792 DEBUG(3,("sam_lockout_policy\n"));
794 tmp_ctx = talloc_stackframe();
795 if (tmp_ctx == NULL) {
796 return NT_STATUS_NO_MEMORY;
799 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
800 if (!NT_STATUS_IS_OK(status)) {
801 goto error;
804 status = rpccli_samr_QueryDomainInfo(samr_pipe,
805 mem_ctx,
806 &dom_pol,
808 &info);
809 if (!NT_STATUS_IS_OK(status)) {
810 goto error;
813 *lockout_policy = info->info12;
815 error:
816 TALLOC_FREE(tmp_ctx);
817 return status;
820 static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
821 TALLOC_CTX *mem_ctx,
822 struct samr_DomInfo1 *passwd_policy)
824 struct rpc_pipe_client *samr_pipe;
825 struct policy_handle dom_pol;
826 union samr_DomainInfo *info = NULL;
827 TALLOC_CTX *tmp_ctx;
828 NTSTATUS status;
830 DEBUG(3,("sam_password_policy\n"));
832 tmp_ctx = talloc_stackframe();
833 if (tmp_ctx == NULL) {
834 return NT_STATUS_NO_MEMORY;
837 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
838 if (!NT_STATUS_IS_OK(status)) {
839 goto error;
842 status = rpccli_samr_QueryDomainInfo(samr_pipe,
843 mem_ctx,
844 &dom_pol,
846 &info);
847 if (!NT_STATUS_IS_OK(status)) {
848 goto error;
851 *passwd_policy = info->info1;
853 error:
854 TALLOC_FREE(tmp_ctx);
855 return status;
858 /* Lookup groups a user is a member of. */
859 static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
860 TALLOC_CTX *mem_ctx,
861 const struct dom_sid *user_sid,
862 uint32_t *pnum_groups,
863 struct dom_sid **puser_grpsids)
865 struct rpc_pipe_client *samr_pipe;
866 struct policy_handle dom_pol;
867 struct dom_sid *user_grpsids = NULL;
868 uint32_t num_groups = 0;
869 TALLOC_CTX *tmp_ctx;
870 NTSTATUS status;
872 DEBUG(3,("sam_lookup_usergroups\n"));
874 if (pnum_groups) {
875 *pnum_groups = 0;
878 tmp_ctx = talloc_stackframe();
879 if (tmp_ctx == NULL) {
880 return NT_STATUS_NO_MEMORY;
883 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
884 if (!NT_STATUS_IS_OK(status)) {
885 goto done;
888 status = rpc_lookup_usergroups(tmp_ctx,
889 samr_pipe,
890 &dom_pol,
891 &domain->sid,
892 user_sid,
893 &num_groups,
894 &user_grpsids);
895 if (!NT_STATUS_IS_OK(status)) {
896 goto done;
899 if (pnum_groups) {
900 *pnum_groups = num_groups;
903 if (puser_grpsids) {
904 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
907 done:
908 TALLOC_FREE(tmp_ctx);
909 return status;
912 static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
913 TALLOC_CTX *mem_ctx,
914 uint32_t num_sids,
915 const struct dom_sid *sids,
916 uint32_t *pnum_aliases,
917 uint32_t **palias_rids)
919 struct rpc_pipe_client *samr_pipe;
920 struct policy_handle dom_pol;
921 uint32_t num_aliases = 0;
922 uint32_t *alias_rids = NULL;
923 TALLOC_CTX *tmp_ctx;
924 NTSTATUS status;
926 DEBUG(3,("sam_lookup_useraliases\n"));
928 if (pnum_aliases) {
929 *pnum_aliases = 0;
932 tmp_ctx = talloc_stackframe();
933 if (tmp_ctx == NULL) {
934 return NT_STATUS_NO_MEMORY;
937 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
938 if (!NT_STATUS_IS_OK(status)) {
939 goto done;
942 status = rpc_lookup_useraliases(tmp_ctx,
943 samr_pipe,
944 &dom_pol,
945 num_sids,
946 sids,
947 &num_aliases,
948 &alias_rids);
949 if (!NT_STATUS_IS_OK(status)) {
950 goto done;
953 if (pnum_aliases) {
954 *pnum_aliases = num_aliases;
957 if (palias_rids) {
958 *palias_rids = talloc_move(mem_ctx, &alias_rids);
961 done:
962 TALLOC_FREE(tmp_ctx);
963 return status;
966 /* find the sequence number for a domain */
967 static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
968 uint32_t *pseq)
970 struct rpc_pipe_client *samr_pipe;
971 struct policy_handle dom_pol;
972 uint32_t seq;
973 TALLOC_CTX *tmp_ctx;
974 NTSTATUS status;
976 DEBUG(3,("samr: sequence number\n"));
978 if (pseq) {
979 *pseq = DOM_SEQUENCE_NONE;
982 tmp_ctx = talloc_stackframe();
983 if (tmp_ctx == NULL) {
984 return NT_STATUS_NO_MEMORY;
987 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
988 if (!NT_STATUS_IS_OK(status)) {
989 goto done;
992 status = rpc_sequence_number(tmp_ctx,
993 samr_pipe,
994 &dom_pol,
995 domain->name,
996 &seq);
997 if (!NT_STATUS_IS_OK(status)) {
998 goto done;
1001 if (pseq) {
1002 *pseq = seq;
1004 done:
1005 TALLOC_FREE(tmp_ctx);
1006 return status;
1009 /* the rpc backend methods are exposed via this structure */
1010 struct winbindd_methods builtin_passdb_methods = {
1011 .consistent = false,
1013 .query_user_list = builtin_query_user_list,
1014 .enum_dom_groups = builtin_enum_dom_groups,
1015 .enum_local_groups = sam_enum_local_groups,
1016 .name_to_sid = sam_name_to_sid,
1017 .sid_to_name = sam_sid_to_name,
1018 .rids_to_names = sam_rids_to_names,
1019 .query_user = builtin_query_user,
1020 .lookup_usergroups = sam_lookup_usergroups,
1021 .lookup_useraliases = sam_lookup_useraliases,
1022 .lookup_groupmem = sam_lookup_groupmem,
1023 .sequence_number = sam_sequence_number,
1024 .lockout_policy = sam_lockout_policy,
1025 .password_policy = sam_password_policy,
1026 .trusted_domains = builtin_trusted_domains
1029 /* the rpc backend methods are exposed via this structure */
1030 struct winbindd_methods sam_passdb_methods = {
1031 .consistent = false,
1033 .query_user_list = sam_query_user_list,
1034 .enum_dom_groups = sam_enum_dom_groups,
1035 .enum_local_groups = sam_enum_local_groups,
1036 .name_to_sid = sam_name_to_sid,
1037 .sid_to_name = sam_sid_to_name,
1038 .rids_to_names = sam_rids_to_names,
1039 .query_user = sam_query_user,
1040 .lookup_usergroups = sam_lookup_usergroups,
1041 .lookup_useraliases = sam_lookup_useraliases,
1042 .lookup_groupmem = sam_lookup_groupmem,
1043 .sequence_number = sam_sequence_number,
1044 .lockout_policy = sam_lockout_policy,
1045 .password_policy = sam_password_policy,
1046 .trusted_domains = sam_trusted_domains