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
)
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
)
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
)
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 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 POLICY_HND lsa_policy
;
283 if (name
== NULL
|| *name
=='\0') {
284 full_name
= talloc_asprintf(mem_ctx
, "%s", domain_name
);
285 } else if (domain_name
== NULL
|| *domain_name
== '\0') {
286 full_name
= talloc_asprintf(mem_ctx
, "%s", name
);
288 full_name
= talloc_asprintf(mem_ctx
, "%s\\%s", domain_name
, name
);
291 DEBUG(0, ("talloc_asprintf failed!\n"));
292 return NT_STATUS_NO_MEMORY
;
295 DEBUG(3,("rpc: name_to_sid name=%s\n", full_name
));
297 ws_name_return( full_name
, WB_REPLACE_CHAR
);
299 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", full_name
?full_name
:"", domain_name
));
301 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
302 if (!NT_STATUS_IS_OK(result
))
305 result
= rpccli_lsa_lookup_names(cli
, mem_ctx
, &lsa_policy
, 1,
306 (const char**) &full_name
, NULL
, 1, &sids
, &types
);
308 if (!NT_STATUS_IS_OK(result
))
311 /* Return rid and type if lookup successful */
313 sid_copy(sid
, &sids
[0]);
320 convert a domain SID to a user or group name
322 NTSTATUS
msrpc_sid_to_name(struct winbindd_domain
*domain
,
327 enum lsa_SidType
*type
)
331 enum lsa_SidType
*types
= NULL
;
333 struct rpc_pipe_client
*cli
;
334 POLICY_HND lsa_policy
;
336 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid
),
339 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
340 if (!NT_STATUS_IS_OK(result
)) {
341 DEBUG(2,("msrpc_sid_to_name: cm_connect_lsa() failed (%s)\n",
347 result
= rpccli_lsa_lookup_sids(cli
, mem_ctx
, &lsa_policy
,
348 1, sid
, &domains
, &names
, &types
);
349 if (!NT_STATUS_IS_OK(result
)) {
350 DEBUG(2,("msrpc_sid_to_name: rpccli_lsa_lookup_sids() failed (%s)\n",
355 *type
= (enum lsa_SidType
)types
[0];
356 *domain_name
= domains
[0];
359 ws_name_replace( *name
, WB_REPLACE_CHAR
);
361 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains
[0], *name
));
365 NTSTATUS
msrpc_rids_to_names(struct winbindd_domain
*domain
,
372 enum lsa_SidType
**types
)
376 struct rpc_pipe_client
*cli
;
377 POLICY_HND lsa_policy
;
382 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain
->name
));
385 sids
= TALLOC_ARRAY(mem_ctx
, DOM_SID
, num_rids
);
387 return NT_STATUS_NO_MEMORY
;
393 for (i
=0; i
<num_rids
; i
++) {
394 if (!sid_compose(&sids
[i
], sid
, rids
[i
])) {
395 return NT_STATUS_INTERNAL_ERROR
;
399 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
400 if (!NT_STATUS_IS_OK(result
)) {
404 result
= rpccli_lsa_lookup_sids(cli
, mem_ctx
, &lsa_policy
,
405 num_rids
, sids
, &domains
,
407 if (!NT_STATUS_IS_OK(result
) &&
408 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
413 for (i
=0; i
<num_rids
; i
++) {
414 if ((*types
)[i
] != SID_NAME_UNKNOWN
) {
415 ws_name_replace( ret_names
[i
], WB_REPLACE_CHAR
);
416 *domain_name
= domains
[i
];
423 /* Lookup user information from a rid or username. */
424 static NTSTATUS
query_user(struct winbindd_domain
*domain
,
426 const DOM_SID
*user_sid
,
427 WINBIND_USERINFO
*user_info
)
429 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
430 POLICY_HND dom_pol
, user_pol
;
431 union samr_UserInfo
*info
= NULL
;
433 struct netr_SamInfo3
*user
;
434 struct rpc_pipe_client
*cli
;
436 DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid
)));
438 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
439 return NT_STATUS_UNSUCCESSFUL
;
441 user_info
->homedir
= NULL
;
442 user_info
->shell
= NULL
;
443 user_info
->primary_gid
= (gid_t
)-1;
445 /* try netsamlogon cache first */
447 if ( (user
= netsamlogon_cache_get( mem_ctx
, user_sid
)) != NULL
)
450 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
451 sid_string_dbg(user_sid
)));
453 sid_compose(&user_info
->user_sid
, &domain
->sid
, user
->base
.rid
);
454 sid_compose(&user_info
->group_sid
, &domain
->sid
,
455 user
->base
.primary_gid
);
457 user_info
->acct_name
= talloc_strdup(mem_ctx
,
458 user
->base
.account_name
.string
);
459 user_info
->full_name
= talloc_strdup(mem_ctx
,
460 user
->base
.full_name
.string
);
467 if ( !winbindd_can_contact_domain( domain
) ) {
468 DEBUG(10,("query_user: No incoming trust for domain %s\n",
473 if ( !winbindd_can_contact_domain( domain
) ) {
474 DEBUG(10,("query_user: No incoming trust for domain %s\n",
479 if ( !winbindd_can_contact_domain( domain
) ) {
480 DEBUG(10,("query_user: No incoming trust for domain %s\n",
485 /* no cache; hit the wire */
487 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
488 if (!NT_STATUS_IS_OK(result
))
491 /* Get user handle */
492 result
= rpccli_samr_OpenUser(cli
, mem_ctx
,
494 SEC_RIGHTS_MAXIMUM_ALLOWED
,
498 if (!NT_STATUS_IS_OK(result
))
502 result
= rpccli_samr_QueryUserInfo(cli
, mem_ctx
,
507 rpccli_samr_Close(cli
, mem_ctx
, &user_pol
);
509 if (!NT_STATUS_IS_OK(result
))
512 sid_compose(&user_info
->user_sid
, &domain
->sid
, user_rid
);
513 sid_compose(&user_info
->group_sid
, &domain
->sid
,
514 info
->info21
.primary_gid
);
515 user_info
->acct_name
= talloc_strdup(mem_ctx
,
516 info
->info21
.account_name
.string
);
517 user_info
->full_name
= talloc_strdup(mem_ctx
,
518 info
->info21
.full_name
.string
);
519 user_info
->homedir
= NULL
;
520 user_info
->shell
= NULL
;
521 user_info
->primary_gid
= (gid_t
)-1;
526 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
527 static NTSTATUS
lookup_usergroups(struct winbindd_domain
*domain
,
529 const DOM_SID
*user_sid
,
530 uint32
*num_groups
, DOM_SID
**user_grpsids
)
532 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
533 POLICY_HND dom_pol
, user_pol
;
534 uint32 des_access
= SEC_RIGHTS_MAXIMUM_ALLOWED
;
535 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
538 struct rpc_pipe_client
*cli
;
540 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid
)));
542 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
543 return NT_STATUS_UNSUCCESSFUL
;
546 *user_grpsids
= NULL
;
548 /* so lets see if we have a cached user_info_3 */
549 result
= lookup_usergroups_cached(domain
, mem_ctx
, user_sid
,
550 num_groups
, user_grpsids
);
552 if (NT_STATUS_IS_OK(result
)) {
556 if ( !winbindd_can_contact_domain( domain
) ) {
557 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
560 /* Tell the cache manager not to remember this one */
562 return NT_STATUS_SYNCHRONIZATION_REQUIRED
;
565 /* no cache; hit the wire */
567 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
568 if (!NT_STATUS_IS_OK(result
))
571 /* Get user handle */
572 result
= rpccli_samr_OpenUser(cli
, mem_ctx
,
578 if (!NT_STATUS_IS_OK(result
))
581 /* Query user rids */
582 result
= rpccli_samr_GetGroupsForUser(cli
, mem_ctx
,
585 *num_groups
= rid_array
->count
;
587 rpccli_samr_Close(cli
, mem_ctx
, &user_pol
);
589 if (!NT_STATUS_IS_OK(result
) || (*num_groups
) == 0)
592 (*user_grpsids
) = TALLOC_ARRAY(mem_ctx
, DOM_SID
, *num_groups
);
593 if (!(*user_grpsids
))
594 return NT_STATUS_NO_MEMORY
;
596 for (i
=0;i
<(*num_groups
);i
++) {
597 sid_copy(&((*user_grpsids
)[i
]), &domain
->sid
);
598 sid_append_rid(&((*user_grpsids
)[i
]),
599 rid_array
->rids
[i
].rid
);
605 NTSTATUS
msrpc_lookup_useraliases(struct winbindd_domain
*domain
,
607 uint32 num_sids
, const DOM_SID
*sids
,
608 uint32
*num_aliases
, uint32
**alias_rids
)
610 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
612 uint32 num_query_sids
= 0;
614 struct rpc_pipe_client
*cli
;
615 struct samr_Ids alias_rids_query
;
616 int rangesize
= MAX_SAM_ENTRIES_W2K
;
617 uint32 total_sids
= 0;
623 DEBUG(3,("rpc: lookup_useraliases\n"));
625 if ( !winbindd_can_contact_domain( domain
) ) {
626 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
631 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
632 if (!NT_STATUS_IS_OK(result
))
637 struct lsa_SidArray sid_array
;
639 ZERO_STRUCT(sid_array
);
641 num_query_sids
= MIN(num_sids
- total_sids
, rangesize
);
643 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
644 num_queries
, num_query_sids
));
646 if (num_query_sids
) {
647 sid_array
.sids
= TALLOC_ZERO_ARRAY(mem_ctx
, struct lsa_SidPtr
, num_query_sids
);
648 if (sid_array
.sids
== NULL
) {
649 return NT_STATUS_NO_MEMORY
;
652 sid_array
.sids
= NULL
;
655 for (i
=0; i
<num_query_sids
; i
++) {
656 sid_array
.sids
[i
].sid
= sid_dup_talloc(mem_ctx
, &sids
[total_sids
++]);
657 if (!sid_array
.sids
[i
].sid
) {
658 TALLOC_FREE(sid_array
.sids
);
659 return NT_STATUS_NO_MEMORY
;
662 sid_array
.num_sids
= num_query_sids
;
665 result
= rpccli_samr_GetAliasMembership(cli
, mem_ctx
,
670 if (!NT_STATUS_IS_OK(result
)) {
673 TALLOC_FREE(sid_array
.sids
);
679 for (i
=0; i
<alias_rids_query
.count
; i
++) {
680 size_t na
= *num_aliases
;
681 if (!add_rid_to_array_unique(mem_ctx
, alias_rids_query
.ids
[i
],
683 return NT_STATUS_NO_MEMORY
;
688 TALLOC_FREE(sid_array
.sids
);
692 } while (total_sids
< num_sids
);
695 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
696 "(rangesize: %d)\n", *num_aliases
, num_queries
, rangesize
));
702 /* Lookup group membership given a rid. */
703 static NTSTATUS
lookup_groupmem(struct winbindd_domain
*domain
,
705 const DOM_SID
*group_sid
, uint32
*num_names
,
706 DOM_SID
**sid_mem
, char ***names
,
709 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
710 uint32 i
, total_names
= 0;
711 POLICY_HND dom_pol
, group_pol
;
712 uint32 des_access
= SEC_RIGHTS_MAXIMUM_ALLOWED
;
713 uint32
*rid_mem
= NULL
;
716 struct rpc_pipe_client
*cli
;
717 unsigned int orig_timeout
;
718 struct samr_RidTypeArray
*rids
= NULL
;
720 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain
->name
,
721 sid_string_dbg(group_sid
)));
723 if ( !winbindd_can_contact_domain( domain
) ) {
724 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
729 if (!sid_peek_check_rid(&domain
->sid
, group_sid
, &group_rid
))
730 return NT_STATUS_UNSUCCESSFUL
;
734 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
735 if (!NT_STATUS_IS_OK(result
))
738 result
= rpccli_samr_OpenGroup(cli
, mem_ctx
,
744 if (!NT_STATUS_IS_OK(result
))
747 /* Step #1: Get a list of user rids that are the members of the
750 /* This call can take a long time - allow the server to time out.
751 35 seconds should do it. */
753 orig_timeout
= cli_set_timeout(cli
->cli
, 35000);
755 result
= rpccli_samr_QueryGroupMember(cli
, mem_ctx
,
759 /* And restore our original timeout. */
760 cli_set_timeout(cli
->cli
, orig_timeout
);
762 rpccli_samr_Close(cli
, mem_ctx
, &group_pol
);
764 if (!NT_STATUS_IS_OK(result
))
767 *num_names
= rids
->count
;
768 rid_mem
= rids
->rids
;
777 /* Step #2: Convert list of rids into list of usernames. Do this
778 in bunches of ~1000 to avoid crashing NT4. It looks like there
779 is a buffer overflow or something like that lurking around
782 #define MAX_LOOKUP_RIDS 900
784 *names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, *num_names
);
785 *name_types
= TALLOC_ZERO_ARRAY(mem_ctx
, uint32
, *num_names
);
786 *sid_mem
= TALLOC_ZERO_ARRAY(mem_ctx
, DOM_SID
, *num_names
);
788 for (j
=0;j
<(*num_names
);j
++)
789 sid_compose(&(*sid_mem
)[j
], &domain
->sid
, rid_mem
[j
]);
791 if (*num_names
>0 && (!*names
|| !*name_types
))
792 return NT_STATUS_NO_MEMORY
;
794 for (i
= 0; i
< *num_names
; i
+= MAX_LOOKUP_RIDS
) {
795 int num_lookup_rids
= MIN(*num_names
- i
, MAX_LOOKUP_RIDS
);
796 struct lsa_Strings tmp_names
;
797 struct samr_Ids tmp_types
;
799 /* Lookup a chunk of rids */
801 result
= rpccli_samr_LookupRids(cli
, mem_ctx
,
808 /* see if we have a real error (and yes the
809 STATUS_SOME_UNMAPPED is the one returned from 2k) */
811 if (!NT_STATUS_IS_OK(result
) &&
812 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
))
815 /* Copy result into array. The talloc system will take
816 care of freeing the temporary arrays later on. */
818 if (tmp_names
.count
!= tmp_types
.count
) {
819 return NT_STATUS_UNSUCCESSFUL
;
822 for (r
=0; r
<tmp_names
.count
; r
++) {
823 (*names
)[i
+r
] = CONST_DISCARD(char *, tmp_names
.names
[r
].string
);
824 (*name_types
)[i
+r
] = tmp_types
.ids
[r
];
827 total_names
+= tmp_names
.count
;
830 *num_names
= total_names
;
839 static int get_ldap_seq(const char *server
, int port
, uint32
*seq
)
843 const char *attrs
[] = {"highestCommittedUSN", NULL
};
844 LDAPMessage
*res
= NULL
;
845 char **values
= NULL
;
848 *seq
= DOM_SEQUENCE_NONE
;
851 * Parameterised (5) second timeout on open. This is needed as the
852 * search timeout doesn't seem to apply to doing an open as well. JRA.
855 ldp
= ldap_open_with_timeout(server
, port
, lp_ldap_timeout());
859 /* Timeout if no response within 20 seconds. */
863 if (ldap_search_st(ldp
, "", LDAP_SCOPE_BASE
, "(objectclass=*)",
864 CONST_DISCARD(char **, attrs
), 0, &to
, &res
))
867 if (ldap_count_entries(ldp
, res
) != 1)
870 values
= ldap_get_values(ldp
, res
, "highestCommittedUSN");
871 if (!values
|| !values
[0])
874 *seq
= atoi(values
[0]);
880 ldap_value_free(values
);
888 /**********************************************************************
889 Get the sequence number for a Windows AD native mode domain using
891 **********************************************************************/
893 static int get_ldap_sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
896 char addr
[INET6_ADDRSTRLEN
];
898 print_sockaddr(addr
, sizeof(addr
), &domain
->dcaddr
);
899 if ((ret
= get_ldap_seq(addr
, LDAP_PORT
, seq
)) == 0) {
900 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
901 "number for Domain (%s) from DC (%s)\n",
902 domain
->name
, addr
));
907 #endif /* HAVE_LDAP */
909 /* find the sequence number for a domain */
910 static NTSTATUS
sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
913 union samr_DomainInfo
*info
= NULL
;
916 bool got_seq_num
= False
;
917 struct rpc_pipe_client
*cli
;
919 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain
->name
));
921 if ( !winbindd_can_contact_domain( domain
) ) {
922 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
928 *seq
= DOM_SEQUENCE_NONE
;
930 if (!(mem_ctx
= talloc_init("sequence_number[rpc]")))
931 return NT_STATUS_NO_MEMORY
;
934 if ( domain
->active_directory
)
938 DEBUG(8,("using get_ldap_seq() to retrieve the "
939 "sequence number\n"));
941 res
= get_ldap_sequence_number( domain
, seq
);
944 result
= NT_STATUS_OK
;
945 DEBUG(10,("domain_sequence_number: LDAP for "
947 domain
->name
, *seq
));
951 DEBUG(10,("domain_sequence_number: failed to get LDAP "
952 "sequence number for domain %s\n",
955 #endif /* HAVE_LDAP */
957 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
958 if (!NT_STATUS_IS_OK(result
)) {
962 /* Query domain info */
964 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
969 if (NT_STATUS_IS_OK(result
)) {
970 *seq
= info
->info8
.sequence_num
;
975 /* retry with info-level 2 in case the dc does not support info-level 8
976 * (like all older samba2 and samba3 dc's) - Guenther */
978 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
983 if (NT_STATUS_IS_OK(result
)) {
984 *seq
= info
->info2
.sequence_num
;
990 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
991 domain
->name
, (unsigned)*seq
));
993 DEBUG(10,("domain_sequence_number: failed to get sequence "
994 "number (%u) for domain %s\n",
995 (unsigned)*seq
, domain
->name
));
1000 talloc_destroy(mem_ctx
);
1005 /* get a list of trusted domains */
1006 static NTSTATUS
trusted_domains(struct winbindd_domain
*domain
,
1007 TALLOC_CTX
*mem_ctx
,
1008 uint32
*num_domains
,
1013 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1014 uint32 enum_ctx
= 0;
1015 struct rpc_pipe_client
*cli
;
1016 POLICY_HND lsa_policy
;
1018 DEBUG(3,("rpc: trusted_domains\n"));
1025 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
1026 if (!NT_STATUS_IS_OK(result
))
1029 result
= STATUS_MORE_ENTRIES
;
1031 while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
1034 struct lsa_DomainList dom_list
;
1036 result
= rpccli_lsa_EnumTrustDom(cli
, mem_ctx
,
1042 if (!NT_STATUS_IS_OK(result
) &&
1043 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
))
1046 start_idx
= *num_domains
;
1047 *num_domains
+= dom_list
.count
;
1048 *names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *names
,
1049 char *, *num_domains
);
1050 *dom_sids
= TALLOC_REALLOC_ARRAY(mem_ctx
, *dom_sids
,
1051 DOM_SID
, *num_domains
);
1052 *alt_names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *alt_names
,
1053 char *, *num_domains
);
1054 if ((*names
== NULL
) || (*dom_sids
== NULL
) ||
1055 (*alt_names
== NULL
))
1056 return NT_STATUS_NO_MEMORY
;
1058 for (i
=0; i
<dom_list
.count
; i
++) {
1059 (*names
)[start_idx
+i
] = CONST_DISCARD(char *, dom_list
.domains
[i
].name
.string
);
1060 (*dom_sids
)[start_idx
+i
] = *dom_list
.domains
[i
].sid
;
1061 (*alt_names
)[start_idx
+i
] = talloc_strdup(mem_ctx
, "");
1067 /* find the lockout policy for a domain */
1068 NTSTATUS
msrpc_lockout_policy(struct winbindd_domain
*domain
,
1069 TALLOC_CTX
*mem_ctx
,
1070 struct samr_DomInfo12
*lockout_policy
)
1073 struct rpc_pipe_client
*cli
;
1075 union samr_DomainInfo
*info
= NULL
;
1077 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain
->name
));
1079 if ( !winbindd_can_contact_domain( domain
) ) {
1080 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1082 return NT_STATUS_NOT_SUPPORTED
;
1085 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1086 if (!NT_STATUS_IS_OK(result
)) {
1090 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1094 if (!NT_STATUS_IS_OK(result
)) {
1098 *lockout_policy
= info
->info12
;
1100 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1101 info
->info12
.lockout_threshold
));
1108 /* find the password policy for a domain */
1109 NTSTATUS
msrpc_password_policy(struct winbindd_domain
*domain
,
1110 TALLOC_CTX
*mem_ctx
,
1111 struct samr_DomInfo1
*password_policy
)
1114 struct rpc_pipe_client
*cli
;
1116 union samr_DomainInfo
*info
= NULL
;
1118 DEBUG(10,("rpc: fetch password policy for %s\n", domain
->name
));
1120 if ( !winbindd_can_contact_domain( domain
) ) {
1121 DEBUG(10,("msrpc_password_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 *password_policy
= info
->info1
;
1141 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1142 info
->info1
.min_password_length
));
1150 /* the rpc backend methods are exposed via this structure */
1151 struct winbindd_methods msrpc_methods
= {
1158 msrpc_rids_to_names
,
1161 msrpc_lookup_useraliases
,
1164 msrpc_lockout_policy
,
1165 msrpc_password_policy
,