correctly handle aio_error() and errno
[Samba/bb.git] / source3 / winbindd / winbindd_rpc.c
blobac5c3d2d93a66339406c82b8c97c68fa63e26373
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"
28 #undef DBGC_CLASS
29 #define DBGC_CLASS DBGC_WINBIND
32 /* Query display info for a domain. This returns enough information plus a
33 bit extra to give an overview of domain users for the User Manager
34 application. */
35 static NTSTATUS query_user_list(struct winbindd_domain *domain,
36 TALLOC_CTX *mem_ctx,
37 uint32 *num_entries,
38 struct wbint_userinfo **info)
40 NTSTATUS result;
41 struct policy_handle dom_pol;
42 unsigned int i, start_idx;
43 uint32 loop_count;
44 struct rpc_pipe_client *cli;
46 DEBUG(3,("rpc: query_user_list\n"));
48 *num_entries = 0;
49 *info = NULL;
51 if ( !winbindd_can_contact_domain( domain ) ) {
52 DEBUG(10,("query_user_list: No incoming trust for domain %s\n",
53 domain->name));
54 return NT_STATUS_OK;
57 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
58 if (!NT_STATUS_IS_OK(result))
59 return result;
61 i = start_idx = 0;
62 loop_count = 0;
64 do {
65 uint32 num_dom_users, j;
66 uint32 max_entries, max_size;
67 uint32_t total_size, returned_size;
69 union samr_DispInfo disp_info;
71 /* this next bit is copied from net_user_list_internal() */
73 get_query_dispinfo_params(loop_count, &max_entries,
74 &max_size);
76 result = rpccli_samr_QueryDisplayInfo(cli, mem_ctx,
77 &dom_pol,
79 start_idx,
80 max_entries,
81 max_size,
82 &total_size,
83 &returned_size,
84 &disp_info);
85 num_dom_users = disp_info.info1.count;
86 start_idx += disp_info.info1.count;
87 loop_count++;
89 *num_entries += num_dom_users;
91 *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
92 struct wbint_userinfo,
93 *num_entries);
95 if (!(*info)) {
96 return NT_STATUS_NO_MEMORY;
99 for (j = 0; j < num_dom_users; i++, j++) {
101 uint32_t rid = disp_info.info1.entries[j].rid;
103 (*info)[i].acct_name = talloc_strdup(mem_ctx,
104 disp_info.info1.entries[j].account_name.string);
105 (*info)[i].full_name = talloc_strdup(mem_ctx,
106 disp_info.info1.entries[j].full_name.string);
107 (*info)[i].homedir = NULL;
108 (*info)[i].shell = NULL;
109 sid_compose(&(*info)[i].user_sid, &domain->sid, rid);
111 /* For the moment we set the primary group for
112 every user to be the Domain Users group.
113 There are serious problems with determining
114 the actual primary group for large domains.
115 This should really be made into a 'winbind
116 force group' smb.conf parameter or
117 something like that. */
119 sid_compose(&(*info)[i].group_sid, &domain->sid,
120 DOMAIN_GROUP_RID_USERS);
123 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
125 return result;
128 /* list all domain groups */
129 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
130 TALLOC_CTX *mem_ctx,
131 uint32 *num_entries,
132 struct acct_info **info)
134 struct policy_handle dom_pol;
135 NTSTATUS status;
136 uint32 start = 0;
137 struct rpc_pipe_client *cli;
139 *num_entries = 0;
140 *info = NULL;
142 DEBUG(3,("rpc: enum_dom_groups\n"));
144 if ( !winbindd_can_contact_domain( domain ) ) {
145 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
146 domain->name));
147 return NT_STATUS_OK;
150 status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
151 if (!NT_STATUS_IS_OK(status))
152 return status;
154 do {
155 struct samr_SamArray *sam_array = NULL;
156 uint32 count = 0;
157 TALLOC_CTX *mem_ctx2;
158 int g;
160 mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
162 /* start is updated by this call. */
163 status = rpccli_samr_EnumDomainGroups(cli, mem_ctx2,
164 &dom_pol,
165 &start,
166 &sam_array,
167 0xFFFF, /* buffer size? */
168 &count);
170 if (!NT_STATUS_IS_OK(status) &&
171 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
172 talloc_destroy(mem_ctx2);
173 break;
176 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
177 struct acct_info,
178 (*num_entries) + count);
179 if (! *info) {
180 talloc_destroy(mem_ctx2);
181 return NT_STATUS_NO_MEMORY;
184 for (g=0; g < count; g++) {
186 fstrcpy((*info)[*num_entries + g].acct_name,
187 sam_array->entries[g].name.string);
188 (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
191 (*num_entries) += count;
192 talloc_destroy(mem_ctx2);
193 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
195 return NT_STATUS_OK;
198 /* List all domain groups */
200 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
201 TALLOC_CTX *mem_ctx,
202 uint32 *num_entries,
203 struct acct_info **info)
205 struct policy_handle dom_pol;
206 NTSTATUS result;
207 struct rpc_pipe_client *cli;
209 *num_entries = 0;
210 *info = NULL;
212 DEBUG(3,("rpc: enum_local_groups\n"));
214 if ( !winbindd_can_contact_domain( domain ) ) {
215 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
216 domain->name));
217 return NT_STATUS_OK;
220 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
221 if (!NT_STATUS_IS_OK(result))
222 return result;
224 do {
225 struct samr_SamArray *sam_array = NULL;
226 uint32 count = 0, start = *num_entries;
227 TALLOC_CTX *mem_ctx2;
228 int g;
230 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
232 result = rpccli_samr_EnumDomainAliases(cli, mem_ctx2,
233 &dom_pol,
234 &start,
235 &sam_array,
236 0xFFFF, /* buffer size? */
237 &count);
238 if (!NT_STATUS_IS_OK(result) &&
239 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
241 talloc_destroy(mem_ctx2);
242 return result;
245 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
246 struct acct_info,
247 (*num_entries) + count);
248 if (! *info) {
249 talloc_destroy(mem_ctx2);
250 return NT_STATUS_NO_MEMORY;
253 for (g=0; g < count; g++) {
255 fstrcpy((*info)[*num_entries + g].acct_name,
256 sam_array->entries[g].name.string);
257 (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
260 (*num_entries) += count;
261 talloc_destroy(mem_ctx2);
263 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
265 return NT_STATUS_OK;
268 /* convert a single name to a sid in a domain */
269 static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
270 TALLOC_CTX *mem_ctx,
271 const char *domain_name,
272 const char *name,
273 uint32_t flags,
274 DOM_SID *sid,
275 enum lsa_SidType *type)
277 NTSTATUS result;
278 DOM_SID *sids = NULL;
279 enum lsa_SidType *types = NULL;
280 char *full_name = NULL;
281 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
282 char *mapped_name = NULL;
284 if (name == NULL || *name=='\0') {
285 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
286 } else if (domain_name == NULL || *domain_name == '\0') {
287 full_name = talloc_asprintf(mem_ctx, "%s", name);
288 } else {
289 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
291 if (!full_name) {
292 DEBUG(0, ("talloc_asprintf failed!\n"));
293 return NT_STATUS_NO_MEMORY;
296 DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
298 name_map_status = normalize_name_unmap(mem_ctx, full_name,
299 &mapped_name);
301 /* Reset the full_name pointer if we mapped anytthing */
303 if (NT_STATUS_IS_OK(name_map_status) ||
304 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
306 full_name = mapped_name;
309 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
310 full_name?full_name:"", domain_name ));
312 result = winbindd_lookup_names(mem_ctx, domain, 1,
313 (const char **)&full_name, NULL,
314 &sids, &types);
315 if (!NT_STATUS_IS_OK(result))
316 return result;
318 /* Return rid and type if lookup successful */
320 sid_copy(sid, &sids[0]);
321 *type = types[0];
323 return NT_STATUS_OK;
327 convert a domain SID to a user or group name
329 static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
330 TALLOC_CTX *mem_ctx,
331 const DOM_SID *sid,
332 char **domain_name,
333 char **name,
334 enum lsa_SidType *type)
336 char **domains;
337 char **names;
338 enum lsa_SidType *types = NULL;
339 NTSTATUS result;
340 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
341 char *mapped_name = NULL;
343 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
344 domain->name ));
346 result = winbindd_lookup_sids(mem_ctx,
347 domain,
349 sid,
350 &domains,
351 &names,
352 &types);
353 if (!NT_STATUS_IS_OK(result)) {
354 DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n",
355 nt_errstr(result)));
356 return result;
360 *type = (enum lsa_SidType)types[0];
361 *domain_name = domains[0];
362 *name = names[0];
364 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
366 name_map_status = normalize_name_map(mem_ctx, domain, *name,
367 &mapped_name);
368 if (NT_STATUS_IS_OK(name_map_status) ||
369 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
371 *name = mapped_name;
372 DEBUG(5,("returning mapped name -- %s\n", *name));
375 return NT_STATUS_OK;
378 static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
379 TALLOC_CTX *mem_ctx,
380 const DOM_SID *sid,
381 uint32 *rids,
382 size_t num_rids,
383 char **domain_name,
384 char ***names,
385 enum lsa_SidType **types)
387 char **domains;
388 NTSTATUS result;
389 DOM_SID *sids;
390 size_t i;
391 char **ret_names;
393 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name ));
395 if (num_rids) {
396 sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids);
397 if (sids == NULL) {
398 return NT_STATUS_NO_MEMORY;
400 } else {
401 sids = NULL;
404 for (i=0; i<num_rids; i++) {
405 if (!sid_compose(&sids[i], sid, rids[i])) {
406 return NT_STATUS_INTERNAL_ERROR;
410 result = winbindd_lookup_sids(mem_ctx,
411 domain,
412 num_rids,
413 sids,
414 &domains,
415 names,
416 types);
418 if (!NT_STATUS_IS_OK(result) &&
419 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
420 return result;
423 ret_names = *names;
424 for (i=0; i<num_rids; i++) {
425 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
426 char *mapped_name = NULL;
428 if ((*types)[i] != SID_NAME_UNKNOWN) {
429 name_map_status = normalize_name_map(mem_ctx,
430 domain,
431 ret_names[i],
432 &mapped_name);
433 if (NT_STATUS_IS_OK(name_map_status) ||
434 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
436 ret_names[i] = mapped_name;
439 *domain_name = domains[i];
443 return result;
446 /* Lookup user information from a rid or username. */
447 static NTSTATUS query_user(struct winbindd_domain *domain,
448 TALLOC_CTX *mem_ctx,
449 const DOM_SID *user_sid,
450 struct wbint_userinfo *user_info)
452 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
453 struct policy_handle dom_pol, user_pol;
454 union samr_UserInfo *info = NULL;
455 uint32 user_rid;
456 struct netr_SamInfo3 *user;
457 struct rpc_pipe_client *cli;
459 DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid)));
461 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
462 return NT_STATUS_UNSUCCESSFUL;
464 user_info->homedir = NULL;
465 user_info->shell = NULL;
466 user_info->primary_gid = (gid_t)-1;
468 /* try netsamlogon cache first */
470 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
473 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
474 sid_string_dbg(user_sid)));
476 sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
477 sid_compose(&user_info->group_sid, &domain->sid,
478 user->base.primary_gid);
480 user_info->acct_name = talloc_strdup(mem_ctx,
481 user->base.account_name.string);
482 user_info->full_name = talloc_strdup(mem_ctx,
483 user->base.full_name.string);
485 TALLOC_FREE(user);
487 return NT_STATUS_OK;
490 if ( !winbindd_can_contact_domain( domain ) ) {
491 DEBUG(10,("query_user: No incoming trust for domain %s\n",
492 domain->name));
493 return NT_STATUS_OK;
496 /* no cache; hit the wire */
498 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
499 if (!NT_STATUS_IS_OK(result))
500 return result;
502 /* Get user handle */
503 result = rpccli_samr_OpenUser(cli, mem_ctx,
504 &dom_pol,
505 SEC_FLAG_MAXIMUM_ALLOWED,
506 user_rid,
507 &user_pol);
509 if (!NT_STATUS_IS_OK(result))
510 return result;
512 /* Get user info */
513 result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
514 &user_pol,
515 0x15,
516 &info);
518 rpccli_samr_Close(cli, mem_ctx, &user_pol);
520 if (!NT_STATUS_IS_OK(result))
521 return result;
523 sid_compose(&user_info->user_sid, &domain->sid, user_rid);
524 sid_compose(&user_info->group_sid, &domain->sid,
525 info->info21.primary_gid);
526 user_info->acct_name = talloc_strdup(mem_ctx,
527 info->info21.account_name.string);
528 user_info->full_name = talloc_strdup(mem_ctx,
529 info->info21.full_name.string);
530 user_info->homedir = NULL;
531 user_info->shell = NULL;
532 user_info->primary_gid = (gid_t)-1;
534 return NT_STATUS_OK;
537 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
538 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
539 TALLOC_CTX *mem_ctx,
540 const DOM_SID *user_sid,
541 uint32 *num_groups, DOM_SID **user_grpsids)
543 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
544 struct policy_handle dom_pol, user_pol;
545 uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
546 struct samr_RidWithAttributeArray *rid_array = NULL;
547 unsigned int i;
548 uint32 user_rid;
549 struct rpc_pipe_client *cli;
551 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid)));
553 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
554 return NT_STATUS_UNSUCCESSFUL;
556 *num_groups = 0;
557 *user_grpsids = NULL;
559 /* so lets see if we have a cached user_info_3 */
560 result = lookup_usergroups_cached(domain, mem_ctx, user_sid,
561 num_groups, user_grpsids);
563 if (NT_STATUS_IS_OK(result)) {
564 return NT_STATUS_OK;
567 if ( !winbindd_can_contact_domain( domain ) ) {
568 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
569 domain->name));
571 /* Tell the cache manager not to remember this one */
573 return NT_STATUS_SYNCHRONIZATION_REQUIRED;
576 /* no cache; hit the wire */
578 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
579 if (!NT_STATUS_IS_OK(result))
580 return result;
582 /* Get user handle */
583 result = rpccli_samr_OpenUser(cli, mem_ctx,
584 &dom_pol,
585 des_access,
586 user_rid,
587 &user_pol);
589 if (!NT_STATUS_IS_OK(result))
590 return result;
592 /* Query user rids */
593 result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
594 &user_pol,
595 &rid_array);
596 *num_groups = rid_array->count;
598 rpccli_samr_Close(cli, mem_ctx, &user_pol);
600 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
601 return result;
603 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
604 if (!(*user_grpsids))
605 return NT_STATUS_NO_MEMORY;
607 for (i=0;i<(*num_groups);i++) {
608 sid_copy(&((*user_grpsids)[i]), &domain->sid);
609 sid_append_rid(&((*user_grpsids)[i]),
610 rid_array->rids[i].rid);
613 return NT_STATUS_OK;
616 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
618 static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
619 TALLOC_CTX *mem_ctx,
620 uint32 num_sids, const DOM_SID *sids,
621 uint32 *num_aliases,
622 uint32 **alias_rids)
624 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
625 struct policy_handle dom_pol;
626 uint32 num_query_sids = 0;
627 int i;
628 struct rpc_pipe_client *cli;
629 struct samr_Ids alias_rids_query;
630 int rangesize = MAX_SAM_ENTRIES_W2K;
631 uint32 total_sids = 0;
632 int num_queries = 1;
634 *num_aliases = 0;
635 *alias_rids = NULL;
637 DEBUG(3,("rpc: lookup_useraliases\n"));
639 if ( !winbindd_can_contact_domain( domain ) ) {
640 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
641 domain->name));
642 return NT_STATUS_OK;
645 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
646 if (!NT_STATUS_IS_OK(result))
647 return result;
649 do {
650 /* prepare query */
651 struct lsa_SidArray sid_array;
653 ZERO_STRUCT(sid_array);
655 num_query_sids = MIN(num_sids - total_sids, rangesize);
657 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
658 num_queries, num_query_sids));
660 if (num_query_sids) {
661 sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
662 if (sid_array.sids == NULL) {
663 return NT_STATUS_NO_MEMORY;
665 } else {
666 sid_array.sids = NULL;
669 for (i=0; i<num_query_sids; i++) {
670 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]);
671 if (!sid_array.sids[i].sid) {
672 TALLOC_FREE(sid_array.sids);
673 return NT_STATUS_NO_MEMORY;
676 sid_array.num_sids = num_query_sids;
678 /* do request */
679 result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
680 &dom_pol,
681 &sid_array,
682 &alias_rids_query);
684 if (!NT_STATUS_IS_OK(result)) {
685 *num_aliases = 0;
686 *alias_rids = NULL;
687 TALLOC_FREE(sid_array.sids);
688 goto done;
691 /* process output */
693 for (i=0; i<alias_rids_query.count; i++) {
694 size_t na = *num_aliases;
695 if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],
696 alias_rids, &na)) {
697 return NT_STATUS_NO_MEMORY;
699 *num_aliases = na;
702 TALLOC_FREE(sid_array.sids);
704 num_queries++;
706 } while (total_sids < num_sids);
708 done:
709 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
710 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
712 return result;
716 /* Lookup group membership given a rid. */
717 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
718 TALLOC_CTX *mem_ctx,
719 const DOM_SID *group_sid,
720 enum lsa_SidType type,
721 uint32 *num_names,
722 DOM_SID **sid_mem, char ***names,
723 uint32 **name_types)
725 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
726 uint32 i, total_names = 0;
727 struct policy_handle dom_pol, group_pol;
728 uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
729 uint32 *rid_mem = NULL;
730 uint32 group_rid;
731 unsigned int j, r;
732 struct rpc_pipe_client *cli;
733 unsigned int orig_timeout;
734 struct samr_RidTypeArray *rids = NULL;
736 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
737 sid_string_dbg(group_sid)));
739 if ( !winbindd_can_contact_domain( domain ) ) {
740 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
741 domain->name));
742 return NT_STATUS_OK;
745 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
746 return NT_STATUS_UNSUCCESSFUL;
748 *num_names = 0;
750 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
751 if (!NT_STATUS_IS_OK(result))
752 return result;
754 result = rpccli_samr_OpenGroup(cli, mem_ctx,
755 &dom_pol,
756 des_access,
757 group_rid,
758 &group_pol);
760 if (!NT_STATUS_IS_OK(result))
761 return result;
763 /* Step #1: Get a list of user rids that are the members of the
764 group. */
766 /* This call can take a long time - allow the server to time out.
767 35 seconds should do it. */
769 orig_timeout = rpccli_set_timeout(cli, 35000);
771 result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
772 &group_pol,
773 &rids);
775 /* And restore our original timeout. */
776 rpccli_set_timeout(cli, orig_timeout);
778 rpccli_samr_Close(cli, mem_ctx, &group_pol);
780 if (!NT_STATUS_IS_OK(result))
781 return result;
783 *num_names = rids->count;
784 rid_mem = rids->rids;
786 if (!*num_names) {
787 names = NULL;
788 name_types = NULL;
789 sid_mem = NULL;
790 return NT_STATUS_OK;
793 /* Step #2: Convert list of rids into list of usernames. Do this
794 in bunches of ~1000 to avoid crashing NT4. It looks like there
795 is a buffer overflow or something like that lurking around
796 somewhere. */
798 #define MAX_LOOKUP_RIDS 900
800 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
801 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
802 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
804 for (j=0;j<(*num_names);j++)
805 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
807 if (*num_names>0 && (!*names || !*name_types))
808 return NT_STATUS_NO_MEMORY;
810 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
811 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
812 struct lsa_Strings tmp_names;
813 struct samr_Ids tmp_types;
815 /* Lookup a chunk of rids */
817 result = rpccli_samr_LookupRids(cli, mem_ctx,
818 &dom_pol,
819 num_lookup_rids,
820 &rid_mem[i],
821 &tmp_names,
822 &tmp_types);
824 /* see if we have a real error (and yes the
825 STATUS_SOME_UNMAPPED is the one returned from 2k) */
827 if (!NT_STATUS_IS_OK(result) &&
828 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
829 return result;
831 /* Copy result into array. The talloc system will take
832 care of freeing the temporary arrays later on. */
834 if (tmp_names.count != tmp_types.count) {
835 return NT_STATUS_UNSUCCESSFUL;
838 for (r=0; r<tmp_names.count; r++) {
839 if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
840 continue;
842 (*names)[total_names] = fill_domain_username_talloc(
843 mem_ctx, domain->name,
844 tmp_names.names[r].string, true);
845 (*name_types)[total_names] = tmp_types.ids[r];
846 total_names += 1;
850 *num_names = total_names;
852 return NT_STATUS_OK;
855 #ifdef HAVE_LDAP
857 #include <ldap.h>
859 static int get_ldap_seq(const char *server, int port, uint32 *seq)
861 int ret = -1;
862 struct timeval to;
863 const char *attrs[] = {"highestCommittedUSN", NULL};
864 LDAPMessage *res = NULL;
865 char **values = NULL;
866 LDAP *ldp = NULL;
868 *seq = DOM_SEQUENCE_NONE;
871 * Parameterised (5) second timeout on open. This is needed as the
872 * search timeout doesn't seem to apply to doing an open as well. JRA.
875 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
876 if (ldp == NULL)
877 return -1;
879 /* Timeout if no response within 20 seconds. */
880 to.tv_sec = 10;
881 to.tv_usec = 0;
883 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
884 CONST_DISCARD(char **, attrs), 0, &to, &res))
885 goto done;
887 if (ldap_count_entries(ldp, res) != 1)
888 goto done;
890 values = ldap_get_values(ldp, res, "highestCommittedUSN");
891 if (!values || !values[0])
892 goto done;
894 *seq = atoi(values[0]);
895 ret = 0;
897 done:
899 if (values)
900 ldap_value_free(values);
901 if (res)
902 ldap_msgfree(res);
903 if (ldp)
904 ldap_unbind(ldp);
905 return ret;
908 /**********************************************************************
909 Get the sequence number for a Windows AD native mode domain using
910 LDAP queries.
911 **********************************************************************/
913 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
915 int ret = -1;
916 char addr[INET6_ADDRSTRLEN];
918 print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
919 if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
920 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
921 "number for Domain (%s) from DC (%s)\n",
922 domain->name, addr));
924 return ret;
927 #endif /* HAVE_LDAP */
929 /* find the sequence number for a domain */
930 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
932 TALLOC_CTX *mem_ctx;
933 union samr_DomainInfo *info = NULL;
934 NTSTATUS result;
935 struct policy_handle dom_pol;
936 bool got_seq_num = False;
937 struct rpc_pipe_client *cli;
939 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
941 if ( !winbindd_can_contact_domain( domain ) ) {
942 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
943 domain->name));
944 *seq = time(NULL);
945 return NT_STATUS_OK;
948 *seq = DOM_SEQUENCE_NONE;
950 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
951 return NT_STATUS_NO_MEMORY;
953 #ifdef HAVE_LDAP
954 if ( domain->active_directory )
956 int res;
958 DEBUG(8,("using get_ldap_seq() to retrieve the "
959 "sequence number\n"));
961 res = get_ldap_sequence_number( domain, seq );
962 if (res == 0)
964 result = NT_STATUS_OK;
965 DEBUG(10,("domain_sequence_number: LDAP for "
966 "domain %s is %u\n",
967 domain->name, *seq));
968 goto done;
971 DEBUG(10,("domain_sequence_number: failed to get LDAP "
972 "sequence number for domain %s\n",
973 domain->name ));
975 #endif /* HAVE_LDAP */
977 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
978 if (!NT_STATUS_IS_OK(result)) {
979 goto done;
982 /* Query domain info */
984 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
985 &dom_pol,
987 &info);
989 if (NT_STATUS_IS_OK(result)) {
990 *seq = info->info8.sequence_num;
991 got_seq_num = True;
992 goto seq_num;
995 /* retry with info-level 2 in case the dc does not support info-level 8
996 * (like all older samba2 and samba3 dc's) - Guenther */
998 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
999 &dom_pol,
1001 &info);
1003 if (NT_STATUS_IS_OK(result)) {
1004 *seq = info->general.sequence_num;
1005 got_seq_num = True;
1008 seq_num:
1009 if (got_seq_num) {
1010 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1011 domain->name, (unsigned)*seq));
1012 } else {
1013 DEBUG(10,("domain_sequence_number: failed to get sequence "
1014 "number (%u) for domain %s\n",
1015 (unsigned)*seq, domain->name ));
1018 done:
1020 talloc_destroy(mem_ctx);
1022 return result;
1025 /* get a list of trusted domains */
1026 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
1027 TALLOC_CTX *mem_ctx,
1028 uint32 *num_domains,
1029 char ***names,
1030 char ***alt_names,
1031 DOM_SID **dom_sids)
1033 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1034 uint32 enum_ctx = 0;
1035 struct rpc_pipe_client *cli;
1036 struct policy_handle lsa_policy;
1038 DEBUG(3,("rpc: trusted_domains\n"));
1040 *num_domains = 0;
1041 *names = NULL;
1042 *alt_names = NULL;
1043 *dom_sids = NULL;
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 = *num_domains;
1067 *num_domains += dom_list.count;
1068 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
1069 char *, *num_domains);
1070 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
1071 DOM_SID, *num_domains);
1072 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,
1073 char *, *num_domains);
1074 if ((*names == NULL) || (*dom_sids == NULL) ||
1075 (*alt_names == NULL))
1076 return NT_STATUS_NO_MEMORY;
1078 for (i=0; i<dom_list.count; i++) {
1079 (*names)[start_idx+i] = CONST_DISCARD(char *, dom_list.domains[i].name.string);
1080 (*dom_sids)[start_idx+i] = *dom_list.domains[i].sid;
1081 (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
1084 return result;
1087 /* find the lockout policy for a domain */
1088 static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
1089 TALLOC_CTX *mem_ctx,
1090 struct samr_DomInfo12 *lockout_policy)
1092 NTSTATUS result;
1093 struct rpc_pipe_client *cli;
1094 struct policy_handle dom_pol;
1095 union samr_DomainInfo *info = NULL;
1097 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
1099 if ( !winbindd_can_contact_domain( domain ) ) {
1100 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1101 domain->name));
1102 return NT_STATUS_NOT_SUPPORTED;
1105 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1106 if (!NT_STATUS_IS_OK(result)) {
1107 goto done;
1110 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1111 &dom_pol,
1113 &info);
1114 if (!NT_STATUS_IS_OK(result)) {
1115 goto done;
1118 *lockout_policy = info->info12;
1120 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1121 info->info12.lockout_threshold));
1123 done:
1125 return result;
1128 /* find the password policy for a domain */
1129 static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1130 TALLOC_CTX *mem_ctx,
1131 struct samr_DomInfo1 *password_policy)
1133 NTSTATUS result;
1134 struct rpc_pipe_client *cli;
1135 struct policy_handle dom_pol;
1136 union samr_DomainInfo *info = NULL;
1138 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
1140 if ( !winbindd_can_contact_domain( domain ) ) {
1141 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1142 domain->name));
1143 return NT_STATUS_NOT_SUPPORTED;
1146 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1147 if (!NT_STATUS_IS_OK(result)) {
1148 goto done;
1151 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1152 &dom_pol,
1154 &info);
1155 if (!NT_STATUS_IS_OK(result)) {
1156 goto done;
1159 *password_policy = info->info1;
1161 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1162 info->info1.min_password_length));
1164 done:
1166 return result;
1169 typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli,
1170 TALLOC_CTX *mem_ctx,
1171 struct policy_handle *pol,
1172 int num_sids,
1173 const DOM_SID *sids,
1174 char ***pdomains,
1175 char ***pnames,
1176 enum lsa_SidType **ptypes);
1178 NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
1179 struct winbindd_domain *domain,
1180 uint32_t num_sids,
1181 const struct dom_sid *sids,
1182 char ***domains,
1183 char ***names,
1184 enum lsa_SidType **types)
1186 NTSTATUS status;
1187 struct rpc_pipe_client *cli = NULL;
1188 struct policy_handle lsa_policy;
1189 unsigned int orig_timeout;
1190 lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;
1192 if (domain->can_do_ncacn_ip_tcp) {
1193 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1194 if (NT_STATUS_IS_OK(status)) {
1195 lookup_sids_fn = rpccli_lsa_lookup_sids3;
1196 goto lookup;
1198 domain->can_do_ncacn_ip_tcp = false;
1200 status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1202 if (!NT_STATUS_IS_OK(status)) {
1203 return status;
1206 lookup:
1208 * This call can take a long time
1209 * allow the server to time out.
1210 * 35 seconds should do it.
1212 orig_timeout = rpccli_set_timeout(cli, 35000);
1214 status = lookup_sids_fn(cli,
1215 mem_ctx,
1216 &lsa_policy,
1217 num_sids,
1218 sids,
1219 domains,
1220 names,
1221 types);
1223 /* And restore our original timeout. */
1224 rpccli_set_timeout(cli, orig_timeout);
1226 if (!NT_STATUS_IS_OK(status)) {
1227 return status;
1230 return status;
1233 typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
1234 TALLOC_CTX *mem_ctx,
1235 struct policy_handle *pol,
1236 int num_names,
1237 const char **names,
1238 const char ***dom_names,
1239 int level,
1240 struct dom_sid **sids,
1241 enum lsa_SidType **types);
1243 NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
1244 struct winbindd_domain *domain,
1245 uint32_t num_names,
1246 const char **names,
1247 const char ***domains,
1248 struct dom_sid **sids,
1249 enum lsa_SidType **types)
1251 NTSTATUS status;
1252 struct rpc_pipe_client *cli = NULL;
1253 struct policy_handle lsa_policy;
1254 unsigned int orig_timeout;
1255 lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names;
1257 if (domain->can_do_ncacn_ip_tcp) {
1258 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1259 if (NT_STATUS_IS_OK(status)) {
1260 lookup_names_fn = rpccli_lsa_lookup_names4;
1261 goto lookup;
1263 domain->can_do_ncacn_ip_tcp = false;
1265 status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1267 if (!NT_STATUS_IS_OK(status)) {
1268 return status;
1271 lookup:
1274 * This call can take a long time
1275 * allow the server to time out.
1276 * 35 seconds should do it.
1278 orig_timeout = rpccli_set_timeout(cli, 35000);
1280 status = lookup_names_fn(cli,
1281 mem_ctx,
1282 &lsa_policy,
1283 num_names,
1284 (const char **) names,
1285 domains,
1287 sids,
1288 types);
1290 /* And restore our original timeout. */
1291 rpccli_set_timeout(cli, orig_timeout);
1293 if (!NT_STATUS_IS_OK(status)) {
1294 return status;
1297 return status;
1300 /* the rpc backend methods are exposed via this structure */
1301 struct winbindd_methods msrpc_methods = {
1302 False,
1303 query_user_list,
1304 enum_dom_groups,
1305 enum_local_groups,
1306 msrpc_name_to_sid,
1307 msrpc_sid_to_name,
1308 msrpc_rids_to_names,
1309 query_user,
1310 lookup_usergroups,
1311 msrpc_lookup_useraliases,
1312 lookup_groupmem,
1313 sequence_number,
1314 msrpc_lockout_policy,
1315 msrpc_password_policy,
1316 trusted_domains,