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 NTSTATUS name_map_status
= NT_STATUS_UNSUCCESSFUL
;
358 char *mapped_name
= NULL
;
360 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid
),
363 result
= winbindd_lookup_sids(mem_ctx
,
370 if (!NT_STATUS_IS_OK(result
)) {
371 DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n",
377 *type
= (enum lsa_SidType
)types
[0];
378 *domain_name
= domains
[0];
381 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains
[0], *name
));
383 name_map_status
= normalize_name_map(mem_ctx
, domain
, *name
,
385 if (NT_STATUS_IS_OK(name_map_status
) ||
386 NT_STATUS_EQUAL(name_map_status
, NT_STATUS_FILE_RENAMED
))
389 DEBUG(5,("returning mapped name -- %s\n", *name
));
395 static NTSTATUS
msrpc_rids_to_names(struct winbindd_domain
*domain
,
402 enum lsa_SidType
**types
)
410 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain
->name
));
413 sids
= TALLOC_ARRAY(mem_ctx
, DOM_SID
, num_rids
);
415 return NT_STATUS_NO_MEMORY
;
421 for (i
=0; i
<num_rids
; i
++) {
422 if (!sid_compose(&sids
[i
], sid
, rids
[i
])) {
423 return NT_STATUS_INTERNAL_ERROR
;
427 result
= winbindd_lookup_sids(mem_ctx
,
435 if (!NT_STATUS_IS_OK(result
) &&
436 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
441 for (i
=0; i
<num_rids
; i
++) {
442 NTSTATUS name_map_status
= NT_STATUS_UNSUCCESSFUL
;
443 char *mapped_name
= NULL
;
445 if ((*types
)[i
] != SID_NAME_UNKNOWN
) {
446 name_map_status
= normalize_name_map(mem_ctx
,
450 if (NT_STATUS_IS_OK(name_map_status
) ||
451 NT_STATUS_EQUAL(name_map_status
, NT_STATUS_FILE_RENAMED
))
453 ret_names
[i
] = mapped_name
;
456 *domain_name
= domains
[i
];
463 /* Lookup user information from a rid or username. */
464 static NTSTATUS
query_user(struct winbindd_domain
*domain
,
466 const DOM_SID
*user_sid
,
467 struct wbint_userinfo
*user_info
)
469 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
470 struct policy_handle dom_pol
, user_pol
;
471 union samr_UserInfo
*info
= NULL
;
473 struct netr_SamInfo3
*user
;
474 struct rpc_pipe_client
*cli
;
476 DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid
)));
478 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
479 return NT_STATUS_UNSUCCESSFUL
;
481 user_info
->homedir
= NULL
;
482 user_info
->shell
= NULL
;
483 user_info
->primary_gid
= (gid_t
)-1;
485 /* try netsamlogon cache first */
487 if ( (user
= netsamlogon_cache_get( mem_ctx
, user_sid
)) != NULL
)
490 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
491 sid_string_dbg(user_sid
)));
493 sid_compose(&user_info
->user_sid
, &domain
->sid
, user
->base
.rid
);
494 sid_compose(&user_info
->group_sid
, &domain
->sid
,
495 user
->base
.primary_gid
);
497 user_info
->acct_name
= talloc_strdup(mem_ctx
,
498 user
->base
.account_name
.string
);
499 user_info
->full_name
= talloc_strdup(mem_ctx
,
500 user
->base
.full_name
.string
);
507 if ( !winbindd_can_contact_domain( domain
) ) {
508 DEBUG(10,("query_user: No incoming trust for domain %s\n",
513 if ( !winbindd_can_contact_domain( domain
) ) {
514 DEBUG(10,("query_user: No incoming trust for domain %s\n",
519 if ( !winbindd_can_contact_domain( domain
) ) {
520 DEBUG(10,("query_user: No incoming trust for domain %s\n",
525 /* no cache; hit the wire */
527 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
528 if (!NT_STATUS_IS_OK(result
))
531 /* Get user handle */
532 result
= rpccli_samr_OpenUser(cli
, mem_ctx
,
534 SEC_FLAG_MAXIMUM_ALLOWED
,
538 if (!NT_STATUS_IS_OK(result
))
542 result
= rpccli_samr_QueryUserInfo(cli
, mem_ctx
,
547 rpccli_samr_Close(cli
, mem_ctx
, &user_pol
);
549 if (!NT_STATUS_IS_OK(result
))
552 sid_compose(&user_info
->user_sid
, &domain
->sid
, user_rid
);
553 sid_compose(&user_info
->group_sid
, &domain
->sid
,
554 info
->info21
.primary_gid
);
555 user_info
->acct_name
= talloc_strdup(mem_ctx
,
556 info
->info21
.account_name
.string
);
557 user_info
->full_name
= talloc_strdup(mem_ctx
,
558 info
->info21
.full_name
.string
);
559 user_info
->homedir
= NULL
;
560 user_info
->shell
= NULL
;
561 user_info
->primary_gid
= (gid_t
)-1;
566 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
567 static NTSTATUS
lookup_usergroups(struct winbindd_domain
*domain
,
569 const DOM_SID
*user_sid
,
570 uint32
*num_groups
, DOM_SID
**user_grpsids
)
572 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
573 struct policy_handle dom_pol
, user_pol
;
574 uint32 des_access
= SEC_FLAG_MAXIMUM_ALLOWED
;
575 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
578 struct rpc_pipe_client
*cli
;
580 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid
)));
582 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
583 return NT_STATUS_UNSUCCESSFUL
;
586 *user_grpsids
= NULL
;
588 /* so lets see if we have a cached user_info_3 */
589 result
= lookup_usergroups_cached(domain
, mem_ctx
, user_sid
,
590 num_groups
, user_grpsids
);
592 if (NT_STATUS_IS_OK(result
)) {
596 if ( !winbindd_can_contact_domain( domain
) ) {
597 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
600 /* Tell the cache manager not to remember this one */
602 return NT_STATUS_SYNCHRONIZATION_REQUIRED
;
605 /* no cache; hit the wire */
607 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
608 if (!NT_STATUS_IS_OK(result
))
611 /* Get user handle */
612 result
= rpccli_samr_OpenUser(cli
, mem_ctx
,
618 if (!NT_STATUS_IS_OK(result
))
621 /* Query user rids */
622 result
= rpccli_samr_GetGroupsForUser(cli
, mem_ctx
,
625 *num_groups
= rid_array
->count
;
627 rpccli_samr_Close(cli
, mem_ctx
, &user_pol
);
629 if (!NT_STATUS_IS_OK(result
) || (*num_groups
) == 0)
632 (*user_grpsids
) = TALLOC_ARRAY(mem_ctx
, DOM_SID
, *num_groups
);
633 if (!(*user_grpsids
))
634 return NT_STATUS_NO_MEMORY
;
636 for (i
=0;i
<(*num_groups
);i
++) {
637 sid_copy(&((*user_grpsids
)[i
]), &domain
->sid
);
638 sid_append_rid(&((*user_grpsids
)[i
]),
639 rid_array
->rids
[i
].rid
);
645 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
647 static NTSTATUS
msrpc_lookup_useraliases(struct winbindd_domain
*domain
,
649 uint32 num_sids
, const DOM_SID
*sids
,
653 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
654 struct policy_handle dom_pol
;
655 uint32 num_query_sids
= 0;
657 struct rpc_pipe_client
*cli
;
658 struct samr_Ids alias_rids_query
;
659 int rangesize
= MAX_SAM_ENTRIES_W2K
;
660 uint32 total_sids
= 0;
666 DEBUG(3,("rpc: lookup_useraliases\n"));
668 if ( !winbindd_can_contact_domain( domain
) ) {
669 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
674 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
675 if (!NT_STATUS_IS_OK(result
))
680 struct lsa_SidArray sid_array
;
682 ZERO_STRUCT(sid_array
);
684 num_query_sids
= MIN(num_sids
- total_sids
, rangesize
);
686 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
687 num_queries
, num_query_sids
));
689 if (num_query_sids
) {
690 sid_array
.sids
= TALLOC_ZERO_ARRAY(mem_ctx
, struct lsa_SidPtr
, num_query_sids
);
691 if (sid_array
.sids
== NULL
) {
692 return NT_STATUS_NO_MEMORY
;
695 sid_array
.sids
= NULL
;
698 for (i
=0; i
<num_query_sids
; i
++) {
699 sid_array
.sids
[i
].sid
= sid_dup_talloc(mem_ctx
, &sids
[total_sids
++]);
700 if (!sid_array
.sids
[i
].sid
) {
701 TALLOC_FREE(sid_array
.sids
);
702 return NT_STATUS_NO_MEMORY
;
705 sid_array
.num_sids
= num_query_sids
;
708 result
= rpccli_samr_GetAliasMembership(cli
, mem_ctx
,
713 if (!NT_STATUS_IS_OK(result
)) {
716 TALLOC_FREE(sid_array
.sids
);
722 for (i
=0; i
<alias_rids_query
.count
; i
++) {
723 size_t na
= *num_aliases
;
724 if (!add_rid_to_array_unique(mem_ctx
, alias_rids_query
.ids
[i
],
726 return NT_STATUS_NO_MEMORY
;
731 TALLOC_FREE(sid_array
.sids
);
735 } while (total_sids
< num_sids
);
738 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
739 "(rangesize: %d)\n", *num_aliases
, num_queries
, rangesize
));
745 /* Lookup group membership given a rid. */
746 static NTSTATUS
lookup_groupmem(struct winbindd_domain
*domain
,
748 const DOM_SID
*group_sid
,
749 enum lsa_SidType type
,
751 DOM_SID
**sid_mem
, char ***names
,
754 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
755 uint32 i
, total_names
= 0;
756 struct policy_handle dom_pol
, group_pol
;
757 uint32 des_access
= SEC_FLAG_MAXIMUM_ALLOWED
;
758 uint32
*rid_mem
= NULL
;
761 struct rpc_pipe_client
*cli
;
762 unsigned int orig_timeout
;
763 struct samr_RidTypeArray
*rids
= NULL
;
765 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain
->name
,
766 sid_string_dbg(group_sid
)));
768 if ( !winbindd_can_contact_domain( domain
) ) {
769 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
774 if (!sid_peek_check_rid(&domain
->sid
, group_sid
, &group_rid
))
775 return NT_STATUS_UNSUCCESSFUL
;
779 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
780 if (!NT_STATUS_IS_OK(result
))
783 result
= rpccli_samr_OpenGroup(cli
, mem_ctx
,
789 if (!NT_STATUS_IS_OK(result
))
792 /* Step #1: Get a list of user rids that are the members of the
795 /* This call can take a long time - allow the server to time out.
796 35 seconds should do it. */
798 orig_timeout
= rpccli_set_timeout(cli
, 35000);
800 result
= rpccli_samr_QueryGroupMember(cli
, mem_ctx
,
804 /* And restore our original timeout. */
805 rpccli_set_timeout(cli
, orig_timeout
);
807 rpccli_samr_Close(cli
, mem_ctx
, &group_pol
);
809 if (!NT_STATUS_IS_OK(result
))
812 *num_names
= rids
->count
;
813 rid_mem
= rids
->rids
;
822 /* Step #2: Convert list of rids into list of usernames. Do this
823 in bunches of ~1000 to avoid crashing NT4. It looks like there
824 is a buffer overflow or something like that lurking around
827 #define MAX_LOOKUP_RIDS 900
829 *names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, *num_names
);
830 *name_types
= TALLOC_ZERO_ARRAY(mem_ctx
, uint32
, *num_names
);
831 *sid_mem
= TALLOC_ZERO_ARRAY(mem_ctx
, DOM_SID
, *num_names
);
833 for (j
=0;j
<(*num_names
);j
++)
834 sid_compose(&(*sid_mem
)[j
], &domain
->sid
, rid_mem
[j
]);
836 if (*num_names
>0 && (!*names
|| !*name_types
))
837 return NT_STATUS_NO_MEMORY
;
839 for (i
= 0; i
< *num_names
; i
+= MAX_LOOKUP_RIDS
) {
840 int num_lookup_rids
= MIN(*num_names
- i
, MAX_LOOKUP_RIDS
);
841 struct lsa_Strings tmp_names
;
842 struct samr_Ids tmp_types
;
844 /* Lookup a chunk of rids */
846 result
= rpccli_samr_LookupRids(cli
, mem_ctx
,
853 /* see if we have a real error (and yes the
854 STATUS_SOME_UNMAPPED is the one returned from 2k) */
856 if (!NT_STATUS_IS_OK(result
) &&
857 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
))
860 /* Copy result into array. The talloc system will take
861 care of freeing the temporary arrays later on. */
863 if (tmp_names
.count
!= tmp_types
.count
) {
864 return NT_STATUS_UNSUCCESSFUL
;
867 for (r
=0; r
<tmp_names
.count
; r
++) {
868 if (tmp_types
.ids
[r
] == SID_NAME_UNKNOWN
) {
871 (*names
)[total_names
] = fill_domain_username_talloc(
872 mem_ctx
, domain
->name
,
873 tmp_names
.names
[r
].string
, true);
874 (*name_types
)[total_names
] = tmp_types
.ids
[r
];
879 *num_names
= total_names
;
888 static int get_ldap_seq(const char *server
, int port
, uint32
*seq
)
892 const char *attrs
[] = {"highestCommittedUSN", NULL
};
893 LDAPMessage
*res
= NULL
;
894 char **values
= NULL
;
897 *seq
= DOM_SEQUENCE_NONE
;
900 * Parameterised (5) second timeout on open. This is needed as the
901 * search timeout doesn't seem to apply to doing an open as well. JRA.
904 ldp
= ldap_open_with_timeout(server
, port
, lp_ldap_timeout());
908 /* Timeout if no response within 20 seconds. */
912 if (ldap_search_st(ldp
, "", LDAP_SCOPE_BASE
, "(objectclass=*)",
913 CONST_DISCARD(char **, attrs
), 0, &to
, &res
))
916 if (ldap_count_entries(ldp
, res
) != 1)
919 values
= ldap_get_values(ldp
, res
, "highestCommittedUSN");
920 if (!values
|| !values
[0])
923 *seq
= atoi(values
[0]);
929 ldap_value_free(values
);
937 /**********************************************************************
938 Get the sequence number for a Windows AD native mode domain using
940 **********************************************************************/
942 static int get_ldap_sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
945 char addr
[INET6_ADDRSTRLEN
];
947 print_sockaddr(addr
, sizeof(addr
), &domain
->dcaddr
);
948 if ((ret
= get_ldap_seq(addr
, LDAP_PORT
, seq
)) == 0) {
949 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
950 "number for Domain (%s) from DC (%s)\n",
951 domain
->name
, addr
));
956 #endif /* HAVE_LDAP */
958 /* find the sequence number for a domain */
959 static NTSTATUS
sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
962 union samr_DomainInfo
*info
= NULL
;
964 struct policy_handle dom_pol
;
965 bool got_seq_num
= False
;
966 struct rpc_pipe_client
*cli
;
968 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain
->name
));
970 if ( !winbindd_can_contact_domain( domain
) ) {
971 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
977 *seq
= DOM_SEQUENCE_NONE
;
979 if (!(mem_ctx
= talloc_init("sequence_number[rpc]")))
980 return NT_STATUS_NO_MEMORY
;
983 if ( domain
->active_directory
)
987 DEBUG(8,("using get_ldap_seq() to retrieve the "
988 "sequence number\n"));
990 res
= get_ldap_sequence_number( domain
, seq
);
993 result
= NT_STATUS_OK
;
994 DEBUG(10,("domain_sequence_number: LDAP for "
996 domain
->name
, *seq
));
1000 DEBUG(10,("domain_sequence_number: failed to get LDAP "
1001 "sequence number for domain %s\n",
1004 #endif /* HAVE_LDAP */
1006 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1007 if (!NT_STATUS_IS_OK(result
)) {
1011 /* Query domain info */
1013 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1018 if (NT_STATUS_IS_OK(result
)) {
1019 *seq
= info
->info8
.sequence_num
;
1024 /* retry with info-level 2 in case the dc does not support info-level 8
1025 * (like all older samba2 and samba3 dc's) - Guenther */
1027 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1032 if (NT_STATUS_IS_OK(result
)) {
1033 *seq
= info
->general
.sequence_num
;
1039 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1040 domain
->name
, (unsigned)*seq
));
1042 DEBUG(10,("domain_sequence_number: failed to get sequence "
1043 "number (%u) for domain %s\n",
1044 (unsigned)*seq
, domain
->name
));
1049 talloc_destroy(mem_ctx
);
1054 /* get a list of trusted domains */
1055 static NTSTATUS
trusted_domains(struct winbindd_domain
*domain
,
1056 TALLOC_CTX
*mem_ctx
,
1057 uint32
*num_domains
,
1062 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1063 uint32 enum_ctx
= 0;
1064 struct rpc_pipe_client
*cli
;
1065 struct policy_handle lsa_policy
;
1067 DEBUG(3,("rpc: trusted_domains\n"));
1074 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
1075 if (!NT_STATUS_IS_OK(result
))
1078 result
= STATUS_MORE_ENTRIES
;
1080 while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
1083 struct lsa_DomainList dom_list
;
1085 result
= rpccli_lsa_EnumTrustDom(cli
, mem_ctx
,
1091 if (!NT_STATUS_IS_OK(result
) &&
1092 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
))
1095 start_idx
= *num_domains
;
1096 *num_domains
+= dom_list
.count
;
1097 *names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *names
,
1098 char *, *num_domains
);
1099 *dom_sids
= TALLOC_REALLOC_ARRAY(mem_ctx
, *dom_sids
,
1100 DOM_SID
, *num_domains
);
1101 *alt_names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *alt_names
,
1102 char *, *num_domains
);
1103 if ((*names
== NULL
) || (*dom_sids
== NULL
) ||
1104 (*alt_names
== NULL
))
1105 return NT_STATUS_NO_MEMORY
;
1107 for (i
=0; i
<dom_list
.count
; i
++) {
1108 (*names
)[start_idx
+i
] = CONST_DISCARD(char *, dom_list
.domains
[i
].name
.string
);
1109 (*dom_sids
)[start_idx
+i
] = *dom_list
.domains
[i
].sid
;
1110 (*alt_names
)[start_idx
+i
] = talloc_strdup(mem_ctx
, "");
1116 /* find the lockout policy for a domain */
1117 static NTSTATUS
msrpc_lockout_policy(struct winbindd_domain
*domain
,
1118 TALLOC_CTX
*mem_ctx
,
1119 struct samr_DomInfo12
*lockout_policy
)
1122 struct rpc_pipe_client
*cli
;
1123 struct policy_handle dom_pol
;
1124 union samr_DomainInfo
*info
= NULL
;
1126 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain
->name
));
1128 if ( !winbindd_can_contact_domain( domain
) ) {
1129 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1131 return NT_STATUS_NOT_SUPPORTED
;
1134 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1135 if (!NT_STATUS_IS_OK(result
)) {
1139 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1143 if (!NT_STATUS_IS_OK(result
)) {
1147 *lockout_policy
= info
->info12
;
1149 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1150 info
->info12
.lockout_threshold
));
1157 /* find the password policy for a domain */
1158 static NTSTATUS
msrpc_password_policy(struct winbindd_domain
*domain
,
1159 TALLOC_CTX
*mem_ctx
,
1160 struct samr_DomInfo1
*password_policy
)
1163 struct rpc_pipe_client
*cli
;
1164 struct policy_handle dom_pol
;
1165 union samr_DomainInfo
*info
= NULL
;
1167 DEBUG(10,("rpc: fetch password policy for %s\n", domain
->name
));
1169 if ( !winbindd_can_contact_domain( domain
) ) {
1170 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1172 return NT_STATUS_NOT_SUPPORTED
;
1175 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1176 if (!NT_STATUS_IS_OK(result
)) {
1180 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1184 if (!NT_STATUS_IS_OK(result
)) {
1188 *password_policy
= info
->info1
;
1190 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1191 info
->info1
.min_password_length
));
1198 NTSTATUS
winbindd_lookup_sids(TALLOC_CTX
*mem_ctx
,
1199 struct winbindd_domain
*domain
,
1201 const struct dom_sid
*sids
,
1204 enum lsa_SidType
**types
)
1207 struct rpc_pipe_client
*cli
= NULL
;
1208 struct policy_handle lsa_policy
;
1209 unsigned int orig_timeout
;
1211 status
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
1212 if (!NT_STATUS_IS_OK(status
)) {
1217 * This call can take a long time
1218 * allow the server to time out.
1219 * 35 seconds should do it.
1221 orig_timeout
= rpccli_set_timeout(cli
, 35000);
1223 status
= rpccli_lsa_lookup_sids(cli
, mem_ctx
, &lsa_policy
,
1224 num_sids
, sids
, domains
,
1227 /* And restore our original timeout. */
1228 rpccli_set_timeout(cli
, orig_timeout
);
1230 if (!NT_STATUS_IS_OK(status
)) {
1238 /* the rpc backend methods are exposed via this structure */
1239 struct winbindd_methods msrpc_methods
= {
1246 msrpc_rids_to_names
,
1249 msrpc_lookup_useraliases
,
1252 msrpc_lockout_policy
,
1253 msrpc_password_policy
,