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
)
42 unsigned int i
, start_idx
;
44 struct rpc_pipe_client
*cli
;
46 DEBUG(3,("rpc: query_user_list\n"));
51 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
52 if (!NT_STATUS_IS_OK(result
))
60 uint32 num_dom_users
, j
;
61 uint32 max_entries
, max_size
;
67 ctr
.sam
.info1
= &info1
;
69 if (!(ctx2
= talloc_init("winbindd enum_users")))
70 return NT_STATUS_NO_MEMORY
;
72 /* this next bit is copied from net_user_list_internal() */
74 get_query_dispinfo_params(loop_count
, &max_entries
,
77 result
= rpccli_samr_query_dispinfo(cli
, mem_ctx
, &dom_pol
,
80 max_entries
, max_size
,
85 *num_entries
+= num_dom_users
;
87 *info
= TALLOC_REALLOC_ARRAY(mem_ctx
, *info
, WINBIND_USERINFO
,
92 return NT_STATUS_NO_MEMORY
;
95 for (j
= 0; j
< num_dom_users
; i
++, j
++) {
96 fstring username
, fullname
;
97 uint32 rid
= ctr
.sam
.info1
->sam
[j
].rid_user
;
99 unistr2_to_ascii( username
, &(&ctr
.sam
.info1
->str
[j
])->uni_acct_name
, sizeof(username
)-1);
100 unistr2_to_ascii( fullname
, &(&ctr
.sam
.info1
->str
[j
])->uni_full_name
, sizeof(fullname
)-1);
102 (*info
)[i
].acct_name
= talloc_strdup(mem_ctx
, username
);
103 (*info
)[i
].full_name
= talloc_strdup(mem_ctx
, fullname
);
104 (*info
)[i
].homedir
= NULL
;
105 (*info
)[i
].shell
= NULL
;
106 sid_compose(&(*info
)[i
].user_sid
, &domain
->sid
, rid
);
108 /* For the moment we set the primary group for
109 every user to be the Domain Users group.
110 There are serious problems with determining
111 the actual primary group for large domains.
112 This should really be made into a 'winbind
113 force group' smb.conf parameter or
114 something like that. */
116 sid_compose(&(*info
)[i
].group_sid
, &domain
->sid
,
117 DOMAIN_GROUP_RID_USERS
);
120 talloc_destroy(ctx2
);
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 status
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
144 if (!NT_STATUS_IS_OK(status
))
148 struct acct_info
*info2
= NULL
;
150 TALLOC_CTX
*mem_ctx2
;
152 mem_ctx2
= talloc_init("enum_dom_groups[rpc]");
154 /* start is updated by this call. */
155 status
= rpccli_samr_enum_dom_groups(cli
, mem_ctx2
, &dom_pol
,
157 0xFFFF, /* buffer size? */
160 if (!NT_STATUS_IS_OK(status
) &&
161 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
162 talloc_destroy(mem_ctx2
);
166 (*info
) = TALLOC_REALLOC_ARRAY(mem_ctx
, *info
,
168 (*num_entries
) + count
);
170 talloc_destroy(mem_ctx2
);
171 return NT_STATUS_NO_MEMORY
;
174 memcpy(&(*info
)[*num_entries
], info2
, count
*sizeof(*info2
));
175 (*num_entries
) += count
;
176 talloc_destroy(mem_ctx2
);
177 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
182 /* List all domain groups */
184 static NTSTATUS
enum_local_groups(struct winbindd_domain
*domain
,
187 struct acct_info
**info
)
191 struct rpc_pipe_client
*cli
;
196 DEBUG(3,("rpc: enum_local_groups\n"));
198 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
199 if (!NT_STATUS_IS_OK(result
))
203 struct acct_info
*info2
= NULL
;
204 uint32 count
= 0, start
= *num_entries
;
205 TALLOC_CTX
*mem_ctx2
;
207 mem_ctx2
= talloc_init("enum_dom_local_groups[rpc]");
209 result
= rpccli_samr_enum_als_groups( cli
, mem_ctx2
, &dom_pol
,
210 &start
, 0xFFFF, &info2
,
213 if (!NT_STATUS_IS_OK(result
) &&
214 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
) )
216 talloc_destroy(mem_ctx2
);
220 (*info
) = TALLOC_REALLOC_ARRAY(mem_ctx
, *info
,
222 (*num_entries
) + count
);
224 talloc_destroy(mem_ctx2
);
225 return NT_STATUS_NO_MEMORY
;
228 memcpy(&(*info
)[*num_entries
], info2
, count
*sizeof(*info2
));
229 (*num_entries
) += count
;
230 talloc_destroy(mem_ctx2
);
232 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
237 /* convert a single name to a sid in a domain */
238 NTSTATUS
msrpc_name_to_sid(struct winbindd_domain
*domain
,
240 const char *domain_name
,
243 enum lsa_SidType
*type
)
246 DOM_SID
*sids
= NULL
;
247 enum lsa_SidType
*types
= NULL
;
248 char *full_name
= NULL
;
249 struct rpc_pipe_client
*cli
;
250 POLICY_HND lsa_policy
;
252 if(name
== NULL
|| *name
=='\0') {
253 DEBUG(3,("rpc: name_to_sid name=%s\n", domain_name
));
254 full_name
= talloc_asprintf(mem_ctx
, "%s", domain_name
);
256 DEBUG(3,("rpc: name_to_sid name=%s\\%s\n", domain_name
, name
));
257 full_name
= talloc_asprintf(mem_ctx
, "%s\\%s", domain_name
, name
);
260 DEBUG(0, ("talloc_asprintf failed!\n"));
261 return NT_STATUS_NO_MEMORY
;
264 ws_name_return( full_name
, WB_REPLACE_CHAR
);
266 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", full_name
?full_name
:"", domain_name
));
268 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
269 if (!NT_STATUS_IS_OK(result
))
272 result
= rpccli_lsa_lookup_names(cli
, mem_ctx
, &lsa_policy
, 1,
273 (const char**) &full_name
, NULL
, &sids
, &types
);
275 if (!NT_STATUS_IS_OK(result
))
278 /* Return rid and type if lookup successful */
280 sid_copy(sid
, &sids
[0]);
287 convert a domain SID to a user or group name
289 NTSTATUS
msrpc_sid_to_name(struct winbindd_domain
*domain
,
294 enum lsa_SidType
*type
)
298 enum lsa_SidType
*types
;
300 struct rpc_pipe_client
*cli
;
301 POLICY_HND lsa_policy
;
303 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_static(sid
),
306 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
307 if (!NT_STATUS_IS_OK(result
))
310 result
= rpccli_lsa_lookup_sids(cli
, mem_ctx
, &lsa_policy
,
311 1, sid
, &domains
, &names
, &types
);
312 if (!NT_STATUS_IS_OK(result
))
315 *type
= (enum lsa_SidType
)types
[0];
316 *domain_name
= domains
[0];
319 ws_name_replace( *name
, WB_REPLACE_CHAR
);
321 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains
[0], *name
));
325 NTSTATUS
msrpc_rids_to_names(struct winbindd_domain
*domain
,
332 enum lsa_SidType
**types
)
336 struct rpc_pipe_client
*cli
;
337 POLICY_HND lsa_policy
;
342 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain
->name
));
345 sids
= TALLOC_ARRAY(mem_ctx
, DOM_SID
, num_rids
);
347 return NT_STATUS_NO_MEMORY
;
353 for (i
=0; i
<num_rids
; i
++) {
354 if (!sid_compose(&sids
[i
], sid
, rids
[i
])) {
355 return NT_STATUS_INTERNAL_ERROR
;
359 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
360 if (!NT_STATUS_IS_OK(result
)) {
364 result
= rpccli_lsa_lookup_sids(cli
, mem_ctx
, &lsa_policy
,
365 num_rids
, sids
, &domains
,
367 if (!NT_STATUS_IS_OK(result
) &&
368 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
373 for (i
=0; i
<num_rids
; i
++) {
374 if ((*types
)[i
] != SID_NAME_UNKNOWN
) {
375 ws_name_replace( ret_names
[i
], WB_REPLACE_CHAR
);
376 *domain_name
= domains
[i
];
383 /* Lookup user information from a rid or username. */
384 static NTSTATUS
query_user(struct winbindd_domain
*domain
,
386 const DOM_SID
*user_sid
,
387 WINBIND_USERINFO
*user_info
)
389 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
390 POLICY_HND dom_pol
, user_pol
;
391 SAM_USERINFO_CTR
*ctr
;
394 NET_USER_INFO_3
*user
;
395 struct rpc_pipe_client
*cli
;
397 DEBUG(3,("rpc: query_user sid=%s\n",
398 sid_to_string(sid_string
, user_sid
)));
400 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
401 return NT_STATUS_UNSUCCESSFUL
;
403 /* try netsamlogon cache first */
405 if ( (user
= netsamlogon_cache_get( mem_ctx
, user_sid
)) != NULL
)
408 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
409 sid_string_static(user_sid
)));
411 sid_compose(&user_info
->user_sid
, &domain
->sid
, user_rid
);
412 sid_compose(&user_info
->group_sid
, &domain
->sid
,
415 user_info
->acct_name
= unistr2_tdup(mem_ctx
,
416 &user
->uni_user_name
);
417 user_info
->full_name
= unistr2_tdup(mem_ctx
,
418 &user
->uni_full_name
);
420 user_info
->homedir
= NULL
;
421 user_info
->shell
= NULL
;
422 user_info
->primary_gid
= (gid_t
)-1;
429 /* no cache; hit the wire */
431 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
432 if (!NT_STATUS_IS_OK(result
))
435 /* Get user handle */
436 result
= rpccli_samr_open_user(cli
, mem_ctx
, &dom_pol
,
437 SEC_RIGHTS_MAXIMUM_ALLOWED
, user_rid
,
440 if (!NT_STATUS_IS_OK(result
))
444 result
= rpccli_samr_query_userinfo(cli
, mem_ctx
, &user_pol
,
447 rpccli_samr_close(cli
, mem_ctx
, &user_pol
);
449 if (!NT_STATUS_IS_OK(result
))
452 sid_compose(&user_info
->user_sid
, &domain
->sid
, user_rid
);
453 sid_compose(&user_info
->group_sid
, &domain
->sid
,
454 ctr
->info
.id21
->group_rid
);
455 user_info
->acct_name
= unistr2_tdup(mem_ctx
,
456 &ctr
->info
.id21
->uni_user_name
);
457 user_info
->full_name
= unistr2_tdup(mem_ctx
,
458 &ctr
->info
.id21
->uni_full_name
);
459 user_info
->homedir
= NULL
;
460 user_info
->shell
= NULL
;
461 user_info
->primary_gid
= (gid_t
)-1;
466 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
467 static NTSTATUS
lookup_usergroups(struct winbindd_domain
*domain
,
469 const DOM_SID
*user_sid
,
470 uint32
*num_groups
, DOM_SID
**user_grpsids
)
472 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
473 POLICY_HND dom_pol
, user_pol
;
474 uint32 des_access
= SEC_RIGHTS_MAXIMUM_ALLOWED
;
475 DOM_GID
*user_groups
;
479 struct rpc_pipe_client
*cli
;
481 DEBUG(3,("rpc: lookup_usergroups sid=%s\n",
482 sid_to_string(sid_string
, user_sid
)));
484 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
485 return NT_STATUS_UNSUCCESSFUL
;
488 *user_grpsids
= NULL
;
490 /* so lets see if we have a cached user_info_3 */
491 result
= lookup_usergroups_cached(domain
, mem_ctx
, user_sid
,
492 num_groups
, user_grpsids
);
494 if (NT_STATUS_IS_OK(result
)) {
498 /* no cache; hit the wire */
500 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
501 if (!NT_STATUS_IS_OK(result
))
504 /* Get user handle */
505 result
= rpccli_samr_open_user(cli
, mem_ctx
, &dom_pol
,
506 des_access
, user_rid
, &user_pol
);
508 if (!NT_STATUS_IS_OK(result
))
511 /* Query user rids */
512 result
= rpccli_samr_query_usergroups(cli
, mem_ctx
, &user_pol
,
513 num_groups
, &user_groups
);
515 rpccli_samr_close(cli
, mem_ctx
, &user_pol
);
517 if (!NT_STATUS_IS_OK(result
) || (*num_groups
) == 0)
520 (*user_grpsids
) = TALLOC_ARRAY(mem_ctx
, DOM_SID
, *num_groups
);
521 if (!(*user_grpsids
))
522 return NT_STATUS_NO_MEMORY
;
524 for (i
=0;i
<(*num_groups
);i
++) {
525 sid_copy(&((*user_grpsids
)[i
]), &domain
->sid
);
526 sid_append_rid(&((*user_grpsids
)[i
]),
527 user_groups
[i
].g_rid
);
533 NTSTATUS
msrpc_lookup_useraliases(struct winbindd_domain
*domain
,
535 uint32 num_sids
, const DOM_SID
*sids
,
536 uint32
*num_aliases
, uint32
**alias_rids
)
538 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
540 DOM_SID2
*query_sids
;
541 uint32 num_query_sids
= 0;
543 struct rpc_pipe_client
*cli
;
544 uint32
*alias_rids_query
, num_aliases_query
;
545 int rangesize
= MAX_SAM_ENTRIES_W2K
;
546 uint32 total_sids
= 0;
552 DEBUG(3,("rpc: lookup_useraliases\n"));
554 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
555 if (!NT_STATUS_IS_OK(result
))
561 num_query_sids
= MIN(num_sids
- total_sids
, rangesize
);
563 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
564 num_queries
, num_query_sids
));
566 if (num_query_sids
) {
567 query_sids
= TALLOC_ARRAY(mem_ctx
, DOM_SID2
, num_query_sids
);
568 if (query_sids
== NULL
) {
569 return NT_STATUS_NO_MEMORY
;
575 for (i
=0; i
<num_query_sids
; i
++) {
576 sid_copy(&query_sids
[i
].sid
, &sids
[total_sids
++]);
577 query_sids
[i
].num_auths
= query_sids
[i
].sid
.num_auths
;
582 result
= rpccli_samr_query_useraliases(cli
, mem_ctx
, &dom_pol
,
583 num_query_sids
, query_sids
,
587 if (!NT_STATUS_IS_OK(result
)) {
590 TALLOC_FREE(query_sids
);
596 for (i
=0; i
<num_aliases_query
; i
++) {
597 size_t na
= *num_aliases
;
598 if (!add_rid_to_array_unique(mem_ctx
, alias_rids_query
[i
],
600 return NT_STATUS_NO_MEMORY
;
605 TALLOC_FREE(query_sids
);
609 } while (total_sids
< num_sids
);
612 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
613 "(rangesize: %d)\n", *num_aliases
, num_queries
, rangesize
));
619 /* Lookup group membership given a rid. */
620 static NTSTATUS
lookup_groupmem(struct winbindd_domain
*domain
,
622 const DOM_SID
*group_sid
, uint32
*num_names
,
623 DOM_SID
**sid_mem
, char ***names
,
626 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
627 uint32 i
, total_names
= 0;
628 POLICY_HND dom_pol
, group_pol
;
629 uint32 des_access
= SEC_RIGHTS_MAXIMUM_ALLOWED
;
630 uint32
*rid_mem
= NULL
;
634 struct rpc_pipe_client
*cli
;
635 unsigned int orig_timeout
;
637 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain
->name
,
638 sid_to_string(sid_string
, group_sid
)));
640 if (!sid_peek_check_rid(&domain
->sid
, group_sid
, &group_rid
))
641 return NT_STATUS_UNSUCCESSFUL
;
645 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
646 if (!NT_STATUS_IS_OK(result
))
649 result
= rpccli_samr_open_group(cli
, mem_ctx
, &dom_pol
,
650 des_access
, group_rid
, &group_pol
);
652 if (!NT_STATUS_IS_OK(result
))
655 /* Step #1: Get a list of user rids that are the members of the
658 /* This call can take a long time - allow the server to time out.
659 35 seconds should do it. */
661 orig_timeout
= cli_set_timeout(cli
->cli
, 35000);
663 result
= rpccli_samr_query_groupmem(cli
, mem_ctx
,
664 &group_pol
, num_names
, &rid_mem
,
667 /* And restore our original timeout. */
668 cli_set_timeout(cli
->cli
, orig_timeout
);
670 rpccli_samr_close(cli
, mem_ctx
, &group_pol
);
672 if (!NT_STATUS_IS_OK(result
))
682 /* Step #2: Convert list of rids into list of usernames. Do this
683 in bunches of ~1000 to avoid crashing NT4. It looks like there
684 is a buffer overflow or something like that lurking around
687 #define MAX_LOOKUP_RIDS 900
689 *names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, *num_names
);
690 *name_types
= TALLOC_ZERO_ARRAY(mem_ctx
, uint32
, *num_names
);
691 *sid_mem
= TALLOC_ZERO_ARRAY(mem_ctx
, DOM_SID
, *num_names
);
693 for (j
=0;j
<(*num_names
);j
++)
694 sid_compose(&(*sid_mem
)[j
], &domain
->sid
, rid_mem
[j
]);
696 if (*num_names
>0 && (!*names
|| !*name_types
))
697 return NT_STATUS_NO_MEMORY
;
699 for (i
= 0; i
< *num_names
; i
+= MAX_LOOKUP_RIDS
) {
700 int num_lookup_rids
= MIN(*num_names
- i
, MAX_LOOKUP_RIDS
);
701 uint32 tmp_num_names
= 0;
702 char **tmp_names
= NULL
;
703 uint32
*tmp_types
= NULL
;
705 /* Lookup a chunk of rids */
707 result
= rpccli_samr_lookup_rids(cli
, mem_ctx
,
712 &tmp_names
, &tmp_types
);
714 /* see if we have a real error (and yes the
715 STATUS_SOME_UNMAPPED is the one returned from 2k) */
717 if (!NT_STATUS_IS_OK(result
) &&
718 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
))
721 /* Copy result into array. The talloc system will take
722 care of freeing the temporary arrays later on. */
724 memcpy(&(*names
)[i
], tmp_names
, sizeof(char *) *
727 memcpy(&(*name_types
)[i
], tmp_types
, sizeof(uint32
) *
730 total_names
+= tmp_num_names
;
733 *num_names
= total_names
;
742 static int get_ldap_seq(const char *server
, int port
, uint32
*seq
)
746 const char *attrs
[] = {"highestCommittedUSN", NULL
};
747 LDAPMessage
*res
= NULL
;
748 char **values
= NULL
;
751 *seq
= DOM_SEQUENCE_NONE
;
754 * Parameterised (5) second timeout on open. This is needed as the
755 * search timeout doesn't seem to apply to doing an open as well. JRA.
758 ldp
= ldap_open_with_timeout(server
, port
, lp_ldap_timeout());
762 /* Timeout if no response within 20 seconds. */
766 if (ldap_search_st(ldp
, "", LDAP_SCOPE_BASE
, "(objectclass=*)",
767 CONST_DISCARD(char **, attrs
), 0, &to
, &res
))
770 if (ldap_count_entries(ldp
, res
) != 1)
773 values
= ldap_get_values(ldp
, res
, "highestCommittedUSN");
774 if (!values
|| !values
[0])
777 *seq
= atoi(values
[0]);
783 ldap_value_free(values
);
791 /**********************************************************************
792 Get the sequence number for a Windows AD native mode domain using
794 **********************************************************************/
796 static int get_ldap_sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
801 fstrcpy( ipstr
, inet_ntoa(domain
->dcaddr
.sin_addr
));
802 if ((ret
= get_ldap_seq( ipstr
, LDAP_PORT
, seq
)) == 0) {
803 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
804 "number for Domain (%s) from DC (%s)\n",
805 domain
->name
, ipstr
));
810 #endif /* HAVE_LDAP */
812 /* find the sequence number for a domain */
813 static NTSTATUS
sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
819 BOOL got_seq_num
= False
;
820 struct rpc_pipe_client
*cli
;
822 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain
->name
));
824 *seq
= DOM_SEQUENCE_NONE
;
826 if (!(mem_ctx
= talloc_init("sequence_number[rpc]")))
827 return NT_STATUS_NO_MEMORY
;
830 if ( domain
->native_mode
)
834 DEBUG(8,("using get_ldap_seq() to retrieve the "
835 "sequence number\n"));
837 res
= get_ldap_sequence_number( domain
, seq
);
840 result
= NT_STATUS_OK
;
841 DEBUG(10,("domain_sequence_number: LDAP for "
843 domain
->name
, *seq
));
847 DEBUG(10,("domain_sequence_number: failed to get LDAP "
848 "sequence number for domain %s\n",
851 #endif /* HAVE_LDAP */
853 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
854 if (!NT_STATUS_IS_OK(result
)) {
858 /* Query domain info */
860 result
= rpccli_samr_query_dom_info(cli
, mem_ctx
, &dom_pol
, 8, &ctr
);
862 if (NT_STATUS_IS_OK(result
)) {
863 *seq
= ctr
.info
.inf8
.seq_num
;
868 /* retry with info-level 2 in case the dc does not support info-level 8
869 * (like all older samba2 and samba3 dc's - Guenther */
871 result
= rpccli_samr_query_dom_info(cli
, mem_ctx
, &dom_pol
, 2, &ctr
);
873 if (NT_STATUS_IS_OK(result
)) {
874 *seq
= ctr
.info
.inf2
.seq_num
;
880 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
881 domain
->name
, (unsigned)*seq
));
883 DEBUG(10,("domain_sequence_number: failed to get sequence "
884 "number (%u) for domain %s\n",
885 (unsigned)*seq
, domain
->name
));
890 talloc_destroy(mem_ctx
);
895 /* get a list of trusted domains */
896 static NTSTATUS
trusted_domains(struct winbindd_domain
*domain
,
903 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
905 struct rpc_pipe_client
*cli
;
906 POLICY_HND lsa_policy
;
908 DEBUG(3,("rpc: trusted_domains\n"));
915 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
916 if (!NT_STATUS_IS_OK(result
))
919 result
= STATUS_MORE_ENTRIES
;
921 while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
922 uint32 start_idx
, num
;
927 result
= rpccli_lsa_enum_trust_dom(cli
, mem_ctx
,
928 &lsa_policy
, &enum_ctx
,
932 if (!NT_STATUS_IS_OK(result
) &&
933 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
))
936 start_idx
= *num_domains
;
938 *names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *names
,
939 char *, *num_domains
);
940 *dom_sids
= TALLOC_REALLOC_ARRAY(mem_ctx
, *dom_sids
,
941 DOM_SID
, *num_domains
);
942 *alt_names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *alt_names
,
943 char *, *num_domains
);
944 if ((*names
== NULL
) || (*dom_sids
== NULL
) ||
945 (*alt_names
== NULL
))
946 return NT_STATUS_NO_MEMORY
;
948 for (i
=0; i
<num
; i
++) {
949 (*names
)[start_idx
+i
] = tmp_names
[i
];
950 (*dom_sids
)[start_idx
+i
] = tmp_sids
[i
];
951 (*alt_names
)[start_idx
+i
] = talloc_strdup(mem_ctx
, "");
957 /* find the lockout policy for a domain */
958 NTSTATUS
msrpc_lockout_policy(struct winbindd_domain
*domain
,
960 SAM_UNK_INFO_12
*lockout_policy
)
963 struct rpc_pipe_client
*cli
;
967 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain
->name
));
969 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
970 if (!NT_STATUS_IS_OK(result
)) {
974 result
= rpccli_samr_query_dom_info(cli
, mem_ctx
, &dom_pol
, 12, &ctr
);
975 if (!NT_STATUS_IS_OK(result
)) {
979 *lockout_policy
= ctr
.info
.inf12
;
981 DEBUG(10,("msrpc_lockout_policy: bad_attempt_lockout %d\n",
982 ctr
.info
.inf12
.bad_attempt_lockout
));
989 /* find the password policy for a domain */
990 NTSTATUS
msrpc_password_policy(struct winbindd_domain
*domain
,
992 SAM_UNK_INFO_1
*password_policy
)
995 struct rpc_pipe_client
*cli
;
999 DEBUG(10,("rpc: fetch password policy for %s\n", domain
->name
));
1001 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1002 if (!NT_STATUS_IS_OK(result
)) {
1006 result
= rpccli_samr_query_dom_info(cli
, mem_ctx
, &dom_pol
, 1, &ctr
);
1007 if (!NT_STATUS_IS_OK(result
)) {
1011 *password_policy
= ctr
.info
.inf1
;
1013 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1014 ctr
.info
.inf1
.min_length_password
));
1022 /* the rpc backend methods are exposed via this structure */
1023 struct winbindd_methods msrpc_methods
= {
1030 msrpc_rids_to_names
,
1033 msrpc_lookup_useraliases
,
1036 msrpc_lockout_policy
,
1037 msrpc_password_policy
,