s4:upgradeprovision Rework script, and reset machine account pw
[Samba/cd1.git] / source3 / winbindd / winbindd_rpc.c
blobb92637072277b0fe7dafa1bb8ef7a70c23511b31
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 NT_STATUS_OK;
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 NT_STATUS_OK;
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_copy(&((*user_grpsids)[i]), &domain->sid);
616 sid_append_rid(&((*user_grpsids)[i]),
617 rid_array->rids[i].rid);
620 return NT_STATUS_OK;
623 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
625 static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
626 TALLOC_CTX *mem_ctx,
627 uint32 num_sids, const DOM_SID *sids,
628 uint32 *num_aliases,
629 uint32 **alias_rids)
631 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
632 struct policy_handle dom_pol;
633 uint32 num_query_sids = 0;
634 int i;
635 struct rpc_pipe_client *cli;
636 struct samr_Ids alias_rids_query;
637 int rangesize = MAX_SAM_ENTRIES_W2K;
638 uint32 total_sids = 0;
639 int num_queries = 1;
641 *num_aliases = 0;
642 *alias_rids = NULL;
644 DEBUG(3,("rpc: lookup_useraliases\n"));
646 if ( !winbindd_can_contact_domain( domain ) ) {
647 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
648 domain->name));
649 return NT_STATUS_OK;
652 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
653 if (!NT_STATUS_IS_OK(result))
654 return result;
656 do {
657 /* prepare query */
658 struct lsa_SidArray sid_array;
660 ZERO_STRUCT(sid_array);
662 num_query_sids = MIN(num_sids - total_sids, rangesize);
664 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
665 num_queries, num_query_sids));
667 if (num_query_sids) {
668 sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
669 if (sid_array.sids == NULL) {
670 return NT_STATUS_NO_MEMORY;
672 } else {
673 sid_array.sids = NULL;
676 for (i=0; i<num_query_sids; i++) {
677 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]);
678 if (!sid_array.sids[i].sid) {
679 TALLOC_FREE(sid_array.sids);
680 return NT_STATUS_NO_MEMORY;
683 sid_array.num_sids = num_query_sids;
685 /* do request */
686 result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
687 &dom_pol,
688 &sid_array,
689 &alias_rids_query);
691 if (!NT_STATUS_IS_OK(result)) {
692 *num_aliases = 0;
693 *alias_rids = NULL;
694 TALLOC_FREE(sid_array.sids);
695 goto done;
698 /* process output */
700 for (i=0; i<alias_rids_query.count; i++) {
701 size_t na = *num_aliases;
702 if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],
703 alias_rids, &na)) {
704 return NT_STATUS_NO_MEMORY;
706 *num_aliases = na;
709 TALLOC_FREE(sid_array.sids);
711 num_queries++;
713 } while (total_sids < num_sids);
715 done:
716 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
717 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
719 return result;
723 /* Lookup group membership given a rid. */
724 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
725 TALLOC_CTX *mem_ctx,
726 const DOM_SID *group_sid,
727 enum lsa_SidType type,
728 uint32 *num_names,
729 DOM_SID **sid_mem, char ***names,
730 uint32 **name_types)
732 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
733 uint32 i, total_names = 0;
734 struct policy_handle dom_pol, group_pol;
735 uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
736 uint32 *rid_mem = NULL;
737 uint32 group_rid;
738 unsigned int j, r;
739 struct rpc_pipe_client *cli;
740 unsigned int orig_timeout;
741 struct samr_RidTypeArray *rids = NULL;
743 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
744 sid_string_dbg(group_sid)));
746 if ( !winbindd_can_contact_domain( domain ) ) {
747 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
748 domain->name));
749 return NT_STATUS_OK;
752 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
753 return NT_STATUS_UNSUCCESSFUL;
755 *num_names = 0;
757 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
758 if (!NT_STATUS_IS_OK(result))
759 return result;
761 result = rpccli_samr_OpenGroup(cli, mem_ctx,
762 &dom_pol,
763 des_access,
764 group_rid,
765 &group_pol);
767 if (!NT_STATUS_IS_OK(result))
768 return result;
770 /* Step #1: Get a list of user rids that are the members of the
771 group. */
773 /* This call can take a long time - allow the server to time out.
774 35 seconds should do it. */
776 orig_timeout = rpccli_set_timeout(cli, 35000);
778 result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
779 &group_pol,
780 &rids);
782 /* And restore our original timeout. */
783 rpccli_set_timeout(cli, orig_timeout);
785 rpccli_samr_Close(cli, mem_ctx, &group_pol);
787 if (!NT_STATUS_IS_OK(result))
788 return result;
790 *num_names = rids->count;
791 rid_mem = rids->rids;
793 if (!*num_names) {
794 names = NULL;
795 name_types = NULL;
796 sid_mem = NULL;
797 return NT_STATUS_OK;
800 /* Step #2: Convert list of rids into list of usernames. Do this
801 in bunches of ~1000 to avoid crashing NT4. It looks like there
802 is a buffer overflow or something like that lurking around
803 somewhere. */
805 #define MAX_LOOKUP_RIDS 900
807 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
808 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
809 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
811 for (j=0;j<(*num_names);j++)
812 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
814 if (*num_names>0 && (!*names || !*name_types))
815 return NT_STATUS_NO_MEMORY;
817 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
818 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
819 struct lsa_Strings tmp_names;
820 struct samr_Ids tmp_types;
822 /* Lookup a chunk of rids */
824 result = rpccli_samr_LookupRids(cli, mem_ctx,
825 &dom_pol,
826 num_lookup_rids,
827 &rid_mem[i],
828 &tmp_names,
829 &tmp_types);
831 /* see if we have a real error (and yes the
832 STATUS_SOME_UNMAPPED is the one returned from 2k) */
834 if (!NT_STATUS_IS_OK(result) &&
835 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
836 return result;
838 /* Copy result into array. The talloc system will take
839 care of freeing the temporary arrays later on. */
841 if (tmp_names.count != tmp_types.count) {
842 return NT_STATUS_UNSUCCESSFUL;
845 for (r=0; r<tmp_names.count; r++) {
846 if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
847 continue;
849 (*names)[total_names] = fill_domain_username_talloc(
850 mem_ctx, domain->name,
851 tmp_names.names[r].string, true);
852 (*name_types)[total_names] = tmp_types.ids[r];
853 total_names += 1;
857 *num_names = total_names;
859 return NT_STATUS_OK;
862 #ifdef HAVE_LDAP
864 #include <ldap.h>
866 static int get_ldap_seq(const char *server, int port, uint32 *seq)
868 int ret = -1;
869 struct timeval to;
870 const char *attrs[] = {"highestCommittedUSN", NULL};
871 LDAPMessage *res = NULL;
872 char **values = NULL;
873 LDAP *ldp = NULL;
875 *seq = DOM_SEQUENCE_NONE;
878 * Parameterised (5) second timeout on open. This is needed as the
879 * search timeout doesn't seem to apply to doing an open as well. JRA.
882 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
883 if (ldp == NULL)
884 return -1;
886 /* Timeout if no response within 20 seconds. */
887 to.tv_sec = 10;
888 to.tv_usec = 0;
890 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
891 CONST_DISCARD(char **, attrs), 0, &to, &res))
892 goto done;
894 if (ldap_count_entries(ldp, res) != 1)
895 goto done;
897 values = ldap_get_values(ldp, res, "highestCommittedUSN");
898 if (!values || !values[0])
899 goto done;
901 *seq = atoi(values[0]);
902 ret = 0;
904 done:
906 if (values)
907 ldap_value_free(values);
908 if (res)
909 ldap_msgfree(res);
910 if (ldp)
911 ldap_unbind(ldp);
912 return ret;
915 /**********************************************************************
916 Get the sequence number for a Windows AD native mode domain using
917 LDAP queries.
918 **********************************************************************/
920 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
922 int ret = -1;
923 char addr[INET6_ADDRSTRLEN];
925 print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
926 if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
927 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
928 "number for Domain (%s) from DC (%s)\n",
929 domain->name, addr));
931 return ret;
934 #endif /* HAVE_LDAP */
936 /* find the sequence number for a domain */
937 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
939 TALLOC_CTX *mem_ctx;
940 union samr_DomainInfo *info = NULL;
941 NTSTATUS result;
942 struct policy_handle dom_pol;
943 bool got_seq_num = False;
944 struct rpc_pipe_client *cli;
946 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
948 if ( !winbindd_can_contact_domain( domain ) ) {
949 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
950 domain->name));
951 *seq = time(NULL);
952 return NT_STATUS_OK;
955 *seq = DOM_SEQUENCE_NONE;
957 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
958 return NT_STATUS_NO_MEMORY;
960 #ifdef HAVE_LDAP
961 if ( domain->active_directory )
963 int res;
965 DEBUG(8,("using get_ldap_seq() to retrieve the "
966 "sequence number\n"));
968 res = get_ldap_sequence_number( domain, seq );
969 if (res == 0)
971 result = NT_STATUS_OK;
972 DEBUG(10,("domain_sequence_number: LDAP for "
973 "domain %s is %u\n",
974 domain->name, *seq));
975 goto done;
978 DEBUG(10,("domain_sequence_number: failed to get LDAP "
979 "sequence number for domain %s\n",
980 domain->name ));
982 #endif /* HAVE_LDAP */
984 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
985 if (!NT_STATUS_IS_OK(result)) {
986 goto done;
989 /* Query domain info */
991 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
992 &dom_pol,
994 &info);
996 if (NT_STATUS_IS_OK(result)) {
997 *seq = info->info8.sequence_num;
998 got_seq_num = True;
999 goto seq_num;
1002 /* retry with info-level 2 in case the dc does not support info-level 8
1003 * (like all older samba2 and samba3 dc's) - Guenther */
1005 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1006 &dom_pol,
1008 &info);
1010 if (NT_STATUS_IS_OK(result)) {
1011 *seq = info->general.sequence_num;
1012 got_seq_num = True;
1015 seq_num:
1016 if (got_seq_num) {
1017 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1018 domain->name, (unsigned)*seq));
1019 } else {
1020 DEBUG(10,("domain_sequence_number: failed to get sequence "
1021 "number (%u) for domain %s\n",
1022 (unsigned)*seq, domain->name ));
1025 done:
1027 talloc_destroy(mem_ctx);
1029 return result;
1032 /* get a list of trusted domains */
1033 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
1034 TALLOC_CTX *mem_ctx,
1035 uint32 *num_domains,
1036 char ***names,
1037 char ***alt_names,
1038 DOM_SID **dom_sids)
1040 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1041 uint32 enum_ctx = 0;
1042 struct rpc_pipe_client *cli;
1043 struct policy_handle lsa_policy;
1045 DEBUG(3,("rpc: trusted_domains\n"));
1047 *num_domains = 0;
1048 *names = NULL;
1049 *alt_names = NULL;
1050 *dom_sids = NULL;
1052 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1053 if (!NT_STATUS_IS_OK(result))
1054 return result;
1056 result = STATUS_MORE_ENTRIES;
1058 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1059 uint32 start_idx;
1060 int i;
1061 struct lsa_DomainList dom_list;
1063 result = rpccli_lsa_EnumTrustDom(cli, mem_ctx,
1064 &lsa_policy,
1065 &enum_ctx,
1066 &dom_list,
1067 (uint32_t)-1);
1069 if (!NT_STATUS_IS_OK(result) &&
1070 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
1071 break;
1073 start_idx = *num_domains;
1074 *num_domains += dom_list.count;
1075 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
1076 char *, *num_domains);
1077 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
1078 DOM_SID, *num_domains);
1079 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,
1080 char *, *num_domains);
1081 if ((*names == NULL) || (*dom_sids == NULL) ||
1082 (*alt_names == NULL))
1083 return NT_STATUS_NO_MEMORY;
1085 for (i=0; i<dom_list.count; i++) {
1086 (*names)[start_idx+i] = CONST_DISCARD(char *, dom_list.domains[i].name.string);
1087 (*dom_sids)[start_idx+i] = *dom_list.domains[i].sid;
1088 (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
1091 return result;
1094 /* find the lockout policy for a domain */
1095 static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
1096 TALLOC_CTX *mem_ctx,
1097 struct samr_DomInfo12 *lockout_policy)
1099 NTSTATUS result;
1100 struct rpc_pipe_client *cli;
1101 struct policy_handle dom_pol;
1102 union samr_DomainInfo *info = NULL;
1104 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
1106 if ( !winbindd_can_contact_domain( domain ) ) {
1107 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1108 domain->name));
1109 return NT_STATUS_NOT_SUPPORTED;
1112 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1113 if (!NT_STATUS_IS_OK(result)) {
1114 goto done;
1117 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1118 &dom_pol,
1120 &info);
1121 if (!NT_STATUS_IS_OK(result)) {
1122 goto done;
1125 *lockout_policy = info->info12;
1127 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1128 info->info12.lockout_threshold));
1130 done:
1132 return result;
1135 /* find the password policy for a domain */
1136 static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1137 TALLOC_CTX *mem_ctx,
1138 struct samr_DomInfo1 *password_policy)
1140 NTSTATUS result;
1141 struct rpc_pipe_client *cli;
1142 struct policy_handle dom_pol;
1143 union samr_DomainInfo *info = NULL;
1145 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
1147 if ( !winbindd_can_contact_domain( domain ) ) {
1148 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1149 domain->name));
1150 return NT_STATUS_NOT_SUPPORTED;
1153 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1154 if (!NT_STATUS_IS_OK(result)) {
1155 goto done;
1158 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1159 &dom_pol,
1161 &info);
1162 if (!NT_STATUS_IS_OK(result)) {
1163 goto done;
1166 *password_policy = info->info1;
1168 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1169 info->info1.min_password_length));
1171 done:
1173 return result;
1176 typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli,
1177 TALLOC_CTX *mem_ctx,
1178 struct policy_handle *pol,
1179 int num_sids,
1180 const DOM_SID *sids,
1181 char ***pdomains,
1182 char ***pnames,
1183 enum lsa_SidType **ptypes);
1185 NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
1186 struct winbindd_domain *domain,
1187 uint32_t num_sids,
1188 const struct dom_sid *sids,
1189 char ***domains,
1190 char ***names,
1191 enum lsa_SidType **types)
1193 NTSTATUS status;
1194 struct rpc_pipe_client *cli = NULL;
1195 struct policy_handle lsa_policy;
1196 unsigned int orig_timeout;
1197 lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;
1199 if (domain->can_do_ncacn_ip_tcp) {
1200 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1201 if (NT_STATUS_IS_OK(status)) {
1202 lookup_sids_fn = rpccli_lsa_lookup_sids3;
1203 goto lookup;
1205 domain->can_do_ncacn_ip_tcp = false;
1207 status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1209 if (!NT_STATUS_IS_OK(status)) {
1210 return status;
1213 lookup:
1215 * This call can take a long time
1216 * allow the server to time out.
1217 * 35 seconds should do it.
1219 orig_timeout = rpccli_set_timeout(cli, 35000);
1221 status = lookup_sids_fn(cli,
1222 mem_ctx,
1223 &lsa_policy,
1224 num_sids,
1225 sids,
1226 domains,
1227 names,
1228 types);
1230 /* And restore our original timeout. */
1231 rpccli_set_timeout(cli, orig_timeout);
1233 if (!NT_STATUS_IS_OK(status)) {
1234 return status;
1237 return status;
1240 typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
1241 TALLOC_CTX *mem_ctx,
1242 struct policy_handle *pol,
1243 int num_names,
1244 const char **names,
1245 const char ***dom_names,
1246 int level,
1247 struct dom_sid **sids,
1248 enum lsa_SidType **types);
1250 NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
1251 struct winbindd_domain *domain,
1252 uint32_t num_names,
1253 const char **names,
1254 const char ***domains,
1255 struct dom_sid **sids,
1256 enum lsa_SidType **types)
1258 NTSTATUS status;
1259 struct rpc_pipe_client *cli = NULL;
1260 struct policy_handle lsa_policy;
1261 unsigned int orig_timeout;
1262 lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names;
1264 if (domain->can_do_ncacn_ip_tcp) {
1265 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1266 if (NT_STATUS_IS_OK(status)) {
1267 lookup_names_fn = rpccli_lsa_lookup_names4;
1268 goto lookup;
1270 domain->can_do_ncacn_ip_tcp = false;
1272 status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1274 if (!NT_STATUS_IS_OK(status)) {
1275 return status;
1278 lookup:
1281 * This call can take a long time
1282 * allow the server to time out.
1283 * 35 seconds should do it.
1285 orig_timeout = rpccli_set_timeout(cli, 35000);
1287 status = lookup_names_fn(cli,
1288 mem_ctx,
1289 &lsa_policy,
1290 num_names,
1291 (const char **) names,
1292 domains,
1294 sids,
1295 types);
1297 /* And restore our original timeout. */
1298 rpccli_set_timeout(cli, orig_timeout);
1300 if (!NT_STATUS_IS_OK(status)) {
1301 return status;
1304 return status;
1307 /* the rpc backend methods are exposed via this structure */
1308 struct winbindd_methods msrpc_methods = {
1309 False,
1310 query_user_list,
1311 enum_dom_groups,
1312 enum_local_groups,
1313 msrpc_name_to_sid,
1314 msrpc_sid_to_name,
1315 msrpc_rids_to_names,
1316 query_user,
1317 lookup_usergroups,
1318 msrpc_lookup_useraliases,
1319 lookup_groupmem,
1320 sequence_number,
1321 msrpc_lockout_policy,
1322 msrpc_password_policy,
1323 trusted_domains,