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/>.
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
35 static NTSTATUS
query_user_list(struct winbindd_domain
*domain
,
38 struct wbint_userinfo
**info
)
41 struct policy_handle dom_pol
;
42 unsigned int i
, start_idx
;
44 struct rpc_pipe_client
*cli
;
46 DEBUG(3,("rpc: query_user_list\n"));
51 if ( !winbindd_can_contact_domain( domain
) ) {
52 DEBUG(10,("query_user_list: No incoming trust for domain %s\n",
57 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
58 if (!NT_STATUS_IS_OK(result
))
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
,
76 result
= rpccli_samr_QueryDisplayInfo(cli
, mem_ctx
,
85 num_dom_users
= disp_info
.info1
.count
;
86 start_idx
+= disp_info
.info1
.count
;
89 *num_entries
+= num_dom_users
;
91 *info
= TALLOC_REALLOC_ARRAY(mem_ctx
, *info
,
92 struct wbint_userinfo
,
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
));
128 /* list all domain groups */
129 static NTSTATUS
enum_dom_groups(struct winbindd_domain
*domain
,
132 struct acct_info
**info
)
134 struct policy_handle dom_pol
;
137 struct rpc_pipe_client
*cli
;
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",
150 status
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
151 if (!NT_STATUS_IS_OK(status
))
155 struct samr_SamArray
*sam_array
= NULL
;
157 TALLOC_CTX
*mem_ctx2
;
160 mem_ctx2
= talloc_init("enum_dom_groups[rpc]");
162 /* start is updated by this call. */
163 status
= rpccli_samr_EnumDomainGroups(cli
, mem_ctx2
,
167 0xFFFF, /* buffer size? */
170 if (!NT_STATUS_IS_OK(status
) &&
171 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
172 talloc_destroy(mem_ctx2
);
176 (*info
) = TALLOC_REALLOC_ARRAY(mem_ctx
, *info
,
178 (*num_entries
) + count
);
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
));
198 /* List all domain groups */
200 static NTSTATUS
enum_local_groups(struct winbindd_domain
*domain
,
203 struct acct_info
**info
)
205 struct policy_handle dom_pol
;
207 struct rpc_pipe_client
*cli
;
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",
220 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
221 if (!NT_STATUS_IS_OK(result
))
225 struct samr_SamArray
*sam_array
= NULL
;
226 uint32 count
= 0, start
= *num_entries
;
227 TALLOC_CTX
*mem_ctx2
;
230 mem_ctx2
= talloc_init("enum_dom_local_groups[rpc]");
232 result
= rpccli_samr_EnumDomainAliases(cli
, mem_ctx2
,
236 0xFFFF, /* buffer size? */
238 if (!NT_STATUS_IS_OK(result
) &&
239 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
) )
241 talloc_destroy(mem_ctx2
);
245 (*info
) = TALLOC_REALLOC_ARRAY(mem_ctx
, *info
,
247 (*num_entries
) + count
);
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
));
268 /* convert a single name to a sid in a domain */
269 static NTSTATUS
msrpc_name_to_sid(struct winbindd_domain
*domain
,
271 const char *domain_name
,
275 enum lsa_SidType
*type
)
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
);
292 full_name
= talloc_asprintf(mem_ctx
, "%s\\%s", domain_name
, 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
,
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
))
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
))
335 /* Return rid and type if lookup successful */
337 sid_copy(sid
, &sids
[0]);
344 convert a domain SID to a user or group name
346 static NTSTATUS
msrpc_sid_to_name(struct winbindd_domain
*domain
,
351 enum lsa_SidType
*type
)
355 enum lsa_SidType
*types
= NULL
;
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
),
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",
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",
393 *type
= (enum lsa_SidType
)types
[0];
394 *domain_name
= domains
[0];
397 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains
[0], *name
));
399 name_map_status
= normalize_name_map(mem_ctx
, domain
, *name
,
401 if (NT_STATUS_IS_OK(name_map_status
) ||
402 NT_STATUS_EQUAL(name_map_status
, NT_STATUS_FILE_RENAMED
))
405 DEBUG(5,("returning mapped name -- %s\n", *name
));
411 static NTSTATUS
msrpc_rids_to_names(struct winbindd_domain
*domain
,
418 enum lsa_SidType
**types
)
422 struct rpc_pipe_client
*cli
;
423 struct policy_handle lsa_policy
;
427 unsigned int orig_timeout
;
429 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain
->name
));
432 sids
= TALLOC_ARRAY(mem_ctx
, DOM_SID
, num_rids
);
434 return NT_STATUS_NO_MEMORY
;
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
)) {
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
,
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
)) {
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
,
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
];
493 /* Lookup user information from a rid or username. */
494 static NTSTATUS
query_user(struct winbindd_domain
*domain
,
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
;
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
);
537 if ( !winbindd_can_contact_domain( domain
) ) {
538 DEBUG(10,("query_user: No incoming trust for domain %s\n",
543 if ( !winbindd_can_contact_domain( domain
) ) {
544 DEBUG(10,("query_user: No incoming trust for domain %s\n",
549 if ( !winbindd_can_contact_domain( domain
) ) {
550 DEBUG(10,("query_user: No incoming trust for domain %s\n",
555 /* no cache; hit the wire */
557 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
558 if (!NT_STATUS_IS_OK(result
))
561 /* Get user handle */
562 result
= rpccli_samr_OpenUser(cli
, mem_ctx
,
564 SEC_FLAG_MAXIMUM_ALLOWED
,
568 if (!NT_STATUS_IS_OK(result
))
572 result
= rpccli_samr_QueryUserInfo(cli
, mem_ctx
,
577 rpccli_samr_Close(cli
, mem_ctx
, &user_pol
);
579 if (!NT_STATUS_IS_OK(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;
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
,
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
;
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
;
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
)) {
626 if ( !winbindd_can_contact_domain( domain
) ) {
627 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
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
))
641 /* Get user handle */
642 result
= rpccli_samr_OpenUser(cli
, mem_ctx
,
648 if (!NT_STATUS_IS_OK(result
))
651 /* Query user rids */
652 result
= rpccli_samr_GetGroupsForUser(cli
, mem_ctx
,
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)
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
);
675 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
677 static NTSTATUS
msrpc_lookup_useraliases(struct winbindd_domain
*domain
,
679 uint32 num_sids
, const DOM_SID
*sids
,
683 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
684 struct policy_handle dom_pol
;
685 uint32 num_query_sids
= 0;
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;
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",
704 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
705 if (!NT_STATUS_IS_OK(result
))
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
;
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
;
738 result
= rpccli_samr_GetAliasMembership(cli
, mem_ctx
,
743 if (!NT_STATUS_IS_OK(result
)) {
746 TALLOC_FREE(sid_array
.sids
);
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
],
756 return NT_STATUS_NO_MEMORY
;
761 TALLOC_FREE(sid_array
.sids
);
765 } while (total_sids
< num_sids
);
768 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
769 "(rangesize: %d)\n", *num_aliases
, num_queries
, rangesize
));
775 /* Lookup group membership given a rid. */
776 static NTSTATUS
lookup_groupmem(struct winbindd_domain
*domain
,
778 const DOM_SID
*group_sid
, uint32
*num_names
,
779 DOM_SID
**sid_mem
, char ***names
,
782 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
783 uint32 i
, total_names
= 0;
784 struct policy_handle dom_pol
, group_pol
;
785 uint32 des_access
= SEC_FLAG_MAXIMUM_ALLOWED
;
786 uint32
*rid_mem
= NULL
;
789 struct rpc_pipe_client
*cli
;
790 unsigned int orig_timeout
;
791 struct samr_RidTypeArray
*rids
= NULL
;
793 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain
->name
,
794 sid_string_dbg(group_sid
)));
796 if ( !winbindd_can_contact_domain( domain
) ) {
797 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
802 if (!sid_peek_check_rid(&domain
->sid
, group_sid
, &group_rid
))
803 return NT_STATUS_UNSUCCESSFUL
;
807 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
808 if (!NT_STATUS_IS_OK(result
))
811 result
= rpccli_samr_OpenGroup(cli
, mem_ctx
,
817 if (!NT_STATUS_IS_OK(result
))
820 /* Step #1: Get a list of user rids that are the members of the
823 /* This call can take a long time - allow the server to time out.
824 35 seconds should do it. */
826 orig_timeout
= rpccli_set_timeout(cli
, 35000);
828 result
= rpccli_samr_QueryGroupMember(cli
, mem_ctx
,
832 /* And restore our original timeout. */
833 rpccli_set_timeout(cli
, orig_timeout
);
835 rpccli_samr_Close(cli
, mem_ctx
, &group_pol
);
837 if (!NT_STATUS_IS_OK(result
))
840 *num_names
= rids
->count
;
841 rid_mem
= rids
->rids
;
850 /* Step #2: Convert list of rids into list of usernames. Do this
851 in bunches of ~1000 to avoid crashing NT4. It looks like there
852 is a buffer overflow or something like that lurking around
855 #define MAX_LOOKUP_RIDS 900
857 *names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, *num_names
);
858 *name_types
= TALLOC_ZERO_ARRAY(mem_ctx
, uint32
, *num_names
);
859 *sid_mem
= TALLOC_ZERO_ARRAY(mem_ctx
, DOM_SID
, *num_names
);
861 for (j
=0;j
<(*num_names
);j
++)
862 sid_compose(&(*sid_mem
)[j
], &domain
->sid
, rid_mem
[j
]);
864 if (*num_names
>0 && (!*names
|| !*name_types
))
865 return NT_STATUS_NO_MEMORY
;
867 for (i
= 0; i
< *num_names
; i
+= MAX_LOOKUP_RIDS
) {
868 int num_lookup_rids
= MIN(*num_names
- i
, MAX_LOOKUP_RIDS
);
869 struct lsa_Strings tmp_names
;
870 struct samr_Ids tmp_types
;
872 /* Lookup a chunk of rids */
874 result
= rpccli_samr_LookupRids(cli
, mem_ctx
,
881 /* see if we have a real error (and yes the
882 STATUS_SOME_UNMAPPED is the one returned from 2k) */
884 if (!NT_STATUS_IS_OK(result
) &&
885 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
))
888 /* Copy result into array. The talloc system will take
889 care of freeing the temporary arrays later on. */
891 if (tmp_names
.count
!= tmp_types
.count
) {
892 return NT_STATUS_UNSUCCESSFUL
;
895 for (r
=0; r
<tmp_names
.count
; r
++) {
896 if (tmp_types
.ids
[r
] == SID_NAME_UNKNOWN
) {
899 (*names
)[total_names
] = fill_domain_username_talloc(
900 mem_ctx
, domain
->name
,
901 tmp_names
.names
[r
].string
, true);
902 (*name_types
)[total_names
] = tmp_types
.ids
[r
];
907 *num_names
= total_names
;
916 static int get_ldap_seq(const char *server
, int port
, uint32
*seq
)
920 const char *attrs
[] = {"highestCommittedUSN", NULL
};
921 LDAPMessage
*res
= NULL
;
922 char **values
= NULL
;
925 *seq
= DOM_SEQUENCE_NONE
;
928 * Parameterised (5) second timeout on open. This is needed as the
929 * search timeout doesn't seem to apply to doing an open as well. JRA.
932 ldp
= ldap_open_with_timeout(server
, port
, lp_ldap_timeout());
936 /* Timeout if no response within 20 seconds. */
940 if (ldap_search_st(ldp
, "", LDAP_SCOPE_BASE
, "(objectclass=*)",
941 CONST_DISCARD(char **, attrs
), 0, &to
, &res
))
944 if (ldap_count_entries(ldp
, res
) != 1)
947 values
= ldap_get_values(ldp
, res
, "highestCommittedUSN");
948 if (!values
|| !values
[0])
951 *seq
= atoi(values
[0]);
957 ldap_value_free(values
);
965 /**********************************************************************
966 Get the sequence number for a Windows AD native mode domain using
968 **********************************************************************/
970 static int get_ldap_sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
973 char addr
[INET6_ADDRSTRLEN
];
975 print_sockaddr(addr
, sizeof(addr
), &domain
->dcaddr
);
976 if ((ret
= get_ldap_seq(addr
, LDAP_PORT
, seq
)) == 0) {
977 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
978 "number for Domain (%s) from DC (%s)\n",
979 domain
->name
, addr
));
984 #endif /* HAVE_LDAP */
986 /* find the sequence number for a domain */
987 static NTSTATUS
sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
990 union samr_DomainInfo
*info
= NULL
;
992 struct policy_handle dom_pol
;
993 bool got_seq_num
= False
;
994 struct rpc_pipe_client
*cli
;
996 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain
->name
));
998 if ( !winbindd_can_contact_domain( domain
) ) {
999 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
1002 return NT_STATUS_OK
;
1005 *seq
= DOM_SEQUENCE_NONE
;
1007 if (!(mem_ctx
= talloc_init("sequence_number[rpc]")))
1008 return NT_STATUS_NO_MEMORY
;
1011 if ( domain
->active_directory
)
1015 DEBUG(8,("using get_ldap_seq() to retrieve the "
1016 "sequence number\n"));
1018 res
= get_ldap_sequence_number( domain
, seq
);
1021 result
= NT_STATUS_OK
;
1022 DEBUG(10,("domain_sequence_number: LDAP for "
1023 "domain %s is %u\n",
1024 domain
->name
, *seq
));
1028 DEBUG(10,("domain_sequence_number: failed to get LDAP "
1029 "sequence number for domain %s\n",
1032 #endif /* HAVE_LDAP */
1034 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1035 if (!NT_STATUS_IS_OK(result
)) {
1039 /* Query domain info */
1041 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1046 if (NT_STATUS_IS_OK(result
)) {
1047 *seq
= info
->info8
.sequence_num
;
1052 /* retry with info-level 2 in case the dc does not support info-level 8
1053 * (like all older samba2 and samba3 dc's) - Guenther */
1055 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1060 if (NT_STATUS_IS_OK(result
)) {
1061 *seq
= info
->general
.sequence_num
;
1067 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1068 domain
->name
, (unsigned)*seq
));
1070 DEBUG(10,("domain_sequence_number: failed to get sequence "
1071 "number (%u) for domain %s\n",
1072 (unsigned)*seq
, domain
->name
));
1077 talloc_destroy(mem_ctx
);
1082 /* get a list of trusted domains */
1083 static NTSTATUS
trusted_domains(struct winbindd_domain
*domain
,
1084 TALLOC_CTX
*mem_ctx
,
1085 uint32
*num_domains
,
1090 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1091 uint32 enum_ctx
= 0;
1092 struct rpc_pipe_client
*cli
;
1093 struct policy_handle lsa_policy
;
1095 DEBUG(3,("rpc: trusted_domains\n"));
1102 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
1103 if (!NT_STATUS_IS_OK(result
))
1106 result
= STATUS_MORE_ENTRIES
;
1108 while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
1111 struct lsa_DomainList dom_list
;
1113 result
= rpccli_lsa_EnumTrustDom(cli
, mem_ctx
,
1119 if (!NT_STATUS_IS_OK(result
) &&
1120 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
))
1123 start_idx
= *num_domains
;
1124 *num_domains
+= dom_list
.count
;
1125 *names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *names
,
1126 char *, *num_domains
);
1127 *dom_sids
= TALLOC_REALLOC_ARRAY(mem_ctx
, *dom_sids
,
1128 DOM_SID
, *num_domains
);
1129 *alt_names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *alt_names
,
1130 char *, *num_domains
);
1131 if ((*names
== NULL
) || (*dom_sids
== NULL
) ||
1132 (*alt_names
== NULL
))
1133 return NT_STATUS_NO_MEMORY
;
1135 for (i
=0; i
<dom_list
.count
; i
++) {
1136 (*names
)[start_idx
+i
] = CONST_DISCARD(char *, dom_list
.domains
[i
].name
.string
);
1137 (*dom_sids
)[start_idx
+i
] = *dom_list
.domains
[i
].sid
;
1138 (*alt_names
)[start_idx
+i
] = talloc_strdup(mem_ctx
, "");
1144 /* find the lockout policy for a domain */
1145 static NTSTATUS
msrpc_lockout_policy(struct winbindd_domain
*domain
,
1146 TALLOC_CTX
*mem_ctx
,
1147 struct samr_DomInfo12
*lockout_policy
)
1150 struct rpc_pipe_client
*cli
;
1151 struct policy_handle dom_pol
;
1152 union samr_DomainInfo
*info
= NULL
;
1154 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain
->name
));
1156 if ( !winbindd_can_contact_domain( domain
) ) {
1157 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1159 return NT_STATUS_NOT_SUPPORTED
;
1162 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1163 if (!NT_STATUS_IS_OK(result
)) {
1167 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1171 if (!NT_STATUS_IS_OK(result
)) {
1175 *lockout_policy
= info
->info12
;
1177 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1178 info
->info12
.lockout_threshold
));
1185 /* find the password policy for a domain */
1186 static NTSTATUS
msrpc_password_policy(struct winbindd_domain
*domain
,
1187 TALLOC_CTX
*mem_ctx
,
1188 struct samr_DomInfo1
*password_policy
)
1191 struct rpc_pipe_client
*cli
;
1192 struct policy_handle dom_pol
;
1193 union samr_DomainInfo
*info
= NULL
;
1195 DEBUG(10,("rpc: fetch password policy for %s\n", domain
->name
));
1197 if ( !winbindd_can_contact_domain( domain
) ) {
1198 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1200 return NT_STATUS_NOT_SUPPORTED
;
1203 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1204 if (!NT_STATUS_IS_OK(result
)) {
1208 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1212 if (!NT_STATUS_IS_OK(result
)) {
1216 *password_policy
= info
->info1
;
1218 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1219 info
->info1
.min_password_length
));
1227 /* the rpc backend methods are exposed via this structure */
1228 struct winbindd_methods msrpc_methods
= {
1235 msrpc_rids_to_names
,
1238 msrpc_lookup_useraliases
,
1241 msrpc_lockout_policy
,
1242 msrpc_password_policy
,