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
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
43 BOOL got_dom_pol
= False
;
44 uint32 des_access
= SEC_RIGHTS_MAXIMUM_ALLOWED
;
45 unsigned int i
, start_idx
, retry
;
48 DEBUG(3,("rpc: query_user_list\n"));
57 if ( !NT_STATUS_IS_OK(result
= cm_get_sam_handle(domain
, &hnd
)) )
60 /* Get domain handle */
62 result
= cli_samr_open_domain(hnd
->cli
, mem_ctx
, &hnd
->pol
,
63 des_access
, &domain
->sid
, &dom_pol
);
65 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) && hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
67 if (!NT_STATUS_IS_OK(result
))
77 uint32 num_dom_users
, j
;
78 uint32 max_entries
, max_size
;
84 ctr
.sam
.info1
= &info1
;
86 if (!(ctx2
= talloc_init("winbindd enum_users"))) {
87 result
= NT_STATUS_NO_MEMORY
;
91 /* this next bit is copied from net_user_list_internal() */
93 get_query_dispinfo_params( loop_count
, &max_entries
, &max_size
);
95 result
= cli_samr_query_dispinfo(hnd
->cli
, mem_ctx
, &dom_pol
,
96 &start_idx
, 1, &num_dom_users
, max_entries
, max_size
, &ctr
);
100 *num_entries
+= num_dom_users
;
102 *info
= TALLOC_REALLOC_ARRAY( mem_ctx
, *info
, WINBIND_USERINFO
, *num_entries
);
105 result
= NT_STATUS_NO_MEMORY
;
106 talloc_destroy(ctx2
);
110 for (j
= 0; j
< num_dom_users
; i
++, j
++) {
111 fstring username
, fullname
;
112 uint32 rid
= ctr
.sam
.info1
->sam
[j
].rid_user
;
114 unistr2_to_ascii( username
, &(&ctr
.sam
.info1
->str
[j
])->uni_acct_name
, sizeof(username
)-1);
115 unistr2_to_ascii( fullname
, &(&ctr
.sam
.info1
->str
[j
])->uni_full_name
, sizeof(fullname
)-1);
117 (*info
)[i
].acct_name
= talloc_strdup(mem_ctx
, username
);
118 (*info
)[i
].full_name
= talloc_strdup(mem_ctx
, fullname
);
119 (*info
)[i
].user_sid
= rid_to_talloced_sid(domain
, mem_ctx
, rid
);
121 /* For the moment we set the primary group for
122 every user to be the Domain Users group.
123 There are serious problems with determining
124 the actual primary group for large domains.
125 This should really be made into a 'winbind
126 force group' smb.conf parameter or
127 something like that. */
129 (*info
)[i
].group_sid
= rid_to_talloced_sid(domain
,
130 mem_ctx
, DOMAIN_GROUP_RID_USERS
);
133 talloc_destroy(ctx2
);
135 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
140 cli_samr_close(hnd
->cli
, mem_ctx
, &dom_pol
);
145 /* list all domain groups */
146 static NTSTATUS
enum_dom_groups(struct winbindd_domain
*domain
,
149 struct acct_info
**info
)
151 uint32 des_access
= SEC_RIGHTS_MAXIMUM_ALLOWED
;
162 DEBUG(3,("rpc: enum_dom_groups\n"));
166 if (!NT_STATUS_IS_OK(result
= cm_get_sam_handle(domain
, &hnd
)))
169 status
= cli_samr_open_domain(hnd
->cli
, mem_ctx
,
170 &hnd
->pol
, des_access
, &domain
->sid
, &dom_pol
);
171 } while (!NT_STATUS_IS_OK(status
) && (retry
++ < 1) && hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
173 if (!NT_STATUS_IS_OK(status
))
177 struct acct_info
*info2
= NULL
;
179 TALLOC_CTX
*mem_ctx2
;
181 mem_ctx2
= talloc_init("enum_dom_groups[rpc]");
183 /* start is updated by this call. */
184 status
= cli_samr_enum_dom_groups(hnd
->cli
, mem_ctx2
, &dom_pol
,
186 0xFFFF, /* buffer size? */
189 if (!NT_STATUS_IS_OK(status
) &&
190 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
191 talloc_destroy(mem_ctx2
);
195 (*info
) = TALLOC_REALLOC_ARRAY(mem_ctx
, *info
, struct acct_info
, (*num_entries
) + count
);
197 talloc_destroy(mem_ctx2
);
198 cli_samr_close(hnd
->cli
, mem_ctx
, &dom_pol
);
199 return NT_STATUS_NO_MEMORY
;
202 memcpy(&(*info
)[*num_entries
], info2
, count
*sizeof(*info2
));
203 (*num_entries
) += count
;
204 talloc_destroy(mem_ctx2
);
205 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
207 cli_samr_close(hnd
->cli
, mem_ctx
, &dom_pol
);
212 /* List all domain groups */
214 static NTSTATUS
enum_local_groups(struct winbindd_domain
*domain
,
217 struct acct_info
**info
)
219 uint32 des_access
= SEC_RIGHTS_MAXIMUM_ALLOWED
;
230 if ( !NT_STATUS_IS_OK(result
= cm_get_sam_handle(domain
, &hnd
)) )
233 result
= cli_samr_open_domain( hnd
->cli
, mem_ctx
, &hnd
->pol
,
234 des_access
, &domain
->sid
, &dom_pol
);
235 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) && hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
237 if ( !NT_STATUS_IS_OK(result
))
241 struct acct_info
*info2
= NULL
;
242 uint32 count
= 0, start
= *num_entries
;
243 TALLOC_CTX
*mem_ctx2
;
245 mem_ctx2
= talloc_init("enum_dom_local_groups[rpc]");
247 result
= cli_samr_enum_als_groups( hnd
->cli
, mem_ctx2
, &dom_pol
,
248 &start
, 0xFFFF, &info2
, &count
);
250 if ( !NT_STATUS_IS_OK(result
)
251 && !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
) )
253 talloc_destroy(mem_ctx2
);
257 (*info
) = TALLOC_REALLOC_ARRAY(mem_ctx
, *info
, struct acct_info
, (*num_entries
) + count
);
259 talloc_destroy(mem_ctx2
);
260 cli_samr_close(hnd
->cli
, mem_ctx
, &dom_pol
);
261 return NT_STATUS_NO_MEMORY
;
264 memcpy(&(*info
)[*num_entries
], info2
, count
*sizeof(*info2
));
265 (*num_entries
) += count
;
266 talloc_destroy(mem_ctx2
);
267 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
269 cli_samr_close(hnd
->cli
, mem_ctx
, &dom_pol
);
274 /* convert a single name to a sid in a domain */
275 NTSTATUS
msrpc_name_to_sid(struct winbindd_domain
*domain
,
277 const char *domain_name
,
280 enum SID_NAME_USE
*type
)
284 DOM_SID
*sids
= NULL
;
285 uint32
*types
= NULL
;
286 const char *full_name
;
289 DEBUG(3,("rpc: name_to_sid name=%s\n", 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,("name_to_sid [rpc] %s for domain %s\n", name
, domain_name
));
302 if (!NT_STATUS_IS_OK(result
= cm_get_lsa_handle(domain
, &hnd
))) {
306 result
= cli_lsa_lookup_names(hnd
->cli
, mem_ctx
, &hnd
->pol
, 1,
307 &full_name
, &sids
, &types
);
308 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) &&
309 hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
311 /* Return rid and type if lookup successful */
313 if (NT_STATUS_IS_OK(result
)) {
314 sid_copy(sid
, &sids
[0]);
315 *type
= (enum SID_NAME_USE
)types
[0];
322 convert a domain SID to a user or group name
324 NTSTATUS
msrpc_sid_to_name(struct winbindd_domain
*domain
,
329 enum SID_NAME_USE
*type
)
338 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_static(sid
),
343 if (!NT_STATUS_IS_OK(result
= cm_get_lsa_handle(domain
, &hnd
)))
346 result
= cli_lsa_lookup_sids(hnd
->cli
, mem_ctx
, &hnd
->pol
,
347 1, sid
, &domains
, &names
, &types
);
348 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) &&
349 hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
351 if (NT_STATUS_IS_OK(result
)) {
352 *type
= (enum SID_NAME_USE
)types
[0];
353 *domain_name
= domains
[0];
355 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains
[0], *name
));
361 /* Lookup user information from a rid or username. */
362 static NTSTATUS
query_user(struct winbindd_domain
*domain
,
364 const DOM_SID
*user_sid
,
365 WINBIND_USERINFO
*user_info
)
367 CLI_POLICY_HND
*hnd
= NULL
;
368 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
369 POLICY_HND dom_pol
, user_pol
;
370 BOOL got_dom_pol
= False
, got_user_pol
= False
;
371 SAM_USERINFO_CTR
*ctr
;
375 NET_USER_INFO_3
*user
;
377 DEBUG(3,("rpc: query_user rid=%s\n", sid_to_string(sid_string
, user_sid
)));
378 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
)) {
382 /* try netsamlogon cache first */
384 if ( (user
= netsamlogon_cache_get( mem_ctx
, user_sid
)) != NULL
)
387 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
388 sid_string_static(user_sid
)));
390 user_info
->user_sid
= rid_to_talloced_sid( domain
, mem_ctx
, user_rid
);
391 user_info
->group_sid
= rid_to_talloced_sid( domain
, mem_ctx
, user
->group_rid
);
393 user_info
->acct_name
= unistr2_tdup(mem_ctx
, &user
->uni_user_name
);
394 user_info
->full_name
= unistr2_tdup(mem_ctx
, &user
->uni_full_name
);
401 /* no cache; hit the wire */
405 /* Get sam handle; if we fail here there is no hope */
407 if (!NT_STATUS_IS_OK(result
= cm_get_sam_handle(domain
, &hnd
)))
410 /* Get domain handle */
412 result
= cli_samr_open_domain(hnd
->cli
, mem_ctx
, &hnd
->pol
,
413 SEC_RIGHTS_MAXIMUM_ALLOWED
,
414 &domain
->sid
, &dom_pol
);
415 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) &&
416 hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
418 if (!NT_STATUS_IS_OK(result
))
423 /* Get user handle */
424 result
= cli_samr_open_user(hnd
->cli
, mem_ctx
, &dom_pol
,
425 SEC_RIGHTS_MAXIMUM_ALLOWED
, user_rid
, &user_pol
);
427 if (!NT_STATUS_IS_OK(result
))
433 result
= cli_samr_query_userinfo(hnd
->cli
, mem_ctx
, &user_pol
,
436 if (!NT_STATUS_IS_OK(result
))
439 cli_samr_close(hnd
->cli
, mem_ctx
, &user_pol
);
440 got_user_pol
= False
;
442 user_info
->user_sid
= rid_to_talloced_sid(domain
, mem_ctx
, user_rid
);
443 user_info
->group_sid
= rid_to_talloced_sid(domain
, mem_ctx
, ctr
->info
.id21
->group_rid
);
444 user_info
->acct_name
= unistr2_tdup(mem_ctx
,
445 &ctr
->info
.id21
->uni_user_name
);
446 user_info
->full_name
= unistr2_tdup(mem_ctx
,
447 &ctr
->info
.id21
->uni_full_name
);
450 /* Clean up policy handles */
452 cli_samr_close(hnd
->cli
, mem_ctx
, &user_pol
);
455 cli_samr_close(hnd
->cli
, mem_ctx
, &dom_pol
);
460 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
461 static NTSTATUS
lookup_usergroups(struct winbindd_domain
*domain
,
463 const DOM_SID
*user_sid
,
464 uint32
*num_groups
, DOM_SID
***user_grpsids
)
467 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
468 POLICY_HND dom_pol
, user_pol
;
469 uint32 des_access
= SEC_RIGHTS_MAXIMUM_ALLOWED
;
470 BOOL got_dom_pol
= False
, got_user_pol
= False
;
471 DOM_GID
*user_groups
;
476 NET_USER_INFO_3
*user
;
478 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_to_string(sid_string
, user_sid
)));
481 *user_grpsids
= NULL
;
483 /* so lets see if we have a cached user_info_3 */
485 if ( (user
= netsamlogon_cache_get( mem_ctx
, user_sid
)) != NULL
)
487 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
488 sid_string_static(user_sid
)));
490 *num_groups
= user
->num_groups
;
492 (*user_grpsids
) = TALLOC_ARRAY(mem_ctx
, DOM_SID
*, *num_groups
);
493 for (i
=0;i
<(*num_groups
);i
++) {
494 (*user_grpsids
)[i
] = rid_to_talloced_sid(domain
, mem_ctx
, user
->gids
[i
].g_rid
);
502 /* no cache; hit the wire */
506 /* Get sam handle; if we fail here there is no hope */
508 if (!NT_STATUS_IS_OK(result
= cm_get_sam_handle(domain
, &hnd
)))
511 /* Get domain handle */
513 result
= cli_samr_open_domain(hnd
->cli
, mem_ctx
, &hnd
->pol
,
514 des_access
, &domain
->sid
, &dom_pol
);
515 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) &&
516 hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
518 if (!NT_STATUS_IS_OK(result
))
524 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
)) {
528 /* Get user handle */
529 result
= cli_samr_open_user(hnd
->cli
, mem_ctx
, &dom_pol
,
530 des_access
, user_rid
, &user_pol
);
532 if (!NT_STATUS_IS_OK(result
))
537 /* Query user rids */
538 result
= cli_samr_query_usergroups(hnd
->cli
, mem_ctx
, &user_pol
,
539 num_groups
, &user_groups
);
541 if (!NT_STATUS_IS_OK(result
) || (*num_groups
) == 0)
544 (*user_grpsids
) = TALLOC_ARRAY(mem_ctx
, DOM_SID
*, *num_groups
);
545 if (!(*user_grpsids
)) {
546 result
= NT_STATUS_NO_MEMORY
;
550 for (i
=0;i
<(*num_groups
);i
++) {
551 (*user_grpsids
)[i
] = rid_to_talloced_sid(domain
, mem_ctx
, user_groups
[i
].g_rid
);
555 /* Clean up policy handles */
557 cli_samr_close(hnd
->cli
, mem_ctx
, &user_pol
);
560 cli_samr_close(hnd
->cli
, mem_ctx
, &dom_pol
);
565 NTSTATUS
msrpc_lookup_useraliases(struct winbindd_domain
*domain
,
567 uint32 num_sids
, DOM_SID
**sids
,
568 uint32
*num_aliases
, uint32
**alias_rids
)
570 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
572 BOOL got_dom_pol
= False
;
582 /* Get sam handle; if we fail here there is no hope */
584 if (!NT_STATUS_IS_OK(result
= cm_get_sam_handle(domain
,
588 /* Get domain handle */
590 result
= cli_samr_open_domain(hnd
->cli
, mem_ctx
, &hnd
->pol
,
591 SEC_RIGHTS_MAXIMUM_ALLOWED
,
592 &domain
->sid
, &dom_pol
);
593 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) &&
594 hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
596 if (!NT_STATUS_IS_OK(result
))
601 sid2
= TALLOC_ARRAY(mem_ctx
, DOM_SID2
, num_sids
);
604 result
= NT_STATUS_NO_MEMORY
;
608 for (i
=0; i
<num_sids
; i
++) {
609 sid_copy(&sid2
[i
].sid
, sids
[i
]);
610 sid2
[i
].num_auths
= sid2
[i
].sid
.num_auths
;
613 result
= cli_samr_query_useraliases(hnd
->cli
, mem_ctx
, &dom_pol
,
615 num_aliases
, alias_rids
);
620 cli_samr_close(hnd
->cli
, mem_ctx
, &dom_pol
);
626 /* Lookup group membership given a rid. */
627 static NTSTATUS
lookup_groupmem(struct winbindd_domain
*domain
,
629 const DOM_SID
*group_sid
, uint32
*num_names
,
630 DOM_SID
***sid_mem
, char ***names
,
633 CLI_POLICY_HND
*hnd
= NULL
;
634 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
635 uint32 i
, total_names
= 0;
636 POLICY_HND dom_pol
, group_pol
;
637 uint32 des_access
= SEC_RIGHTS_MAXIMUM_ALLOWED
;
638 BOOL got_dom_pol
= False
, got_group_pol
= False
;
639 uint32
*rid_mem
= NULL
;
645 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain
->name
, sid_to_string(sid_string
, group_sid
)));
647 if (!sid_peek_check_rid(&domain
->sid
, group_sid
, &group_rid
)) {
656 if (!NT_STATUS_IS_OK(result
= cm_get_sam_handle(domain
, &hnd
)))
659 /* Get domain handle */
661 result
= cli_samr_open_domain(hnd
->cli
, mem_ctx
, &hnd
->pol
,
662 des_access
, &domain
->sid
, &dom_pol
);
663 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) && hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
665 if (!NT_STATUS_IS_OK(result
))
670 /* Get group handle */
672 result
= cli_samr_open_group(hnd
->cli
, mem_ctx
, &dom_pol
,
673 des_access
, group_rid
, &group_pol
);
675 if (!NT_STATUS_IS_OK(result
))
678 got_group_pol
= True
;
680 /* Step #1: Get a list of user rids that are the members of the
683 result
= cli_samr_query_groupmem(hnd
->cli
, mem_ctx
,
684 &group_pol
, num_names
, &rid_mem
,
687 if (!NT_STATUS_IS_OK(result
))
697 /* Step #2: Convert list of rids into list of usernames. Do this
698 in bunches of ~1000 to avoid crashing NT4. It looks like there
699 is a buffer overflow or something like that lurking around
702 #define MAX_LOOKUP_RIDS 900
704 *names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, *num_names
);
705 *name_types
= TALLOC_ZERO_ARRAY(mem_ctx
, uint32
, *num_names
);
706 *sid_mem
= TALLOC_ZERO_ARRAY(mem_ctx
, DOM_SID
*, *num_names
);
708 for (j
=0;j
<(*num_names
);j
++) {
709 (*sid_mem
)[j
] = rid_to_talloced_sid(domain
, mem_ctx
, (rid_mem
)[j
]);
712 if (*num_names
>0 && (!*names
|| !*name_types
)) {
713 result
= NT_STATUS_NO_MEMORY
;
717 for (i
= 0; i
< *num_names
; i
+= MAX_LOOKUP_RIDS
) {
718 int num_lookup_rids
= MIN(*num_names
- i
, MAX_LOOKUP_RIDS
);
719 uint32 tmp_num_names
= 0;
720 char **tmp_names
= NULL
;
721 uint32
*tmp_types
= NULL
;
723 /* Lookup a chunk of rids */
725 result
= cli_samr_lookup_rids(hnd
->cli
, mem_ctx
,
730 &tmp_names
, &tmp_types
);
732 /* see if we have a real error (and yes the STATUS_SOME_UNMAPPED is
733 the one returned from 2k) */
735 if (!NT_STATUS_IS_OK(result
) && NT_STATUS_V(result
) != NT_STATUS_V(STATUS_SOME_UNMAPPED
))
738 /* Copy result into array. The talloc system will take
739 care of freeing the temporary arrays later on. */
741 memcpy(&(*names
)[i
], tmp_names
, sizeof(char *) *
744 memcpy(&(*name_types
)[i
], tmp_types
, sizeof(uint32
) *
747 total_names
+= tmp_num_names
;
750 *num_names
= total_names
;
752 result
= NT_STATUS_OK
;
756 cli_samr_close(hnd
->cli
, mem_ctx
, &group_pol
);
759 cli_samr_close(hnd
->cli
, mem_ctx
, &dom_pol
);
768 static int get_ldap_seq(const char *server
, int port
, uint32
*seq
)
772 const char *attrs
[] = {"highestCommittedUSN", NULL
};
773 LDAPMessage
*res
= NULL
;
774 char **values
= NULL
;
777 *seq
= DOM_SEQUENCE_NONE
;
780 * Parameterised (5) second timeout on open. This is needed as the search timeout
781 * doesn't seem to apply to doing an open as well. JRA.
784 if ((ldp
= ldap_open_with_timeout(server
, port
, lp_ldap_timeout())) == NULL
)
787 /* Timeout if no response within 20 seconds. */
791 if (ldap_search_st(ldp
, "", LDAP_SCOPE_BASE
, "(objectclass=*)",
792 CONST_DISCARD(char **, &attrs
[0]), 0, &to
, &res
))
795 if (ldap_count_entries(ldp
, res
) != 1)
798 values
= ldap_get_values(ldp
, res
, "highestCommittedUSN");
799 if (!values
|| !values
[0])
802 *seq
= atoi(values
[0]);
808 ldap_value_free(values
);
816 /**********************************************************************
817 Get the sequence number for a Windows AD native mode domain using
819 **********************************************************************/
821 static int get_ldap_sequence_number( const char* domain
, uint32
*seq
)
824 int i
, port
= LDAP_PORT
;
825 struct ip_service
*ip_list
= NULL
;
828 if ( !get_sorted_dc_list(domain
, &ip_list
, &count
, False
) ) {
829 DEBUG(3, ("Could not look up dc's for domain %s\n", domain
));
833 /* Finally return first DC that we can contact */
835 for (i
= 0; i
< count
; i
++) {
838 /* since the is an LDAP lookup, default to the LDAP_PORT is not set */
839 port
= (ip_list
[i
].port
!= PORT_NONE
) ? ip_list
[i
].port
: LDAP_PORT
;
841 fstrcpy( ipstr
, inet_ntoa(ip_list
[i
].ip
) );
843 if (is_zero_ip(ip_list
[i
].ip
))
846 if ( (ret
= get_ldap_seq( ipstr
, port
, seq
)) == 0 )
849 /* add to failed connection cache */
850 add_failed_connection_entry( domain
, ipstr
, NT_STATUS_UNSUCCESSFUL
);
855 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence number for Domain (%s) from DC (%s:%d)\n",
856 domain
, inet_ntoa(ip_list
[i
].ip
), port
));
864 #endif /* HAVE_LDAP */
866 /* find the sequence number for a domain */
867 static NTSTATUS
sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
874 BOOL got_dom_pol
= False
;
875 BOOL got_seq_num
= False
;
876 uint32 des_access
= SEC_RIGHTS_MAXIMUM_ALLOWED
;
879 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain
->name
));
881 *seq
= DOM_SEQUENCE_NONE
;
883 if (!(mem_ctx
= talloc_init("sequence_number[rpc]")))
884 return NT_STATUS_NO_MEMORY
;
889 if ( domain
->native_mode
)
891 DEBUG(8,("using get_ldap_seq() to retrieve the sequence number\n"));
893 if ( get_ldap_sequence_number( domain
->name
, seq
) == 0 ) {
894 result
= NT_STATUS_OK
;
895 DEBUG(10,("domain_sequence_number: LDAP for domain %s is %u\n",
896 domain
->name
, *seq
));
900 DEBUG(10,("domain_sequence_number: failed to get LDAP sequence number for domain %s\n",
903 #endif /* HAVE_LDAP */
905 if (!NT_STATUS_IS_OK(result
= cm_get_sam_handle(domain
, &hnd
)))
908 /* Get domain handle */
909 result
= cli_samr_open_domain(hnd
->cli
, mem_ctx
, &hnd
->pol
,
910 des_access
, &domain
->sid
, &dom_pol
);
911 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) && hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
913 if (!NT_STATUS_IS_OK(result
))
918 /* Query domain info */
920 result
= cli_samr_query_dom_info(hnd
->cli
, mem_ctx
, &dom_pol
,
923 if (NT_STATUS_IS_OK(result
)) {
924 *seq
= ctr
.info
.inf8
.seq_num
.low
;
929 /* retry with info-level 2 in case the dc does not support info-level 8
930 * (like all older samba2 and samba3 dc's - Guenther */
932 result
= cli_samr_query_dom_info(hnd
->cli
, mem_ctx
, &dom_pol
,
935 if (NT_STATUS_IS_OK(result
)) {
936 *seq
= ctr
.info
.inf2
.seq_num
.low
;
942 DEBUG(10,("domain_sequence_number: for domain %s is %u\n", domain
->name
, (unsigned)*seq
));
944 DEBUG(10,("domain_sequence_number: failed to get sequence number (%u) for domain %s\n",
945 (unsigned)*seq
, domain
->name
));
951 cli_samr_close(hnd
->cli
, mem_ctx
, &dom_pol
);
953 talloc_destroy(mem_ctx
);
958 /* get a list of trusted domains */
959 static NTSTATUS
trusted_domains(struct winbindd_domain
*domain
,
967 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
971 DEBUG(3,("rpc: trusted_domains\n"));
980 if (!NT_STATUS_IS_OK(result
= cm_get_lsa_handle(find_our_domain(), &hnd
)))
983 result
= STATUS_MORE_ENTRIES
;
985 while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
986 uint32 start_idx
, num
;
991 result
= cli_lsa_enum_trust_dom(hnd
->cli
, mem_ctx
,
992 &hnd
->pol
, &enum_ctx
,
996 if (!NT_STATUS_IS_OK(result
) &&
997 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
))
1000 start_idx
= *num_domains
;
1001 *num_domains
+= num
;
1002 *names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *names
,
1003 char *, *num_domains
);
1004 *dom_sids
= TALLOC_REALLOC_ARRAY(mem_ctx
, *dom_sids
,
1007 if ((*names
== NULL
) || (*dom_sids
== NULL
))
1008 return NT_STATUS_NO_MEMORY
;
1010 for (i
=0; i
<num
; i
++) {
1011 (*names
)[start_idx
+i
] = tmp_names
[i
];
1012 (*dom_sids
)[start_idx
+i
] = tmp_sids
[i
];
1015 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) && hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
1021 /* find the domain sid for a domain */
1022 static NTSTATUS
domain_sid(struct winbindd_domain
*domain
, DOM_SID
*sid
)
1024 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1025 TALLOC_CTX
*mem_ctx
;
1026 CLI_POLICY_HND
*hnd
;
1031 DEBUG(3,("rpc: domain_sid\n"));
1033 if (!(mem_ctx
= talloc_init("domain_sid[rpc]")))
1034 return NT_STATUS_NO_MEMORY
;
1038 /* Get lsa handle */
1039 if (!NT_STATUS_IS_OK(result
= cm_get_lsa_handle(domain
, &hnd
)))
1042 result
= cli_lsa_query_info_policy(hnd
->cli
, mem_ctx
,
1043 &hnd
->pol
, 0x05, &level5_dom
, &alloc_sid
);
1044 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) && hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
1046 if (NT_STATUS_IS_OK(result
)) {
1048 sid_copy(sid
, alloc_sid
);
1050 result
= NT_STATUS_NO_MEMORY
;
1055 talloc_destroy(mem_ctx
);
1059 /* find alternate names list for the domain - none for rpc */
1060 static NTSTATUS
alternate_name(struct winbindd_domain
*domain
)
1062 return NT_STATUS_OK
;
1066 /* the rpc backend methods are exposed via this structure */
1067 struct winbindd_methods msrpc_methods
= {
1076 msrpc_lookup_useraliases
,