s3-netlogon: match all logon levels in netr_SamLogon calls.
[Samba/aatanasov.git] / source3 / winbindd / winbindd_rpc.c
blobf664f222322f056d1f0026c6b9c781479baa18b4
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 struct rpc_pipe_client *cli;
282 struct policy_handle lsa_policy;
283 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
284 char *mapped_name = NULL;
285 unsigned int orig_timeout;
287 if (name == NULL || *name=='\0') {
288 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
289 } else if (domain_name == NULL || *domain_name == '\0') {
290 full_name = talloc_asprintf(mem_ctx, "%s", name);
291 } else {
292 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
294 if (!full_name) {
295 DEBUG(0, ("talloc_asprintf failed!\n"));
296 return NT_STATUS_NO_MEMORY;
299 DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
301 name_map_status = normalize_name_unmap(mem_ctx, full_name,
302 &mapped_name);
304 /* Reset the full_name pointer if we mapped anytthing */
306 if (NT_STATUS_IS_OK(name_map_status) ||
307 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
309 full_name = mapped_name;
312 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
313 full_name?full_name:"", domain_name ));
315 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
316 if (!NT_STATUS_IS_OK(result))
317 return result;
320 * This call can take a long time
321 * allow the server to time out.
322 * 35 seconds should do it.
324 orig_timeout = rpccli_set_timeout(cli, 35000);
326 result = rpccli_lsa_lookup_names(cli, mem_ctx, &lsa_policy, 1,
327 (const char**) &full_name, NULL, 1, &sids, &types);
329 /* And restore our original timeout. */
330 rpccli_set_timeout(cli, orig_timeout);
332 if (!NT_STATUS_IS_OK(result))
333 return result;
335 /* Return rid and type if lookup successful */
337 sid_copy(sid, &sids[0]);
338 *type = types[0];
340 return NT_STATUS_OK;
344 convert a domain SID to a user or group name
346 static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
347 TALLOC_CTX *mem_ctx,
348 const DOM_SID *sid,
349 char **domain_name,
350 char **name,
351 enum lsa_SidType *type)
353 char **domains;
354 char **names;
355 enum lsa_SidType *types = NULL;
356 NTSTATUS result;
357 struct rpc_pipe_client *cli;
358 struct policy_handle lsa_policy;
359 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
360 char *mapped_name = NULL;
361 unsigned int orig_timeout;
363 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
364 domain->name ));
366 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
367 if (!NT_STATUS_IS_OK(result)) {
368 DEBUG(2,("msrpc_sid_to_name: cm_connect_lsa() failed (%s)\n",
369 nt_errstr(result)));
370 return result;
375 * This call can take a long time
376 * allow the server to time out.
377 * 35 seconds should do it.
379 orig_timeout = rpccli_set_timeout(cli, 35000);
381 result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy,
382 1, sid, &domains, &names, &types);
384 /* And restore our original timeout. */
385 rpccli_set_timeout(cli, orig_timeout);
387 if (!NT_STATUS_IS_OK(result)) {
388 DEBUG(2,("msrpc_sid_to_name: rpccli_lsa_lookup_sids() failed (%s)\n",
389 nt_errstr(result)));
390 return result;
393 *type = (enum lsa_SidType)types[0];
394 *domain_name = domains[0];
395 *name = names[0];
397 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
399 name_map_status = normalize_name_map(mem_ctx, domain, *name,
400 &mapped_name);
401 if (NT_STATUS_IS_OK(name_map_status) ||
402 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
404 *name = mapped_name;
405 DEBUG(5,("returning mapped name -- %s\n", *name));
408 return NT_STATUS_OK;
411 static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
412 TALLOC_CTX *mem_ctx,
413 const DOM_SID *sid,
414 uint32 *rids,
415 size_t num_rids,
416 char **domain_name,
417 char ***names,
418 enum lsa_SidType **types)
420 char **domains;
421 NTSTATUS result;
422 struct rpc_pipe_client *cli;
423 struct policy_handle lsa_policy;
424 DOM_SID *sids;
425 size_t i;
426 char **ret_names;
427 unsigned int orig_timeout;
429 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name ));
431 if (num_rids) {
432 sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids);
433 if (sids == NULL) {
434 return NT_STATUS_NO_MEMORY;
436 } else {
437 sids = NULL;
440 for (i=0; i<num_rids; i++) {
441 if (!sid_compose(&sids[i], sid, rids[i])) {
442 return NT_STATUS_INTERNAL_ERROR;
446 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
447 if (!NT_STATUS_IS_OK(result)) {
448 return result;
452 * This call can take a long time
453 * allow the server to time out.
454 * 35 seconds should do it.
456 orig_timeout = rpccli_set_timeout(cli, 35000);
458 result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy,
459 num_rids, sids, &domains,
460 names, types);
462 /* And restore our original timeout. */
463 rpccli_set_timeout(cli, orig_timeout);
465 if (!NT_STATUS_IS_OK(result) &&
466 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
467 return result;
470 ret_names = *names;
471 for (i=0; i<num_rids; i++) {
472 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
473 char *mapped_name = NULL;
475 if ((*types)[i] != SID_NAME_UNKNOWN) {
476 name_map_status = normalize_name_map(mem_ctx,
477 domain,
478 ret_names[i],
479 &mapped_name);
480 if (NT_STATUS_IS_OK(name_map_status) ||
481 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
483 ret_names[i] = mapped_name;
486 *domain_name = domains[i];
490 return result;
493 /* Lookup user information from a rid or username. */
494 static NTSTATUS query_user(struct winbindd_domain *domain,
495 TALLOC_CTX *mem_ctx,
496 const DOM_SID *user_sid,
497 struct wbint_userinfo *user_info)
499 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
500 struct policy_handle dom_pol, user_pol;
501 union samr_UserInfo *info = NULL;
502 uint32 user_rid;
503 struct netr_SamInfo3 *user;
504 struct rpc_pipe_client *cli;
506 DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid)));
508 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
509 return NT_STATUS_UNSUCCESSFUL;
511 user_info->homedir = NULL;
512 user_info->shell = NULL;
513 user_info->primary_gid = (gid_t)-1;
515 /* try netsamlogon cache first */
517 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
520 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
521 sid_string_dbg(user_sid)));
523 sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
524 sid_compose(&user_info->group_sid, &domain->sid,
525 user->base.primary_gid);
527 user_info->acct_name = talloc_strdup(mem_ctx,
528 user->base.account_name.string);
529 user_info->full_name = talloc_strdup(mem_ctx,
530 user->base.full_name.string);
532 TALLOC_FREE(user);
534 return NT_STATUS_OK;
537 if ( !winbindd_can_contact_domain( domain ) ) {
538 DEBUG(10,("query_user: No incoming trust for domain %s\n",
539 domain->name));
540 return NT_STATUS_OK;
543 if ( !winbindd_can_contact_domain( domain ) ) {
544 DEBUG(10,("query_user: No incoming trust for domain %s\n",
545 domain->name));
546 return NT_STATUS_OK;
549 if ( !winbindd_can_contact_domain( domain ) ) {
550 DEBUG(10,("query_user: No incoming trust for domain %s\n",
551 domain->name));
552 return NT_STATUS_OK;
555 /* no cache; hit the wire */
557 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
558 if (!NT_STATUS_IS_OK(result))
559 return result;
561 /* Get user handle */
562 result = rpccli_samr_OpenUser(cli, mem_ctx,
563 &dom_pol,
564 SEC_FLAG_MAXIMUM_ALLOWED,
565 user_rid,
566 &user_pol);
568 if (!NT_STATUS_IS_OK(result))
569 return result;
571 /* Get user info */
572 result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
573 &user_pol,
574 0x15,
575 &info);
577 rpccli_samr_Close(cli, mem_ctx, &user_pol);
579 if (!NT_STATUS_IS_OK(result))
580 return result;
582 sid_compose(&user_info->user_sid, &domain->sid, user_rid);
583 sid_compose(&user_info->group_sid, &domain->sid,
584 info->info21.primary_gid);
585 user_info->acct_name = talloc_strdup(mem_ctx,
586 info->info21.account_name.string);
587 user_info->full_name = talloc_strdup(mem_ctx,
588 info->info21.full_name.string);
589 user_info->homedir = NULL;
590 user_info->shell = NULL;
591 user_info->primary_gid = (gid_t)-1;
593 return NT_STATUS_OK;
596 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
597 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
598 TALLOC_CTX *mem_ctx,
599 const DOM_SID *user_sid,
600 uint32 *num_groups, DOM_SID **user_grpsids)
602 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
603 struct policy_handle dom_pol, user_pol;
604 uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
605 struct samr_RidWithAttributeArray *rid_array = NULL;
606 unsigned int i;
607 uint32 user_rid;
608 struct rpc_pipe_client *cli;
610 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid)));
612 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
613 return NT_STATUS_UNSUCCESSFUL;
615 *num_groups = 0;
616 *user_grpsids = NULL;
618 /* so lets see if we have a cached user_info_3 */
619 result = lookup_usergroups_cached(domain, mem_ctx, user_sid,
620 num_groups, user_grpsids);
622 if (NT_STATUS_IS_OK(result)) {
623 return NT_STATUS_OK;
626 if ( !winbindd_can_contact_domain( domain ) ) {
627 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
628 domain->name));
630 /* Tell the cache manager not to remember this one */
632 return NT_STATUS_SYNCHRONIZATION_REQUIRED;
635 /* no cache; hit the wire */
637 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
638 if (!NT_STATUS_IS_OK(result))
639 return result;
641 /* Get user handle */
642 result = rpccli_samr_OpenUser(cli, mem_ctx,
643 &dom_pol,
644 des_access,
645 user_rid,
646 &user_pol);
648 if (!NT_STATUS_IS_OK(result))
649 return result;
651 /* Query user rids */
652 result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
653 &user_pol,
654 &rid_array);
655 *num_groups = rid_array->count;
657 rpccli_samr_Close(cli, mem_ctx, &user_pol);
659 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
660 return result;
662 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
663 if (!(*user_grpsids))
664 return NT_STATUS_NO_MEMORY;
666 for (i=0;i<(*num_groups);i++) {
667 sid_copy(&((*user_grpsids)[i]), &domain->sid);
668 sid_append_rid(&((*user_grpsids)[i]),
669 rid_array->rids[i].rid);
672 return NT_STATUS_OK;
675 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
677 static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
678 TALLOC_CTX *mem_ctx,
679 uint32 num_sids, const DOM_SID *sids,
680 uint32 *num_aliases,
681 uint32 **alias_rids)
683 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
684 struct policy_handle dom_pol;
685 uint32 num_query_sids = 0;
686 int i;
687 struct rpc_pipe_client *cli;
688 struct samr_Ids alias_rids_query;
689 int rangesize = MAX_SAM_ENTRIES_W2K;
690 uint32 total_sids = 0;
691 int num_queries = 1;
693 *num_aliases = 0;
694 *alias_rids = NULL;
696 DEBUG(3,("rpc: lookup_useraliases\n"));
698 if ( !winbindd_can_contact_domain( domain ) ) {
699 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
700 domain->name));
701 return NT_STATUS_OK;
704 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
705 if (!NT_STATUS_IS_OK(result))
706 return result;
708 do {
709 /* prepare query */
710 struct lsa_SidArray sid_array;
712 ZERO_STRUCT(sid_array);
714 num_query_sids = MIN(num_sids - total_sids, rangesize);
716 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
717 num_queries, num_query_sids));
719 if (num_query_sids) {
720 sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
721 if (sid_array.sids == NULL) {
722 return NT_STATUS_NO_MEMORY;
724 } else {
725 sid_array.sids = NULL;
728 for (i=0; i<num_query_sids; i++) {
729 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]);
730 if (!sid_array.sids[i].sid) {
731 TALLOC_FREE(sid_array.sids);
732 return NT_STATUS_NO_MEMORY;
735 sid_array.num_sids = num_query_sids;
737 /* do request */
738 result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
739 &dom_pol,
740 &sid_array,
741 &alias_rids_query);
743 if (!NT_STATUS_IS_OK(result)) {
744 *num_aliases = 0;
745 *alias_rids = NULL;
746 TALLOC_FREE(sid_array.sids);
747 goto done;
750 /* process output */
752 for (i=0; i<alias_rids_query.count; i++) {
753 size_t na = *num_aliases;
754 if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],
755 alias_rids, &na)) {
756 return NT_STATUS_NO_MEMORY;
758 *num_aliases = na;
761 TALLOC_FREE(sid_array.sids);
763 num_queries++;
765 } while (total_sids < num_sids);
767 done:
768 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
769 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
771 return result;
775 /* Lookup group membership given a rid. */
776 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
777 TALLOC_CTX *mem_ctx,
778 const DOM_SID *group_sid,
779 enum lsa_SidType type,
780 uint32 *num_names,
781 DOM_SID **sid_mem, char ***names,
782 uint32 **name_types)
784 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
785 uint32 i, total_names = 0;
786 struct policy_handle dom_pol, group_pol;
787 uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
788 uint32 *rid_mem = NULL;
789 uint32 group_rid;
790 unsigned int j, r;
791 struct rpc_pipe_client *cli;
792 unsigned int orig_timeout;
793 struct samr_RidTypeArray *rids = NULL;
795 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
796 sid_string_dbg(group_sid)));
798 if ( !winbindd_can_contact_domain( domain ) ) {
799 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
800 domain->name));
801 return NT_STATUS_OK;
804 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
805 return NT_STATUS_UNSUCCESSFUL;
807 *num_names = 0;
809 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
810 if (!NT_STATUS_IS_OK(result))
811 return result;
813 result = rpccli_samr_OpenGroup(cli, mem_ctx,
814 &dom_pol,
815 des_access,
816 group_rid,
817 &group_pol);
819 if (!NT_STATUS_IS_OK(result))
820 return result;
822 /* Step #1: Get a list of user rids that are the members of the
823 group. */
825 /* This call can take a long time - allow the server to time out.
826 35 seconds should do it. */
828 orig_timeout = rpccli_set_timeout(cli, 35000);
830 result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
831 &group_pol,
832 &rids);
834 /* And restore our original timeout. */
835 rpccli_set_timeout(cli, orig_timeout);
837 rpccli_samr_Close(cli, mem_ctx, &group_pol);
839 if (!NT_STATUS_IS_OK(result))
840 return result;
842 *num_names = rids->count;
843 rid_mem = rids->rids;
845 if (!*num_names) {
846 names = NULL;
847 name_types = NULL;
848 sid_mem = NULL;
849 return NT_STATUS_OK;
852 /* Step #2: Convert list of rids into list of usernames. Do this
853 in bunches of ~1000 to avoid crashing NT4. It looks like there
854 is a buffer overflow or something like that lurking around
855 somewhere. */
857 #define MAX_LOOKUP_RIDS 900
859 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
860 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
861 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
863 for (j=0;j<(*num_names);j++)
864 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
866 if (*num_names>0 && (!*names || !*name_types))
867 return NT_STATUS_NO_MEMORY;
869 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
870 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
871 struct lsa_Strings tmp_names;
872 struct samr_Ids tmp_types;
874 /* Lookup a chunk of rids */
876 result = rpccli_samr_LookupRids(cli, mem_ctx,
877 &dom_pol,
878 num_lookup_rids,
879 &rid_mem[i],
880 &tmp_names,
881 &tmp_types);
883 /* see if we have a real error (and yes the
884 STATUS_SOME_UNMAPPED is the one returned from 2k) */
886 if (!NT_STATUS_IS_OK(result) &&
887 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
888 return result;
890 /* Copy result into array. The talloc system will take
891 care of freeing the temporary arrays later on. */
893 if (tmp_names.count != tmp_types.count) {
894 return NT_STATUS_UNSUCCESSFUL;
897 for (r=0; r<tmp_names.count; r++) {
898 if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
899 continue;
901 (*names)[total_names] = fill_domain_username_talloc(
902 mem_ctx, domain->name,
903 tmp_names.names[r].string, true);
904 (*name_types)[total_names] = tmp_types.ids[r];
905 total_names += 1;
909 *num_names = total_names;
911 return NT_STATUS_OK;
914 #ifdef HAVE_LDAP
916 #include <ldap.h>
918 static int get_ldap_seq(const char *server, int port, uint32 *seq)
920 int ret = -1;
921 struct timeval to;
922 const char *attrs[] = {"highestCommittedUSN", NULL};
923 LDAPMessage *res = NULL;
924 char **values = NULL;
925 LDAP *ldp = NULL;
927 *seq = DOM_SEQUENCE_NONE;
930 * Parameterised (5) second timeout on open. This is needed as the
931 * search timeout doesn't seem to apply to doing an open as well. JRA.
934 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
935 if (ldp == NULL)
936 return -1;
938 /* Timeout if no response within 20 seconds. */
939 to.tv_sec = 10;
940 to.tv_usec = 0;
942 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
943 CONST_DISCARD(char **, attrs), 0, &to, &res))
944 goto done;
946 if (ldap_count_entries(ldp, res) != 1)
947 goto done;
949 values = ldap_get_values(ldp, res, "highestCommittedUSN");
950 if (!values || !values[0])
951 goto done;
953 *seq = atoi(values[0]);
954 ret = 0;
956 done:
958 if (values)
959 ldap_value_free(values);
960 if (res)
961 ldap_msgfree(res);
962 if (ldp)
963 ldap_unbind(ldp);
964 return ret;
967 /**********************************************************************
968 Get the sequence number for a Windows AD native mode domain using
969 LDAP queries.
970 **********************************************************************/
972 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
974 int ret = -1;
975 char addr[INET6_ADDRSTRLEN];
977 print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
978 if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
979 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
980 "number for Domain (%s) from DC (%s)\n",
981 domain->name, addr));
983 return ret;
986 #endif /* HAVE_LDAP */
988 /* find the sequence number for a domain */
989 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
991 TALLOC_CTX *mem_ctx;
992 union samr_DomainInfo *info = NULL;
993 NTSTATUS result;
994 struct policy_handle dom_pol;
995 bool got_seq_num = False;
996 struct rpc_pipe_client *cli;
998 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
1000 if ( !winbindd_can_contact_domain( domain ) ) {
1001 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
1002 domain->name));
1003 *seq = time(NULL);
1004 return NT_STATUS_OK;
1007 *seq = DOM_SEQUENCE_NONE;
1009 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
1010 return NT_STATUS_NO_MEMORY;
1012 #ifdef HAVE_LDAP
1013 if ( domain->active_directory )
1015 int res;
1017 DEBUG(8,("using get_ldap_seq() to retrieve the "
1018 "sequence number\n"));
1020 res = get_ldap_sequence_number( domain, seq );
1021 if (res == 0)
1023 result = NT_STATUS_OK;
1024 DEBUG(10,("domain_sequence_number: LDAP for "
1025 "domain %s is %u\n",
1026 domain->name, *seq));
1027 goto done;
1030 DEBUG(10,("domain_sequence_number: failed to get LDAP "
1031 "sequence number for domain %s\n",
1032 domain->name ));
1034 #endif /* HAVE_LDAP */
1036 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1037 if (!NT_STATUS_IS_OK(result)) {
1038 goto done;
1041 /* Query domain info */
1043 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1044 &dom_pol,
1046 &info);
1048 if (NT_STATUS_IS_OK(result)) {
1049 *seq = info->info8.sequence_num;
1050 got_seq_num = True;
1051 goto seq_num;
1054 /* retry with info-level 2 in case the dc does not support info-level 8
1055 * (like all older samba2 and samba3 dc's) - Guenther */
1057 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1058 &dom_pol,
1060 &info);
1062 if (NT_STATUS_IS_OK(result)) {
1063 *seq = info->general.sequence_num;
1064 got_seq_num = True;
1067 seq_num:
1068 if (got_seq_num) {
1069 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1070 domain->name, (unsigned)*seq));
1071 } else {
1072 DEBUG(10,("domain_sequence_number: failed to get sequence "
1073 "number (%u) for domain %s\n",
1074 (unsigned)*seq, domain->name ));
1077 done:
1079 talloc_destroy(mem_ctx);
1081 return result;
1084 /* get a list of trusted domains */
1085 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
1086 TALLOC_CTX *mem_ctx,
1087 uint32 *num_domains,
1088 char ***names,
1089 char ***alt_names,
1090 DOM_SID **dom_sids)
1092 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1093 uint32 enum_ctx = 0;
1094 struct rpc_pipe_client *cli;
1095 struct policy_handle lsa_policy;
1097 DEBUG(3,("rpc: trusted_domains\n"));
1099 *num_domains = 0;
1100 *names = NULL;
1101 *alt_names = NULL;
1102 *dom_sids = NULL;
1104 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1105 if (!NT_STATUS_IS_OK(result))
1106 return result;
1108 result = STATUS_MORE_ENTRIES;
1110 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1111 uint32 start_idx;
1112 int i;
1113 struct lsa_DomainList dom_list;
1115 result = rpccli_lsa_EnumTrustDom(cli, mem_ctx,
1116 &lsa_policy,
1117 &enum_ctx,
1118 &dom_list,
1119 (uint32_t)-1);
1121 if (!NT_STATUS_IS_OK(result) &&
1122 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
1123 break;
1125 start_idx = *num_domains;
1126 *num_domains += dom_list.count;
1127 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
1128 char *, *num_domains);
1129 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
1130 DOM_SID, *num_domains);
1131 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,
1132 char *, *num_domains);
1133 if ((*names == NULL) || (*dom_sids == NULL) ||
1134 (*alt_names == NULL))
1135 return NT_STATUS_NO_MEMORY;
1137 for (i=0; i<dom_list.count; i++) {
1138 (*names)[start_idx+i] = CONST_DISCARD(char *, dom_list.domains[i].name.string);
1139 (*dom_sids)[start_idx+i] = *dom_list.domains[i].sid;
1140 (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
1143 return result;
1146 /* find the lockout policy for a domain */
1147 static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
1148 TALLOC_CTX *mem_ctx,
1149 struct samr_DomInfo12 *lockout_policy)
1151 NTSTATUS result;
1152 struct rpc_pipe_client *cli;
1153 struct policy_handle dom_pol;
1154 union samr_DomainInfo *info = NULL;
1156 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
1158 if ( !winbindd_can_contact_domain( domain ) ) {
1159 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1160 domain->name));
1161 return NT_STATUS_NOT_SUPPORTED;
1164 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1165 if (!NT_STATUS_IS_OK(result)) {
1166 goto done;
1169 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1170 &dom_pol,
1172 &info);
1173 if (!NT_STATUS_IS_OK(result)) {
1174 goto done;
1177 *lockout_policy = info->info12;
1179 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1180 info->info12.lockout_threshold));
1182 done:
1184 return result;
1187 /* find the password policy for a domain */
1188 static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1189 TALLOC_CTX *mem_ctx,
1190 struct samr_DomInfo1 *password_policy)
1192 NTSTATUS result;
1193 struct rpc_pipe_client *cli;
1194 struct policy_handle dom_pol;
1195 union samr_DomainInfo *info = NULL;
1197 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
1199 if ( !winbindd_can_contact_domain( domain ) ) {
1200 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1201 domain->name));
1202 return NT_STATUS_NOT_SUPPORTED;
1205 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1206 if (!NT_STATUS_IS_OK(result)) {
1207 goto done;
1210 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1211 &dom_pol,
1213 &info);
1214 if (!NT_STATUS_IS_OK(result)) {
1215 goto done;
1218 *password_policy = info->info1;
1220 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1221 info->info1.min_password_length));
1223 done:
1225 return result;
1229 /* the rpc backend methods are exposed via this structure */
1230 struct winbindd_methods msrpc_methods = {
1231 False,
1232 query_user_list,
1233 enum_dom_groups,
1234 enum_local_groups,
1235 msrpc_name_to_sid,
1236 msrpc_sid_to_name,
1237 msrpc_rids_to_names,
1238 query_user,
1239 lookup_usergroups,
1240 msrpc_lookup_useraliases,
1241 lookup_groupmem,
1242 sequence_number,
1243 msrpc_lockout_policy,
1244 msrpc_password_policy,
1245 trusted_domains,