README.Coding: Fix typos.
[Samba/fernandojvsilva.git] / source3 / winbindd / winbindd_rpc.c
blobce437f744cafb7aa882d35ab1a426ab5251623ad
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;
102 struct samr_DispEntryGeneral *src;
103 struct wbint_userinfo *dst;
105 src = &(disp_info.info1.entries[j]);
106 dst = &((*info)[i]);
108 dst->acct_name = talloc_strdup(
109 mem_ctx, src->account_name.string);
110 dst->full_name = talloc_strdup(
111 mem_ctx, src->full_name.string);
112 dst->homedir = NULL;
113 dst->shell = NULL;
114 sid_compose(&dst->user_sid, &domain->sid, rid);
116 /* For the moment we set the primary group for
117 every user to be the Domain Users group.
118 There are serious problems with determining
119 the actual primary group for large domains.
120 This should really be made into a 'winbind
121 force group' smb.conf parameter or
122 something like that. */
124 sid_compose(&dst->group_sid, &domain->sid,
125 DOMAIN_GROUP_RID_USERS);
128 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
130 return result;
133 /* list all domain groups */
134 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
135 TALLOC_CTX *mem_ctx,
136 uint32 *num_entries,
137 struct acct_info **info)
139 struct policy_handle dom_pol;
140 NTSTATUS status;
141 uint32 start = 0;
142 struct rpc_pipe_client *cli;
144 *num_entries = 0;
145 *info = NULL;
147 DEBUG(3,("rpc: enum_dom_groups\n"));
149 if ( !winbindd_can_contact_domain( domain ) ) {
150 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
151 domain->name));
152 return NT_STATUS_OK;
155 status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
156 if (!NT_STATUS_IS_OK(status))
157 return status;
159 do {
160 struct samr_SamArray *sam_array = NULL;
161 uint32 count = 0;
162 TALLOC_CTX *mem_ctx2;
163 int g;
165 mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
167 /* start is updated by this call. */
168 status = rpccli_samr_EnumDomainGroups(cli, mem_ctx2,
169 &dom_pol,
170 &start,
171 &sam_array,
172 0xFFFF, /* buffer size? */
173 &count);
175 if (!NT_STATUS_IS_OK(status) &&
176 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
177 talloc_destroy(mem_ctx2);
178 break;
181 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
182 struct acct_info,
183 (*num_entries) + count);
184 if (! *info) {
185 talloc_destroy(mem_ctx2);
186 return NT_STATUS_NO_MEMORY;
189 for (g=0; g < count; g++) {
191 fstrcpy((*info)[*num_entries + g].acct_name,
192 sam_array->entries[g].name.string);
193 (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
196 (*num_entries) += count;
197 talloc_destroy(mem_ctx2);
198 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
200 return NT_STATUS_OK;
203 /* List all domain groups */
205 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
206 TALLOC_CTX *mem_ctx,
207 uint32 *num_entries,
208 struct acct_info **info)
210 struct policy_handle dom_pol;
211 NTSTATUS result;
212 struct rpc_pipe_client *cli;
214 *num_entries = 0;
215 *info = NULL;
217 DEBUG(3,("rpc: enum_local_groups\n"));
219 if ( !winbindd_can_contact_domain( domain ) ) {
220 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
221 domain->name));
222 return NT_STATUS_OK;
225 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
226 if (!NT_STATUS_IS_OK(result))
227 return result;
229 do {
230 struct samr_SamArray *sam_array = NULL;
231 uint32 count = 0, start = *num_entries;
232 TALLOC_CTX *mem_ctx2;
233 int g;
235 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
237 result = rpccli_samr_EnumDomainAliases(cli, mem_ctx2,
238 &dom_pol,
239 &start,
240 &sam_array,
241 0xFFFF, /* buffer size? */
242 &count);
243 if (!NT_STATUS_IS_OK(result) &&
244 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
246 talloc_destroy(mem_ctx2);
247 return result;
250 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
251 struct acct_info,
252 (*num_entries) + count);
253 if (! *info) {
254 talloc_destroy(mem_ctx2);
255 return NT_STATUS_NO_MEMORY;
258 for (g=0; g < count; g++) {
260 fstrcpy((*info)[*num_entries + g].acct_name,
261 sam_array->entries[g].name.string);
262 (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
265 (*num_entries) += count;
266 talloc_destroy(mem_ctx2);
268 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
270 return NT_STATUS_OK;
273 /* convert a single name to a sid in a domain */
274 static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
275 TALLOC_CTX *mem_ctx,
276 const char *domain_name,
277 const char *name,
278 uint32_t flags,
279 DOM_SID *sid,
280 enum lsa_SidType *type)
282 NTSTATUS result;
283 DOM_SID *sids = NULL;
284 enum lsa_SidType *types = NULL;
285 char *full_name = NULL;
286 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
287 char *mapped_name = NULL;
289 if (name == NULL || *name=='\0') {
290 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
291 } else if (domain_name == NULL || *domain_name == '\0') {
292 full_name = talloc_asprintf(mem_ctx, "%s", name);
293 } else {
294 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
296 if (!full_name) {
297 DEBUG(0, ("talloc_asprintf failed!\n"));
298 return NT_STATUS_NO_MEMORY;
301 DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
303 name_map_status = normalize_name_unmap(mem_ctx, full_name,
304 &mapped_name);
306 /* Reset the full_name pointer if we mapped anytthing */
308 if (NT_STATUS_IS_OK(name_map_status) ||
309 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
311 full_name = mapped_name;
314 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
315 full_name?full_name:"", domain_name ));
317 result = winbindd_lookup_names(mem_ctx, domain, 1,
318 (const char **)&full_name, NULL,
319 &sids, &types);
320 if (!NT_STATUS_IS_OK(result))
321 return result;
323 /* Return rid and type if lookup successful */
325 sid_copy(sid, &sids[0]);
326 *type = types[0];
328 return NT_STATUS_OK;
332 convert a domain SID to a user or group name
334 static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
335 TALLOC_CTX *mem_ctx,
336 const DOM_SID *sid,
337 char **domain_name,
338 char **name,
339 enum lsa_SidType *type)
341 char **domains;
342 char **names;
343 enum lsa_SidType *types = NULL;
344 NTSTATUS result;
345 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
346 char *mapped_name = NULL;
348 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
349 domain->name ));
351 result = winbindd_lookup_sids(mem_ctx,
352 domain,
354 sid,
355 &domains,
356 &names,
357 &types);
358 if (!NT_STATUS_IS_OK(result)) {
359 DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n",
360 nt_errstr(result)));
361 return result;
365 *type = (enum lsa_SidType)types[0];
366 *domain_name = domains[0];
367 *name = names[0];
369 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
371 name_map_status = normalize_name_map(mem_ctx, domain, *name,
372 &mapped_name);
373 if (NT_STATUS_IS_OK(name_map_status) ||
374 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
376 *name = mapped_name;
377 DEBUG(5,("returning mapped name -- %s\n", *name));
380 return NT_STATUS_OK;
383 static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
384 TALLOC_CTX *mem_ctx,
385 const DOM_SID *sid,
386 uint32 *rids,
387 size_t num_rids,
388 char **domain_name,
389 char ***names,
390 enum lsa_SidType **types)
392 char **domains;
393 NTSTATUS result;
394 DOM_SID *sids;
395 size_t i;
396 char **ret_names;
398 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name ));
400 if (num_rids) {
401 sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids);
402 if (sids == NULL) {
403 return NT_STATUS_NO_MEMORY;
405 } else {
406 sids = NULL;
409 for (i=0; i<num_rids; i++) {
410 if (!sid_compose(&sids[i], sid, rids[i])) {
411 return NT_STATUS_INTERNAL_ERROR;
415 result = winbindd_lookup_sids(mem_ctx,
416 domain,
417 num_rids,
418 sids,
419 &domains,
420 names,
421 types);
423 if (!NT_STATUS_IS_OK(result) &&
424 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
425 return result;
428 ret_names = *names;
429 for (i=0; i<num_rids; i++) {
430 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
431 char *mapped_name = NULL;
433 if ((*types)[i] != SID_NAME_UNKNOWN) {
434 name_map_status = normalize_name_map(mem_ctx,
435 domain,
436 ret_names[i],
437 &mapped_name);
438 if (NT_STATUS_IS_OK(name_map_status) ||
439 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
441 ret_names[i] = mapped_name;
444 *domain_name = domains[i];
448 return result;
451 /* Lookup user information from a rid or username. */
452 static NTSTATUS query_user(struct winbindd_domain *domain,
453 TALLOC_CTX *mem_ctx,
454 const DOM_SID *user_sid,
455 struct wbint_userinfo *user_info)
457 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
458 struct policy_handle dom_pol, user_pol;
459 union samr_UserInfo *info = NULL;
460 uint32 user_rid;
461 struct netr_SamInfo3 *user;
462 struct rpc_pipe_client *cli;
464 DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid)));
466 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
467 return NT_STATUS_UNSUCCESSFUL;
469 user_info->homedir = NULL;
470 user_info->shell = NULL;
471 user_info->primary_gid = (gid_t)-1;
473 /* try netsamlogon cache first */
475 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
478 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
479 sid_string_dbg(user_sid)));
481 sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
482 sid_compose(&user_info->group_sid, &domain->sid,
483 user->base.primary_gid);
485 user_info->acct_name = talloc_strdup(mem_ctx,
486 user->base.account_name.string);
487 user_info->full_name = talloc_strdup(mem_ctx,
488 user->base.full_name.string);
490 TALLOC_FREE(user);
492 return NT_STATUS_OK;
495 if ( !winbindd_can_contact_domain( domain ) ) {
496 DEBUG(10,("query_user: No incoming trust for domain %s\n",
497 domain->name));
498 return NT_STATUS_OK;
501 /* no cache; hit the wire */
503 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
504 if (!NT_STATUS_IS_OK(result))
505 return result;
507 /* Get user handle */
508 result = rpccli_samr_OpenUser(cli, mem_ctx,
509 &dom_pol,
510 SEC_FLAG_MAXIMUM_ALLOWED,
511 user_rid,
512 &user_pol);
514 if (!NT_STATUS_IS_OK(result))
515 return result;
517 /* Get user info */
518 result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
519 &user_pol,
520 0x15,
521 &info);
523 rpccli_samr_Close(cli, mem_ctx, &user_pol);
525 if (!NT_STATUS_IS_OK(result))
526 return result;
528 sid_compose(&user_info->user_sid, &domain->sid, user_rid);
529 sid_compose(&user_info->group_sid, &domain->sid,
530 info->info21.primary_gid);
531 user_info->acct_name = talloc_strdup(mem_ctx,
532 info->info21.account_name.string);
533 user_info->full_name = talloc_strdup(mem_ctx,
534 info->info21.full_name.string);
535 user_info->homedir = NULL;
536 user_info->shell = NULL;
537 user_info->primary_gid = (gid_t)-1;
539 return NT_STATUS_OK;
542 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
543 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
544 TALLOC_CTX *mem_ctx,
545 const DOM_SID *user_sid,
546 uint32 *num_groups, DOM_SID **user_grpsids)
548 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
549 struct policy_handle dom_pol, user_pol;
550 uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
551 struct samr_RidWithAttributeArray *rid_array = NULL;
552 unsigned int i;
553 uint32 user_rid;
554 struct rpc_pipe_client *cli;
556 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid)));
558 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
559 return NT_STATUS_UNSUCCESSFUL;
561 *num_groups = 0;
562 *user_grpsids = NULL;
564 /* so lets see if we have a cached user_info_3 */
565 result = lookup_usergroups_cached(domain, mem_ctx, user_sid,
566 num_groups, user_grpsids);
568 if (NT_STATUS_IS_OK(result)) {
569 return NT_STATUS_OK;
572 if ( !winbindd_can_contact_domain( domain ) ) {
573 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
574 domain->name));
576 /* Tell the cache manager not to remember this one */
578 return NT_STATUS_SYNCHRONIZATION_REQUIRED;
581 /* no cache; hit the wire */
583 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
584 if (!NT_STATUS_IS_OK(result))
585 return result;
587 /* Get user handle */
588 result = rpccli_samr_OpenUser(cli, mem_ctx,
589 &dom_pol,
590 des_access,
591 user_rid,
592 &user_pol);
594 if (!NT_STATUS_IS_OK(result))
595 return result;
597 /* Query user rids */
598 result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
599 &user_pol,
600 &rid_array);
601 *num_groups = rid_array->count;
603 rpccli_samr_Close(cli, mem_ctx, &user_pol);
605 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
606 return result;
608 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
609 if (!(*user_grpsids))
610 return NT_STATUS_NO_MEMORY;
612 for (i=0;i<(*num_groups);i++) {
613 sid_copy(&((*user_grpsids)[i]), &domain->sid);
614 sid_append_rid(&((*user_grpsids)[i]),
615 rid_array->rids[i].rid);
618 return NT_STATUS_OK;
621 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
623 static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
624 TALLOC_CTX *mem_ctx,
625 uint32 num_sids, const DOM_SID *sids,
626 uint32 *num_aliases,
627 uint32 **alias_rids)
629 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
630 struct policy_handle dom_pol;
631 uint32 num_query_sids = 0;
632 int i;
633 struct rpc_pipe_client *cli;
634 struct samr_Ids alias_rids_query;
635 int rangesize = MAX_SAM_ENTRIES_W2K;
636 uint32 total_sids = 0;
637 int num_queries = 1;
639 *num_aliases = 0;
640 *alias_rids = NULL;
642 DEBUG(3,("rpc: lookup_useraliases\n"));
644 if ( !winbindd_can_contact_domain( domain ) ) {
645 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
646 domain->name));
647 return NT_STATUS_OK;
650 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
651 if (!NT_STATUS_IS_OK(result))
652 return result;
654 do {
655 /* prepare query */
656 struct lsa_SidArray sid_array;
658 ZERO_STRUCT(sid_array);
660 num_query_sids = MIN(num_sids - total_sids, rangesize);
662 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
663 num_queries, num_query_sids));
665 if (num_query_sids) {
666 sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
667 if (sid_array.sids == NULL) {
668 return NT_STATUS_NO_MEMORY;
670 } else {
671 sid_array.sids = NULL;
674 for (i=0; i<num_query_sids; i++) {
675 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]);
676 if (!sid_array.sids[i].sid) {
677 TALLOC_FREE(sid_array.sids);
678 return NT_STATUS_NO_MEMORY;
681 sid_array.num_sids = num_query_sids;
683 /* do request */
684 result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
685 &dom_pol,
686 &sid_array,
687 &alias_rids_query);
689 if (!NT_STATUS_IS_OK(result)) {
690 *num_aliases = 0;
691 *alias_rids = NULL;
692 TALLOC_FREE(sid_array.sids);
693 goto done;
696 /* process output */
698 for (i=0; i<alias_rids_query.count; i++) {
699 size_t na = *num_aliases;
700 if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],
701 alias_rids, &na)) {
702 return NT_STATUS_NO_MEMORY;
704 *num_aliases = na;
707 TALLOC_FREE(sid_array.sids);
709 num_queries++;
711 } while (total_sids < num_sids);
713 done:
714 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
715 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
717 return result;
721 /* Lookup group membership given a rid. */
722 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
723 TALLOC_CTX *mem_ctx,
724 const DOM_SID *group_sid,
725 enum lsa_SidType type,
726 uint32 *num_names,
727 DOM_SID **sid_mem, char ***names,
728 uint32 **name_types)
730 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
731 uint32 i, total_names = 0;
732 struct policy_handle dom_pol, group_pol;
733 uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
734 uint32 *rid_mem = NULL;
735 uint32 group_rid;
736 unsigned int j, r;
737 struct rpc_pipe_client *cli;
738 unsigned int orig_timeout;
739 struct samr_RidTypeArray *rids = NULL;
741 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
742 sid_string_dbg(group_sid)));
744 if ( !winbindd_can_contact_domain( domain ) ) {
745 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
746 domain->name));
747 return NT_STATUS_OK;
750 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
751 return NT_STATUS_UNSUCCESSFUL;
753 *num_names = 0;
755 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
756 if (!NT_STATUS_IS_OK(result))
757 return result;
759 result = rpccli_samr_OpenGroup(cli, mem_ctx,
760 &dom_pol,
761 des_access,
762 group_rid,
763 &group_pol);
765 if (!NT_STATUS_IS_OK(result))
766 return result;
768 /* Step #1: Get a list of user rids that are the members of the
769 group. */
771 /* This call can take a long time - allow the server to time out.
772 35 seconds should do it. */
774 orig_timeout = rpccli_set_timeout(cli, 35000);
776 result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
777 &group_pol,
778 &rids);
780 /* And restore our original timeout. */
781 rpccli_set_timeout(cli, orig_timeout);
783 rpccli_samr_Close(cli, mem_ctx, &group_pol);
785 if (!NT_STATUS_IS_OK(result))
786 return result;
788 *num_names = rids->count;
789 rid_mem = rids->rids;
791 if (!*num_names) {
792 names = NULL;
793 name_types = NULL;
794 sid_mem = NULL;
795 return NT_STATUS_OK;
798 /* Step #2: Convert list of rids into list of usernames. Do this
799 in bunches of ~1000 to avoid crashing NT4. It looks like there
800 is a buffer overflow or something like that lurking around
801 somewhere. */
803 #define MAX_LOOKUP_RIDS 900
805 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
806 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
807 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
809 for (j=0;j<(*num_names);j++)
810 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
812 if (*num_names>0 && (!*names || !*name_types))
813 return NT_STATUS_NO_MEMORY;
815 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
816 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
817 struct lsa_Strings tmp_names;
818 struct samr_Ids tmp_types;
820 /* Lookup a chunk of rids */
822 result = rpccli_samr_LookupRids(cli, mem_ctx,
823 &dom_pol,
824 num_lookup_rids,
825 &rid_mem[i],
826 &tmp_names,
827 &tmp_types);
829 /* see if we have a real error (and yes the
830 STATUS_SOME_UNMAPPED is the one returned from 2k) */
832 if (!NT_STATUS_IS_OK(result) &&
833 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
834 return result;
836 /* Copy result into array. The talloc system will take
837 care of freeing the temporary arrays later on. */
839 if (tmp_names.count != tmp_types.count) {
840 return NT_STATUS_UNSUCCESSFUL;
843 for (r=0; r<tmp_names.count; r++) {
844 if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
845 continue;
847 (*names)[total_names] = fill_domain_username_talloc(
848 mem_ctx, domain->name,
849 tmp_names.names[r].string, true);
850 (*name_types)[total_names] = tmp_types.ids[r];
851 total_names += 1;
855 *num_names = total_names;
857 return NT_STATUS_OK;
860 #ifdef HAVE_LDAP
862 #include <ldap.h>
864 static int get_ldap_seq(const char *server, int port, uint32 *seq)
866 int ret = -1;
867 struct timeval to;
868 const char *attrs[] = {"highestCommittedUSN", NULL};
869 LDAPMessage *res = NULL;
870 char **values = NULL;
871 LDAP *ldp = NULL;
873 *seq = DOM_SEQUENCE_NONE;
876 * Parameterised (5) second timeout on open. This is needed as the
877 * search timeout doesn't seem to apply to doing an open as well. JRA.
880 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
881 if (ldp == NULL)
882 return -1;
884 /* Timeout if no response within 20 seconds. */
885 to.tv_sec = 10;
886 to.tv_usec = 0;
888 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
889 CONST_DISCARD(char **, attrs), 0, &to, &res))
890 goto done;
892 if (ldap_count_entries(ldp, res) != 1)
893 goto done;
895 values = ldap_get_values(ldp, res, "highestCommittedUSN");
896 if (!values || !values[0])
897 goto done;
899 *seq = atoi(values[0]);
900 ret = 0;
902 done:
904 if (values)
905 ldap_value_free(values);
906 if (res)
907 ldap_msgfree(res);
908 if (ldp)
909 ldap_unbind(ldp);
910 return ret;
913 /**********************************************************************
914 Get the sequence number for a Windows AD native mode domain using
915 LDAP queries.
916 **********************************************************************/
918 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
920 int ret = -1;
921 char addr[INET6_ADDRSTRLEN];
923 print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
924 if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
925 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
926 "number for Domain (%s) from DC (%s)\n",
927 domain->name, addr));
929 return ret;
932 #endif /* HAVE_LDAP */
934 /* find the sequence number for a domain */
935 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
937 TALLOC_CTX *mem_ctx;
938 union samr_DomainInfo *info = NULL;
939 NTSTATUS result;
940 struct policy_handle dom_pol;
941 bool got_seq_num = False;
942 struct rpc_pipe_client *cli;
944 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
946 if ( !winbindd_can_contact_domain( domain ) ) {
947 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
948 domain->name));
949 *seq = time(NULL);
950 return NT_STATUS_OK;
953 *seq = DOM_SEQUENCE_NONE;
955 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
956 return NT_STATUS_NO_MEMORY;
958 #ifdef HAVE_LDAP
959 if ( domain->active_directory )
961 int res;
963 DEBUG(8,("using get_ldap_seq() to retrieve the "
964 "sequence number\n"));
966 res = get_ldap_sequence_number( domain, seq );
967 if (res == 0)
969 result = NT_STATUS_OK;
970 DEBUG(10,("domain_sequence_number: LDAP for "
971 "domain %s is %u\n",
972 domain->name, *seq));
973 goto done;
976 DEBUG(10,("domain_sequence_number: failed to get LDAP "
977 "sequence number for domain %s\n",
978 domain->name ));
980 #endif /* HAVE_LDAP */
982 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
983 if (!NT_STATUS_IS_OK(result)) {
984 goto done;
987 /* Query domain info */
989 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
990 &dom_pol,
992 &info);
994 if (NT_STATUS_IS_OK(result)) {
995 *seq = info->info8.sequence_num;
996 got_seq_num = True;
997 goto seq_num;
1000 /* retry with info-level 2 in case the dc does not support info-level 8
1001 * (like all older samba2 and samba3 dc's) - Guenther */
1003 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1004 &dom_pol,
1006 &info);
1008 if (NT_STATUS_IS_OK(result)) {
1009 *seq = info->general.sequence_num;
1010 got_seq_num = True;
1013 seq_num:
1014 if (got_seq_num) {
1015 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1016 domain->name, (unsigned)*seq));
1017 } else {
1018 DEBUG(10,("domain_sequence_number: failed to get sequence "
1019 "number (%u) for domain %s\n",
1020 (unsigned)*seq, domain->name ));
1023 done:
1025 talloc_destroy(mem_ctx);
1027 return result;
1030 /* get a list of trusted domains */
1031 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
1032 TALLOC_CTX *mem_ctx,
1033 uint32 *num_domains,
1034 char ***names,
1035 char ***alt_names,
1036 DOM_SID **dom_sids)
1038 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1039 uint32 enum_ctx = 0;
1040 struct rpc_pipe_client *cli;
1041 struct policy_handle lsa_policy;
1043 DEBUG(3,("rpc: trusted_domains\n"));
1045 *num_domains = 0;
1046 *names = NULL;
1047 *alt_names = NULL;
1048 *dom_sids = NULL;
1050 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1051 if (!NT_STATUS_IS_OK(result))
1052 return result;
1054 result = STATUS_MORE_ENTRIES;
1056 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1057 uint32 start_idx;
1058 int i;
1059 struct lsa_DomainList dom_list;
1061 result = rpccli_lsa_EnumTrustDom(cli, mem_ctx,
1062 &lsa_policy,
1063 &enum_ctx,
1064 &dom_list,
1065 (uint32_t)-1);
1067 if (!NT_STATUS_IS_OK(result) &&
1068 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
1069 break;
1071 start_idx = *num_domains;
1072 *num_domains += dom_list.count;
1073 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
1074 char *, *num_domains);
1075 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
1076 DOM_SID, *num_domains);
1077 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,
1078 char *, *num_domains);
1079 if ((*names == NULL) || (*dom_sids == NULL) ||
1080 (*alt_names == NULL))
1081 return NT_STATUS_NO_MEMORY;
1083 for (i=0; i<dom_list.count; i++) {
1084 (*names)[start_idx+i] = CONST_DISCARD(char *, dom_list.domains[i].name.string);
1085 (*dom_sids)[start_idx+i] = *dom_list.domains[i].sid;
1086 (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
1089 return result;
1092 /* find the lockout policy for a domain */
1093 static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
1094 TALLOC_CTX *mem_ctx,
1095 struct samr_DomInfo12 *lockout_policy)
1097 NTSTATUS result;
1098 struct rpc_pipe_client *cli;
1099 struct policy_handle dom_pol;
1100 union samr_DomainInfo *info = NULL;
1102 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
1104 if ( !winbindd_can_contact_domain( domain ) ) {
1105 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1106 domain->name));
1107 return NT_STATUS_NOT_SUPPORTED;
1110 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1111 if (!NT_STATUS_IS_OK(result)) {
1112 goto done;
1115 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1116 &dom_pol,
1118 &info);
1119 if (!NT_STATUS_IS_OK(result)) {
1120 goto done;
1123 *lockout_policy = info->info12;
1125 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1126 info->info12.lockout_threshold));
1128 done:
1130 return result;
1133 /* find the password policy for a domain */
1134 static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1135 TALLOC_CTX *mem_ctx,
1136 struct samr_DomInfo1 *password_policy)
1138 NTSTATUS result;
1139 struct rpc_pipe_client *cli;
1140 struct policy_handle dom_pol;
1141 union samr_DomainInfo *info = NULL;
1143 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
1145 if ( !winbindd_can_contact_domain( domain ) ) {
1146 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1147 domain->name));
1148 return NT_STATUS_NOT_SUPPORTED;
1151 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1152 if (!NT_STATUS_IS_OK(result)) {
1153 goto done;
1156 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1157 &dom_pol,
1159 &info);
1160 if (!NT_STATUS_IS_OK(result)) {
1161 goto done;
1164 *password_policy = info->info1;
1166 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1167 info->info1.min_password_length));
1169 done:
1171 return result;
1174 typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli,
1175 TALLOC_CTX *mem_ctx,
1176 struct policy_handle *pol,
1177 int num_sids,
1178 const DOM_SID *sids,
1179 char ***pdomains,
1180 char ***pnames,
1181 enum lsa_SidType **ptypes);
1183 NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
1184 struct winbindd_domain *domain,
1185 uint32_t num_sids,
1186 const struct dom_sid *sids,
1187 char ***domains,
1188 char ***names,
1189 enum lsa_SidType **types)
1191 NTSTATUS status;
1192 struct rpc_pipe_client *cli = NULL;
1193 struct policy_handle lsa_policy;
1194 unsigned int orig_timeout;
1195 lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;
1197 if (domain->can_do_ncacn_ip_tcp) {
1198 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1199 if (NT_STATUS_IS_OK(status)) {
1200 lookup_sids_fn = rpccli_lsa_lookup_sids3;
1201 goto lookup;
1203 domain->can_do_ncacn_ip_tcp = false;
1205 status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1207 if (!NT_STATUS_IS_OK(status)) {
1208 return status;
1211 lookup:
1213 * This call can take a long time
1214 * allow the server to time out.
1215 * 35 seconds should do it.
1217 orig_timeout = rpccli_set_timeout(cli, 35000);
1219 status = lookup_sids_fn(cli,
1220 mem_ctx,
1221 &lsa_policy,
1222 num_sids,
1223 sids,
1224 domains,
1225 names,
1226 types);
1228 /* And restore our original timeout. */
1229 rpccli_set_timeout(cli, orig_timeout);
1231 if (!NT_STATUS_IS_OK(status)) {
1232 return status;
1235 return status;
1238 typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
1239 TALLOC_CTX *mem_ctx,
1240 struct policy_handle *pol,
1241 int num_names,
1242 const char **names,
1243 const char ***dom_names,
1244 int level,
1245 struct dom_sid **sids,
1246 enum lsa_SidType **types);
1248 NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
1249 struct winbindd_domain *domain,
1250 uint32_t num_names,
1251 const char **names,
1252 const char ***domains,
1253 struct dom_sid **sids,
1254 enum lsa_SidType **types)
1256 NTSTATUS status;
1257 struct rpc_pipe_client *cli = NULL;
1258 struct policy_handle lsa_policy;
1259 unsigned int orig_timeout;
1260 lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names;
1262 if (domain->can_do_ncacn_ip_tcp) {
1263 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1264 if (NT_STATUS_IS_OK(status)) {
1265 lookup_names_fn = rpccli_lsa_lookup_names4;
1266 goto lookup;
1268 domain->can_do_ncacn_ip_tcp = false;
1270 status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1272 if (!NT_STATUS_IS_OK(status)) {
1273 return status;
1276 lookup:
1279 * This call can take a long time
1280 * allow the server to time out.
1281 * 35 seconds should do it.
1283 orig_timeout = rpccli_set_timeout(cli, 35000);
1285 status = lookup_names_fn(cli,
1286 mem_ctx,
1287 &lsa_policy,
1288 num_names,
1289 (const char **) names,
1290 domains,
1292 sids,
1293 types);
1295 /* And restore our original timeout. */
1296 rpccli_set_timeout(cli, orig_timeout);
1298 if (!NT_STATUS_IS_OK(status)) {
1299 return status;
1302 return status;
1305 /* the rpc backend methods are exposed via this structure */
1306 struct winbindd_methods msrpc_methods = {
1307 False,
1308 query_user_list,
1309 enum_dom_groups,
1310 enum_local_groups,
1311 msrpc_name_to_sid,
1312 msrpc_sid_to_name,
1313 msrpc_rids_to_names,
1314 query_user,
1315 lookup_usergroups,
1316 msrpc_lookup_useraliases,
1317 lookup_groupmem,
1318 sequence_number,
1319 msrpc_lockout_policy,
1320 msrpc_password_policy,
1321 trusted_domains,