2 Unix SMB/CIFS implementation.
4 Winbind rpc backend functions
6 Copyright (C) Tim Potter 2000-2001,2003
7 Copyright (C) Andrew Tridgell 2001
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #define DBGC_CLASS DBGC_WINBIND
31 /* Query display info for a domain. This returns enough information plus a
32 bit extra to give an overview of domain users for the User Manager
34 static NTSTATUS
query_user_list(struct winbindd_domain
*domain
,
37 WINBIND_USERINFO
**info
)
40 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
42 BOOL got_dom_pol
= False
;
43 uint32 des_access
= SEC_RIGHTS_MAXIMUM_ALLOWED
;
44 unsigned int i
, start_idx
, retry
;
47 DEBUG(3,("rpc: query_user_list\n"));
56 if ( !NT_STATUS_IS_OK(result
= cm_get_sam_handle(domain
, &hnd
)) )
59 /* Get domain handle */
61 result
= cli_samr_open_domain(hnd
->cli
, mem_ctx
, &hnd
->pol
,
62 des_access
, &domain
->sid
, &dom_pol
);
64 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) && hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
66 if (!NT_STATUS_IS_OK(result
))
76 uint32 num_dom_users
, j
;
77 uint32 max_entries
, max_size
;
83 ctr
.sam
.info1
= &info1
;
85 if (!(ctx2
= talloc_init("winbindd enum_users"))) {
86 result
= NT_STATUS_NO_MEMORY
;
90 /* this next bit is copied from net_user_list_internal() */
92 get_query_dispinfo_params( loop_count
, &max_entries
, &max_size
);
94 result
= cli_samr_query_dispinfo(hnd
->cli
, mem_ctx
, &dom_pol
,
95 &start_idx
, 1, &num_dom_users
, max_entries
, max_size
, &ctr
);
99 *num_entries
+= num_dom_users
;
101 *info
= talloc_realloc( mem_ctx
, *info
,
102 (*num_entries
) * sizeof(WINBIND_USERINFO
));
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(mem_ctx
, *info
,
196 sizeof(**info
) * ((*num_entries
) + count
));
198 talloc_destroy(mem_ctx2
);
199 cli_samr_close(hnd
->cli
, mem_ctx
, &dom_pol
);
200 return NT_STATUS_NO_MEMORY
;
203 memcpy(&(*info
)[*num_entries
], info2
, count
*sizeof(*info2
));
204 (*num_entries
) += count
;
205 talloc_destroy(mem_ctx2
);
206 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
208 cli_samr_close(hnd
->cli
, mem_ctx
, &dom_pol
);
213 /* List all domain groups */
215 static NTSTATUS
enum_local_groups(struct winbindd_domain
*domain
,
218 struct acct_info
**info
)
220 uint32 des_access
= SEC_RIGHTS_MAXIMUM_ALLOWED
;
231 if ( !NT_STATUS_IS_OK(result
= cm_get_sam_handle(domain
, &hnd
)) )
234 result
= cli_samr_open_domain( hnd
->cli
, mem_ctx
, &hnd
->pol
,
235 des_access
, &domain
->sid
, &dom_pol
);
236 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) && hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
238 if ( !NT_STATUS_IS_OK(result
))
242 struct acct_info
*info2
= NULL
;
243 uint32 count
= 0, start
= *num_entries
;
244 TALLOC_CTX
*mem_ctx2
;
246 mem_ctx2
= talloc_init("enum_dom_local_groups[rpc]");
248 result
= cli_samr_enum_als_groups( hnd
->cli
, mem_ctx2
, &dom_pol
,
249 &start
, 0xFFFF, &info2
, &count
);
251 if ( !NT_STATUS_IS_OK(result
)
252 && !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
) )
254 talloc_destroy(mem_ctx2
);
258 (*info
) = talloc_realloc(mem_ctx
, *info
,
259 sizeof(**info
) * ((*num_entries
) + count
));
261 talloc_destroy(mem_ctx2
);
262 cli_samr_close(hnd
->cli
, mem_ctx
, &dom_pol
);
263 return NT_STATUS_NO_MEMORY
;
266 memcpy(&(*info
)[*num_entries
], info2
, count
*sizeof(*info2
));
267 (*num_entries
) += count
;
268 talloc_destroy(mem_ctx2
);
269 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
271 cli_samr_close(hnd
->cli
, mem_ctx
, &dom_pol
);
276 /* convert a single name to a sid in a domain */
277 NTSTATUS
msrpc_name_to_sid(struct winbindd_domain
*domain
,
279 const char *domain_name
,
282 enum SID_NAME_USE
*type
)
286 DOM_SID
*sids
= NULL
;
287 uint32
*types
= NULL
;
288 const char *full_name
;
291 DEBUG(3,("rpc: name_to_sid name=%s\n", name
));
293 full_name
= talloc_asprintf(mem_ctx
, "%s\\%s", domain_name
, name
);
296 DEBUG(0, ("talloc_asprintf failed!\n"));
297 return NT_STATUS_NO_MEMORY
;
300 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", name
, domain_name
));
304 if (!NT_STATUS_IS_OK(result
= cm_get_lsa_handle(domain
, &hnd
))) {
308 result
= cli_lsa_lookup_names(hnd
->cli
, mem_ctx
, &hnd
->pol
, 1,
309 &full_name
, &sids
, &types
);
310 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) &&
311 hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
313 /* Return rid and type if lookup successful */
315 if (NT_STATUS_IS_OK(result
)) {
316 sid_copy(sid
, &sids
[0]);
317 *type
= (enum SID_NAME_USE
)types
[0];
324 convert a domain SID to a user or group name
326 NTSTATUS
msrpc_sid_to_name(struct winbindd_domain
*domain
,
331 enum SID_NAME_USE
*type
)
340 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_static(sid
),
345 if (!NT_STATUS_IS_OK(result
= cm_get_lsa_handle(domain
, &hnd
)))
348 result
= cli_lsa_lookup_sids(hnd
->cli
, mem_ctx
, &hnd
->pol
,
349 1, sid
, &domains
, &names
, &types
);
350 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) &&
351 hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
353 if (NT_STATUS_IS_OK(result
)) {
354 *type
= (enum SID_NAME_USE
)types
[0];
355 *domain_name
= domains
[0];
357 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains
[0], *name
));
363 /* Lookup user information from a rid or username. */
364 static NTSTATUS
query_user(struct winbindd_domain
*domain
,
366 const DOM_SID
*user_sid
,
367 WINBIND_USERINFO
*user_info
)
369 CLI_POLICY_HND
*hnd
= NULL
;
370 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
371 POLICY_HND dom_pol
, user_pol
;
372 BOOL got_dom_pol
= False
, got_user_pol
= False
;
373 SAM_USERINFO_CTR
*ctr
;
377 NET_USER_INFO_3
*user
;
379 DEBUG(3,("rpc: query_user rid=%s\n", sid_to_string(sid_string
, user_sid
)));
380 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
)) {
384 /* try netsamlogon cache first */
386 if ( (user
= netsamlogon_cache_get( mem_ctx
, user_sid
)) != NULL
)
389 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
390 sid_string_static(user_sid
)));
392 user_info
->user_sid
= rid_to_talloced_sid( domain
, mem_ctx
, user_rid
);
393 user_info
->group_sid
= rid_to_talloced_sid( domain
, mem_ctx
, user
->group_rid
);
395 user_info
->acct_name
= unistr2_tdup(mem_ctx
, &user
->uni_user_name
);
396 user_info
->full_name
= unistr2_tdup(mem_ctx
, &user
->uni_full_name
);
403 /* no cache; hit the wire */
407 /* Get sam handle; if we fail here there is no hope */
409 if (!NT_STATUS_IS_OK(result
= cm_get_sam_handle(domain
, &hnd
)))
412 /* Get domain handle */
414 result
= cli_samr_open_domain(hnd
->cli
, mem_ctx
, &hnd
->pol
,
415 SEC_RIGHTS_MAXIMUM_ALLOWED
,
416 &domain
->sid
, &dom_pol
);
417 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) &&
418 hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
420 if (!NT_STATUS_IS_OK(result
))
425 /* Get user handle */
426 result
= cli_samr_open_user(hnd
->cli
, mem_ctx
, &dom_pol
,
427 SEC_RIGHTS_MAXIMUM_ALLOWED
, user_rid
, &user_pol
);
429 if (!NT_STATUS_IS_OK(result
))
435 result
= cli_samr_query_userinfo(hnd
->cli
, mem_ctx
, &user_pol
,
438 if (!NT_STATUS_IS_OK(result
))
441 cli_samr_close(hnd
->cli
, mem_ctx
, &user_pol
);
442 got_user_pol
= False
;
444 user_info
->user_sid
= rid_to_talloced_sid(domain
, mem_ctx
, user_rid
);
445 user_info
->group_sid
= rid_to_talloced_sid(domain
, mem_ctx
, ctr
->info
.id21
->group_rid
);
446 user_info
->acct_name
= unistr2_tdup(mem_ctx
,
447 &ctr
->info
.id21
->uni_user_name
);
448 user_info
->full_name
= unistr2_tdup(mem_ctx
,
449 &ctr
->info
.id21
->uni_full_name
);
452 /* Clean up policy handles */
454 cli_samr_close(hnd
->cli
, mem_ctx
, &user_pol
);
457 cli_samr_close(hnd
->cli
, mem_ctx
, &dom_pol
);
462 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
463 static NTSTATUS
lookup_usergroups(struct winbindd_domain
*domain
,
465 const DOM_SID
*user_sid
,
466 uint32
*num_groups
, DOM_SID
***user_grpsids
)
469 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
470 POLICY_HND dom_pol
, user_pol
;
471 uint32 des_access
= SEC_RIGHTS_MAXIMUM_ALLOWED
;
472 BOOL got_dom_pol
= False
, got_user_pol
= False
;
473 DOM_GID
*user_groups
;
478 NET_USER_INFO_3
*user
;
480 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_to_string(sid_string
, user_sid
)));
483 *user_grpsids
= NULL
;
485 /* so lets see if we have a cached user_info_3 */
487 if ( (user
= netsamlogon_cache_get( mem_ctx
, user_sid
)) != NULL
)
489 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
490 sid_string_static(user_sid
)));
492 *num_groups
= user
->num_groups
;
494 (*user_grpsids
) = talloc(mem_ctx
, sizeof(DOM_SID
*) * (*num_groups
));
495 for (i
=0;i
<(*num_groups
);i
++) {
496 (*user_grpsids
)[i
] = rid_to_talloced_sid(domain
, mem_ctx
, user
->gids
[i
].g_rid
);
504 /* no cache; hit the wire */
508 /* Get sam handle; if we fail here there is no hope */
510 if (!NT_STATUS_IS_OK(result
= cm_get_sam_handle(domain
, &hnd
)))
513 /* Get domain handle */
515 result
= cli_samr_open_domain(hnd
->cli
, mem_ctx
, &hnd
->pol
,
516 des_access
, &domain
->sid
, &dom_pol
);
517 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) &&
518 hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
520 if (!NT_STATUS_IS_OK(result
))
526 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
)) {
530 /* Get user handle */
531 result
= cli_samr_open_user(hnd
->cli
, mem_ctx
, &dom_pol
,
532 des_access
, user_rid
, &user_pol
);
534 if (!NT_STATUS_IS_OK(result
))
539 /* Query user rids */
540 result
= cli_samr_query_usergroups(hnd
->cli
, mem_ctx
, &user_pol
,
541 num_groups
, &user_groups
);
543 if (!NT_STATUS_IS_OK(result
) || (*num_groups
) == 0)
546 (*user_grpsids
) = talloc(mem_ctx
, sizeof(DOM_SID
*) * (*num_groups
));
547 if (!(*user_grpsids
)) {
548 result
= NT_STATUS_NO_MEMORY
;
552 for (i
=0;i
<(*num_groups
);i
++) {
553 (*user_grpsids
)[i
] = rid_to_talloced_sid(domain
, mem_ctx
, user_groups
[i
].g_rid
);
557 /* Clean up policy handles */
559 cli_samr_close(hnd
->cli
, mem_ctx
, &user_pol
);
562 cli_samr_close(hnd
->cli
, mem_ctx
, &dom_pol
);
568 /* Lookup group membership given a rid. */
569 static NTSTATUS
lookup_groupmem(struct winbindd_domain
*domain
,
571 const DOM_SID
*group_sid
, uint32
*num_names
,
572 DOM_SID
***sid_mem
, char ***names
,
575 CLI_POLICY_HND
*hnd
= NULL
;
576 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
577 uint32 i
, total_names
= 0;
578 POLICY_HND dom_pol
, group_pol
;
579 uint32 des_access
= SEC_RIGHTS_MAXIMUM_ALLOWED
;
580 BOOL got_dom_pol
= False
, got_group_pol
= False
;
581 uint32
*rid_mem
= NULL
;
587 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain
->name
, sid_to_string(sid_string
, group_sid
)));
589 if (!sid_peek_check_rid(&domain
->sid
, group_sid
, &group_rid
)) {
598 if (!NT_STATUS_IS_OK(result
= cm_get_sam_handle(domain
, &hnd
)))
601 /* Get domain handle */
603 result
= cli_samr_open_domain(hnd
->cli
, mem_ctx
, &hnd
->pol
,
604 des_access
, &domain
->sid
, &dom_pol
);
605 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) && hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
607 if (!NT_STATUS_IS_OK(result
))
612 /* Get group handle */
614 result
= cli_samr_open_group(hnd
->cli
, mem_ctx
, &dom_pol
,
615 des_access
, group_rid
, &group_pol
);
617 if (!NT_STATUS_IS_OK(result
))
620 got_group_pol
= True
;
622 /* Step #1: Get a list of user rids that are the members of the
625 result
= cli_samr_query_groupmem(hnd
->cli
, mem_ctx
,
626 &group_pol
, num_names
, &rid_mem
,
629 if (!NT_STATUS_IS_OK(result
))
639 /* Step #2: Convert list of rids into list of usernames. Do this
640 in bunches of ~1000 to avoid crashing NT4. It looks like there
641 is a buffer overflow or something like that lurking around
644 #define MAX_LOOKUP_RIDS 900
646 *names
= talloc_zero(mem_ctx
, *num_names
* sizeof(char *));
647 *name_types
= talloc_zero(mem_ctx
, *num_names
* sizeof(uint32
));
648 *sid_mem
= talloc_zero(mem_ctx
, *num_names
* sizeof(DOM_SID
*));
650 for (j
=0;j
<(*num_names
);j
++) {
651 (*sid_mem
)[j
] = rid_to_talloced_sid(domain
, mem_ctx
, (rid_mem
)[j
]);
654 if (*num_names
>0 && (!*names
|| !*name_types
)) {
655 result
= NT_STATUS_NO_MEMORY
;
659 for (i
= 0; i
< *num_names
; i
+= MAX_LOOKUP_RIDS
) {
660 int num_lookup_rids
= MIN(*num_names
- i
, MAX_LOOKUP_RIDS
);
661 uint32 tmp_num_names
= 0;
662 char **tmp_names
= NULL
;
663 uint32
*tmp_types
= NULL
;
665 /* Lookup a chunk of rids */
667 result
= cli_samr_lookup_rids(hnd
->cli
, mem_ctx
,
668 &dom_pol
, 1000, /* flags */
672 &tmp_names
, &tmp_types
);
674 /* see if we have a real error (and yes the STATUS_SOME_UNMAPPED is
675 the one returned from 2k) */
677 if (!NT_STATUS_IS_OK(result
) && NT_STATUS_V(result
) != NT_STATUS_V(STATUS_SOME_UNMAPPED
))
680 /* Copy result into array. The talloc system will take
681 care of freeing the temporary arrays later on. */
683 memcpy(&(*names
)[i
], tmp_names
, sizeof(char *) *
686 memcpy(&(*name_types
)[i
], tmp_types
, sizeof(uint32
) *
689 total_names
+= tmp_num_names
;
692 *num_names
= total_names
;
694 result
= NT_STATUS_OK
;
698 cli_samr_close(hnd
->cli
, mem_ctx
, &group_pol
);
701 cli_samr_close(hnd
->cli
, mem_ctx
, &dom_pol
);
710 static SIG_ATOMIC_T gotalarm
;
712 /***************************************************************
713 Signal function to tell us we timed out.
714 ****************************************************************/
716 static void gotalarm_sig(void)
721 static LDAP
*ldap_open_with_timeout(const char *server
, int port
, unsigned int to
)
727 CatchSignal(SIGALRM
, SIGNAL_CAST gotalarm_sig
);
729 /* End setup timeout. */
731 ldp
= ldap_open(server
, port
);
733 /* Teardown timeout. */
734 CatchSignal(SIGALRM
, SIGNAL_CAST SIG_IGN
);
740 static int get_ldap_seq(const char *server
, int port
, uint32
*seq
)
744 char *attrs
[] = {"highestCommittedUSN", NULL
};
745 LDAPMessage
*res
= NULL
;
746 char **values
= NULL
;
749 *seq
= DOM_SEQUENCE_NONE
;
752 * 10 second timeout on open. This is needed as the search timeout
753 * doesn't seem to apply to doing an open as well. JRA.
756 if ((ldp
= ldap_open_with_timeout(server
, port
, 10)) == NULL
)
759 /* Timeout if no response within 20 seconds. */
763 if (ldap_search_st(ldp
, "", LDAP_SCOPE_BASE
, "(objectclass=*)", &attrs
[0], 0, &to
, &res
))
766 if (ldap_count_entries(ldp
, res
) != 1)
769 values
= ldap_get_values(ldp
, res
, "highestCommittedUSN");
770 if (!values
|| !values
[0])
773 *seq
= atoi(values
[0]);
779 ldap_value_free(values
);
787 /**********************************************************************
788 Get the sequence number for a Windows AD native mode domain using
790 **********************************************************************/
792 static int get_ldap_sequence_number( const char* domain
, uint32
*seq
)
795 int i
, port
= LDAP_PORT
;
796 struct ip_service
*ip_list
= NULL
;
799 if ( !get_sorted_dc_list(domain
, &ip_list
, &count
, False
) ) {
800 DEBUG(3, ("Could not look up dc's for domain %s\n", domain
));
804 /* Finally return first DC that we can contact */
806 for (i
= 0; i
< count
; i
++) {
809 /* since the is an LDAP lookup, default to the LDAP_PORT is not set */
810 port
= (ip_list
[i
].port
!= PORT_NONE
) ? ip_list
[i
].port
: LDAP_PORT
;
812 fstrcpy( ipstr
, inet_ntoa(ip_list
[i
].ip
) );
814 if (is_zero_ip(ip_list
[i
].ip
))
817 if ( (ret
= get_ldap_seq( ipstr
, port
, seq
)) == 0 )
820 /* add to failed connection cache */
821 add_failed_connection_entry( domain
, ipstr
, NT_STATUS_UNSUCCESSFUL
);
826 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence number for Domain (%s) from DC (%s:%d)\n",
827 domain
, inet_ntoa(ip_list
[i
].ip
), port
));
835 #endif /* HAVE_LDAP */
837 /* find the sequence number for a domain */
838 static NTSTATUS
sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
843 uint16 switch_value
= 2;
846 BOOL got_dom_pol
= False
;
847 uint32 des_access
= SEC_RIGHTS_MAXIMUM_ALLOWED
;
850 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain
->name
));
852 *seq
= DOM_SEQUENCE_NONE
;
854 if (!(mem_ctx
= talloc_init("sequence_number[rpc]")))
855 return NT_STATUS_NO_MEMORY
;
860 if ( domain
->native_mode
)
862 DEBUG(8,("using get_ldap_seq() to retrieve the sequence number\n"));
864 if ( get_ldap_sequence_number( domain
->name
, seq
) == 0 ) {
865 result
= NT_STATUS_OK
;
866 DEBUG(10,("domain_sequence_number: LDAP for domain %s is %u\n",
867 domain
->name
, *seq
));
871 DEBUG(10,("domain_sequence_number: failed to get LDAP sequence number for domain %s\n",
874 #endif /* HAVE_LDAP */
876 if (!NT_STATUS_IS_OK(result
= cm_get_sam_handle(domain
, &hnd
)))
879 /* Get domain handle */
880 result
= cli_samr_open_domain(hnd
->cli
, mem_ctx
, &hnd
->pol
,
881 des_access
, &domain
->sid
, &dom_pol
);
882 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) && hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
884 if (!NT_STATUS_IS_OK(result
))
889 /* Query domain info */
891 result
= cli_samr_query_dom_info(hnd
->cli
, mem_ctx
, &dom_pol
,
894 if (NT_STATUS_IS_OK(result
)) {
895 *seq
= ctr
.info
.inf2
.seq_num
;
896 DEBUG(10,("domain_sequence_number: for domain %s is %u\n", domain
->name
, (unsigned)*seq
));
898 DEBUG(10,("domain_sequence_number: failed to get sequence number (%u) for domain %s\n",
899 (unsigned)*seq
, domain
->name
));
905 cli_samr_close(hnd
->cli
, mem_ctx
, &dom_pol
);
907 talloc_destroy(mem_ctx
);
912 /* get a list of trusted domains */
913 static NTSTATUS
trusted_domains(struct winbindd_domain
*domain
,
921 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
925 DEBUG(3,("rpc: trusted_domains\n"));
932 if (!NT_STATUS_IS_OK(result
= cm_get_lsa_handle(find_our_domain(), &hnd
)))
935 result
= cli_lsa_enum_trust_dom(hnd
->cli
, mem_ctx
,
936 &hnd
->pol
, &enum_ctx
,
937 num_domains
, names
, dom_sids
);
938 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) && hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
944 /* find the domain sid for a domain */
945 static NTSTATUS
domain_sid(struct winbindd_domain
*domain
, DOM_SID
*sid
)
947 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
954 DEBUG(3,("rpc: domain_sid\n"));
956 if (!(mem_ctx
= talloc_init("domain_sid[rpc]")))
957 return NT_STATUS_NO_MEMORY
;
962 if (!NT_STATUS_IS_OK(result
= cm_get_lsa_handle(domain
, &hnd
)))
965 result
= cli_lsa_query_info_policy(hnd
->cli
, mem_ctx
,
966 &hnd
->pol
, 0x05, &level5_dom
, &alloc_sid
);
967 } while (!NT_STATUS_IS_OK(result
) && (retry
++ < 1) && hnd
&& hnd
->cli
&& hnd
->cli
->fd
== -1);
969 if (NT_STATUS_IS_OK(result
)) {
971 sid_copy(sid
, alloc_sid
);
973 result
= NT_STATUS_NO_MEMORY
;
978 talloc_destroy(mem_ctx
);
982 /* find alternate names list for the domain - none for rpc */
983 static NTSTATUS
alternate_name(struct winbindd_domain
*domain
)
989 /* the rpc backend methods are exposed via this structure */
990 struct winbindd_methods msrpc_methods
= {