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 WINBIND_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
, WINBIND_USERINFO
,
95 return NT_STATUS_NO_MEMORY
;
98 for (j
= 0; j
< num_dom_users
; i
++, j
++) {
100 uint32_t rid
= disp_info
.info1
.entries
[j
].rid
;
102 (*info
)[i
].acct_name
= talloc_strdup(mem_ctx
,
103 disp_info
.info1
.entries
[j
].account_name
.string
);
104 (*info
)[i
].full_name
= talloc_strdup(mem_ctx
,
105 disp_info
.info1
.entries
[j
].full_name
.string
);
106 (*info
)[i
].homedir
= NULL
;
107 (*info
)[i
].shell
= NULL
;
108 sid_compose(&(*info
)[i
].user_sid
, &domain
->sid
, rid
);
110 /* For the moment we set the primary group for
111 every user to be the Domain Users group.
112 There are serious problems with determining
113 the actual primary group for large domains.
114 This should really be made into a 'winbind
115 force group' smb.conf parameter or
116 something like that. */
118 sid_compose(&(*info
)[i
].group_sid
, &domain
->sid
,
119 DOMAIN_GROUP_RID_USERS
);
122 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
127 /* list all domain groups */
128 static NTSTATUS
enum_dom_groups(struct winbindd_domain
*domain
,
131 struct acct_info
**info
)
133 struct policy_handle dom_pol
;
136 struct rpc_pipe_client
*cli
;
141 DEBUG(3,("rpc: enum_dom_groups\n"));
143 if ( !winbindd_can_contact_domain( domain
) ) {
144 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
149 status
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
150 if (!NT_STATUS_IS_OK(status
))
154 struct samr_SamArray
*sam_array
= NULL
;
156 TALLOC_CTX
*mem_ctx2
;
159 mem_ctx2
= talloc_init("enum_dom_groups[rpc]");
161 /* start is updated by this call. */
162 status
= rpccli_samr_EnumDomainGroups(cli
, mem_ctx2
,
166 0xFFFF, /* buffer size? */
169 if (!NT_STATUS_IS_OK(status
) &&
170 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
171 talloc_destroy(mem_ctx2
);
175 (*info
) = TALLOC_REALLOC_ARRAY(mem_ctx
, *info
,
177 (*num_entries
) + count
);
179 talloc_destroy(mem_ctx2
);
180 return NT_STATUS_NO_MEMORY
;
183 for (g
=0; g
< count
; g
++) {
185 fstrcpy((*info
)[*num_entries
+ g
].acct_name
,
186 sam_array
->entries
[g
].name
.string
);
187 (*info
)[*num_entries
+ g
].rid
= sam_array
->entries
[g
].idx
;
190 (*num_entries
) += count
;
191 talloc_destroy(mem_ctx2
);
192 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
197 /* List all domain groups */
199 static NTSTATUS
enum_local_groups(struct winbindd_domain
*domain
,
202 struct acct_info
**info
)
204 struct policy_handle dom_pol
;
206 struct rpc_pipe_client
*cli
;
211 DEBUG(3,("rpc: enum_local_groups\n"));
213 if ( !winbindd_can_contact_domain( domain
) ) {
214 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
219 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
220 if (!NT_STATUS_IS_OK(result
))
224 struct samr_SamArray
*sam_array
= NULL
;
225 uint32 count
= 0, start
= *num_entries
;
226 TALLOC_CTX
*mem_ctx2
;
229 mem_ctx2
= talloc_init("enum_dom_local_groups[rpc]");
231 result
= rpccli_samr_EnumDomainAliases(cli
, mem_ctx2
,
235 0xFFFF, /* buffer size? */
237 if (!NT_STATUS_IS_OK(result
) &&
238 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
) )
240 talloc_destroy(mem_ctx2
);
244 (*info
) = TALLOC_REALLOC_ARRAY(mem_ctx
, *info
,
246 (*num_entries
) + count
);
248 talloc_destroy(mem_ctx2
);
249 return NT_STATUS_NO_MEMORY
;
252 for (g
=0; g
< count
; g
++) {
254 fstrcpy((*info
)[*num_entries
+ g
].acct_name
,
255 sam_array
->entries
[g
].name
.string
);
256 (*info
)[*num_entries
+ g
].rid
= sam_array
->entries
[g
].idx
;
259 (*num_entries
) += count
;
260 talloc_destroy(mem_ctx2
);
262 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
267 /* convert a single name to a sid in a domain */
268 static NTSTATUS
msrpc_name_to_sid(struct winbindd_domain
*domain
,
270 enum winbindd_cmd original_cmd
,
271 const char *domain_name
,
274 enum lsa_SidType
*type
)
277 DOM_SID
*sids
= NULL
;
278 enum lsa_SidType
*types
= NULL
;
279 char *full_name
= NULL
;
280 struct rpc_pipe_client
*cli
;
281 struct policy_handle lsa_policy
;
282 NTSTATUS name_map_status
= NT_STATUS_UNSUCCESSFUL
;
283 char *mapped_name
= NULL
;
285 if (name
== NULL
|| *name
=='\0') {
286 full_name
= talloc_asprintf(mem_ctx
, "%s", domain_name
);
287 } else if (domain_name
== NULL
|| *domain_name
== '\0') {
288 full_name
= talloc_asprintf(mem_ctx
, "%s", name
);
290 full_name
= talloc_asprintf(mem_ctx
, "%s\\%s", domain_name
, name
);
293 DEBUG(0, ("talloc_asprintf failed!\n"));
294 return NT_STATUS_NO_MEMORY
;
297 DEBUG(3,("rpc: name_to_sid name=%s\n", full_name
));
299 name_map_status
= normalize_name_unmap(mem_ctx
, full_name
,
302 /* Reset the full_name pointer if we mapped anytthing */
304 if (NT_STATUS_IS_OK(name_map_status
) ||
305 NT_STATUS_EQUAL(name_map_status
, NT_STATUS_FILE_RENAMED
))
307 full_name
= mapped_name
;
310 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
311 full_name
?full_name
:"", domain_name
));
313 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
314 if (!NT_STATUS_IS_OK(result
))
317 result
= rpccli_lsa_lookup_names(cli
, mem_ctx
, &lsa_policy
, 1,
318 (const char**) &full_name
, NULL
, 1, &sids
, &types
);
320 if (!NT_STATUS_IS_OK(result
))
323 /* Return rid and type if lookup successful */
325 sid_copy(sid
, &sids
[0]);
332 convert a domain SID to a user or group name
334 static NTSTATUS
msrpc_sid_to_name(struct winbindd_domain
*domain
,
339 enum lsa_SidType
*type
)
343 enum lsa_SidType
*types
= NULL
;
345 struct rpc_pipe_client
*cli
;
346 struct policy_handle lsa_policy
;
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
),
353 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
354 if (!NT_STATUS_IS_OK(result
)) {
355 DEBUG(2,("msrpc_sid_to_name: cm_connect_lsa() failed (%s)\n",
361 result
= rpccli_lsa_lookup_sids(cli
, mem_ctx
, &lsa_policy
,
362 1, sid
, &domains
, &names
, &types
);
363 if (!NT_STATUS_IS_OK(result
)) {
364 DEBUG(2,("msrpc_sid_to_name: rpccli_lsa_lookup_sids() failed (%s)\n",
369 *type
= (enum lsa_SidType
)types
[0];
370 *domain_name
= domains
[0];
373 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains
[0], *name
));
375 name_map_status
= normalize_name_map(mem_ctx
, domain
, *name
,
377 if (NT_STATUS_IS_OK(name_map_status
) ||
378 NT_STATUS_EQUAL(name_map_status
, NT_STATUS_FILE_RENAMED
))
381 DEBUG(5,("returning mapped name -- %s\n", *name
));
387 static NTSTATUS
msrpc_rids_to_names(struct winbindd_domain
*domain
,
394 enum lsa_SidType
**types
)
398 struct rpc_pipe_client
*cli
;
399 struct policy_handle lsa_policy
;
404 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain
->name
));
407 sids
= TALLOC_ARRAY(mem_ctx
, DOM_SID
, num_rids
);
409 return NT_STATUS_NO_MEMORY
;
415 for (i
=0; i
<num_rids
; i
++) {
416 if (!sid_compose(&sids
[i
], sid
, rids
[i
])) {
417 return NT_STATUS_INTERNAL_ERROR
;
421 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
422 if (!NT_STATUS_IS_OK(result
)) {
426 result
= rpccli_lsa_lookup_sids(cli
, mem_ctx
, &lsa_policy
,
427 num_rids
, sids
, &domains
,
429 if (!NT_STATUS_IS_OK(result
) &&
430 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
435 for (i
=0; i
<num_rids
; i
++) {
436 NTSTATUS name_map_status
= NT_STATUS_UNSUCCESSFUL
;
437 char *mapped_name
= NULL
;
439 if ((*types
)[i
] != SID_NAME_UNKNOWN
) {
440 name_map_status
= normalize_name_map(mem_ctx
,
444 if (NT_STATUS_IS_OK(name_map_status
) ||
445 NT_STATUS_EQUAL(name_map_status
, NT_STATUS_FILE_RENAMED
))
447 ret_names
[i
] = mapped_name
;
450 *domain_name
= domains
[i
];
457 /* Lookup user information from a rid or username. */
458 static NTSTATUS
query_user(struct winbindd_domain
*domain
,
460 const DOM_SID
*user_sid
,
461 WINBIND_USERINFO
*user_info
)
463 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
464 struct policy_handle dom_pol
, user_pol
;
465 union samr_UserInfo
*info
= NULL
;
467 struct netr_SamInfo3
*user
;
468 struct rpc_pipe_client
*cli
;
470 DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid
)));
472 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
473 return NT_STATUS_UNSUCCESSFUL
;
475 user_info
->homedir
= NULL
;
476 user_info
->shell
= NULL
;
477 user_info
->primary_gid
= (gid_t
)-1;
479 /* try netsamlogon cache first */
481 if ( (user
= netsamlogon_cache_get( mem_ctx
, user_sid
)) != NULL
)
484 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
485 sid_string_dbg(user_sid
)));
487 sid_compose(&user_info
->user_sid
, &domain
->sid
, user
->base
.rid
);
488 sid_compose(&user_info
->group_sid
, &domain
->sid
,
489 user
->base
.primary_gid
);
491 user_info
->acct_name
= talloc_strdup(mem_ctx
,
492 user
->base
.account_name
.string
);
493 user_info
->full_name
= talloc_strdup(mem_ctx
,
494 user
->base
.full_name
.string
);
501 if ( !winbindd_can_contact_domain( domain
) ) {
502 DEBUG(10,("query_user: No incoming trust for domain %s\n",
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 /* no cache; hit the wire */
521 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
522 if (!NT_STATUS_IS_OK(result
))
525 /* Get user handle */
526 result
= rpccli_samr_OpenUser(cli
, mem_ctx
,
528 SEC_FLAG_MAXIMUM_ALLOWED
,
532 if (!NT_STATUS_IS_OK(result
))
536 result
= rpccli_samr_QueryUserInfo(cli
, mem_ctx
,
541 rpccli_samr_Close(cli
, mem_ctx
, &user_pol
);
543 if (!NT_STATUS_IS_OK(result
))
546 sid_compose(&user_info
->user_sid
, &domain
->sid
, user_rid
);
547 sid_compose(&user_info
->group_sid
, &domain
->sid
,
548 info
->info21
.primary_gid
);
549 user_info
->acct_name
= talloc_strdup(mem_ctx
,
550 info
->info21
.account_name
.string
);
551 user_info
->full_name
= talloc_strdup(mem_ctx
,
552 info
->info21
.full_name
.string
);
553 user_info
->homedir
= NULL
;
554 user_info
->shell
= NULL
;
555 user_info
->primary_gid
= (gid_t
)-1;
560 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
561 static NTSTATUS
lookup_usergroups(struct winbindd_domain
*domain
,
563 const DOM_SID
*user_sid
,
564 uint32
*num_groups
, DOM_SID
**user_grpsids
)
566 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
567 struct policy_handle dom_pol
, user_pol
;
568 uint32 des_access
= SEC_FLAG_MAXIMUM_ALLOWED
;
569 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
572 struct rpc_pipe_client
*cli
;
574 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid
)));
576 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
577 return NT_STATUS_UNSUCCESSFUL
;
580 *user_grpsids
= NULL
;
582 /* so lets see if we have a cached user_info_3 */
583 result
= lookup_usergroups_cached(domain
, mem_ctx
, user_sid
,
584 num_groups
, user_grpsids
);
586 if (NT_STATUS_IS_OK(result
)) {
590 if ( !winbindd_can_contact_domain( domain
) ) {
591 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
594 /* Tell the cache manager not to remember this one */
596 return NT_STATUS_SYNCHRONIZATION_REQUIRED
;
599 /* no cache; hit the wire */
601 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
602 if (!NT_STATUS_IS_OK(result
))
605 /* Get user handle */
606 result
= rpccli_samr_OpenUser(cli
, mem_ctx
,
612 if (!NT_STATUS_IS_OK(result
))
615 /* Query user rids */
616 result
= rpccli_samr_GetGroupsForUser(cli
, mem_ctx
,
619 *num_groups
= rid_array
->count
;
621 rpccli_samr_Close(cli
, mem_ctx
, &user_pol
);
623 if (!NT_STATUS_IS_OK(result
) || (*num_groups
) == 0)
626 (*user_grpsids
) = TALLOC_ARRAY(mem_ctx
, DOM_SID
, *num_groups
);
627 if (!(*user_grpsids
))
628 return NT_STATUS_NO_MEMORY
;
630 for (i
=0;i
<(*num_groups
);i
++) {
631 sid_copy(&((*user_grpsids
)[i
]), &domain
->sid
);
632 sid_append_rid(&((*user_grpsids
)[i
]),
633 rid_array
->rids
[i
].rid
);
639 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
641 static NTSTATUS
msrpc_lookup_useraliases(struct winbindd_domain
*domain
,
643 uint32 num_sids
, const DOM_SID
*sids
,
647 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
648 struct policy_handle dom_pol
;
649 uint32 num_query_sids
= 0;
651 struct rpc_pipe_client
*cli
;
652 struct samr_Ids alias_rids_query
;
653 int rangesize
= MAX_SAM_ENTRIES_W2K
;
654 uint32 total_sids
= 0;
660 DEBUG(3,("rpc: lookup_useraliases\n"));
662 if ( !winbindd_can_contact_domain( domain
) ) {
663 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
668 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
669 if (!NT_STATUS_IS_OK(result
))
674 struct lsa_SidArray sid_array
;
676 ZERO_STRUCT(sid_array
);
678 num_query_sids
= MIN(num_sids
- total_sids
, rangesize
);
680 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
681 num_queries
, num_query_sids
));
683 if (num_query_sids
) {
684 sid_array
.sids
= TALLOC_ZERO_ARRAY(mem_ctx
, struct lsa_SidPtr
, num_query_sids
);
685 if (sid_array
.sids
== NULL
) {
686 return NT_STATUS_NO_MEMORY
;
689 sid_array
.sids
= NULL
;
692 for (i
=0; i
<num_query_sids
; i
++) {
693 sid_array
.sids
[i
].sid
= sid_dup_talloc(mem_ctx
, &sids
[total_sids
++]);
694 if (!sid_array
.sids
[i
].sid
) {
695 TALLOC_FREE(sid_array
.sids
);
696 return NT_STATUS_NO_MEMORY
;
699 sid_array
.num_sids
= num_query_sids
;
702 result
= rpccli_samr_GetAliasMembership(cli
, mem_ctx
,
707 if (!NT_STATUS_IS_OK(result
)) {
710 TALLOC_FREE(sid_array
.sids
);
716 for (i
=0; i
<alias_rids_query
.count
; i
++) {
717 size_t na
= *num_aliases
;
718 if (!add_rid_to_array_unique(mem_ctx
, alias_rids_query
.ids
[i
],
720 return NT_STATUS_NO_MEMORY
;
725 TALLOC_FREE(sid_array
.sids
);
729 } while (total_sids
< num_sids
);
732 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
733 "(rangesize: %d)\n", *num_aliases
, num_queries
, rangesize
));
739 /* Lookup group membership given a rid. */
740 static NTSTATUS
lookup_groupmem(struct winbindd_domain
*domain
,
742 const DOM_SID
*group_sid
, uint32
*num_names
,
743 DOM_SID
**sid_mem
, char ***names
,
746 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
747 uint32 i
, total_names
= 0;
748 struct policy_handle dom_pol
, group_pol
;
749 uint32 des_access
= SEC_FLAG_MAXIMUM_ALLOWED
;
750 uint32
*rid_mem
= NULL
;
753 struct rpc_pipe_client
*cli
;
754 unsigned int orig_timeout
;
755 struct samr_RidTypeArray
*rids
= NULL
;
757 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain
->name
,
758 sid_string_dbg(group_sid
)));
760 if ( !winbindd_can_contact_domain( domain
) ) {
761 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
766 if (!sid_peek_check_rid(&domain
->sid
, group_sid
, &group_rid
))
767 return NT_STATUS_UNSUCCESSFUL
;
771 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
772 if (!NT_STATUS_IS_OK(result
))
775 result
= rpccli_samr_OpenGroup(cli
, mem_ctx
,
781 if (!NT_STATUS_IS_OK(result
))
784 /* Step #1: Get a list of user rids that are the members of the
787 /* This call can take a long time - allow the server to time out.
788 35 seconds should do it. */
790 orig_timeout
= rpccli_set_timeout(cli
, 35000);
792 result
= rpccli_samr_QueryGroupMember(cli
, mem_ctx
,
796 /* And restore our original timeout. */
797 rpccli_set_timeout(cli
, orig_timeout
);
799 rpccli_samr_Close(cli
, mem_ctx
, &group_pol
);
801 if (!NT_STATUS_IS_OK(result
))
804 *num_names
= rids
->count
;
805 rid_mem
= rids
->rids
;
814 /* Step #2: Convert list of rids into list of usernames. Do this
815 in bunches of ~1000 to avoid crashing NT4. It looks like there
816 is a buffer overflow or something like that lurking around
819 #define MAX_LOOKUP_RIDS 900
821 *names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, *num_names
);
822 *name_types
= TALLOC_ZERO_ARRAY(mem_ctx
, uint32
, *num_names
);
823 *sid_mem
= TALLOC_ZERO_ARRAY(mem_ctx
, DOM_SID
, *num_names
);
825 for (j
=0;j
<(*num_names
);j
++)
826 sid_compose(&(*sid_mem
)[j
], &domain
->sid
, rid_mem
[j
]);
828 if (*num_names
>0 && (!*names
|| !*name_types
))
829 return NT_STATUS_NO_MEMORY
;
831 for (i
= 0; i
< *num_names
; i
+= MAX_LOOKUP_RIDS
) {
832 int num_lookup_rids
= MIN(*num_names
- i
, MAX_LOOKUP_RIDS
);
833 struct lsa_Strings tmp_names
;
834 struct samr_Ids tmp_types
;
836 /* Lookup a chunk of rids */
838 result
= rpccli_samr_LookupRids(cli
, mem_ctx
,
845 /* see if we have a real error (and yes the
846 STATUS_SOME_UNMAPPED is the one returned from 2k) */
848 if (!NT_STATUS_IS_OK(result
) &&
849 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
))
852 /* Copy result into array. The talloc system will take
853 care of freeing the temporary arrays later on. */
855 if (tmp_names
.count
!= tmp_types
.count
) {
856 return NT_STATUS_UNSUCCESSFUL
;
859 for (r
=0; r
<tmp_names
.count
; r
++) {
860 if (tmp_types
.ids
[r
] == SID_NAME_UNKNOWN
) {
863 (*names
)[total_names
] = fill_domain_username_talloc(
864 mem_ctx
, domain
->name
,
865 tmp_names
.names
[r
].string
, true);
866 (*name_types
)[total_names
] = tmp_types
.ids
[r
];
871 *num_names
= total_names
;
880 static int get_ldap_seq(const char *server
, int port
, uint32
*seq
)
884 const char *attrs
[] = {"highestCommittedUSN", NULL
};
885 LDAPMessage
*res
= NULL
;
886 char **values
= NULL
;
889 *seq
= DOM_SEQUENCE_NONE
;
892 * Parameterised (5) second timeout on open. This is needed as the
893 * search timeout doesn't seem to apply to doing an open as well. JRA.
896 ldp
= ldap_open_with_timeout(server
, port
, lp_ldap_timeout());
900 /* Timeout if no response within 20 seconds. */
904 if (ldap_search_st(ldp
, "", LDAP_SCOPE_BASE
, "(objectclass=*)",
905 CONST_DISCARD(char **, attrs
), 0, &to
, &res
))
908 if (ldap_count_entries(ldp
, res
) != 1)
911 values
= ldap_get_values(ldp
, res
, "highestCommittedUSN");
912 if (!values
|| !values
[0])
915 *seq
= atoi(values
[0]);
921 ldap_value_free(values
);
929 /**********************************************************************
930 Get the sequence number for a Windows AD native mode domain using
932 **********************************************************************/
934 static int get_ldap_sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
937 char addr
[INET6_ADDRSTRLEN
];
939 print_sockaddr(addr
, sizeof(addr
), &domain
->dcaddr
);
940 if ((ret
= get_ldap_seq(addr
, LDAP_PORT
, seq
)) == 0) {
941 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
942 "number for Domain (%s) from DC (%s)\n",
943 domain
->name
, addr
));
948 #endif /* HAVE_LDAP */
950 /* find the sequence number for a domain */
951 static NTSTATUS
sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
954 union samr_DomainInfo
*info
= NULL
;
956 struct policy_handle dom_pol
;
957 bool got_seq_num
= False
;
958 struct rpc_pipe_client
*cli
;
960 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain
->name
));
962 if ( !winbindd_can_contact_domain( domain
) ) {
963 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
969 *seq
= DOM_SEQUENCE_NONE
;
971 if (!(mem_ctx
= talloc_init("sequence_number[rpc]")))
972 return NT_STATUS_NO_MEMORY
;
975 if ( domain
->active_directory
)
979 DEBUG(8,("using get_ldap_seq() to retrieve the "
980 "sequence number\n"));
982 res
= get_ldap_sequence_number( domain
, seq
);
985 result
= NT_STATUS_OK
;
986 DEBUG(10,("domain_sequence_number: LDAP for "
988 domain
->name
, *seq
));
992 DEBUG(10,("domain_sequence_number: failed to get LDAP "
993 "sequence number for domain %s\n",
996 #endif /* HAVE_LDAP */
998 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
999 if (!NT_STATUS_IS_OK(result
)) {
1003 /* Query domain info */
1005 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1010 if (NT_STATUS_IS_OK(result
)) {
1011 *seq
= info
->info8
.sequence_num
;
1016 /* retry with info-level 2 in case the dc does not support info-level 8
1017 * (like all older samba2 and samba3 dc's) - Guenther */
1019 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1024 if (NT_STATUS_IS_OK(result
)) {
1025 *seq
= info
->general
.sequence_num
;
1031 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1032 domain
->name
, (unsigned)*seq
));
1034 DEBUG(10,("domain_sequence_number: failed to get sequence "
1035 "number (%u) for domain %s\n",
1036 (unsigned)*seq
, domain
->name
));
1041 talloc_destroy(mem_ctx
);
1046 /* get a list of trusted domains */
1047 static NTSTATUS
trusted_domains(struct winbindd_domain
*domain
,
1048 TALLOC_CTX
*mem_ctx
,
1049 uint32
*num_domains
,
1054 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1055 uint32 enum_ctx
= 0;
1056 struct rpc_pipe_client
*cli
;
1057 struct policy_handle lsa_policy
;
1059 DEBUG(3,("rpc: trusted_domains\n"));
1066 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
1067 if (!NT_STATUS_IS_OK(result
))
1070 result
= STATUS_MORE_ENTRIES
;
1072 while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
1075 struct lsa_DomainList dom_list
;
1077 result
= rpccli_lsa_EnumTrustDom(cli
, mem_ctx
,
1083 if (!NT_STATUS_IS_OK(result
) &&
1084 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
))
1087 start_idx
= *num_domains
;
1088 *num_domains
+= dom_list
.count
;
1089 *names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *names
,
1090 char *, *num_domains
);
1091 *dom_sids
= TALLOC_REALLOC_ARRAY(mem_ctx
, *dom_sids
,
1092 DOM_SID
, *num_domains
);
1093 *alt_names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *alt_names
,
1094 char *, *num_domains
);
1095 if ((*names
== NULL
) || (*dom_sids
== NULL
) ||
1096 (*alt_names
== NULL
))
1097 return NT_STATUS_NO_MEMORY
;
1099 for (i
=0; i
<dom_list
.count
; i
++) {
1100 (*names
)[start_idx
+i
] = CONST_DISCARD(char *, dom_list
.domains
[i
].name
.string
);
1101 (*dom_sids
)[start_idx
+i
] = *dom_list
.domains
[i
].sid
;
1102 (*alt_names
)[start_idx
+i
] = talloc_strdup(mem_ctx
, "");
1108 /* find the lockout policy for a domain */
1109 static NTSTATUS
msrpc_lockout_policy(struct winbindd_domain
*domain
,
1110 TALLOC_CTX
*mem_ctx
,
1111 struct samr_DomInfo12
*lockout_policy
)
1114 struct rpc_pipe_client
*cli
;
1115 struct policy_handle dom_pol
;
1116 union samr_DomainInfo
*info
= NULL
;
1118 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain
->name
));
1120 if ( !winbindd_can_contact_domain( domain
) ) {
1121 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1123 return NT_STATUS_NOT_SUPPORTED
;
1126 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1127 if (!NT_STATUS_IS_OK(result
)) {
1131 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1135 if (!NT_STATUS_IS_OK(result
)) {
1139 *lockout_policy
= info
->info12
;
1141 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1142 info
->info12
.lockout_threshold
));
1149 /* find the password policy for a domain */
1150 static NTSTATUS
msrpc_password_policy(struct winbindd_domain
*domain
,
1151 TALLOC_CTX
*mem_ctx
,
1152 struct samr_DomInfo1
*password_policy
)
1155 struct rpc_pipe_client
*cli
;
1156 struct policy_handle dom_pol
;
1157 union samr_DomainInfo
*info
= NULL
;
1159 DEBUG(10,("rpc: fetch password policy for %s\n", domain
->name
));
1161 if ( !winbindd_can_contact_domain( domain
) ) {
1162 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1164 return NT_STATUS_NOT_SUPPORTED
;
1167 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1168 if (!NT_STATUS_IS_OK(result
)) {
1172 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1176 if (!NT_STATUS_IS_OK(result
)) {
1180 *password_policy
= info
->info1
;
1182 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1183 info
->info1
.min_password_length
));
1191 /* the rpc backend methods are exposed via this structure */
1192 struct winbindd_methods msrpc_methods
= {
1199 msrpc_rids_to_names
,
1202 msrpc_lookup_useraliases
,
1205 msrpc_lockout_policy
,
1206 msrpc_password_policy
,