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/>.
27 #include "../librpc/gen_ndr/cli_samr.h"
28 #include "../librpc/gen_ndr/cli_lsa.h"
31 #define DBGC_CLASS DBGC_WINBIND
34 /* Query display info for a domain. This returns enough information plus a
35 bit extra to give an overview of domain users for the User Manager
37 static NTSTATUS
query_user_list(struct winbindd_domain
*domain
,
40 struct wbint_userinfo
**info
)
43 struct policy_handle dom_pol
;
44 unsigned int i
, start_idx
;
46 struct rpc_pipe_client
*cli
;
48 DEBUG(3,("rpc: query_user_list\n"));
53 if ( !winbindd_can_contact_domain( domain
) ) {
54 DEBUG(10,("query_user_list: No incoming trust for domain %s\n",
59 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
60 if (!NT_STATUS_IS_OK(result
))
67 uint32 num_dom_users
, j
;
68 uint32 max_entries
, max_size
;
69 uint32_t total_size
, returned_size
;
71 union samr_DispInfo disp_info
;
73 /* this next bit is copied from net_user_list_internal() */
75 get_query_dispinfo_params(loop_count
, &max_entries
,
78 result
= rpccli_samr_QueryDisplayInfo(cli
, mem_ctx
,
87 num_dom_users
= disp_info
.info1
.count
;
88 start_idx
+= disp_info
.info1
.count
;
91 *num_entries
+= num_dom_users
;
93 *info
= TALLOC_REALLOC_ARRAY(mem_ctx
, *info
,
94 struct wbint_userinfo
,
98 return NT_STATUS_NO_MEMORY
;
101 for (j
= 0; j
< num_dom_users
; i
++, j
++) {
103 uint32_t rid
= disp_info
.info1
.entries
[j
].rid
;
105 (*info
)[i
].acct_name
= talloc_strdup(mem_ctx
,
106 disp_info
.info1
.entries
[j
].account_name
.string
);
107 (*info
)[i
].full_name
= talloc_strdup(mem_ctx
,
108 disp_info
.info1
.entries
[j
].full_name
.string
);
109 (*info
)[i
].homedir
= NULL
;
110 (*info
)[i
].shell
= NULL
;
111 sid_compose(&(*info
)[i
].user_sid
, &domain
->sid
, rid
);
113 /* For the moment we set the primary group for
114 every user to be the Domain Users group.
115 There are serious problems with determining
116 the actual primary group for large domains.
117 This should really be made into a 'winbind
118 force group' smb.conf parameter or
119 something like that. */
121 sid_compose(&(*info
)[i
].group_sid
, &domain
->sid
,
122 DOMAIN_GROUP_RID_USERS
);
125 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
130 /* list all domain groups */
131 static NTSTATUS
enum_dom_groups(struct winbindd_domain
*domain
,
134 struct acct_info
**info
)
136 struct policy_handle dom_pol
;
139 struct rpc_pipe_client
*cli
;
144 DEBUG(3,("rpc: enum_dom_groups\n"));
146 if ( !winbindd_can_contact_domain( domain
) ) {
147 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
152 status
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
153 if (!NT_STATUS_IS_OK(status
))
157 struct samr_SamArray
*sam_array
= NULL
;
159 TALLOC_CTX
*mem_ctx2
;
162 mem_ctx2
= talloc_init("enum_dom_groups[rpc]");
164 /* start is updated by this call. */
165 status
= rpccli_samr_EnumDomainGroups(cli
, mem_ctx2
,
169 0xFFFF, /* buffer size? */
172 if (!NT_STATUS_IS_OK(status
) &&
173 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
174 talloc_destroy(mem_ctx2
);
178 (*info
) = TALLOC_REALLOC_ARRAY(mem_ctx
, *info
,
180 (*num_entries
) + count
);
182 talloc_destroy(mem_ctx2
);
183 return NT_STATUS_NO_MEMORY
;
186 for (g
=0; g
< count
; g
++) {
188 fstrcpy((*info
)[*num_entries
+ g
].acct_name
,
189 sam_array
->entries
[g
].name
.string
);
190 (*info
)[*num_entries
+ g
].rid
= sam_array
->entries
[g
].idx
;
193 (*num_entries
) += count
;
194 talloc_destroy(mem_ctx2
);
195 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
200 /* List all domain groups */
202 static NTSTATUS
enum_local_groups(struct winbindd_domain
*domain
,
205 struct acct_info
**info
)
207 struct policy_handle dom_pol
;
209 struct rpc_pipe_client
*cli
;
214 DEBUG(3,("rpc: enum_local_groups\n"));
216 if ( !winbindd_can_contact_domain( domain
) ) {
217 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
222 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
223 if (!NT_STATUS_IS_OK(result
))
227 struct samr_SamArray
*sam_array
= NULL
;
228 uint32 count
= 0, start
= *num_entries
;
229 TALLOC_CTX
*mem_ctx2
;
232 mem_ctx2
= talloc_init("enum_dom_local_groups[rpc]");
234 result
= rpccli_samr_EnumDomainAliases(cli
, mem_ctx2
,
238 0xFFFF, /* buffer size? */
240 if (!NT_STATUS_IS_OK(result
) &&
241 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
) )
243 talloc_destroy(mem_ctx2
);
247 (*info
) = TALLOC_REALLOC_ARRAY(mem_ctx
, *info
,
249 (*num_entries
) + count
);
251 talloc_destroy(mem_ctx2
);
252 return NT_STATUS_NO_MEMORY
;
255 for (g
=0; g
< count
; g
++) {
257 fstrcpy((*info
)[*num_entries
+ g
].acct_name
,
258 sam_array
->entries
[g
].name
.string
);
259 (*info
)[*num_entries
+ g
].rid
= sam_array
->entries
[g
].idx
;
262 (*num_entries
) += count
;
263 talloc_destroy(mem_ctx2
);
265 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
270 /* convert a single name to a sid in a domain */
271 static NTSTATUS
msrpc_name_to_sid(struct winbindd_domain
*domain
,
273 const char *domain_name
,
277 enum lsa_SidType
*type
)
280 DOM_SID
*sids
= NULL
;
281 enum lsa_SidType
*types
= NULL
;
282 char *full_name
= NULL
;
283 NTSTATUS name_map_status
= NT_STATUS_UNSUCCESSFUL
;
284 char *mapped_name
= NULL
;
286 if (name
== NULL
|| *name
=='\0') {
287 full_name
= talloc_asprintf(mem_ctx
, "%s", domain_name
);
288 } else if (domain_name
== NULL
|| *domain_name
== '\0') {
289 full_name
= talloc_asprintf(mem_ctx
, "%s", name
);
291 full_name
= talloc_asprintf(mem_ctx
, "%s\\%s", domain_name
, name
);
294 DEBUG(0, ("talloc_asprintf failed!\n"));
295 return NT_STATUS_NO_MEMORY
;
298 DEBUG(3,("rpc: name_to_sid name=%s\n", full_name
));
300 name_map_status
= normalize_name_unmap(mem_ctx
, full_name
,
303 /* Reset the full_name pointer if we mapped anytthing */
305 if (NT_STATUS_IS_OK(name_map_status
) ||
306 NT_STATUS_EQUAL(name_map_status
, NT_STATUS_FILE_RENAMED
))
308 full_name
= mapped_name
;
311 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
312 full_name
?full_name
:"", domain_name
));
314 result
= winbindd_lookup_names(mem_ctx
, domain
, 1,
315 (const char **)&full_name
, NULL
,
317 if (!NT_STATUS_IS_OK(result
))
320 /* Return rid and type if lookup successful */
322 sid_copy(sid
, &sids
[0]);
329 convert a domain SID to a user or group name
331 static NTSTATUS
msrpc_sid_to_name(struct winbindd_domain
*domain
,
336 enum lsa_SidType
*type
)
340 enum lsa_SidType
*types
= NULL
;
342 NTSTATUS name_map_status
= NT_STATUS_UNSUCCESSFUL
;
343 char *mapped_name
= NULL
;
345 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid
),
348 result
= winbindd_lookup_sids(mem_ctx
,
355 if (!NT_STATUS_IS_OK(result
)) {
356 DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n",
362 *type
= (enum lsa_SidType
)types
[0];
363 *domain_name
= domains
[0];
366 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains
[0], *name
));
368 name_map_status
= normalize_name_map(mem_ctx
, domain
, *name
,
370 if (NT_STATUS_IS_OK(name_map_status
) ||
371 NT_STATUS_EQUAL(name_map_status
, NT_STATUS_FILE_RENAMED
))
374 DEBUG(5,("returning mapped name -- %s\n", *name
));
380 static NTSTATUS
msrpc_rids_to_names(struct winbindd_domain
*domain
,
387 enum lsa_SidType
**types
)
395 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain
->name
));
398 sids
= TALLOC_ARRAY(mem_ctx
, DOM_SID
, num_rids
);
400 return NT_STATUS_NO_MEMORY
;
406 for (i
=0; i
<num_rids
; i
++) {
407 if (!sid_compose(&sids
[i
], sid
, rids
[i
])) {
408 return NT_STATUS_INTERNAL_ERROR
;
412 result
= winbindd_lookup_sids(mem_ctx
,
420 if (!NT_STATUS_IS_OK(result
) &&
421 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
426 for (i
=0; i
<num_rids
; i
++) {
427 NTSTATUS name_map_status
= NT_STATUS_UNSUCCESSFUL
;
428 char *mapped_name
= NULL
;
430 if ((*types
)[i
] != SID_NAME_UNKNOWN
) {
431 name_map_status
= normalize_name_map(mem_ctx
,
435 if (NT_STATUS_IS_OK(name_map_status
) ||
436 NT_STATUS_EQUAL(name_map_status
, NT_STATUS_FILE_RENAMED
))
438 ret_names
[i
] = mapped_name
;
441 *domain_name
= domains
[i
];
448 /* Lookup user information from a rid or username. */
449 static NTSTATUS
query_user(struct winbindd_domain
*domain
,
451 const DOM_SID
*user_sid
,
452 struct wbint_userinfo
*user_info
)
454 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
455 struct policy_handle dom_pol
, user_pol
;
456 union samr_UserInfo
*info
= NULL
;
458 struct netr_SamInfo3
*user
;
459 struct rpc_pipe_client
*cli
;
461 DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid
)));
463 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
464 return NT_STATUS_UNSUCCESSFUL
;
466 user_info
->homedir
= NULL
;
467 user_info
->shell
= NULL
;
468 user_info
->primary_gid
= (gid_t
)-1;
470 /* try netsamlogon cache first */
472 if ( (user
= netsamlogon_cache_get( mem_ctx
, user_sid
)) != NULL
)
475 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
476 sid_string_dbg(user_sid
)));
478 sid_compose(&user_info
->user_sid
, &domain
->sid
, user
->base
.rid
);
479 sid_compose(&user_info
->group_sid
, &domain
->sid
,
480 user
->base
.primary_gid
);
482 user_info
->acct_name
= talloc_strdup(mem_ctx
,
483 user
->base
.account_name
.string
);
484 user_info
->full_name
= talloc_strdup(mem_ctx
,
485 user
->base
.full_name
.string
);
492 if ( !winbindd_can_contact_domain( domain
) ) {
493 DEBUG(10,("query_user: No incoming trust for domain %s\n",
498 /* no cache; hit the wire */
500 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
501 if (!NT_STATUS_IS_OK(result
))
504 /* Get user handle */
505 result
= rpccli_samr_OpenUser(cli
, mem_ctx
,
507 SEC_FLAG_MAXIMUM_ALLOWED
,
511 if (!NT_STATUS_IS_OK(result
))
515 result
= rpccli_samr_QueryUserInfo(cli
, mem_ctx
,
520 rpccli_samr_Close(cli
, mem_ctx
, &user_pol
);
522 if (!NT_STATUS_IS_OK(result
))
525 sid_compose(&user_info
->user_sid
, &domain
->sid
, user_rid
);
526 sid_compose(&user_info
->group_sid
, &domain
->sid
,
527 info
->info21
.primary_gid
);
528 user_info
->acct_name
= talloc_strdup(mem_ctx
,
529 info
->info21
.account_name
.string
);
530 user_info
->full_name
= talloc_strdup(mem_ctx
,
531 info
->info21
.full_name
.string
);
532 user_info
->homedir
= NULL
;
533 user_info
->shell
= NULL
;
534 user_info
->primary_gid
= (gid_t
)-1;
539 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
540 static NTSTATUS
lookup_usergroups(struct winbindd_domain
*domain
,
542 const DOM_SID
*user_sid
,
543 uint32
*num_groups
, DOM_SID
**user_grpsids
)
545 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
546 struct policy_handle dom_pol
, user_pol
;
547 uint32 des_access
= SEC_FLAG_MAXIMUM_ALLOWED
;
548 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
551 struct rpc_pipe_client
*cli
;
553 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid
)));
555 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
556 return NT_STATUS_UNSUCCESSFUL
;
559 *user_grpsids
= NULL
;
561 /* so lets see if we have a cached user_info_3 */
562 result
= lookup_usergroups_cached(domain
, mem_ctx
, user_sid
,
563 num_groups
, user_grpsids
);
565 if (NT_STATUS_IS_OK(result
)) {
569 if ( !winbindd_can_contact_domain( domain
) ) {
570 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
573 /* Tell the cache manager not to remember this one */
575 return NT_STATUS_SYNCHRONIZATION_REQUIRED
;
578 /* no cache; hit the wire */
580 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
581 if (!NT_STATUS_IS_OK(result
))
584 /* Get user handle */
585 result
= rpccli_samr_OpenUser(cli
, mem_ctx
,
591 if (!NT_STATUS_IS_OK(result
))
594 /* Query user rids */
595 result
= rpccli_samr_GetGroupsForUser(cli
, mem_ctx
,
598 *num_groups
= rid_array
->count
;
600 rpccli_samr_Close(cli
, mem_ctx
, &user_pol
);
602 if (!NT_STATUS_IS_OK(result
) || (*num_groups
) == 0)
605 (*user_grpsids
) = TALLOC_ARRAY(mem_ctx
, DOM_SID
, *num_groups
);
606 if (!(*user_grpsids
))
607 return NT_STATUS_NO_MEMORY
;
609 for (i
=0;i
<(*num_groups
);i
++) {
610 sid_copy(&((*user_grpsids
)[i
]), &domain
->sid
);
611 sid_append_rid(&((*user_grpsids
)[i
]),
612 rid_array
->rids
[i
].rid
);
618 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
620 static NTSTATUS
msrpc_lookup_useraliases(struct winbindd_domain
*domain
,
622 uint32 num_sids
, const DOM_SID
*sids
,
626 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
627 struct policy_handle dom_pol
;
628 uint32 num_query_sids
= 0;
630 struct rpc_pipe_client
*cli
;
631 struct samr_Ids alias_rids_query
;
632 int rangesize
= MAX_SAM_ENTRIES_W2K
;
633 uint32 total_sids
= 0;
639 DEBUG(3,("rpc: lookup_useraliases\n"));
641 if ( !winbindd_can_contact_domain( domain
) ) {
642 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
647 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
648 if (!NT_STATUS_IS_OK(result
))
653 struct lsa_SidArray sid_array
;
655 ZERO_STRUCT(sid_array
);
657 num_query_sids
= MIN(num_sids
- total_sids
, rangesize
);
659 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
660 num_queries
, num_query_sids
));
662 if (num_query_sids
) {
663 sid_array
.sids
= TALLOC_ZERO_ARRAY(mem_ctx
, struct lsa_SidPtr
, num_query_sids
);
664 if (sid_array
.sids
== NULL
) {
665 return NT_STATUS_NO_MEMORY
;
668 sid_array
.sids
= NULL
;
671 for (i
=0; i
<num_query_sids
; i
++) {
672 sid_array
.sids
[i
].sid
= sid_dup_talloc(mem_ctx
, &sids
[total_sids
++]);
673 if (!sid_array
.sids
[i
].sid
) {
674 TALLOC_FREE(sid_array
.sids
);
675 return NT_STATUS_NO_MEMORY
;
678 sid_array
.num_sids
= num_query_sids
;
681 result
= rpccli_samr_GetAliasMembership(cli
, mem_ctx
,
686 if (!NT_STATUS_IS_OK(result
)) {
689 TALLOC_FREE(sid_array
.sids
);
695 for (i
=0; i
<alias_rids_query
.count
; i
++) {
696 size_t na
= *num_aliases
;
697 if (!add_rid_to_array_unique(mem_ctx
, alias_rids_query
.ids
[i
],
699 return NT_STATUS_NO_MEMORY
;
704 TALLOC_FREE(sid_array
.sids
);
708 } while (total_sids
< num_sids
);
711 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
712 "(rangesize: %d)\n", *num_aliases
, num_queries
, rangesize
));
718 /* Lookup group membership given a rid. */
719 static NTSTATUS
lookup_groupmem(struct winbindd_domain
*domain
,
721 const DOM_SID
*group_sid
,
722 enum lsa_SidType type
,
724 DOM_SID
**sid_mem
, char ***names
,
727 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
728 uint32 i
, total_names
= 0;
729 struct policy_handle dom_pol
, group_pol
;
730 uint32 des_access
= SEC_FLAG_MAXIMUM_ALLOWED
;
731 uint32
*rid_mem
= NULL
;
734 struct rpc_pipe_client
*cli
;
735 unsigned int orig_timeout
;
736 struct samr_RidTypeArray
*rids
= NULL
;
738 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain
->name
,
739 sid_string_dbg(group_sid
)));
741 if ( !winbindd_can_contact_domain( domain
) ) {
742 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
747 if (!sid_peek_check_rid(&domain
->sid
, group_sid
, &group_rid
))
748 return NT_STATUS_UNSUCCESSFUL
;
752 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
753 if (!NT_STATUS_IS_OK(result
))
756 result
= rpccli_samr_OpenGroup(cli
, mem_ctx
,
762 if (!NT_STATUS_IS_OK(result
))
765 /* Step #1: Get a list of user rids that are the members of the
768 /* This call can take a long time - allow the server to time out.
769 35 seconds should do it. */
771 orig_timeout
= rpccli_set_timeout(cli
, 35000);
773 result
= rpccli_samr_QueryGroupMember(cli
, mem_ctx
,
777 /* And restore our original timeout. */
778 rpccli_set_timeout(cli
, orig_timeout
);
780 rpccli_samr_Close(cli
, mem_ctx
, &group_pol
);
782 if (!NT_STATUS_IS_OK(result
))
785 *num_names
= rids
->count
;
786 rid_mem
= rids
->rids
;
795 /* Step #2: Convert list of rids into list of usernames. Do this
796 in bunches of ~1000 to avoid crashing NT4. It looks like there
797 is a buffer overflow or something like that lurking around
800 #define MAX_LOOKUP_RIDS 900
802 *names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, *num_names
);
803 *name_types
= TALLOC_ZERO_ARRAY(mem_ctx
, uint32
, *num_names
);
804 *sid_mem
= TALLOC_ZERO_ARRAY(mem_ctx
, DOM_SID
, *num_names
);
806 for (j
=0;j
<(*num_names
);j
++)
807 sid_compose(&(*sid_mem
)[j
], &domain
->sid
, rid_mem
[j
]);
809 if (*num_names
>0 && (!*names
|| !*name_types
))
810 return NT_STATUS_NO_MEMORY
;
812 for (i
= 0; i
< *num_names
; i
+= MAX_LOOKUP_RIDS
) {
813 int num_lookup_rids
= MIN(*num_names
- i
, MAX_LOOKUP_RIDS
);
814 struct lsa_Strings tmp_names
;
815 struct samr_Ids tmp_types
;
817 /* Lookup a chunk of rids */
819 result
= rpccli_samr_LookupRids(cli
, mem_ctx
,
826 /* see if we have a real error (and yes the
827 STATUS_SOME_UNMAPPED is the one returned from 2k) */
829 if (!NT_STATUS_IS_OK(result
) &&
830 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
))
833 /* Copy result into array. The talloc system will take
834 care of freeing the temporary arrays later on. */
836 if (tmp_names
.count
!= tmp_types
.count
) {
837 return NT_STATUS_UNSUCCESSFUL
;
840 for (r
=0; r
<tmp_names
.count
; r
++) {
841 if (tmp_types
.ids
[r
] == SID_NAME_UNKNOWN
) {
844 (*names
)[total_names
] = fill_domain_username_talloc(
845 mem_ctx
, domain
->name
,
846 tmp_names
.names
[r
].string
, true);
847 (*name_types
)[total_names
] = tmp_types
.ids
[r
];
852 *num_names
= total_names
;
861 static int get_ldap_seq(const char *server
, int port
, uint32
*seq
)
865 const char *attrs
[] = {"highestCommittedUSN", NULL
};
866 LDAPMessage
*res
= NULL
;
867 char **values
= NULL
;
870 *seq
= DOM_SEQUENCE_NONE
;
873 * Parameterised (5) second timeout on open. This is needed as the
874 * search timeout doesn't seem to apply to doing an open as well. JRA.
877 ldp
= ldap_open_with_timeout(server
, port
, lp_ldap_timeout());
881 /* Timeout if no response within 20 seconds. */
885 if (ldap_search_st(ldp
, "", LDAP_SCOPE_BASE
, "(objectclass=*)",
886 CONST_DISCARD(char **, attrs
), 0, &to
, &res
))
889 if (ldap_count_entries(ldp
, res
) != 1)
892 values
= ldap_get_values(ldp
, res
, "highestCommittedUSN");
893 if (!values
|| !values
[0])
896 *seq
= atoi(values
[0]);
902 ldap_value_free(values
);
910 /**********************************************************************
911 Get the sequence number for a Windows AD native mode domain using
913 **********************************************************************/
915 static int get_ldap_sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
918 char addr
[INET6_ADDRSTRLEN
];
920 print_sockaddr(addr
, sizeof(addr
), &domain
->dcaddr
);
921 if ((ret
= get_ldap_seq(addr
, LDAP_PORT
, seq
)) == 0) {
922 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
923 "number for Domain (%s) from DC (%s)\n",
924 domain
->name
, addr
));
929 #endif /* HAVE_LDAP */
931 /* find the sequence number for a domain */
932 static NTSTATUS
sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
935 union samr_DomainInfo
*info
= NULL
;
937 struct policy_handle dom_pol
;
938 bool got_seq_num
= False
;
939 struct rpc_pipe_client
*cli
;
941 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain
->name
));
943 if ( !winbindd_can_contact_domain( domain
) ) {
944 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
950 *seq
= DOM_SEQUENCE_NONE
;
952 if (!(mem_ctx
= talloc_init("sequence_number[rpc]")))
953 return NT_STATUS_NO_MEMORY
;
956 if ( domain
->active_directory
)
960 DEBUG(8,("using get_ldap_seq() to retrieve the "
961 "sequence number\n"));
963 res
= get_ldap_sequence_number( domain
, seq
);
966 result
= NT_STATUS_OK
;
967 DEBUG(10,("domain_sequence_number: LDAP for "
969 domain
->name
, *seq
));
973 DEBUG(10,("domain_sequence_number: failed to get LDAP "
974 "sequence number for domain %s\n",
977 #endif /* HAVE_LDAP */
979 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
980 if (!NT_STATUS_IS_OK(result
)) {
984 /* Query domain info */
986 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
991 if (NT_STATUS_IS_OK(result
)) {
992 *seq
= info
->info8
.sequence_num
;
997 /* retry with info-level 2 in case the dc does not support info-level 8
998 * (like all older samba2 and samba3 dc's) - Guenther */
1000 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1005 if (NT_STATUS_IS_OK(result
)) {
1006 *seq
= info
->general
.sequence_num
;
1012 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1013 domain
->name
, (unsigned)*seq
));
1015 DEBUG(10,("domain_sequence_number: failed to get sequence "
1016 "number (%u) for domain %s\n",
1017 (unsigned)*seq
, domain
->name
));
1022 talloc_destroy(mem_ctx
);
1027 /* get a list of trusted domains */
1028 static NTSTATUS
trusted_domains(struct winbindd_domain
*domain
,
1029 TALLOC_CTX
*mem_ctx
,
1030 uint32
*num_domains
,
1035 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1036 uint32 enum_ctx
= 0;
1037 struct rpc_pipe_client
*cli
;
1038 struct policy_handle lsa_policy
;
1040 DEBUG(3,("rpc: trusted_domains\n"));
1047 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
1048 if (!NT_STATUS_IS_OK(result
))
1051 result
= STATUS_MORE_ENTRIES
;
1053 while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
1056 struct lsa_DomainList dom_list
;
1058 result
= rpccli_lsa_EnumTrustDom(cli
, mem_ctx
,
1064 if (!NT_STATUS_IS_OK(result
) &&
1065 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
))
1068 start_idx
= *num_domains
;
1069 *num_domains
+= dom_list
.count
;
1070 *names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *names
,
1071 char *, *num_domains
);
1072 *dom_sids
= TALLOC_REALLOC_ARRAY(mem_ctx
, *dom_sids
,
1073 DOM_SID
, *num_domains
);
1074 *alt_names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *alt_names
,
1075 char *, *num_domains
);
1076 if ((*names
== NULL
) || (*dom_sids
== NULL
) ||
1077 (*alt_names
== NULL
))
1078 return NT_STATUS_NO_MEMORY
;
1080 for (i
=0; i
<dom_list
.count
; i
++) {
1081 (*names
)[start_idx
+i
] = CONST_DISCARD(char *, dom_list
.domains
[i
].name
.string
);
1082 (*dom_sids
)[start_idx
+i
] = *dom_list
.domains
[i
].sid
;
1083 (*alt_names
)[start_idx
+i
] = talloc_strdup(mem_ctx
, "");
1089 /* find the lockout policy for a domain */
1090 static NTSTATUS
msrpc_lockout_policy(struct winbindd_domain
*domain
,
1091 TALLOC_CTX
*mem_ctx
,
1092 struct samr_DomInfo12
*lockout_policy
)
1095 struct rpc_pipe_client
*cli
;
1096 struct policy_handle dom_pol
;
1097 union samr_DomainInfo
*info
= NULL
;
1099 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain
->name
));
1101 if ( !winbindd_can_contact_domain( domain
) ) {
1102 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1104 return NT_STATUS_NOT_SUPPORTED
;
1107 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1108 if (!NT_STATUS_IS_OK(result
)) {
1112 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1116 if (!NT_STATUS_IS_OK(result
)) {
1120 *lockout_policy
= info
->info12
;
1122 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1123 info
->info12
.lockout_threshold
));
1130 /* find the password policy for a domain */
1131 static NTSTATUS
msrpc_password_policy(struct winbindd_domain
*domain
,
1132 TALLOC_CTX
*mem_ctx
,
1133 struct samr_DomInfo1
*password_policy
)
1136 struct rpc_pipe_client
*cli
;
1137 struct policy_handle dom_pol
;
1138 union samr_DomainInfo
*info
= NULL
;
1140 DEBUG(10,("rpc: fetch password policy for %s\n", domain
->name
));
1142 if ( !winbindd_can_contact_domain( domain
) ) {
1143 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1145 return NT_STATUS_NOT_SUPPORTED
;
1148 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1149 if (!NT_STATUS_IS_OK(result
)) {
1153 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1157 if (!NT_STATUS_IS_OK(result
)) {
1161 *password_policy
= info
->info1
;
1163 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1164 info
->info1
.min_password_length
));
1171 typedef NTSTATUS (*lookup_sids_fn_t
)(struct rpc_pipe_client
*cli
,
1172 TALLOC_CTX
*mem_ctx
,
1173 struct policy_handle
*pol
,
1175 const DOM_SID
*sids
,
1178 enum lsa_SidType
**ptypes
);
1180 NTSTATUS
winbindd_lookup_sids(TALLOC_CTX
*mem_ctx
,
1181 struct winbindd_domain
*domain
,
1183 const struct dom_sid
*sids
,
1186 enum lsa_SidType
**types
)
1189 struct rpc_pipe_client
*cli
= NULL
;
1190 struct policy_handle lsa_policy
;
1191 unsigned int orig_timeout
;
1192 lookup_sids_fn_t lookup_sids_fn
= rpccli_lsa_lookup_sids
;
1194 if (domain
->can_do_ncacn_ip_tcp
) {
1195 status
= cm_connect_lsa_tcp(domain
, mem_ctx
, &cli
);
1196 if (NT_STATUS_IS_OK(status
)) {
1197 lookup_sids_fn
= rpccli_lsa_lookup_sids3
;
1200 domain
->can_do_ncacn_ip_tcp
= false;
1202 status
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
1204 if (!NT_STATUS_IS_OK(status
)) {
1210 * This call can take a long time
1211 * allow the server to time out.
1212 * 35 seconds should do it.
1214 orig_timeout
= rpccli_set_timeout(cli
, 35000);
1216 status
= lookup_sids_fn(cli
,
1225 /* And restore our original timeout. */
1226 rpccli_set_timeout(cli
, orig_timeout
);
1228 if (!NT_STATUS_IS_OK(status
)) {
1235 typedef NTSTATUS (*lookup_names_fn_t
)(struct rpc_pipe_client
*cli
,
1236 TALLOC_CTX
*mem_ctx
,
1237 struct policy_handle
*pol
,
1240 const char ***dom_names
,
1242 struct dom_sid
**sids
,
1243 enum lsa_SidType
**types
);
1245 NTSTATUS
winbindd_lookup_names(TALLOC_CTX
*mem_ctx
,
1246 struct winbindd_domain
*domain
,
1249 const char ***domains
,
1250 struct dom_sid
**sids
,
1251 enum lsa_SidType
**types
)
1254 struct rpc_pipe_client
*cli
= NULL
;
1255 struct policy_handle lsa_policy
;
1256 unsigned int orig_timeout
;
1257 lookup_names_fn_t lookup_names_fn
= rpccli_lsa_lookup_names
;
1259 if (domain
->can_do_ncacn_ip_tcp
) {
1260 status
= cm_connect_lsa_tcp(domain
, mem_ctx
, &cli
);
1261 if (NT_STATUS_IS_OK(status
)) {
1262 lookup_names_fn
= rpccli_lsa_lookup_names4
;
1265 domain
->can_do_ncacn_ip_tcp
= false;
1267 status
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
1269 if (!NT_STATUS_IS_OK(status
)) {
1276 * This call can take a long time
1277 * allow the server to time out.
1278 * 35 seconds should do it.
1280 orig_timeout
= rpccli_set_timeout(cli
, 35000);
1282 status
= lookup_names_fn(cli
,
1286 (const char **) names
,
1292 /* And restore our original timeout. */
1293 rpccli_set_timeout(cli
, orig_timeout
);
1295 if (!NT_STATUS_IS_OK(status
)) {
1302 /* the rpc backend methods are exposed via this structure */
1303 struct winbindd_methods msrpc_methods
= {
1310 msrpc_rids_to_names
,
1313 msrpc_lookup_useraliases
,
1316 msrpc_lockout_policy
,
1317 msrpc_password_policy
,