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 status
= NT_STATUS_NO_MEMORY
;
175 memcpy(&(*info
)[*num_entries
], info2
, count
*sizeof(*info2
));
176 (*num_entries
) += count
;
177 talloc_destroy(mem_ctx2
);
178 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
183 /* List all domain groups */
185 static NTSTATUS
enum_local_groups(struct winbindd_domain
*domain
,
188 struct acct_info
**info
)
192 struct rpc_pipe_client
*cli
;
197 DEBUG(3,("rpc: enum_local_groups\n"));
199 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
200 if (!NT_STATUS_IS_OK(result
))
204 struct acct_info
*info2
= NULL
;
205 uint32 count
= 0, start
= *num_entries
;
206 TALLOC_CTX
*mem_ctx2
;
208 mem_ctx2
= talloc_init("enum_dom_local_groups[rpc]");
210 result
= rpccli_samr_enum_als_groups( cli
, mem_ctx2
, &dom_pol
,
211 &start
, 0xFFFF, &info2
,
214 if (!NT_STATUS_IS_OK(result
) &&
215 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
) )
217 talloc_destroy(mem_ctx2
);
221 (*info
) = TALLOC_REALLOC_ARRAY(mem_ctx
, *info
,
223 (*num_entries
) + count
);
225 talloc_destroy(mem_ctx2
);
226 return NT_STATUS_NO_MEMORY
;
229 memcpy(&(*info
)[*num_entries
], info2
, count
*sizeof(*info2
));
230 (*num_entries
) += count
;
231 talloc_destroy(mem_ctx2
);
233 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
238 /* convert a single name to a sid in a domain */
239 NTSTATUS
msrpc_name_to_sid(struct winbindd_domain
*domain
,
241 const char *domain_name
,
244 enum SID_NAME_USE
*type
)
247 DOM_SID
*sids
= NULL
;
248 uint32
*types
= NULL
;
249 const char *full_name
;
250 struct rpc_pipe_client
*cli
;
251 POLICY_HND lsa_policy
;
253 if(name
== NULL
|| *name
=='\0') {
254 DEBUG(3,("rpc: name_to_sid name=%s\n", domain_name
));
255 full_name
= talloc_asprintf(mem_ctx
, "%s", domain_name
);
257 DEBUG(3,("rpc: name_to_sid name=%s\\%s\n", domain_name
, name
));
258 full_name
= talloc_asprintf(mem_ctx
, "%s\\%s", domain_name
, name
);
261 DEBUG(0, ("talloc_asprintf failed!\n"));
262 return NT_STATUS_NO_MEMORY
;
265 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", name
?name
:"", domain_name
));
267 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
268 if (!NT_STATUS_IS_OK(result
))
271 result
= rpccli_lsa_lookup_names(cli
, mem_ctx
, &lsa_policy
, 1,
272 &full_name
, NULL
, &sids
, &types
);
274 if (!NT_STATUS_IS_OK(result
))
277 /* Return rid and type if lookup successful */
279 sid_copy(sid
, &sids
[0]);
280 *type
= (enum SID_NAME_USE
)types
[0];
286 convert a domain SID to a user or group name
288 NTSTATUS
msrpc_sid_to_name(struct winbindd_domain
*domain
,
293 enum SID_NAME_USE
*type
)
299 struct rpc_pipe_client
*cli
;
300 POLICY_HND lsa_policy
;
302 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_static(sid
),
305 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
306 if (!NT_STATUS_IS_OK(result
))
309 result
= rpccli_lsa_lookup_sids(cli
, mem_ctx
, &lsa_policy
,
310 1, sid
, &domains
, &names
, &types
);
311 if (!NT_STATUS_IS_OK(result
))
314 *type
= (enum SID_NAME_USE
)types
[0];
315 *domain_name
= domains
[0];
317 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains
[0], *name
));
321 /* Lookup user information from a rid or username. */
322 static NTSTATUS
query_user(struct winbindd_domain
*domain
,
324 const DOM_SID
*user_sid
,
325 WINBIND_USERINFO
*user_info
)
327 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
328 POLICY_HND dom_pol
, user_pol
;
329 SAM_USERINFO_CTR
*ctr
;
332 NET_USER_INFO_3
*user
;
333 struct rpc_pipe_client
*cli
;
335 DEBUG(3,("rpc: query_user rid=%s\n",
336 sid_to_string(sid_string
, user_sid
)));
338 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
339 return NT_STATUS_UNSUCCESSFUL
;
341 /* try netsamlogon cache first */
343 if ( (user
= netsamlogon_cache_get( mem_ctx
, user_sid
)) != NULL
)
346 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
347 sid_string_static(user_sid
)));
349 sid_compose(&user_info
->user_sid
, &domain
->sid
, user_rid
);
350 sid_compose(&user_info
->group_sid
, &domain
->sid
,
353 user_info
->acct_name
= unistr2_tdup(mem_ctx
,
354 &user
->uni_user_name
);
355 user_info
->full_name
= unistr2_tdup(mem_ctx
,
356 &user
->uni_full_name
);
358 user_info
->homedir
= NULL
;
359 user_info
->shell
= NULL
;
366 /* no cache; hit the wire */
368 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
369 if (!NT_STATUS_IS_OK(result
))
372 /* Get user handle */
373 result
= rpccli_samr_open_user(cli
, mem_ctx
, &dom_pol
,
374 SEC_RIGHTS_MAXIMUM_ALLOWED
, user_rid
,
377 if (!NT_STATUS_IS_OK(result
))
381 result
= rpccli_samr_query_userinfo(cli
, mem_ctx
, &user_pol
,
384 rpccli_samr_close(cli
, mem_ctx
, &user_pol
);
386 if (!NT_STATUS_IS_OK(result
))
389 sid_compose(&user_info
->user_sid
, &domain
->sid
, user_rid
);
390 sid_compose(&user_info
->group_sid
, &domain
->sid
,
391 ctr
->info
.id21
->group_rid
);
392 user_info
->acct_name
= unistr2_tdup(mem_ctx
,
393 &ctr
->info
.id21
->uni_user_name
);
394 user_info
->full_name
= unistr2_tdup(mem_ctx
,
395 &ctr
->info
.id21
->uni_full_name
);
396 user_info
->homedir
= NULL
;
397 user_info
->shell
= NULL
;
402 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
403 static NTSTATUS
lookup_usergroups(struct winbindd_domain
*domain
,
405 const DOM_SID
*user_sid
,
406 uint32
*num_groups
, DOM_SID
**user_grpsids
)
408 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
409 POLICY_HND dom_pol
, user_pol
;
410 uint32 des_access
= SEC_RIGHTS_MAXIMUM_ALLOWED
;
411 DOM_GID
*user_groups
;
415 NET_USER_INFO_3
*user
;
416 struct rpc_pipe_client
*cli
;
418 DEBUG(3,("rpc: lookup_usergroups sid=%s\n",
419 sid_to_string(sid_string
, user_sid
)));
421 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
422 return NT_STATUS_UNSUCCESSFUL
;
425 *user_grpsids
= NULL
;
427 /* so lets see if we have a cached user_info_3 */
429 if ( (user
= netsamlogon_cache_get( mem_ctx
, user_sid
)) != NULL
)
431 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
432 sid_string_static(user_sid
)));
434 *num_groups
= user
->num_groups
;
436 (*user_grpsids
) = TALLOC_ARRAY(mem_ctx
, DOM_SID
, *num_groups
);
437 for (i
=0;i
<(*num_groups
);i
++) {
438 sid_copy(&((*user_grpsids
)[i
]), &domain
->sid
);
439 sid_append_rid(&((*user_grpsids
)[i
]),
440 user
->gids
[i
].g_rid
);
448 /* no cache; hit the wire */
450 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
451 if (!NT_STATUS_IS_OK(result
))
454 /* Get user handle */
455 result
= rpccli_samr_open_user(cli
, mem_ctx
, &dom_pol
,
456 des_access
, user_rid
, &user_pol
);
458 if (!NT_STATUS_IS_OK(result
))
461 /* Query user rids */
462 result
= rpccli_samr_query_usergroups(cli
, mem_ctx
, &user_pol
,
463 num_groups
, &user_groups
);
465 rpccli_samr_close(cli
, mem_ctx
, &user_pol
);
467 if (!NT_STATUS_IS_OK(result
) || (*num_groups
) == 0)
470 (*user_grpsids
) = TALLOC_ARRAY(mem_ctx
, DOM_SID
, *num_groups
);
471 if (!(*user_grpsids
))
472 return NT_STATUS_NO_MEMORY
;
474 for (i
=0;i
<(*num_groups
);i
++) {
475 sid_copy(&((*user_grpsids
)[i
]), &domain
->sid
);
476 sid_append_rid(&((*user_grpsids
)[i
]),
477 user_groups
[i
].g_rid
);
483 NTSTATUS
msrpc_lookup_useraliases(struct winbindd_domain
*domain
,
485 uint32 num_sids
, const DOM_SID
*sids
,
486 uint32
*num_aliases
, uint32
**alias_rids
)
488 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
492 struct rpc_pipe_client
*cli
;
497 DEBUG(3,("rpc: lookup_useraliases\n"));
499 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
500 if (!NT_STATUS_IS_OK(result
))
503 sid2
= TALLOC_ARRAY(mem_ctx
, DOM_SID2
, num_sids
);
506 return NT_STATUS_NO_MEMORY
;
508 for (i
=0; i
<num_sids
; i
++) {
509 sid_copy(&sid2
[i
].sid
, &sids
[i
]);
510 sid2
[i
].num_auths
= sid2
[i
].sid
.num_auths
;
513 result
= rpccli_samr_query_useraliases(cli
, mem_ctx
, &dom_pol
,
515 num_aliases
, alias_rids
);
521 /* Lookup group membership given a rid. */
522 static NTSTATUS
lookup_groupmem(struct winbindd_domain
*domain
,
524 const DOM_SID
*group_sid
, uint32
*num_names
,
525 DOM_SID
**sid_mem
, char ***names
,
528 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
529 uint32 i
, total_names
= 0;
530 POLICY_HND dom_pol
, group_pol
;
531 uint32 des_access
= SEC_RIGHTS_MAXIMUM_ALLOWED
;
532 uint32
*rid_mem
= NULL
;
536 struct rpc_pipe_client
*cli
;
538 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain
->name
,
539 sid_to_string(sid_string
, group_sid
)));
541 if (!sid_peek_check_rid(&domain
->sid
, group_sid
, &group_rid
))
542 return NT_STATUS_UNSUCCESSFUL
;
546 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
547 if (!NT_STATUS_IS_OK(result
))
550 result
= rpccli_samr_open_group(cli
, mem_ctx
, &dom_pol
,
551 des_access
, group_rid
, &group_pol
);
553 if (!NT_STATUS_IS_OK(result
))
556 /* Step #1: Get a list of user rids that are the members of the
559 result
= rpccli_samr_query_groupmem(cli
, mem_ctx
,
560 &group_pol
, num_names
, &rid_mem
,
563 rpccli_samr_close(cli
, mem_ctx
, &group_pol
);
565 if (!NT_STATUS_IS_OK(result
))
575 /* Step #2: Convert list of rids into list of usernames. Do this
576 in bunches of ~1000 to avoid crashing NT4. It looks like there
577 is a buffer overflow or something like that lurking around
580 #define MAX_LOOKUP_RIDS 900
582 *names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, *num_names
);
583 *name_types
= TALLOC_ZERO_ARRAY(mem_ctx
, uint32
, *num_names
);
584 *sid_mem
= TALLOC_ZERO_ARRAY(mem_ctx
, DOM_SID
, *num_names
);
586 for (j
=0;j
<(*num_names
);j
++)
587 sid_compose(&(*sid_mem
)[j
], &domain
->sid
, rid_mem
[j
]);
589 if (*num_names
>0 && (!*names
|| !*name_types
))
590 return NT_STATUS_NO_MEMORY
;
592 for (i
= 0; i
< *num_names
; i
+= MAX_LOOKUP_RIDS
) {
593 int num_lookup_rids
= MIN(*num_names
- i
, MAX_LOOKUP_RIDS
);
594 uint32 tmp_num_names
= 0;
595 char **tmp_names
= NULL
;
596 uint32
*tmp_types
= NULL
;
598 /* Lookup a chunk of rids */
600 result
= rpccli_samr_lookup_rids(cli
, mem_ctx
,
605 &tmp_names
, &tmp_types
);
607 /* see if we have a real error (and yes the
608 STATUS_SOME_UNMAPPED is the one returned from 2k) */
610 if (!NT_STATUS_IS_OK(result
) &&
611 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
))
614 /* Copy result into array. The talloc system will take
615 care of freeing the temporary arrays later on. */
617 memcpy(&(*names
)[i
], tmp_names
, sizeof(char *) *
620 memcpy(&(*name_types
)[i
], tmp_types
, sizeof(uint32
) *
623 total_names
+= tmp_num_names
;
626 *num_names
= total_names
;
635 static int get_ldap_seq(const char *server
, int port
, uint32
*seq
)
639 const char *attrs
[] = {"highestCommittedUSN", NULL
};
640 LDAPMessage
*res
= NULL
;
641 char **values
= NULL
;
644 *seq
= DOM_SEQUENCE_NONE
;
647 * Parameterised (5) second timeout on open. This is needed as the
648 * search timeout doesn't seem to apply to doing an open as well. JRA.
651 ldp
= ldap_open_with_timeout(server
, port
, lp_ldap_timeout());
655 /* Timeout if no response within 20 seconds. */
659 if (ldap_search_st(ldp
, "", LDAP_SCOPE_BASE
, "(objectclass=*)",
660 CONST_DISCARD(char **, attrs
), 0, &to
, &res
))
663 if (ldap_count_entries(ldp
, res
) != 1)
666 values
= ldap_get_values(ldp
, res
, "highestCommittedUSN");
667 if (!values
|| !values
[0])
670 *seq
= atoi(values
[0]);
676 ldap_value_free(values
);
684 /**********************************************************************
685 Get the sequence number for a Windows AD native mode domain using
687 **********************************************************************/
689 static int get_ldap_sequence_number( const char* domain
, uint32
*seq
)
692 int i
, port
= LDAP_PORT
;
693 struct ip_service
*ip_list
= NULL
;
696 if ( !get_sorted_dc_list(domain
, &ip_list
, &count
, False
) ) {
697 DEBUG(3, ("Could not look up dc's for domain %s\n", domain
));
701 /* Finally return first DC that we can contact */
703 for (i
= 0; i
< count
; i
++) {
706 /* since the is an LDAP lookup, default to the LDAP_PORT is
708 port
= (ip_list
[i
].port
!= PORT_NONE
) ?
709 ip_list
[i
].port
: LDAP_PORT
;
711 fstrcpy( ipstr
, inet_ntoa(ip_list
[i
].ip
) );
713 if (is_zero_ip(ip_list
[i
].ip
))
716 if ( (ret
= get_ldap_seq( ipstr
, port
, seq
)) == 0 )
719 /* add to failed connection cache */
720 add_failed_connection_entry( domain
, ipstr
,
721 NT_STATUS_UNSUCCESSFUL
);
726 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
727 "number for Domain (%s) from DC (%s:%d)\n",
728 domain
, inet_ntoa(ip_list
[i
].ip
), port
));
736 #endif /* HAVE_LDAP */
738 /* find the sequence number for a domain */
739 static NTSTATUS
sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
745 BOOL got_seq_num
= False
;
747 struct rpc_pipe_client
*cli
;
749 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain
->name
));
751 *seq
= DOM_SEQUENCE_NONE
;
753 if (!(mem_ctx
= talloc_init("sequence_number[rpc]")))
754 return NT_STATUS_NO_MEMORY
;
759 if ( domain
->native_mode
)
763 DEBUG(8,("using get_ldap_seq() to retrieve the "
764 "sequence number\n"));
766 res
= get_ldap_sequence_number( domain
->name
, seq
);
769 result
= NT_STATUS_OK
;
770 DEBUG(10,("domain_sequence_number: LDAP for "
772 domain
->name
, *seq
));
776 DEBUG(10,("domain_sequence_number: failed to get LDAP "
777 "sequence number for domain %s\n",
780 #endif /* HAVE_LDAP */
782 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
783 if (!NT_STATUS_IS_OK(result
)) {
787 /* Query domain info */
789 result
= rpccli_samr_query_dom_info(cli
, mem_ctx
, &dom_pol
, 8, &ctr
);
791 if (NT_STATUS_IS_OK(result
)) {
792 *seq
= ctr
.info
.inf8
.seq_num
.low
;
797 /* retry with info-level 2 in case the dc does not support info-level 8
798 * (like all older samba2 and samba3 dc's - Guenther */
800 result
= rpccli_samr_query_dom_info(cli
, mem_ctx
, &dom_pol
, 2, &ctr
);
802 if (NT_STATUS_IS_OK(result
)) {
803 *seq
= ctr
.info
.inf2
.seq_num
.low
;
809 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
810 domain
->name
, (unsigned)*seq
));
812 DEBUG(10,("domain_sequence_number: failed to get sequence "
813 "number (%u) for domain %s\n",
814 (unsigned)*seq
, domain
->name
));
819 talloc_destroy(mem_ctx
);
824 /* get a list of trusted domains */
825 static NTSTATUS
trusted_domains(struct winbindd_domain
*domain
,
832 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
834 struct rpc_pipe_client
*cli
;
835 POLICY_HND lsa_policy
;
837 DEBUG(3,("rpc: trusted_domains\n"));
844 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
845 if (!NT_STATUS_IS_OK(result
))
848 result
= STATUS_MORE_ENTRIES
;
850 while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
851 uint32 start_idx
, num
;
856 result
= rpccli_lsa_enum_trust_dom(cli
, mem_ctx
,
857 &lsa_policy
, &enum_ctx
,
861 if (!NT_STATUS_IS_OK(result
) &&
862 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
))
865 start_idx
= *num_domains
;
867 *names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *names
,
868 char *, *num_domains
);
869 *dom_sids
= TALLOC_REALLOC_ARRAY(mem_ctx
, *dom_sids
,
870 DOM_SID
, *num_domains
);
871 *alt_names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *alt_names
,
872 char *, *num_domains
);
873 if ((*names
== NULL
) || (*dom_sids
== NULL
) ||
874 (*alt_names
== NULL
))
875 return NT_STATUS_NO_MEMORY
;
877 for (i
=0; i
<num
; i
++) {
878 (*names
)[start_idx
+i
] = tmp_names
[i
];
879 (*dom_sids
)[start_idx
+i
] = tmp_sids
[i
];
880 (*alt_names
)[start_idx
+i
] = talloc_strdup(mem_ctx
, "");
886 /* find the lockout policy for a domain */
887 NTSTATUS
msrpc_lockout_policy(struct winbindd_domain
*domain
,
889 SAM_UNK_INFO_12
*lockout_policy
)
892 struct rpc_pipe_client
*cli
;
896 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain
->name
));
898 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
899 if (!NT_STATUS_IS_OK(result
)) {
903 result
= rpccli_samr_query_dom_info(cli
, mem_ctx
, &dom_pol
, 12, &ctr
);
904 if (!NT_STATUS_IS_OK(result
)) {
908 *lockout_policy
= ctr
.info
.inf12
;
910 DEBUG(10,("msrpc_lockout_policy: bad_attempt_lockout %d\n",
911 ctr
.info
.inf12
.bad_attempt_lockout
));
918 /* find the password policy for a domain */
919 NTSTATUS
msrpc_password_policy(struct winbindd_domain
*domain
,
921 SAM_UNK_INFO_1
*password_policy
)
924 struct rpc_pipe_client
*cli
;
928 DEBUG(10,("rpc: fetch password policy for %s\n", domain
->name
));
930 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
931 if (!NT_STATUS_IS_OK(result
)) {
935 result
= rpccli_samr_query_dom_info(cli
, mem_ctx
, &dom_pol
, 1, &ctr
);
936 if (!NT_STATUS_IS_OK(result
)) {
940 *password_policy
= ctr
.info
.inf1
;
942 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
943 ctr
.info
.inf1
.min_length_password
));
951 /* the rpc backend methods are exposed via this structure */
952 struct winbindd_methods msrpc_methods
= {
961 msrpc_lookup_useraliases
,
964 msrpc_lockout_policy
,
965 msrpc_password_policy
,