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/>.
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"
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;
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",
60 /* create a samr connection */
61 status = rpc_pipe_open_internal(talloc_autofree_context(),
62 &ndr_table_samr.syntax_id,
66 if (!NT_STATUS_IS_OK(status)) {
67 DEBUG(0, ("open_samr_pipe: Could not connect to samr_pipe: %s\n",
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)
86 struct policy_handle samr_connect_hnd;
88 status = open_internal_samr_pipe(mem_ctx, samr_pipe);
89 if (!NT_STATUS_IS_OK(status)) {
93 status = rpccli_samr_Connect2((*samr_pipe),
95 (*samr_pipe)->desthost,
96 SEC_FLAG_MAXIMUM_ALLOWED,
98 if (!NT_STATUS_IS_OK(status)) {
102 status = rpccli_samr_OpenDomain((*samr_pipe),
105 SEC_FLAG_MAXIMUM_ALLOWED,
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;
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",
132 /* create a samr connection */
133 status = rpc_pipe_open_internal(talloc_autofree_context(),
134 &ndr_table_lsarpc.syntax_id,
138 if (!NT_STATUS_IS_OK(status)) {
139 DEBUG(0, ("open_samr_pipe: Could not connect to samr_pipe: %s\n",
152 static NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
153 struct rpc_pipe_client **lsa_pipe,
154 struct policy_handle *lsa_hnd)
158 status = open_internal_lsa_pipe(mem_ctx, lsa_pipe);
159 if (!NT_STATUS_IS_OK(status)) {
163 status = rpccli_lsa_open_policy((*lsa_pipe),
166 SEC_FLAG_MAXIMUM_ALLOWED,
172 /*********************************************************************
173 SAM specific functions.
174 *********************************************************************/
176 /* List all domain groups */
177 static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
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;
189 DEBUG(3,("sam_enum_dom_groups\n"));
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)) {
205 status = rpc_enum_dom_groups(tmp_ctx,
210 if (!NT_STATUS_IS_OK(status)) {
215 *pnum_info = num_info;
219 *pinfo = talloc_move(mem_ctx, &info);
223 TALLOC_FREE(tmp_ctx);
227 /* Query display info for a domain */
228 static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
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;
240 DEBUG(3,("samr_query_user_list\n"));
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)) {
256 status = rpc_query_user_list(tmp_ctx,
262 if (!NT_STATUS_IS_OK(status)) {
267 *pnum_info = num_info;
271 *pinfo = talloc_move(mem_ctx, &info);
275 TALLOC_FREE(tmp_ctx);
279 /* Lookup user information from a rid or username. */
280 static NTSTATUS sam_query_user(struct winbindd_domain *domain,
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, user_pol;
287 union samr_UserInfo *info = NULL;
292 DEBUG(3,("samr: query_user\n"));
294 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) {
295 return NT_STATUS_UNSUCCESSFUL;
299 user_info->homedir = NULL;
300 user_info->shell = NULL;
301 user_info->primary_gid = (gid_t) -1;
304 tmp_ctx = talloc_stackframe();
305 if (tmp_ctx == NULL) {
306 return NT_STATUS_NO_MEMORY;
309 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
310 if (!NT_STATUS_IS_OK(status)) {
314 /* Get user handle */
315 status = rpccli_samr_OpenUser(samr_pipe,
318 SEC_FLAG_MAXIMUM_ALLOWED,
321 if (!NT_STATUS_IS_OK(status)) {
326 status = rpccli_samr_QueryUserInfo(samr_pipe,
332 rpccli_samr_Close(samr_pipe, tmp_ctx, &user_pol);
334 if (!NT_STATUS_IS_OK(status)) {
338 sid_compose(&user_info->user_sid, &domain->sid, user_rid);
339 sid_compose(&user_info->group_sid, &domain->sid,
340 info->info21.primary_gid);
343 user_info->acct_name = talloc_strdup(mem_ctx,
344 info->info21.account_name.string);
345 if (user_info->acct_name == NULL) {
346 status = NT_STATUS_NO_MEMORY;
350 user_info->full_name = talloc_strdup(mem_ctx,
351 info->info21.full_name.string);
352 if (user_info->acct_name == NULL) {
353 status = NT_STATUS_NO_MEMORY;
357 user_info->homedir = NULL;
358 user_info->shell = NULL;
359 user_info->primary_gid = (gid_t)-1;
362 status = NT_STATUS_OK;
364 TALLOC_FREE(tmp_ctx);
368 /* get a list of trusted domains - builtin domain */
369 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
371 struct netr_DomainTrustList *trusts)
373 struct rpc_pipe_client *lsa_pipe;
374 struct netr_DomainTrust *array = NULL;
375 struct policy_handle lsa_policy;
376 uint32_t enum_ctx = 0;
381 DEBUG(3,("samr: trusted domains\n"));
383 tmp_ctx = talloc_stackframe();
384 if (tmp_ctx == NULL) {
385 return NT_STATUS_NO_MEMORY;
388 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
389 if (!NT_STATUS_IS_OK(status)) {
394 struct lsa_DomainList dom_list;
399 * We don't run into deadlocks here, cause winbind_off() is
400 * called in the main function.
402 status = rpccli_lsa_EnumTrustDom(lsa_pipe,
408 if (!NT_STATUS_IS_OK(status)) {
409 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
414 start_idx = trusts->count;
415 count += dom_list.count;
417 array = talloc_realloc(tmp_ctx,
419 struct netr_DomainTrust,
422 status = NT_STATUS_NO_MEMORY;
426 for (i = 0; i < dom_list.count; i++) {
427 struct netr_DomainTrust *trust = &array[i];
432 trust->netbios_name = talloc_move(array,
433 &dom_list.domains[i].name.string);
434 trust->dns_name = NULL;
436 sid = talloc(array, struct dom_sid);
438 status = NT_STATUS_NO_MEMORY;
441 sid_copy(sid, dom_list.domains[i].sid);
444 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
447 trusts->count = count;
448 trusts->array = talloc_move(mem_ctx, &array);
452 TALLOC_FREE(tmp_ctx);
456 /* Lookup group membership given a rid. */
457 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
459 const struct dom_sid *group_sid,
460 enum lsa_SidType type,
461 uint32_t *pnum_names,
462 struct dom_sid **psid_mem,
464 uint32_t **pname_types)
466 struct rpc_pipe_client *samr_pipe;
467 struct policy_handle dom_pol, group_pol;
468 uint32_t samr_access = SEC_FLAG_MAXIMUM_ALLOWED;
469 struct samr_RidTypeArray *rids = NULL;
471 uint32_t *rid_mem = NULL;
473 uint32_t num_names = 0;
474 uint32_t total_names = 0;
475 struct dom_sid *sid_mem = NULL;
477 uint32_t *name_types = NULL;
479 struct lsa_Strings tmp_names;
480 struct samr_Ids tmp_types;
486 DEBUG(3,("samr: lookup groupmem\n"));
492 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid)) {
493 return NT_STATUS_UNSUCCESSFUL;
496 tmp_ctx = talloc_stackframe();
497 if (tmp_ctx == NULL) {
498 return NT_STATUS_NO_MEMORY;
501 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
502 if (!NT_STATUS_IS_OK(status)) {
506 status = rpccli_samr_OpenGroup(samr_pipe,
512 if (!NT_STATUS_IS_OK(status)) {
517 * Step #1: Get a list of user rids that are the members of the group.
519 status = rpccli_samr_QueryGroupMember(samr_pipe,
524 rpccli_samr_Close(samr_pipe, tmp_ctx, &group_pol);
526 if (!NT_STATUS_IS_OK(status)) {
530 if (rids == NULL || rids->count == 0) {
536 status = NT_STATUS_OK;
540 num_names = rids->count;
541 rid_mem = rids->rids;
544 * Step #2: Convert list of rids into list of usernames.
546 #define MAX_LOOKUP_RIDS 900
549 names = TALLOC_ZERO_ARRAY(tmp_ctx, char *, num_names);
550 name_types = TALLOC_ZERO_ARRAY(tmp_ctx, uint32_t, num_names);
551 sid_mem = TALLOC_ZERO_ARRAY(tmp_ctx, struct dom_sid, num_names);
552 if (names == NULL || name_types == NULL || sid_mem == NULL) {
553 status = NT_STATUS_NO_MEMORY;
558 for (j = 0; j < num_names; j++) {
559 sid_compose(&sid_mem[j], &domain->sid, rid_mem[j]);
562 status = rpccli_samr_LookupRids(samr_pipe,
569 if (!NT_STATUS_IS_OK(status)) {
570 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
575 /* Copy result into array. The talloc system will take
576 care of freeing the temporary arrays later on. */
577 if (tmp_names.count != tmp_types.count) {
578 status = NT_STATUS_UNSUCCESSFUL;
582 for (r = 0; r < tmp_names.count; r++) {
583 if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
586 names[total_names] = fill_domain_username_talloc(names,
588 tmp_names.names[r].string,
590 name_types[total_names] = tmp_types.ids[r];
595 *pnum_names = total_names;
599 *pnames = talloc_move(mem_ctx, &names);
603 *pname_types = talloc_move(mem_ctx, &name_types);
607 *psid_mem = talloc_move(mem_ctx, &sid_mem);
611 TALLOC_FREE(tmp_ctx);
615 /*********************************************************************
616 BUILTIN specific functions.
617 *********************************************************************/
619 /* List all domain groups */
620 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
623 struct acct_info **info)
625 /* BUILTIN doesn't have domain groups */
631 /* Query display info for a domain */
632 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
635 struct wbint_userinfo **info)
637 /* We don't have users */
643 /* Lookup user information from a rid or username. */
644 static NTSTATUS builtin_query_user(struct winbindd_domain *domain,
646 const struct dom_sid *user_sid,
647 struct wbint_userinfo *user_info)
649 return NT_STATUS_NO_SUCH_USER;
652 /* get a list of trusted domains - builtin domain */
653 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
655 struct netr_DomainTrustList *trusts)
657 ZERO_STRUCTP(trusts);
661 /*********************************************************************
663 *********************************************************************/
665 /* List all local groups (aliases) */
666 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
669 struct acct_info **pinfo)
671 struct rpc_pipe_client *samr_pipe;
672 struct policy_handle dom_pol;
673 struct acct_info *info = NULL;
674 uint32_t num_info = 0;
678 DEBUG(3,("samr: enum local groups\n"));
684 tmp_ctx = talloc_stackframe();
685 if (tmp_ctx == NULL) {
686 return NT_STATUS_NO_MEMORY;
689 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
690 if (!NT_STATUS_IS_OK(status)) {
694 status = rpc_enum_local_groups(mem_ctx,
699 if (!NT_STATUS_IS_OK(status)) {
704 *pnum_info = num_info;
708 *pinfo = talloc_move(mem_ctx, &info);
712 TALLOC_FREE(tmp_ctx);
716 /* convert a single name to a sid in a domain */
717 static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
719 const char *domain_name,
722 struct dom_sid *psid,
723 enum lsa_SidType *ptype)
725 struct rpc_pipe_client *lsa_pipe;
726 struct policy_handle lsa_policy;
728 enum lsa_SidType type;
732 DEBUG(3,("sam_name_to_sid\n"));
734 tmp_ctx = talloc_stackframe();
735 if (tmp_ctx == NULL) {
736 return NT_STATUS_NO_MEMORY;
739 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
740 if (!NT_STATUS_IS_OK(status)) {
744 status = rpc_name_to_sid(tmp_ctx,
752 if (!NT_STATUS_IS_OK(status)) {
757 sid_copy(psid, &sid);
764 TALLOC_FREE(tmp_ctx);
768 /* convert a domain SID to a user or group name */
769 static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
771 const struct dom_sid *sid,
774 enum lsa_SidType *ptype)
776 struct rpc_pipe_client *lsa_pipe;
777 struct policy_handle lsa_policy;
778 char *domain_name = NULL;
780 enum lsa_SidType type;
784 DEBUG(3,("sam_sid_to_name\n"));
787 if (!sid_check_is_in_builtin(sid) &&
788 !sid_check_is_in_our_domain(sid) &&
789 !sid_check_is_in_unix_users(sid) &&
790 !sid_check_is_unix_users(sid) &&
791 !sid_check_is_in_unix_groups(sid) &&
792 !sid_check_is_unix_groups(sid) &&
793 !sid_check_is_in_wellknown_domain(sid)) {
794 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
795 "lookup SID %s\n", sid_string_dbg(sid)));
796 return NT_STATUS_NONE_MAPPED;
799 tmp_ctx = talloc_stackframe();
800 if (tmp_ctx == NULL) {
801 return NT_STATUS_NO_MEMORY;
804 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
805 if (!NT_STATUS_IS_OK(status)) {
809 status = rpc_sid_to_name(tmp_ctx,
823 *pname = talloc_move(mem_ctx, &name);
827 *pdomain_name = talloc_move(mem_ctx, &domain_name);
831 TALLOC_FREE(tmp_ctx);
835 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
837 const struct dom_sid *sid,
842 enum lsa_SidType **ptypes)
844 struct rpc_pipe_client *lsa_pipe;
845 struct policy_handle lsa_policy;
846 enum lsa_SidType *types = NULL;
847 char *domain_name = NULL;
852 DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
855 if (!sid_check_is_in_builtin(sid) &&
856 !sid_check_is_in_our_domain(sid) &&
857 !sid_check_is_in_unix_users(sid) &&
858 !sid_check_is_unix_users(sid) &&
859 !sid_check_is_in_unix_groups(sid) &&
860 !sid_check_is_unix_groups(sid) &&
861 !sid_check_is_in_wellknown_domain(sid)) {
862 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
863 "lookup SID %s\n", sid_string_dbg(sid)));
864 return NT_STATUS_NONE_MAPPED;
867 tmp_ctx = talloc_stackframe();
868 if (tmp_ctx == NULL) {
869 return NT_STATUS_NO_MEMORY;
872 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
873 if (!NT_STATUS_IS_OK(status)) {
877 status = rpc_rids_to_names(tmp_ctx,
887 if (!NT_STATUS_IS_OK(status)) {
892 *pdomain_name = talloc_move(mem_ctx, &domain_name);
896 *ptypes = talloc_move(mem_ctx, &types);
900 *pnames = talloc_move(mem_ctx, &names);
904 TALLOC_FREE(tmp_ctx);
908 static NTSTATUS common_lockout_policy(struct winbindd_domain *domain,
910 struct samr_DomInfo12 *lockout_policy)
912 struct rpc_pipe_client *samr_pipe;
913 struct policy_handle dom_pol;
914 union samr_DomainInfo *info = NULL;
918 DEBUG(3,("samr: lockout policy\n"));
920 tmp_ctx = talloc_stackframe();
921 if (tmp_ctx == NULL) {
922 return NT_STATUS_NO_MEMORY;
925 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
926 if (!NT_STATUS_IS_OK(status)) {
930 status = rpccli_samr_QueryDomainInfo(samr_pipe,
935 if (!NT_STATUS_IS_OK(status)) {
939 *lockout_policy = info->info12;
942 TALLOC_FREE(tmp_ctx);
946 static NTSTATUS common_password_policy(struct winbindd_domain *domain,
948 struct samr_DomInfo1 *passwd_policy)
950 struct rpc_pipe_client *samr_pipe;
951 struct policy_handle dom_pol;
952 union samr_DomainInfo *info = NULL;
956 DEBUG(3,("samr: password policy\n"));
958 tmp_ctx = talloc_stackframe();
959 if (tmp_ctx == NULL) {
960 return NT_STATUS_NO_MEMORY;
963 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
964 if (!NT_STATUS_IS_OK(status)) {
968 status = rpccli_samr_QueryDomainInfo(samr_pipe,
973 if (!NT_STATUS_IS_OK(status)) {
977 *passwd_policy = info->info1;
980 TALLOC_FREE(tmp_ctx);
984 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
985 static NTSTATUS common_lookup_usergroups(struct winbindd_domain *domain,
987 const struct dom_sid *user_sid,
988 uint32_t *pnum_groups,
989 struct dom_sid **puser_grpsids)
991 struct rpc_pipe_client *samr_pipe;
992 struct policy_handle dom_pol, usr_pol;
993 uint32_t samr_access = SEC_FLAG_MAXIMUM_ALLOWED;
994 struct samr_RidWithAttributeArray *rid_array = NULL;
995 struct dom_sid *user_grpsids = NULL;
996 uint32_t num_groups = 0, i;
1001 DEBUG(3,("samr: lookup usergroups\n"));
1003 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) {
1004 return NT_STATUS_UNSUCCESSFUL;
1011 if (puser_grpsids) {
1012 *puser_grpsids = NULL;
1015 tmp_ctx = talloc_stackframe();
1016 if (tmp_ctx == NULL) {
1017 return NT_STATUS_NO_MEMORY;
1020 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
1021 if (!NT_STATUS_IS_OK(status)) {
1025 /* Get user handle */
1026 status = rpccli_samr_OpenUser(samr_pipe,
1032 if (!NT_STATUS_IS_OK(status)) {
1036 /* Query user rids */
1037 status = rpccli_samr_GetGroupsForUser(samr_pipe,
1041 num_groups = rid_array->count;
1043 rpccli_samr_Close(samr_pipe, tmp_ctx, &usr_pol);
1045 if (!NT_STATUS_IS_OK(status) || num_groups == 0) {
1049 user_grpsids = TALLOC_ARRAY(tmp_ctx, struct dom_sid, num_groups);
1050 if (user_grpsids == NULL) {
1051 status = NT_STATUS_NO_MEMORY;
1055 for (i = 0; i < num_groups; i++) {
1056 sid_compose(&(user_grpsids[i]), &domain->sid,
1057 rid_array->rids[i].rid);
1061 *pnum_groups = num_groups;
1064 if (puser_grpsids) {
1065 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
1069 TALLOC_FREE(tmp_ctx);
1073 static NTSTATUS common_lookup_useraliases(struct winbindd_domain *domain,
1074 TALLOC_CTX *mem_ctx,
1076 const struct dom_sid *sids,
1077 uint32_t *pnum_aliases,
1078 uint32_t **palias_rids)
1080 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
1081 struct rpc_pipe_client *samr_pipe;
1082 struct policy_handle dom_pol;
1083 uint32_t num_query_sids = 0;
1084 uint32_t num_queries = 1;
1085 uint32_t num_aliases = 0;
1086 uint32_t total_sids = 0;
1087 uint32_t rangesize = MAX_SAM_ENTRIES_W2K;
1089 struct samr_Ids alias_rids_query;
1090 TALLOC_CTX *tmp_ctx;
1093 DEBUG(3,("samr: lookup useraliases\n"));
1100 *palias_rids = NULL;
1103 tmp_ctx = talloc_stackframe();
1104 if (tmp_ctx == NULL) {
1105 return NT_STATUS_NO_MEMORY;
1108 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
1109 if (!NT_STATUS_IS_OK(status)) {
1115 struct lsa_SidArray sid_array;
1117 ZERO_STRUCT(sid_array);
1119 num_query_sids = MIN(num_sids - total_sids, rangesize);
1121 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
1122 num_queries, num_query_sids));
1124 if (num_query_sids) {
1125 sid_array.sids = TALLOC_ZERO_ARRAY(tmp_ctx, struct lsa_SidPtr, num_query_sids);
1126 if (sid_array.sids == NULL) {
1127 status = NT_STATUS_NO_MEMORY;
1131 sid_array.sids = NULL;
1134 for (i = 0; i < num_query_sids; i++) {
1135 sid_array.sids[i].sid = sid_dup_talloc(tmp_ctx, &sids[total_sids++]);
1136 if (sid_array.sids[i].sid == NULL) {
1137 status = NT_STATUS_NO_MEMORY;
1141 sid_array.num_sids = num_query_sids;
1144 status = rpccli_samr_GetAliasMembership(samr_pipe,
1149 if (!NT_STATUS_IS_OK(status)) {
1154 /* process output */
1155 for (i = 0; i < alias_rids_query.count; i++) {
1156 size_t na = num_aliases;
1158 if (!add_rid_to_array_unique(mem_ctx,
1159 alias_rids_query.ids[i],
1162 status = NT_STATUS_NO_MEMORY;
1171 } while (total_sids < num_sids);
1174 *pnum_aliases = num_aliases;
1178 TALLOC_FREE(tmp_ctx);
1180 #undef MAX_SAM_ENTRIES_W2K
1183 /* find the sequence number for a domain */
1184 static NTSTATUS common_sequence_number(struct winbindd_domain *domain,
1187 struct rpc_pipe_client *samr_pipe;
1188 struct policy_handle dom_pol;
1189 union samr_DomainInfo *info = NULL;
1190 bool got_seq_num = false;
1191 TALLOC_CTX *mem_ctx;
1194 DEBUG(3,("samr: sequence number\n"));
1196 mem_ctx = talloc_init("common_sequence_number");
1197 if (mem_ctx == NULL) {
1198 return NT_STATUS_NO_MEMORY;
1202 *seq = DOM_SEQUENCE_NONE;
1205 status = open_internal_samr_conn(mem_ctx, domain, &samr_pipe, &dom_pol);
1206 if (!NT_STATUS_IS_OK(status)) {
1210 /* query domain info */
1211 status = rpccli_samr_QueryDomainInfo(samr_pipe,
1216 if (NT_STATUS_IS_OK(status)) {
1218 *seq = info->info8.sequence_num;
1224 /* retry with info-level 2 in case the dc does not support info-level 8
1225 * (like all older samba2 and samba3 dc's) - Guenther */
1226 status = rpccli_samr_QueryDomainInfo(samr_pipe,
1231 if (NT_STATUS_IS_OK(status)) {
1233 *seq = info->general.sequence_num;
1240 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1241 domain->name, (unsigned)*seq));
1243 DEBUG(10,("domain_sequence_number: failed to get sequence "
1244 "number (%u) for domain %s\n",
1245 (unsigned) *seq, domain->name ));
1246 status = NT_STATUS_OK;
1250 talloc_destroy(mem_ctx);
1254 /* the rpc backend methods are exposed via this structure */
1255 struct winbindd_methods builtin_passdb_methods = {
1256 .consistent = false,
1258 .query_user_list = builtin_query_user_list,
1259 .enum_dom_groups = builtin_enum_dom_groups,
1260 .enum_local_groups = sam_enum_local_groups,
1261 .name_to_sid = sam_name_to_sid,
1262 .sid_to_name = sam_sid_to_name,
1263 .rids_to_names = sam_rids_to_names,
1264 .query_user = builtin_query_user,
1265 .lookup_usergroups = common_lookup_usergroups,
1266 .lookup_useraliases = common_lookup_useraliases,
1267 .lookup_groupmem = sam_lookup_groupmem,
1268 .sequence_number = common_sequence_number,
1269 .lockout_policy = common_lockout_policy,
1270 .password_policy = common_password_policy,
1271 .trusted_domains = builtin_trusted_domains
1274 /* the rpc backend methods are exposed via this structure */
1275 struct winbindd_methods sam_passdb_methods = {
1276 .consistent = false,
1278 .query_user_list = sam_query_user_list,
1279 .enum_dom_groups = sam_enum_dom_groups,
1280 .enum_local_groups = sam_enum_local_groups,
1281 .name_to_sid = sam_name_to_sid,
1282 .sid_to_name = sam_sid_to_name,
1283 .rids_to_names = sam_rids_to_names,
1284 .query_user = sam_query_user,
1285 .lookup_usergroups = common_lookup_usergroups,
1286 .lookup_useraliases = common_lookup_useraliases,
1287 .lookup_groupmem = sam_lookup_groupmem,
1288 .sequence_number = common_sequence_number,
1289 .lockout_policy = common_lockout_policy,
1290 .password_policy = common_password_policy,
1291 .trusted_domains = sam_trusted_domains