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 NTSTATUS name_map_status
= NT_STATUS_UNSUCCESSFUL
;
282 char *mapped_name
= NULL
;
284 if (name
== NULL
|| *name
=='\0') {
285 full_name
= talloc_asprintf(mem_ctx
, "%s", domain_name
);
286 } else if (domain_name
== NULL
|| *domain_name
== '\0') {
287 full_name
= talloc_asprintf(mem_ctx
, "%s", name
);
289 full_name
= talloc_asprintf(mem_ctx
, "%s\\%s", domain_name
, name
);
292 DEBUG(0, ("talloc_asprintf failed!\n"));
293 return NT_STATUS_NO_MEMORY
;
296 DEBUG(3,("rpc: name_to_sid name=%s\n", full_name
));
298 name_map_status
= normalize_name_unmap(mem_ctx
, full_name
,
301 /* Reset the full_name pointer if we mapped anytthing */
303 if (NT_STATUS_IS_OK(name_map_status
) ||
304 NT_STATUS_EQUAL(name_map_status
, NT_STATUS_FILE_RENAMED
))
306 full_name
= mapped_name
;
309 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
310 full_name
?full_name
:"", domain_name
));
312 result
= winbindd_lookup_names(mem_ctx
, domain
, 1,
313 (const char **)&full_name
, NULL
,
315 if (!NT_STATUS_IS_OK(result
))
318 /* Return rid and type if lookup successful */
320 sid_copy(sid
, &sids
[0]);
327 convert a domain SID to a user or group name
329 static NTSTATUS
msrpc_sid_to_name(struct winbindd_domain
*domain
,
334 enum lsa_SidType
*type
)
338 enum lsa_SidType
*types
= NULL
;
340 NTSTATUS name_map_status
= NT_STATUS_UNSUCCESSFUL
;
341 char *mapped_name
= NULL
;
343 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid
),
346 result
= winbindd_lookup_sids(mem_ctx
,
353 if (!NT_STATUS_IS_OK(result
)) {
354 DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n",
360 *type
= (enum lsa_SidType
)types
[0];
361 *domain_name
= domains
[0];
364 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains
[0], *name
));
366 name_map_status
= normalize_name_map(mem_ctx
, domain
, *name
,
368 if (NT_STATUS_IS_OK(name_map_status
) ||
369 NT_STATUS_EQUAL(name_map_status
, NT_STATUS_FILE_RENAMED
))
372 DEBUG(5,("returning mapped name -- %s\n", *name
));
378 static NTSTATUS
msrpc_rids_to_names(struct winbindd_domain
*domain
,
385 enum lsa_SidType
**types
)
393 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain
->name
));
396 sids
= TALLOC_ARRAY(mem_ctx
, DOM_SID
, num_rids
);
398 return NT_STATUS_NO_MEMORY
;
404 for (i
=0; i
<num_rids
; i
++) {
405 if (!sid_compose(&sids
[i
], sid
, rids
[i
])) {
406 return NT_STATUS_INTERNAL_ERROR
;
410 result
= winbindd_lookup_sids(mem_ctx
,
418 if (!NT_STATUS_IS_OK(result
) &&
419 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
424 for (i
=0; i
<num_rids
; i
++) {
425 NTSTATUS name_map_status
= NT_STATUS_UNSUCCESSFUL
;
426 char *mapped_name
= NULL
;
428 if ((*types
)[i
] != SID_NAME_UNKNOWN
) {
429 name_map_status
= normalize_name_map(mem_ctx
,
433 if (NT_STATUS_IS_OK(name_map_status
) ||
434 NT_STATUS_EQUAL(name_map_status
, NT_STATUS_FILE_RENAMED
))
436 ret_names
[i
] = mapped_name
;
439 *domain_name
= domains
[i
];
446 /* Lookup user information from a rid or username. */
447 static NTSTATUS
query_user(struct winbindd_domain
*domain
,
449 const DOM_SID
*user_sid
,
450 struct wbint_userinfo
*user_info
)
452 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
453 struct policy_handle dom_pol
, user_pol
;
454 union samr_UserInfo
*info
= NULL
;
456 struct netr_SamInfo3
*user
;
457 struct rpc_pipe_client
*cli
;
459 DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid
)));
461 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
462 return NT_STATUS_UNSUCCESSFUL
;
464 user_info
->homedir
= NULL
;
465 user_info
->shell
= NULL
;
466 user_info
->primary_gid
= (gid_t
)-1;
468 /* try netsamlogon cache first */
470 if ( (user
= netsamlogon_cache_get( mem_ctx
, user_sid
)) != NULL
)
473 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
474 sid_string_dbg(user_sid
)));
476 sid_compose(&user_info
->user_sid
, &domain
->sid
, user
->base
.rid
);
477 sid_compose(&user_info
->group_sid
, &domain
->sid
,
478 user
->base
.primary_gid
);
480 user_info
->acct_name
= talloc_strdup(mem_ctx
,
481 user
->base
.account_name
.string
);
482 user_info
->full_name
= talloc_strdup(mem_ctx
,
483 user
->base
.full_name
.string
);
490 if ( !winbindd_can_contact_domain( domain
) ) {
491 DEBUG(10,("query_user: No incoming trust for domain %s\n",
496 /* no cache; hit the wire */
498 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
499 if (!NT_STATUS_IS_OK(result
))
502 /* Get user handle */
503 result
= rpccli_samr_OpenUser(cli
, mem_ctx
,
505 SEC_FLAG_MAXIMUM_ALLOWED
,
509 if (!NT_STATUS_IS_OK(result
))
513 result
= rpccli_samr_QueryUserInfo(cli
, mem_ctx
,
518 rpccli_samr_Close(cli
, mem_ctx
, &user_pol
);
520 if (!NT_STATUS_IS_OK(result
))
523 sid_compose(&user_info
->user_sid
, &domain
->sid
, user_rid
);
524 sid_compose(&user_info
->group_sid
, &domain
->sid
,
525 info
->info21
.primary_gid
);
526 user_info
->acct_name
= talloc_strdup(mem_ctx
,
527 info
->info21
.account_name
.string
);
528 user_info
->full_name
= talloc_strdup(mem_ctx
,
529 info
->info21
.full_name
.string
);
530 user_info
->homedir
= NULL
;
531 user_info
->shell
= NULL
;
532 user_info
->primary_gid
= (gid_t
)-1;
537 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
538 static NTSTATUS
lookup_usergroups(struct winbindd_domain
*domain
,
540 const DOM_SID
*user_sid
,
541 uint32
*num_groups
, DOM_SID
**user_grpsids
)
543 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
544 struct policy_handle dom_pol
, user_pol
;
545 uint32 des_access
= SEC_FLAG_MAXIMUM_ALLOWED
;
546 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
549 struct rpc_pipe_client
*cli
;
551 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid
)));
553 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
554 return NT_STATUS_UNSUCCESSFUL
;
557 *user_grpsids
= NULL
;
559 /* so lets see if we have a cached user_info_3 */
560 result
= lookup_usergroups_cached(domain
, mem_ctx
, user_sid
,
561 num_groups
, user_grpsids
);
563 if (NT_STATUS_IS_OK(result
)) {
567 if ( !winbindd_can_contact_domain( domain
) ) {
568 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
571 /* Tell the cache manager not to remember this one */
573 return NT_STATUS_SYNCHRONIZATION_REQUIRED
;
576 /* no cache; hit the wire */
578 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
579 if (!NT_STATUS_IS_OK(result
))
582 /* Get user handle */
583 result
= rpccli_samr_OpenUser(cli
, mem_ctx
,
589 if (!NT_STATUS_IS_OK(result
))
592 /* Query user rids */
593 result
= rpccli_samr_GetGroupsForUser(cli
, mem_ctx
,
596 *num_groups
= rid_array
->count
;
598 rpccli_samr_Close(cli
, mem_ctx
, &user_pol
);
600 if (!NT_STATUS_IS_OK(result
) || (*num_groups
) == 0)
603 (*user_grpsids
) = TALLOC_ARRAY(mem_ctx
, DOM_SID
, *num_groups
);
604 if (!(*user_grpsids
))
605 return NT_STATUS_NO_MEMORY
;
607 for (i
=0;i
<(*num_groups
);i
++) {
608 sid_copy(&((*user_grpsids
)[i
]), &domain
->sid
);
609 sid_append_rid(&((*user_grpsids
)[i
]),
610 rid_array
->rids
[i
].rid
);
616 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
618 static NTSTATUS
msrpc_lookup_useraliases(struct winbindd_domain
*domain
,
620 uint32 num_sids
, const DOM_SID
*sids
,
624 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
625 struct policy_handle dom_pol
;
626 uint32 num_query_sids
= 0;
628 struct rpc_pipe_client
*cli
;
629 struct samr_Ids alias_rids_query
;
630 int rangesize
= MAX_SAM_ENTRIES_W2K
;
631 uint32 total_sids
= 0;
637 DEBUG(3,("rpc: lookup_useraliases\n"));
639 if ( !winbindd_can_contact_domain( domain
) ) {
640 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
645 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
646 if (!NT_STATUS_IS_OK(result
))
651 struct lsa_SidArray sid_array
;
653 ZERO_STRUCT(sid_array
);
655 num_query_sids
= MIN(num_sids
- total_sids
, rangesize
);
657 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
658 num_queries
, num_query_sids
));
660 if (num_query_sids
) {
661 sid_array
.sids
= TALLOC_ZERO_ARRAY(mem_ctx
, struct lsa_SidPtr
, num_query_sids
);
662 if (sid_array
.sids
== NULL
) {
663 return NT_STATUS_NO_MEMORY
;
666 sid_array
.sids
= NULL
;
669 for (i
=0; i
<num_query_sids
; i
++) {
670 sid_array
.sids
[i
].sid
= sid_dup_talloc(mem_ctx
, &sids
[total_sids
++]);
671 if (!sid_array
.sids
[i
].sid
) {
672 TALLOC_FREE(sid_array
.sids
);
673 return NT_STATUS_NO_MEMORY
;
676 sid_array
.num_sids
= num_query_sids
;
679 result
= rpccli_samr_GetAliasMembership(cli
, mem_ctx
,
684 if (!NT_STATUS_IS_OK(result
)) {
687 TALLOC_FREE(sid_array
.sids
);
693 for (i
=0; i
<alias_rids_query
.count
; i
++) {
694 size_t na
= *num_aliases
;
695 if (!add_rid_to_array_unique(mem_ctx
, alias_rids_query
.ids
[i
],
697 return NT_STATUS_NO_MEMORY
;
702 TALLOC_FREE(sid_array
.sids
);
706 } while (total_sids
< num_sids
);
709 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
710 "(rangesize: %d)\n", *num_aliases
, num_queries
, rangesize
));
716 /* Lookup group membership given a rid. */
717 static NTSTATUS
lookup_groupmem(struct winbindd_domain
*domain
,
719 const DOM_SID
*group_sid
,
720 enum lsa_SidType type
,
722 DOM_SID
**sid_mem
, char ***names
,
725 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
726 uint32 i
, total_names
= 0;
727 struct policy_handle dom_pol
, group_pol
;
728 uint32 des_access
= SEC_FLAG_MAXIMUM_ALLOWED
;
729 uint32
*rid_mem
= NULL
;
732 struct rpc_pipe_client
*cli
;
733 unsigned int orig_timeout
;
734 struct samr_RidTypeArray
*rids
= NULL
;
736 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain
->name
,
737 sid_string_dbg(group_sid
)));
739 if ( !winbindd_can_contact_domain( domain
) ) {
740 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
745 if (!sid_peek_check_rid(&domain
->sid
, group_sid
, &group_rid
))
746 return NT_STATUS_UNSUCCESSFUL
;
750 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
751 if (!NT_STATUS_IS_OK(result
))
754 result
= rpccli_samr_OpenGroup(cli
, mem_ctx
,
760 if (!NT_STATUS_IS_OK(result
))
763 /* Step #1: Get a list of user rids that are the members of the
766 /* This call can take a long time - allow the server to time out.
767 35 seconds should do it. */
769 orig_timeout
= rpccli_set_timeout(cli
, 35000);
771 result
= rpccli_samr_QueryGroupMember(cli
, mem_ctx
,
775 /* And restore our original timeout. */
776 rpccli_set_timeout(cli
, orig_timeout
);
778 rpccli_samr_Close(cli
, mem_ctx
, &group_pol
);
780 if (!NT_STATUS_IS_OK(result
))
783 *num_names
= rids
->count
;
784 rid_mem
= rids
->rids
;
793 /* Step #2: Convert list of rids into list of usernames. Do this
794 in bunches of ~1000 to avoid crashing NT4. It looks like there
795 is a buffer overflow or something like that lurking around
798 #define MAX_LOOKUP_RIDS 900
800 *names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, *num_names
);
801 *name_types
= TALLOC_ZERO_ARRAY(mem_ctx
, uint32
, *num_names
);
802 *sid_mem
= TALLOC_ZERO_ARRAY(mem_ctx
, DOM_SID
, *num_names
);
804 for (j
=0;j
<(*num_names
);j
++)
805 sid_compose(&(*sid_mem
)[j
], &domain
->sid
, rid_mem
[j
]);
807 if (*num_names
>0 && (!*names
|| !*name_types
))
808 return NT_STATUS_NO_MEMORY
;
810 for (i
= 0; i
< *num_names
; i
+= MAX_LOOKUP_RIDS
) {
811 int num_lookup_rids
= MIN(*num_names
- i
, MAX_LOOKUP_RIDS
);
812 struct lsa_Strings tmp_names
;
813 struct samr_Ids tmp_types
;
815 /* Lookup a chunk of rids */
817 result
= rpccli_samr_LookupRids(cli
, mem_ctx
,
824 /* see if we have a real error (and yes the
825 STATUS_SOME_UNMAPPED is the one returned from 2k) */
827 if (!NT_STATUS_IS_OK(result
) &&
828 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
))
831 /* Copy result into array. The talloc system will take
832 care of freeing the temporary arrays later on. */
834 if (tmp_names
.count
!= tmp_types
.count
) {
835 return NT_STATUS_UNSUCCESSFUL
;
838 for (r
=0; r
<tmp_names
.count
; r
++) {
839 if (tmp_types
.ids
[r
] == SID_NAME_UNKNOWN
) {
842 (*names
)[total_names
] = fill_domain_username_talloc(
843 mem_ctx
, domain
->name
,
844 tmp_names
.names
[r
].string
, true);
845 (*name_types
)[total_names
] = tmp_types
.ids
[r
];
850 *num_names
= total_names
;
859 static int get_ldap_seq(const char *server
, int port
, uint32
*seq
)
863 const char *attrs
[] = {"highestCommittedUSN", NULL
};
864 LDAPMessage
*res
= NULL
;
865 char **values
= NULL
;
868 *seq
= DOM_SEQUENCE_NONE
;
871 * Parameterised (5) second timeout on open. This is needed as the
872 * search timeout doesn't seem to apply to doing an open as well. JRA.
875 ldp
= ldap_open_with_timeout(server
, port
, lp_ldap_timeout());
879 /* Timeout if no response within 20 seconds. */
883 if (ldap_search_st(ldp
, "", LDAP_SCOPE_BASE
, "(objectclass=*)",
884 CONST_DISCARD(char **, attrs
), 0, &to
, &res
))
887 if (ldap_count_entries(ldp
, res
) != 1)
890 values
= ldap_get_values(ldp
, res
, "highestCommittedUSN");
891 if (!values
|| !values
[0])
894 *seq
= atoi(values
[0]);
900 ldap_value_free(values
);
908 /**********************************************************************
909 Get the sequence number for a Windows AD native mode domain using
911 **********************************************************************/
913 static int get_ldap_sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
916 char addr
[INET6_ADDRSTRLEN
];
918 print_sockaddr(addr
, sizeof(addr
), &domain
->dcaddr
);
919 if ((ret
= get_ldap_seq(addr
, LDAP_PORT
, seq
)) == 0) {
920 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
921 "number for Domain (%s) from DC (%s)\n",
922 domain
->name
, addr
));
927 #endif /* HAVE_LDAP */
929 /* find the sequence number for a domain */
930 static NTSTATUS
sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
933 union samr_DomainInfo
*info
= NULL
;
935 struct policy_handle dom_pol
;
936 bool got_seq_num
= False
;
937 struct rpc_pipe_client
*cli
;
939 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain
->name
));
941 if ( !winbindd_can_contact_domain( domain
) ) {
942 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
948 *seq
= DOM_SEQUENCE_NONE
;
950 if (!(mem_ctx
= talloc_init("sequence_number[rpc]")))
951 return NT_STATUS_NO_MEMORY
;
954 if ( domain
->active_directory
)
958 DEBUG(8,("using get_ldap_seq() to retrieve the "
959 "sequence number\n"));
961 res
= get_ldap_sequence_number( domain
, seq
);
964 result
= NT_STATUS_OK
;
965 DEBUG(10,("domain_sequence_number: LDAP for "
967 domain
->name
, *seq
));
971 DEBUG(10,("domain_sequence_number: failed to get LDAP "
972 "sequence number for domain %s\n",
975 #endif /* HAVE_LDAP */
977 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
978 if (!NT_STATUS_IS_OK(result
)) {
982 /* Query domain info */
984 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
989 if (NT_STATUS_IS_OK(result
)) {
990 *seq
= info
->info8
.sequence_num
;
995 /* retry with info-level 2 in case the dc does not support info-level 8
996 * (like all older samba2 and samba3 dc's) - Guenther */
998 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1003 if (NT_STATUS_IS_OK(result
)) {
1004 *seq
= info
->general
.sequence_num
;
1010 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1011 domain
->name
, (unsigned)*seq
));
1013 DEBUG(10,("domain_sequence_number: failed to get sequence "
1014 "number (%u) for domain %s\n",
1015 (unsigned)*seq
, domain
->name
));
1020 talloc_destroy(mem_ctx
);
1025 /* get a list of trusted domains */
1026 static NTSTATUS
trusted_domains(struct winbindd_domain
*domain
,
1027 TALLOC_CTX
*mem_ctx
,
1028 uint32
*num_domains
,
1033 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1034 uint32 enum_ctx
= 0;
1035 struct rpc_pipe_client
*cli
;
1036 struct policy_handle lsa_policy
;
1038 DEBUG(3,("rpc: trusted_domains\n"));
1045 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
1046 if (!NT_STATUS_IS_OK(result
))
1049 result
= STATUS_MORE_ENTRIES
;
1051 while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
1054 struct lsa_DomainList dom_list
;
1056 result
= rpccli_lsa_EnumTrustDom(cli
, mem_ctx
,
1062 if (!NT_STATUS_IS_OK(result
) &&
1063 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
))
1066 start_idx
= *num_domains
;
1067 *num_domains
+= dom_list
.count
;
1068 *names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *names
,
1069 char *, *num_domains
);
1070 *dom_sids
= TALLOC_REALLOC_ARRAY(mem_ctx
, *dom_sids
,
1071 DOM_SID
, *num_domains
);
1072 *alt_names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *alt_names
,
1073 char *, *num_domains
);
1074 if ((*names
== NULL
) || (*dom_sids
== NULL
) ||
1075 (*alt_names
== NULL
))
1076 return NT_STATUS_NO_MEMORY
;
1078 for (i
=0; i
<dom_list
.count
; i
++) {
1079 (*names
)[start_idx
+i
] = CONST_DISCARD(char *, dom_list
.domains
[i
].name
.string
);
1080 (*dom_sids
)[start_idx
+i
] = *dom_list
.domains
[i
].sid
;
1081 (*alt_names
)[start_idx
+i
] = talloc_strdup(mem_ctx
, "");
1087 /* find the lockout policy for a domain */
1088 static NTSTATUS
msrpc_lockout_policy(struct winbindd_domain
*domain
,
1089 TALLOC_CTX
*mem_ctx
,
1090 struct samr_DomInfo12
*lockout_policy
)
1093 struct rpc_pipe_client
*cli
;
1094 struct policy_handle dom_pol
;
1095 union samr_DomainInfo
*info
= NULL
;
1097 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain
->name
));
1099 if ( !winbindd_can_contact_domain( domain
) ) {
1100 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1102 return NT_STATUS_NOT_SUPPORTED
;
1105 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1106 if (!NT_STATUS_IS_OK(result
)) {
1110 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1114 if (!NT_STATUS_IS_OK(result
)) {
1118 *lockout_policy
= info
->info12
;
1120 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1121 info
->info12
.lockout_threshold
));
1128 /* find the password policy for a domain */
1129 static NTSTATUS
msrpc_password_policy(struct winbindd_domain
*domain
,
1130 TALLOC_CTX
*mem_ctx
,
1131 struct samr_DomInfo1
*password_policy
)
1134 struct rpc_pipe_client
*cli
;
1135 struct policy_handle dom_pol
;
1136 union samr_DomainInfo
*info
= NULL
;
1138 DEBUG(10,("rpc: fetch password policy for %s\n", domain
->name
));
1140 if ( !winbindd_can_contact_domain( domain
) ) {
1141 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1143 return NT_STATUS_NOT_SUPPORTED
;
1146 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1147 if (!NT_STATUS_IS_OK(result
)) {
1151 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1155 if (!NT_STATUS_IS_OK(result
)) {
1159 *password_policy
= info
->info1
;
1161 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1162 info
->info1
.min_password_length
));
1169 typedef NTSTATUS (*lookup_sids_fn_t
)(struct rpc_pipe_client
*cli
,
1170 TALLOC_CTX
*mem_ctx
,
1171 struct policy_handle
*pol
,
1173 const DOM_SID
*sids
,
1176 enum lsa_SidType
**ptypes
);
1178 NTSTATUS
winbindd_lookup_sids(TALLOC_CTX
*mem_ctx
,
1179 struct winbindd_domain
*domain
,
1181 const struct dom_sid
*sids
,
1184 enum lsa_SidType
**types
)
1187 struct rpc_pipe_client
*cli
= NULL
;
1188 struct policy_handle lsa_policy
;
1189 unsigned int orig_timeout
;
1190 lookup_sids_fn_t lookup_sids_fn
= rpccli_lsa_lookup_sids
;
1192 if (domain
->can_do_ncacn_ip_tcp
) {
1193 status
= cm_connect_lsa_tcp(domain
, mem_ctx
, &cli
);
1194 if (NT_STATUS_IS_OK(status
)) {
1195 lookup_sids_fn
= rpccli_lsa_lookup_sids3
;
1198 domain
->can_do_ncacn_ip_tcp
= false;
1200 status
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
1202 if (!NT_STATUS_IS_OK(status
)) {
1208 * This call can take a long time
1209 * allow the server to time out.
1210 * 35 seconds should do it.
1212 orig_timeout
= rpccli_set_timeout(cli
, 35000);
1214 status
= lookup_sids_fn(cli
,
1223 /* And restore our original timeout. */
1224 rpccli_set_timeout(cli
, orig_timeout
);
1226 if (!NT_STATUS_IS_OK(status
)) {
1233 typedef NTSTATUS (*lookup_names_fn_t
)(struct rpc_pipe_client
*cli
,
1234 TALLOC_CTX
*mem_ctx
,
1235 struct policy_handle
*pol
,
1238 const char ***dom_names
,
1240 struct dom_sid
**sids
,
1241 enum lsa_SidType
**types
);
1243 NTSTATUS
winbindd_lookup_names(TALLOC_CTX
*mem_ctx
,
1244 struct winbindd_domain
*domain
,
1247 const char ***domains
,
1248 struct dom_sid
**sids
,
1249 enum lsa_SidType
**types
)
1252 struct rpc_pipe_client
*cli
= NULL
;
1253 struct policy_handle lsa_policy
;
1254 unsigned int orig_timeout
;
1255 lookup_names_fn_t lookup_names_fn
= rpccli_lsa_lookup_names
;
1257 if (domain
->can_do_ncacn_ip_tcp
) {
1258 status
= cm_connect_lsa_tcp(domain
, mem_ctx
, &cli
);
1259 if (NT_STATUS_IS_OK(status
)) {
1260 lookup_names_fn
= rpccli_lsa_lookup_names4
;
1263 domain
->can_do_ncacn_ip_tcp
= false;
1265 status
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
1267 if (!NT_STATUS_IS_OK(status
)) {
1274 * This call can take a long time
1275 * allow the server to time out.
1276 * 35 seconds should do it.
1278 orig_timeout
= rpccli_set_timeout(cli
, 35000);
1280 status
= lookup_names_fn(cli
,
1284 (const char **) names
,
1290 /* And restore our original timeout. */
1291 rpccli_set_timeout(cli
, orig_timeout
);
1293 if (!NT_STATUS_IS_OK(status
)) {
1300 /* the rpc backend methods are exposed via this structure */
1301 struct winbindd_methods msrpc_methods
= {
1308 msrpc_rids_to_names
,
1311 msrpc_lookup_useraliases
,
1314 msrpc_lockout_policy
,
1315 msrpc_password_policy
,