upgradeprovision: never use xattr it's pointless in this usecase
[Samba/ekacnet.git] / source3 / winbindd / winbindd_rpc.c
blob87494db2bbaa0cec2247e81c2e5007da87553dc7
1 /*
2 Unix SMB/CIFS implementation.
4 Winbind rpc backend functions
6 Copyright (C) Tim Potter 2000-2001,2003
7 Copyright (C) Andrew Tridgell 2001
8 Copyright (C) Volker Lendecke 2005
9 Copyright (C) Guenther Deschner 2008 (pidl conversion)
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "includes.h"
26 #include "winbindd.h"
27 #include "../librpc/gen_ndr/cli_samr.h"
28 #include "../librpc/gen_ndr/cli_lsa.h"
30 #undef DBGC_CLASS
31 #define DBGC_CLASS DBGC_WINBIND
34 /* Query display info for a domain. This returns enough information plus a
35 bit extra to give an overview of domain users for the User Manager
36 application. */
37 static NTSTATUS query_user_list(struct winbindd_domain *domain,
38 TALLOC_CTX *mem_ctx,
39 uint32 *num_entries,
40 struct wbint_userinfo **info)
42 NTSTATUS result;
43 struct policy_handle dom_pol;
44 unsigned int i, start_idx;
45 uint32 loop_count;
46 struct rpc_pipe_client *cli;
48 DEBUG(3,("rpc: query_user_list\n"));
50 *num_entries = 0;
51 *info = NULL;
53 if ( !winbindd_can_contact_domain( domain ) ) {
54 DEBUG(10,("query_user_list: No incoming trust for domain %s\n",
55 domain->name));
56 return NT_STATUS_OK;
59 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
60 if (!NT_STATUS_IS_OK(result))
61 return result;
63 i = start_idx = 0;
64 loop_count = 0;
66 do {
67 uint32 num_dom_users, j;
68 uint32 max_entries, max_size;
69 uint32_t total_size, returned_size;
71 union samr_DispInfo disp_info;
73 /* this next bit is copied from net_user_list_internal() */
75 get_query_dispinfo_params(loop_count, &max_entries,
76 &max_size);
78 result = rpccli_samr_QueryDisplayInfo(cli, mem_ctx,
79 &dom_pol,
81 start_idx,
82 max_entries,
83 max_size,
84 &total_size,
85 &returned_size,
86 &disp_info);
87 num_dom_users = disp_info.info1.count;
88 start_idx += disp_info.info1.count;
89 loop_count++;
91 *num_entries += num_dom_users;
93 *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
94 struct wbint_userinfo,
95 *num_entries);
97 if (!(*info)) {
98 return NT_STATUS_NO_MEMORY;
101 for (j = 0; j < num_dom_users; i++, j++) {
103 uint32_t rid = disp_info.info1.entries[j].rid;
104 struct samr_DispEntryGeneral *src;
105 struct wbint_userinfo *dst;
107 src = &(disp_info.info1.entries[j]);
108 dst = &((*info)[i]);
110 dst->acct_name = talloc_strdup(
111 mem_ctx, src->account_name.string);
112 dst->full_name = talloc_strdup(
113 mem_ctx, src->full_name.string);
114 dst->homedir = NULL;
115 dst->shell = NULL;
116 sid_compose(&dst->user_sid, &domain->sid, rid);
118 /* For the moment we set the primary group for
119 every user to be the Domain Users group.
120 There are serious problems with determining
121 the actual primary group for large domains.
122 This should really be made into a 'winbind
123 force group' smb.conf parameter or
124 something like that. */
126 sid_compose(&dst->group_sid, &domain->sid,
127 DOMAIN_GROUP_RID_USERS);
130 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
132 return result;
135 /* list all domain groups */
136 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
137 TALLOC_CTX *mem_ctx,
138 uint32 *num_entries,
139 struct acct_info **info)
141 struct policy_handle dom_pol;
142 NTSTATUS status;
143 uint32 start = 0;
144 struct rpc_pipe_client *cli;
146 *num_entries = 0;
147 *info = NULL;
149 DEBUG(3,("rpc: enum_dom_groups\n"));
151 if ( !winbindd_can_contact_domain( domain ) ) {
152 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
153 domain->name));
154 return NT_STATUS_OK;
157 status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
158 if (!NT_STATUS_IS_OK(status))
159 return status;
161 do {
162 struct samr_SamArray *sam_array = NULL;
163 uint32 count = 0;
164 TALLOC_CTX *mem_ctx2;
165 int g;
167 mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
169 /* start is updated by this call. */
170 status = rpccli_samr_EnumDomainGroups(cli, mem_ctx2,
171 &dom_pol,
172 &start,
173 &sam_array,
174 0xFFFF, /* buffer size? */
175 &count);
177 if (!NT_STATUS_IS_OK(status) &&
178 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
179 talloc_destroy(mem_ctx2);
180 break;
183 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
184 struct acct_info,
185 (*num_entries) + count);
186 if (! *info) {
187 talloc_destroy(mem_ctx2);
188 return NT_STATUS_NO_MEMORY;
191 for (g=0; g < count; g++) {
193 fstrcpy((*info)[*num_entries + g].acct_name,
194 sam_array->entries[g].name.string);
195 (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
198 (*num_entries) += count;
199 talloc_destroy(mem_ctx2);
200 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
202 return status;
205 /* List all domain groups */
207 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
208 TALLOC_CTX *mem_ctx,
209 uint32 *num_entries,
210 struct acct_info **info)
212 struct policy_handle dom_pol;
213 NTSTATUS result;
214 struct rpc_pipe_client *cli;
216 *num_entries = 0;
217 *info = NULL;
219 DEBUG(3,("rpc: enum_local_groups\n"));
221 if ( !winbindd_can_contact_domain( domain ) ) {
222 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
223 domain->name));
224 return NT_STATUS_OK;
227 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
228 if (!NT_STATUS_IS_OK(result))
229 return result;
231 do {
232 struct samr_SamArray *sam_array = NULL;
233 uint32 count = 0, start = *num_entries;
234 TALLOC_CTX *mem_ctx2;
235 int g;
237 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
239 result = rpccli_samr_EnumDomainAliases(cli, mem_ctx2,
240 &dom_pol,
241 &start,
242 &sam_array,
243 0xFFFF, /* buffer size? */
244 &count);
245 if (!NT_STATUS_IS_OK(result) &&
246 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
248 talloc_destroy(mem_ctx2);
249 return result;
252 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
253 struct acct_info,
254 (*num_entries) + count);
255 if (! *info) {
256 talloc_destroy(mem_ctx2);
257 return NT_STATUS_NO_MEMORY;
260 for (g=0; g < count; g++) {
262 fstrcpy((*info)[*num_entries + g].acct_name,
263 sam_array->entries[g].name.string);
264 (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
267 (*num_entries) += count;
268 talloc_destroy(mem_ctx2);
270 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
272 return result;
275 /* convert a single name to a sid in a domain */
276 static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
277 TALLOC_CTX *mem_ctx,
278 const char *domain_name,
279 const char *name,
280 uint32_t flags,
281 DOM_SID *sid,
282 enum lsa_SidType *type)
284 NTSTATUS result;
285 DOM_SID *sids = NULL;
286 enum lsa_SidType *types = NULL;
287 char *full_name = NULL;
288 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
289 char *mapped_name = NULL;
291 if (name == NULL || *name=='\0') {
292 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
293 } else if (domain_name == NULL || *domain_name == '\0') {
294 full_name = talloc_asprintf(mem_ctx, "%s", name);
295 } else {
296 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
298 if (!full_name) {
299 DEBUG(0, ("talloc_asprintf failed!\n"));
300 return NT_STATUS_NO_MEMORY;
303 DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
305 name_map_status = normalize_name_unmap(mem_ctx, full_name,
306 &mapped_name);
308 /* Reset the full_name pointer if we mapped anytthing */
310 if (NT_STATUS_IS_OK(name_map_status) ||
311 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
313 full_name = mapped_name;
316 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
317 full_name?full_name:"", domain_name ));
319 result = winbindd_lookup_names(mem_ctx, domain, 1,
320 (const char **)&full_name, NULL,
321 &sids, &types);
322 if (!NT_STATUS_IS_OK(result))
323 return result;
325 /* Return rid and type if lookup successful */
327 sid_copy(sid, &sids[0]);
328 *type = types[0];
330 return NT_STATUS_OK;
334 convert a domain SID to a user or group name
336 static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
337 TALLOC_CTX *mem_ctx,
338 const DOM_SID *sid,
339 char **domain_name,
340 char **name,
341 enum lsa_SidType *type)
343 char **domains;
344 char **names;
345 enum lsa_SidType *types = NULL;
346 NTSTATUS result;
347 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
348 char *mapped_name = NULL;
350 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
351 domain->name ));
353 result = winbindd_lookup_sids(mem_ctx,
354 domain,
356 sid,
357 &domains,
358 &names,
359 &types);
360 if (!NT_STATUS_IS_OK(result)) {
361 DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n",
362 nt_errstr(result)));
363 return result;
367 *type = (enum lsa_SidType)types[0];
368 *domain_name = domains[0];
369 *name = names[0];
371 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
373 name_map_status = normalize_name_map(mem_ctx, domain, *name,
374 &mapped_name);
375 if (NT_STATUS_IS_OK(name_map_status) ||
376 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
378 *name = mapped_name;
379 DEBUG(5,("returning mapped name -- %s\n", *name));
382 return NT_STATUS_OK;
385 static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
386 TALLOC_CTX *mem_ctx,
387 const DOM_SID *sid,
388 uint32 *rids,
389 size_t num_rids,
390 char **domain_name,
391 char ***names,
392 enum lsa_SidType **types)
394 char **domains;
395 NTSTATUS result;
396 DOM_SID *sids;
397 size_t i;
398 char **ret_names;
400 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name ));
402 if (num_rids) {
403 sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids);
404 if (sids == NULL) {
405 return NT_STATUS_NO_MEMORY;
407 } else {
408 sids = NULL;
411 for (i=0; i<num_rids; i++) {
412 if (!sid_compose(&sids[i], sid, rids[i])) {
413 return NT_STATUS_INTERNAL_ERROR;
417 result = winbindd_lookup_sids(mem_ctx,
418 domain,
419 num_rids,
420 sids,
421 &domains,
422 names,
423 types);
425 if (!NT_STATUS_IS_OK(result) &&
426 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
427 return result;
430 ret_names = *names;
431 for (i=0; i<num_rids; i++) {
432 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
433 char *mapped_name = NULL;
435 if ((*types)[i] != SID_NAME_UNKNOWN) {
436 name_map_status = normalize_name_map(mem_ctx,
437 domain,
438 ret_names[i],
439 &mapped_name);
440 if (NT_STATUS_IS_OK(name_map_status) ||
441 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
443 ret_names[i] = mapped_name;
446 *domain_name = domains[i];
450 return result;
453 /* Lookup user information from a rid or username. */
454 static NTSTATUS query_user(struct winbindd_domain *domain,
455 TALLOC_CTX *mem_ctx,
456 const DOM_SID *user_sid,
457 struct wbint_userinfo *user_info)
459 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
460 struct policy_handle dom_pol, user_pol;
461 union samr_UserInfo *info = NULL;
462 uint32 user_rid;
463 struct netr_SamInfo3 *user;
464 struct rpc_pipe_client *cli;
466 DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid)));
468 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
469 return NT_STATUS_UNSUCCESSFUL;
471 user_info->homedir = NULL;
472 user_info->shell = NULL;
473 user_info->primary_gid = (gid_t)-1;
475 /* try netsamlogon cache first */
477 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
480 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
481 sid_string_dbg(user_sid)));
483 sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
484 sid_compose(&user_info->group_sid, &domain->sid,
485 user->base.primary_gid);
487 user_info->acct_name = talloc_strdup(mem_ctx,
488 user->base.account_name.string);
489 user_info->full_name = talloc_strdup(mem_ctx,
490 user->base.full_name.string);
492 TALLOC_FREE(user);
494 return NT_STATUS_OK;
497 if ( !winbindd_can_contact_domain( domain ) ) {
498 DEBUG(10,("query_user: No incoming trust for domain %s\n",
499 domain->name));
500 return NT_STATUS_OK;
503 /* no cache; hit the wire */
505 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
506 if (!NT_STATUS_IS_OK(result))
507 return result;
509 /* Get user handle */
510 result = rpccli_samr_OpenUser(cli, mem_ctx,
511 &dom_pol,
512 SEC_FLAG_MAXIMUM_ALLOWED,
513 user_rid,
514 &user_pol);
516 if (!NT_STATUS_IS_OK(result))
517 return result;
519 /* Get user info */
520 result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
521 &user_pol,
522 0x15,
523 &info);
525 rpccli_samr_Close(cli, mem_ctx, &user_pol);
527 if (!NT_STATUS_IS_OK(result))
528 return result;
530 sid_compose(&user_info->user_sid, &domain->sid, user_rid);
531 sid_compose(&user_info->group_sid, &domain->sid,
532 info->info21.primary_gid);
533 user_info->acct_name = talloc_strdup(mem_ctx,
534 info->info21.account_name.string);
535 user_info->full_name = talloc_strdup(mem_ctx,
536 info->info21.full_name.string);
537 user_info->homedir = NULL;
538 user_info->shell = NULL;
539 user_info->primary_gid = (gid_t)-1;
541 return NT_STATUS_OK;
544 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
545 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
546 TALLOC_CTX *mem_ctx,
547 const DOM_SID *user_sid,
548 uint32 *num_groups, DOM_SID **user_grpsids)
550 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
551 struct policy_handle dom_pol, user_pol;
552 uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
553 struct samr_RidWithAttributeArray *rid_array = NULL;
554 unsigned int i;
555 uint32 user_rid;
556 struct rpc_pipe_client *cli;
558 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid)));
560 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
561 return NT_STATUS_UNSUCCESSFUL;
563 *num_groups = 0;
564 *user_grpsids = NULL;
566 /* so lets see if we have a cached user_info_3 */
567 result = lookup_usergroups_cached(domain, mem_ctx, user_sid,
568 num_groups, user_grpsids);
570 if (NT_STATUS_IS_OK(result)) {
571 return NT_STATUS_OK;
574 if ( !winbindd_can_contact_domain( domain ) ) {
575 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
576 domain->name));
578 /* Tell the cache manager not to remember this one */
580 return NT_STATUS_SYNCHRONIZATION_REQUIRED;
583 /* no cache; hit the wire */
585 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
586 if (!NT_STATUS_IS_OK(result))
587 return result;
589 /* Get user handle */
590 result = rpccli_samr_OpenUser(cli, mem_ctx,
591 &dom_pol,
592 des_access,
593 user_rid,
594 &user_pol);
596 if (!NT_STATUS_IS_OK(result))
597 return result;
599 /* Query user rids */
600 result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
601 &user_pol,
602 &rid_array);
603 *num_groups = rid_array->count;
605 rpccli_samr_Close(cli, mem_ctx, &user_pol);
607 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
608 return result;
610 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
611 if (!(*user_grpsids))
612 return NT_STATUS_NO_MEMORY;
614 for (i=0;i<(*num_groups);i++) {
615 sid_compose(&((*user_grpsids)[i]), &domain->sid,
616 rid_array->rids[i].rid);
619 return NT_STATUS_OK;
622 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
624 static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
625 TALLOC_CTX *mem_ctx,
626 uint32 num_sids, const DOM_SID *sids,
627 uint32 *num_aliases,
628 uint32 **alias_rids)
630 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
631 struct policy_handle dom_pol;
632 uint32 num_query_sids = 0;
633 int i;
634 struct rpc_pipe_client *cli;
635 struct samr_Ids alias_rids_query;
636 int rangesize = MAX_SAM_ENTRIES_W2K;
637 uint32 total_sids = 0;
638 int num_queries = 1;
640 *num_aliases = 0;
641 *alias_rids = NULL;
643 DEBUG(3,("rpc: lookup_useraliases\n"));
645 if ( !winbindd_can_contact_domain( domain ) ) {
646 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
647 domain->name));
648 return NT_STATUS_OK;
651 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
652 if (!NT_STATUS_IS_OK(result))
653 return result;
655 do {
656 /* prepare query */
657 struct lsa_SidArray sid_array;
659 ZERO_STRUCT(sid_array);
661 num_query_sids = MIN(num_sids - total_sids, rangesize);
663 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
664 num_queries, num_query_sids));
666 if (num_query_sids) {
667 sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
668 if (sid_array.sids == NULL) {
669 return NT_STATUS_NO_MEMORY;
671 } else {
672 sid_array.sids = NULL;
675 for (i=0; i<num_query_sids; i++) {
676 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]);
677 if (!sid_array.sids[i].sid) {
678 TALLOC_FREE(sid_array.sids);
679 return NT_STATUS_NO_MEMORY;
682 sid_array.num_sids = num_query_sids;
684 /* do request */
685 result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
686 &dom_pol,
687 &sid_array,
688 &alias_rids_query);
690 if (!NT_STATUS_IS_OK(result)) {
691 *num_aliases = 0;
692 *alias_rids = NULL;
693 TALLOC_FREE(sid_array.sids);
694 goto done;
697 /* process output */
699 for (i=0; i<alias_rids_query.count; i++) {
700 size_t na = *num_aliases;
701 if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],
702 alias_rids, &na)) {
703 return NT_STATUS_NO_MEMORY;
705 *num_aliases = na;
708 TALLOC_FREE(sid_array.sids);
710 num_queries++;
712 } while (total_sids < num_sids);
714 done:
715 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
716 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
718 return result;
722 /* Lookup group membership given a rid. */
723 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
724 TALLOC_CTX *mem_ctx,
725 const DOM_SID *group_sid,
726 enum lsa_SidType type,
727 uint32 *num_names,
728 DOM_SID **sid_mem, char ***names,
729 uint32 **name_types)
731 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
732 uint32 i, total_names = 0;
733 struct policy_handle dom_pol, group_pol;
734 uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
735 uint32 *rid_mem = NULL;
736 uint32 group_rid;
737 unsigned int j, r;
738 struct rpc_pipe_client *cli;
739 unsigned int orig_timeout;
740 struct samr_RidTypeArray *rids = NULL;
742 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
743 sid_string_dbg(group_sid)));
745 if ( !winbindd_can_contact_domain( domain ) ) {
746 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
747 domain->name));
748 return NT_STATUS_OK;
751 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
752 return NT_STATUS_UNSUCCESSFUL;
754 *num_names = 0;
756 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
757 if (!NT_STATUS_IS_OK(result))
758 return result;
760 result = rpccli_samr_OpenGroup(cli, mem_ctx,
761 &dom_pol,
762 des_access,
763 group_rid,
764 &group_pol);
766 if (!NT_STATUS_IS_OK(result))
767 return result;
769 /* Step #1: Get a list of user rids that are the members of the
770 group. */
772 /* This call can take a long time - allow the server to time out.
773 35 seconds should do it. */
775 orig_timeout = rpccli_set_timeout(cli, 35000);
777 result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
778 &group_pol,
779 &rids);
781 /* And restore our original timeout. */
782 rpccli_set_timeout(cli, orig_timeout);
784 rpccli_samr_Close(cli, mem_ctx, &group_pol);
786 if (!NT_STATUS_IS_OK(result))
787 return result;
789 if (!rids || !rids->count) {
790 names = NULL;
791 name_types = NULL;
792 sid_mem = NULL;
793 return NT_STATUS_OK;
796 *num_names = rids->count;
797 rid_mem = rids->rids;
799 /* Step #2: Convert list of rids into list of usernames. Do this
800 in bunches of ~1000 to avoid crashing NT4. It looks like there
801 is a buffer overflow or something like that lurking around
802 somewhere. */
804 #define MAX_LOOKUP_RIDS 900
806 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
807 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
808 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
810 for (j=0;j<(*num_names);j++)
811 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
813 if (*num_names>0 && (!*names || !*name_types))
814 return NT_STATUS_NO_MEMORY;
816 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
817 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
818 struct lsa_Strings tmp_names;
819 struct samr_Ids tmp_types;
821 /* Lookup a chunk of rids */
823 result = rpccli_samr_LookupRids(cli, mem_ctx,
824 &dom_pol,
825 num_lookup_rids,
826 &rid_mem[i],
827 &tmp_names,
828 &tmp_types);
830 /* see if we have a real error (and yes the
831 STATUS_SOME_UNMAPPED is the one returned from 2k) */
833 if (!NT_STATUS_IS_OK(result) &&
834 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
835 return result;
837 /* Copy result into array. The talloc system will take
838 care of freeing the temporary arrays later on. */
840 if (tmp_names.count != tmp_types.count) {
841 return NT_STATUS_UNSUCCESSFUL;
844 for (r=0; r<tmp_names.count; r++) {
845 if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
846 continue;
848 (*names)[total_names] = fill_domain_username_talloc(
849 mem_ctx, domain->name,
850 tmp_names.names[r].string, true);
851 (*name_types)[total_names] = tmp_types.ids[r];
852 total_names += 1;
856 *num_names = total_names;
858 return NT_STATUS_OK;
861 #ifdef HAVE_LDAP
863 #include <ldap.h>
865 static int get_ldap_seq(const char *server, int port, uint32 *seq)
867 int ret = -1;
868 struct timeval to;
869 const char *attrs[] = {"highestCommittedUSN", NULL};
870 LDAPMessage *res = NULL;
871 char **values = NULL;
872 LDAP *ldp = NULL;
874 *seq = DOM_SEQUENCE_NONE;
877 * Parameterised (5) second timeout on open. This is needed as the
878 * search timeout doesn't seem to apply to doing an open as well. JRA.
881 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
882 if (ldp == NULL)
883 return -1;
885 /* Timeout if no response within 20 seconds. */
886 to.tv_sec = 10;
887 to.tv_usec = 0;
889 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
890 CONST_DISCARD(char **, attrs), 0, &to, &res))
891 goto done;
893 if (ldap_count_entries(ldp, res) != 1)
894 goto done;
896 values = ldap_get_values(ldp, res, "highestCommittedUSN");
897 if (!values || !values[0])
898 goto done;
900 *seq = atoi(values[0]);
901 ret = 0;
903 done:
905 if (values)
906 ldap_value_free(values);
907 if (res)
908 ldap_msgfree(res);
909 if (ldp)
910 ldap_unbind(ldp);
911 return ret;
914 /**********************************************************************
915 Get the sequence number for a Windows AD native mode domain using
916 LDAP queries.
917 **********************************************************************/
919 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
921 int ret = -1;
922 char addr[INET6_ADDRSTRLEN];
924 print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
925 if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
926 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
927 "number for Domain (%s) from DC (%s)\n",
928 domain->name, addr));
930 return ret;
933 #endif /* HAVE_LDAP */
935 /* find the sequence number for a domain */
936 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
938 TALLOC_CTX *mem_ctx;
939 union samr_DomainInfo *info = NULL;
940 NTSTATUS result;
941 struct policy_handle dom_pol;
942 bool got_seq_num = False;
943 struct rpc_pipe_client *cli;
945 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
947 if ( !winbindd_can_contact_domain( domain ) ) {
948 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
949 domain->name));
950 *seq = time(NULL);
951 return NT_STATUS_OK;
954 *seq = DOM_SEQUENCE_NONE;
956 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
957 return NT_STATUS_NO_MEMORY;
959 #ifdef HAVE_LDAP
960 if ( domain->active_directory )
962 int res;
964 DEBUG(8,("using get_ldap_seq() to retrieve the "
965 "sequence number\n"));
967 res = get_ldap_sequence_number( domain, seq );
968 if (res == 0)
970 result = NT_STATUS_OK;
971 DEBUG(10,("domain_sequence_number: LDAP for "
972 "domain %s is %u\n",
973 domain->name, *seq));
974 goto done;
977 DEBUG(10,("domain_sequence_number: failed to get LDAP "
978 "sequence number for domain %s\n",
979 domain->name ));
981 #endif /* HAVE_LDAP */
983 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
984 if (!NT_STATUS_IS_OK(result)) {
985 goto done;
988 /* Query domain info */
990 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
991 &dom_pol,
993 &info);
995 if (NT_STATUS_IS_OK(result)) {
996 *seq = info->info8.sequence_num;
997 got_seq_num = True;
998 goto seq_num;
1001 /* retry with info-level 2 in case the dc does not support info-level 8
1002 * (like all older samba2 and samba3 dc's) - Guenther */
1004 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1005 &dom_pol,
1007 &info);
1009 if (NT_STATUS_IS_OK(result)) {
1010 *seq = info->general.sequence_num;
1011 got_seq_num = True;
1014 seq_num:
1015 if (got_seq_num) {
1016 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1017 domain->name, (unsigned)*seq));
1018 } else {
1019 DEBUG(10,("domain_sequence_number: failed to get sequence "
1020 "number (%u) for domain %s\n",
1021 (unsigned)*seq, domain->name ));
1024 done:
1026 talloc_destroy(mem_ctx);
1028 return result;
1031 /* get a list of trusted domains */
1032 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
1033 TALLOC_CTX *mem_ctx,
1034 struct netr_DomainTrustList *trusts)
1036 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1037 uint32 enum_ctx = 0;
1038 struct rpc_pipe_client *cli;
1039 struct policy_handle lsa_policy;
1041 DEBUG(3,("rpc: trusted_domains\n"));
1043 ZERO_STRUCTP(trusts);
1045 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1046 if (!NT_STATUS_IS_OK(result))
1047 return result;
1049 result = STATUS_MORE_ENTRIES;
1051 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1052 uint32 start_idx;
1053 int i;
1054 struct lsa_DomainList dom_list;
1056 result = rpccli_lsa_EnumTrustDom(cli, mem_ctx,
1057 &lsa_policy,
1058 &enum_ctx,
1059 &dom_list,
1060 (uint32_t)-1);
1062 if (!NT_STATUS_IS_OK(result) &&
1063 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
1064 break;
1066 start_idx = trusts->count;
1067 trusts->count += dom_list.count;
1069 trusts->array = talloc_realloc(
1070 mem_ctx, trusts->array, struct netr_DomainTrust,
1071 trusts->count);
1072 if (trusts->array == NULL) {
1073 return NT_STATUS_NO_MEMORY;
1076 for (i=0; i<dom_list.count; i++) {
1077 struct netr_DomainTrust *trust = &trusts->array[i];
1078 struct dom_sid *sid;
1080 ZERO_STRUCTP(trust);
1082 trust->netbios_name = talloc_move(
1083 trusts->array,
1084 &dom_list.domains[i].name.string);
1085 trust->dns_name = NULL;
1087 sid = talloc(trusts->array, struct dom_sid);
1088 if (sid == NULL) {
1089 return NT_STATUS_NO_MEMORY;
1091 sid_copy(sid, dom_list.domains[i].sid);
1092 trust->sid = sid;
1095 return result;
1098 /* find the lockout policy for a domain */
1099 static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
1100 TALLOC_CTX *mem_ctx,
1101 struct samr_DomInfo12 *lockout_policy)
1103 NTSTATUS result;
1104 struct rpc_pipe_client *cli;
1105 struct policy_handle dom_pol;
1106 union samr_DomainInfo *info = NULL;
1108 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
1110 if ( !winbindd_can_contact_domain( domain ) ) {
1111 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1112 domain->name));
1113 return NT_STATUS_NOT_SUPPORTED;
1116 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1117 if (!NT_STATUS_IS_OK(result)) {
1118 goto done;
1121 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1122 &dom_pol,
1124 &info);
1125 if (!NT_STATUS_IS_OK(result)) {
1126 goto done;
1129 *lockout_policy = info->info12;
1131 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1132 info->info12.lockout_threshold));
1134 done:
1136 return result;
1139 /* find the password policy for a domain */
1140 static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1141 TALLOC_CTX *mem_ctx,
1142 struct samr_DomInfo1 *password_policy)
1144 NTSTATUS result;
1145 struct rpc_pipe_client *cli;
1146 struct policy_handle dom_pol;
1147 union samr_DomainInfo *info = NULL;
1149 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
1151 if ( !winbindd_can_contact_domain( domain ) ) {
1152 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1153 domain->name));
1154 return NT_STATUS_NOT_SUPPORTED;
1157 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1158 if (!NT_STATUS_IS_OK(result)) {
1159 goto done;
1162 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1163 &dom_pol,
1165 &info);
1166 if (!NT_STATUS_IS_OK(result)) {
1167 goto done;
1170 *password_policy = info->info1;
1172 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1173 info->info1.min_password_length));
1175 done:
1177 return result;
1180 typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli,
1181 TALLOC_CTX *mem_ctx,
1182 struct policy_handle *pol,
1183 int num_sids,
1184 const DOM_SID *sids,
1185 char ***pdomains,
1186 char ***pnames,
1187 enum lsa_SidType **ptypes);
1189 NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
1190 struct winbindd_domain *domain,
1191 uint32_t num_sids,
1192 const struct dom_sid *sids,
1193 char ***domains,
1194 char ***names,
1195 enum lsa_SidType **types)
1197 NTSTATUS status;
1198 struct rpc_pipe_client *cli = NULL;
1199 struct policy_handle lsa_policy;
1200 unsigned int orig_timeout;
1201 lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;
1203 if (domain->can_do_ncacn_ip_tcp) {
1204 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1205 if (NT_STATUS_IS_OK(status)) {
1206 lookup_sids_fn = rpccli_lsa_lookup_sids3;
1207 goto lookup;
1209 domain->can_do_ncacn_ip_tcp = false;
1211 status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1213 if (!NT_STATUS_IS_OK(status)) {
1214 return status;
1217 lookup:
1219 * This call can take a long time
1220 * allow the server to time out.
1221 * 35 seconds should do it.
1223 orig_timeout = rpccli_set_timeout(cli, 35000);
1225 status = lookup_sids_fn(cli,
1226 mem_ctx,
1227 &lsa_policy,
1228 num_sids,
1229 sids,
1230 domains,
1231 names,
1232 types);
1234 /* And restore our original timeout. */
1235 rpccli_set_timeout(cli, orig_timeout);
1237 if (!NT_STATUS_IS_OK(status)) {
1238 return status;
1241 return status;
1244 typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
1245 TALLOC_CTX *mem_ctx,
1246 struct policy_handle *pol,
1247 int num_names,
1248 const char **names,
1249 const char ***dom_names,
1250 int level,
1251 struct dom_sid **sids,
1252 enum lsa_SidType **types);
1254 NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
1255 struct winbindd_domain *domain,
1256 uint32_t num_names,
1257 const char **names,
1258 const char ***domains,
1259 struct dom_sid **sids,
1260 enum lsa_SidType **types)
1262 NTSTATUS status;
1263 struct rpc_pipe_client *cli = NULL;
1264 struct policy_handle lsa_policy;
1265 unsigned int orig_timeout = 0;
1266 lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names;
1268 if (domain->can_do_ncacn_ip_tcp) {
1269 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1270 if (NT_STATUS_IS_OK(status)) {
1271 lookup_names_fn = rpccli_lsa_lookup_names4;
1272 goto lookup;
1274 domain->can_do_ncacn_ip_tcp = false;
1276 status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1278 if (!NT_STATUS_IS_OK(status)) {
1279 return status;
1282 lookup:
1285 * This call can take a long time
1286 * allow the server to time out.
1287 * 35 seconds should do it.
1289 orig_timeout = rpccli_set_timeout(cli, 35000);
1291 status = lookup_names_fn(cli,
1292 mem_ctx,
1293 &lsa_policy,
1294 num_names,
1295 (const char **) names,
1296 domains,
1298 sids,
1299 types);
1301 /* And restore our original timeout. */
1302 rpccli_set_timeout(cli, orig_timeout);
1304 if (!NT_STATUS_IS_OK(status)) {
1305 return status;
1308 return status;
1311 /* the rpc backend methods are exposed via this structure */
1312 struct winbindd_methods msrpc_methods = {
1313 False,
1314 query_user_list,
1315 enum_dom_groups,
1316 enum_local_groups,
1317 msrpc_name_to_sid,
1318 msrpc_sid_to_name,
1319 msrpc_rids_to_names,
1320 query_user,
1321 lookup_usergroups,
1322 msrpc_lookup_useraliases,
1323 lookup_groupmem,
1324 sequence_number,
1325 msrpc_lockout_policy,
1326 msrpc_password_policy,
1327 trusted_domains,