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 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
))
66 uint32 num_dom_users
, j
;
67 uint32 max_entries
, max_size
;
73 ctr
.sam
.info1
= &info1
;
75 if (!(ctx2
= talloc_init("winbindd enum_users")))
76 return NT_STATUS_NO_MEMORY
;
78 /* this next bit is copied from net_user_list_internal() */
80 get_query_dispinfo_params(loop_count
, &max_entries
,
83 result
= rpccli_samr_query_dispinfo(cli
, mem_ctx
, &dom_pol
,
86 max_entries
, max_size
,
91 *num_entries
+= num_dom_users
;
93 *info
= TALLOC_REALLOC_ARRAY(mem_ctx
, *info
, WINBIND_USERINFO
,
98 return NT_STATUS_NO_MEMORY
;
101 for (j
= 0; j
< num_dom_users
; i
++, j
++) {
102 fstring username
, fullname
;
103 uint32 rid
= ctr
.sam
.info1
->sam
[j
].rid_user
;
105 unistr2_to_ascii( username
, &(&ctr
.sam
.info1
->str
[j
])->uni_acct_name
, sizeof(username
)-1);
106 unistr2_to_ascii( fullname
, &(&ctr
.sam
.info1
->str
[j
])->uni_full_name
, sizeof(fullname
)-1);
108 (*info
)[i
].acct_name
= talloc_strdup(mem_ctx
, username
);
109 (*info
)[i
].full_name
= talloc_strdup(mem_ctx
, fullname
);
110 (*info
)[i
].homedir
= NULL
;
111 (*info
)[i
].shell
= NULL
;
112 sid_compose(&(*info
)[i
].user_sid
, &domain
->sid
, rid
);
114 /* For the moment we set the primary group for
115 every user to be the Domain Users group.
116 There are serious problems with determining
117 the actual primary group for large domains.
118 This should really be made into a 'winbind
119 force group' smb.conf parameter or
120 something like that. */
122 sid_compose(&(*info
)[i
].group_sid
, &domain
->sid
,
123 DOMAIN_GROUP_RID_USERS
);
126 talloc_destroy(ctx2
);
128 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
133 /* list all domain groups */
134 static NTSTATUS
enum_dom_groups(struct winbindd_domain
*domain
,
137 struct acct_info
**info
)
142 struct rpc_pipe_client
*cli
;
147 DEBUG(3,("rpc: enum_dom_groups\n"));
149 if ( !winbindd_can_contact_domain( domain
) ) {
150 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
155 status
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
156 if (!NT_STATUS_IS_OK(status
))
160 struct acct_info
*info2
= NULL
;
162 TALLOC_CTX
*mem_ctx2
;
164 mem_ctx2
= talloc_init("enum_dom_groups[rpc]");
166 /* start is updated by this call. */
167 status
= rpccli_samr_enum_dom_groups(cli
, mem_ctx2
, &dom_pol
,
169 0xFFFF, /* buffer size? */
172 if (!NT_STATUS_IS_OK(status
) &&
173 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
174 talloc_destroy(mem_ctx2
);
178 (*info
) = TALLOC_REALLOC_ARRAY(mem_ctx
, *info
,
180 (*num_entries
) + count
);
182 talloc_destroy(mem_ctx2
);
183 status
= NT_STATUS_NO_MEMORY
;
187 memcpy(&(*info
)[*num_entries
], info2
, count
*sizeof(*info2
));
188 (*num_entries
) += count
;
189 talloc_destroy(mem_ctx2
);
190 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
195 /* List all domain groups */
197 static NTSTATUS
enum_local_groups(struct winbindd_domain
*domain
,
200 struct acct_info
**info
)
204 struct rpc_pipe_client
*cli
;
209 DEBUG(3,("rpc: enum_local_groups\n"));
211 if ( !winbindd_can_contact_domain( domain
) ) {
212 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
217 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
218 if (!NT_STATUS_IS_OK(result
))
222 struct acct_info
*info2
= NULL
;
223 uint32 count
= 0, start
= *num_entries
;
224 TALLOC_CTX
*mem_ctx2
;
226 mem_ctx2
= talloc_init("enum_dom_local_groups[rpc]");
228 result
= rpccli_samr_enum_als_groups( cli
, mem_ctx2
, &dom_pol
,
229 &start
, 0xFFFF, &info2
,
232 if (!NT_STATUS_IS_OK(result
) &&
233 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
) )
235 talloc_destroy(mem_ctx2
);
239 (*info
) = TALLOC_REALLOC_ARRAY(mem_ctx
, *info
,
241 (*num_entries
) + count
);
243 talloc_destroy(mem_ctx2
);
244 return NT_STATUS_NO_MEMORY
;
247 memcpy(&(*info
)[*num_entries
], info2
, count
*sizeof(*info2
));
248 (*num_entries
) += count
;
249 talloc_destroy(mem_ctx2
);
251 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
256 /* convert a single name to a sid in a domain */
257 NTSTATUS
msrpc_name_to_sid(struct winbindd_domain
*domain
,
259 const char *domain_name
,
262 enum lsa_SidType
*type
)
265 DOM_SID
*sids
= NULL
;
266 enum lsa_SidType
*types
= NULL
;
267 char *full_name
= NULL
;
268 struct rpc_pipe_client
*cli
;
269 POLICY_HND lsa_policy
;
271 if(name
== NULL
|| *name
=='\0') {
272 DEBUG(3,("rpc: name_to_sid name=%s\n", domain_name
));
273 full_name
= talloc_asprintf(mem_ctx
, "%s", domain_name
);
275 DEBUG(3,("rpc: name_to_sid name=%s\\%s\n", domain_name
, name
));
276 full_name
= talloc_asprintf(mem_ctx
, "%s\\%s", domain_name
, name
);
279 DEBUG(0, ("talloc_asprintf failed!\n"));
280 return NT_STATUS_NO_MEMORY
;
283 ws_name_return( full_name
, WB_REPLACE_CHAR
);
285 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", full_name
?full_name
:"", domain_name
));
287 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
288 if (!NT_STATUS_IS_OK(result
))
291 result
= rpccli_lsa_lookup_names(cli
, mem_ctx
, &lsa_policy
, 1,
292 (const char**) &full_name
, NULL
, &sids
, &types
);
294 if (!NT_STATUS_IS_OK(result
))
297 /* Return rid and type if lookup successful */
299 sid_copy(sid
, &sids
[0]);
306 convert a domain SID to a user or group name
308 NTSTATUS
msrpc_sid_to_name(struct winbindd_domain
*domain
,
313 enum lsa_SidType
*type
)
317 enum lsa_SidType
*types
;
319 struct rpc_pipe_client
*cli
;
320 POLICY_HND lsa_policy
;
322 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_static(sid
),
325 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
326 if (!NT_STATUS_IS_OK(result
)) {
327 DEBUG(2,("msrpc_sid_to_name: cm_connect_lsa() failed (%s)\n",
333 result
= rpccli_lsa_lookup_sids(cli
, mem_ctx
, &lsa_policy
,
334 1, sid
, &domains
, &names
, &types
);
335 if (!NT_STATUS_IS_OK(result
)) {
336 DEBUG(2,("msrpc_sid_to_name: rpccli_lsa_lookup_sids() failed (%s)\n",
341 *type
= (enum lsa_SidType
)types
[0];
342 *domain_name
= domains
[0];
345 ws_name_replace( *name
, WB_REPLACE_CHAR
);
347 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains
[0], *name
));
351 NTSTATUS
msrpc_rids_to_names(struct winbindd_domain
*domain
,
358 enum lsa_SidType
**types
)
362 struct rpc_pipe_client
*cli
;
363 POLICY_HND lsa_policy
;
368 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain
->name
));
371 sids
= TALLOC_ARRAY(mem_ctx
, DOM_SID
, num_rids
);
373 return NT_STATUS_NO_MEMORY
;
379 for (i
=0; i
<num_rids
; i
++) {
380 if (!sid_compose(&sids
[i
], sid
, rids
[i
])) {
381 return NT_STATUS_INTERNAL_ERROR
;
385 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
386 if (!NT_STATUS_IS_OK(result
)) {
390 result
= rpccli_lsa_lookup_sids(cli
, mem_ctx
, &lsa_policy
,
391 num_rids
, sids
, &domains
,
393 if (!NT_STATUS_IS_OK(result
) &&
394 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
399 for (i
=0; i
<num_rids
; i
++) {
400 if ((*types
)[i
] != SID_NAME_UNKNOWN
) {
401 ws_name_replace( ret_names
[i
], WB_REPLACE_CHAR
);
402 *domain_name
= domains
[i
];
409 /* Lookup user information from a rid or username. */
410 static NTSTATUS
query_user(struct winbindd_domain
*domain
,
412 const DOM_SID
*user_sid
,
413 WINBIND_USERINFO
*user_info
)
415 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
416 POLICY_HND dom_pol
, user_pol
;
417 SAM_USERINFO_CTR
*ctr
;
420 NET_USER_INFO_3
*user
;
421 struct rpc_pipe_client
*cli
;
423 DEBUG(3,("rpc: query_user sid=%s\n",
424 sid_to_string(sid_string
, user_sid
)));
426 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
427 return NT_STATUS_UNSUCCESSFUL
;
429 user_info
->homedir
= NULL
;
430 user_info
->shell
= NULL
;
431 user_info
->primary_gid
= (gid_t
)-1;
433 /* try netsamlogon cache first */
435 if ( (user
= netsamlogon_cache_get( mem_ctx
, user_sid
)) != NULL
)
438 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
439 sid_string_static(user_sid
)));
441 sid_compose(&user_info
->user_sid
, &domain
->sid
, user_rid
);
442 sid_compose(&user_info
->group_sid
, &domain
->sid
,
445 user_info
->acct_name
= unistr2_tdup(mem_ctx
,
446 &user
->uni_user_name
);
447 user_info
->full_name
= unistr2_tdup(mem_ctx
,
448 &user
->uni_full_name
);
455 if ( !winbindd_can_contact_domain( domain
) ) {
456 DEBUG(10,("query_user: No incoming trust for domain %s\n",
461 /* no cache; hit the wire */
463 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
464 if (!NT_STATUS_IS_OK(result
))
467 /* Get user handle */
468 result
= rpccli_samr_open_user(cli
, mem_ctx
, &dom_pol
,
469 SEC_RIGHTS_MAXIMUM_ALLOWED
, user_rid
,
472 if (!NT_STATUS_IS_OK(result
))
476 result
= rpccli_samr_query_userinfo(cli
, mem_ctx
, &user_pol
,
479 rpccli_samr_close(cli
, mem_ctx
, &user_pol
);
481 if (!NT_STATUS_IS_OK(result
))
484 sid_compose(&user_info
->user_sid
, &domain
->sid
, user_rid
);
485 sid_compose(&user_info
->group_sid
, &domain
->sid
,
486 ctr
->info
.id21
->group_rid
);
487 user_info
->acct_name
= unistr2_tdup(mem_ctx
,
488 &ctr
->info
.id21
->uni_user_name
);
489 user_info
->full_name
= unistr2_tdup(mem_ctx
,
490 &ctr
->info
.id21
->uni_full_name
);
491 user_info
->homedir
= NULL
;
492 user_info
->shell
= NULL
;
493 user_info
->primary_gid
= (gid_t
)-1;
498 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
499 static NTSTATUS
lookup_usergroups(struct winbindd_domain
*domain
,
501 const DOM_SID
*user_sid
,
502 uint32
*num_groups
, DOM_SID
**user_grpsids
)
504 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
505 POLICY_HND dom_pol
, user_pol
;
506 uint32 des_access
= SEC_RIGHTS_MAXIMUM_ALLOWED
;
507 DOM_GID
*user_groups
;
511 struct rpc_pipe_client
*cli
;
513 DEBUG(3,("rpc: lookup_usergroups sid=%s\n",
514 sid_to_string(sid_string
, user_sid
)));
516 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
517 return NT_STATUS_UNSUCCESSFUL
;
520 *user_grpsids
= NULL
;
522 /* so lets see if we have a cached user_info_3 */
523 result
= lookup_usergroups_cached(domain
, mem_ctx
, user_sid
,
524 num_groups
, user_grpsids
);
526 if (NT_STATUS_IS_OK(result
)) {
530 if ( !winbindd_can_contact_domain( domain
) ) {
531 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
534 /* Tell the cache manager not to remember this one */
536 return NT_STATUS_SYNCHRONIZATION_REQUIRED
;
539 /* no cache; hit the wire */
541 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
542 if (!NT_STATUS_IS_OK(result
))
545 /* Get user handle */
546 result
= rpccli_samr_open_user(cli
, mem_ctx
, &dom_pol
,
547 des_access
, user_rid
, &user_pol
);
549 if (!NT_STATUS_IS_OK(result
))
552 /* Query user rids */
553 result
= rpccli_samr_query_usergroups(cli
, mem_ctx
, &user_pol
,
554 num_groups
, &user_groups
);
556 rpccli_samr_close(cli
, mem_ctx
, &user_pol
);
558 if (!NT_STATUS_IS_OK(result
) || (*num_groups
) == 0)
561 (*user_grpsids
) = TALLOC_ARRAY(mem_ctx
, DOM_SID
, *num_groups
);
562 if (!(*user_grpsids
))
563 return NT_STATUS_NO_MEMORY
;
565 for (i
=0;i
<(*num_groups
);i
++) {
566 sid_copy(&((*user_grpsids
)[i
]), &domain
->sid
);
567 sid_append_rid(&((*user_grpsids
)[i
]),
568 user_groups
[i
].g_rid
);
574 NTSTATUS
msrpc_lookup_useraliases(struct winbindd_domain
*domain
,
576 uint32 num_sids
, const DOM_SID
*sids
,
577 uint32
*num_aliases
, uint32
**alias_rids
)
579 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
581 DOM_SID2
*query_sids
;
582 uint32 num_query_sids
= 0;
584 struct rpc_pipe_client
*cli
;
585 uint32
*alias_rids_query
, num_aliases_query
;
586 int rangesize
= MAX_SAM_ENTRIES_W2K
;
587 uint32 total_sids
= 0;
593 DEBUG(3,("rpc: lookup_useraliases\n"));
595 if ( !winbindd_can_contact_domain( domain
) ) {
596 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
601 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
602 if (!NT_STATUS_IS_OK(result
))
608 num_query_sids
= MIN(num_sids
- total_sids
, rangesize
);
610 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
611 num_queries
, num_query_sids
));
613 if (num_query_sids
) {
614 query_sids
= TALLOC_ARRAY(mem_ctx
, DOM_SID2
, num_query_sids
);
615 if (query_sids
== NULL
) {
616 return NT_STATUS_NO_MEMORY
;
622 for (i
=0; i
<num_query_sids
; i
++) {
623 sid_copy(&query_sids
[i
].sid
, &sids
[total_sids
++]);
624 query_sids
[i
].num_auths
= query_sids
[i
].sid
.num_auths
;
629 result
= rpccli_samr_query_useraliases(cli
, mem_ctx
, &dom_pol
,
630 num_query_sids
, query_sids
,
634 if (!NT_STATUS_IS_OK(result
)) {
637 TALLOC_FREE(query_sids
);
643 for (i
=0; i
<num_aliases_query
; i
++) {
644 size_t na
= *num_aliases
;
645 if (!add_rid_to_array_unique(mem_ctx
, alias_rids_query
[i
],
647 return NT_STATUS_NO_MEMORY
;
652 TALLOC_FREE(query_sids
);
656 } while (total_sids
< num_sids
);
659 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
660 "(rangesize: %d)\n", *num_aliases
, num_queries
, rangesize
));
666 /* Lookup group membership given a rid. */
667 static NTSTATUS
lookup_groupmem(struct winbindd_domain
*domain
,
669 const DOM_SID
*group_sid
, uint32
*num_names
,
670 DOM_SID
**sid_mem
, char ***names
,
673 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
674 uint32 i
, total_names
= 0;
675 POLICY_HND dom_pol
, group_pol
;
676 uint32 des_access
= SEC_RIGHTS_MAXIMUM_ALLOWED
;
677 uint32
*rid_mem
= NULL
;
681 struct rpc_pipe_client
*cli
;
682 unsigned int orig_timeout
;
684 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain
->name
,
685 sid_to_string(sid_string
, group_sid
)));
687 if ( !winbindd_can_contact_domain( domain
) ) {
688 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
693 if (!sid_peek_check_rid(&domain
->sid
, group_sid
, &group_rid
))
694 return NT_STATUS_UNSUCCESSFUL
;
698 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
699 if (!NT_STATUS_IS_OK(result
))
702 result
= rpccli_samr_open_group(cli
, mem_ctx
, &dom_pol
,
703 des_access
, group_rid
, &group_pol
);
705 if (!NT_STATUS_IS_OK(result
))
708 /* Step #1: Get a list of user rids that are the members of the
711 /* This call can take a long time - allow the server to time out.
712 35 seconds should do it. */
714 orig_timeout
= cli_set_timeout(cli
->cli
, 35000);
716 result
= rpccli_samr_query_groupmem(cli
, mem_ctx
,
717 &group_pol
, num_names
, &rid_mem
,
720 /* And restore our original timeout. */
721 cli_set_timeout(cli
->cli
, orig_timeout
);
723 rpccli_samr_close(cli
, mem_ctx
, &group_pol
);
725 if (!NT_STATUS_IS_OK(result
))
735 /* Step #2: Convert list of rids into list of usernames. Do this
736 in bunches of ~1000 to avoid crashing NT4. It looks like there
737 is a buffer overflow or something like that lurking around
740 #define MAX_LOOKUP_RIDS 900
742 *names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, *num_names
);
743 *name_types
= TALLOC_ZERO_ARRAY(mem_ctx
, uint32
, *num_names
);
744 *sid_mem
= TALLOC_ZERO_ARRAY(mem_ctx
, DOM_SID
, *num_names
);
746 for (j
=0;j
<(*num_names
);j
++)
747 sid_compose(&(*sid_mem
)[j
], &domain
->sid
, rid_mem
[j
]);
749 if (*num_names
>0 && (!*names
|| !*name_types
))
750 return NT_STATUS_NO_MEMORY
;
752 for (i
= 0; i
< *num_names
; i
+= MAX_LOOKUP_RIDS
) {
753 int num_lookup_rids
= MIN(*num_names
- i
, MAX_LOOKUP_RIDS
);
754 uint32 tmp_num_names
= 0;
755 char **tmp_names
= NULL
;
756 uint32
*tmp_types
= NULL
;
758 /* Lookup a chunk of rids */
760 result
= rpccli_samr_lookup_rids(cli
, mem_ctx
,
765 &tmp_names
, &tmp_types
);
767 /* see if we have a real error (and yes the
768 STATUS_SOME_UNMAPPED is the one returned from 2k) */
770 if (!NT_STATUS_IS_OK(result
) &&
771 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
))
774 /* Copy result into array. The talloc system will take
775 care of freeing the temporary arrays later on. */
777 memcpy(&(*names
)[i
], tmp_names
, sizeof(char *) *
780 memcpy(&(*name_types
)[i
], tmp_types
, sizeof(uint32
) *
783 total_names
+= tmp_num_names
;
786 *num_names
= total_names
;
795 static int get_ldap_seq(const char *server
, int port
, uint32
*seq
)
799 const char *attrs
[] = {"highestCommittedUSN", NULL
};
800 LDAPMessage
*res
= NULL
;
801 char **values
= NULL
;
804 *seq
= DOM_SEQUENCE_NONE
;
807 * Parameterised (5) second timeout on open. This is needed as the
808 * search timeout doesn't seem to apply to doing an open as well. JRA.
811 ldp
= ldap_open_with_timeout(server
, port
, lp_ldap_timeout());
815 /* Timeout if no response within 20 seconds. */
819 if (ldap_search_st(ldp
, "", LDAP_SCOPE_BASE
, "(objectclass=*)",
820 CONST_DISCARD(char **, attrs
), 0, &to
, &res
))
823 if (ldap_count_entries(ldp
, res
) != 1)
826 values
= ldap_get_values(ldp
, res
, "highestCommittedUSN");
827 if (!values
|| !values
[0])
830 *seq
= atoi(values
[0]);
836 ldap_value_free(values
);
844 /**********************************************************************
845 Get the sequence number for a Windows AD native mode domain using
847 **********************************************************************/
849 static int get_ldap_sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
854 fstrcpy( ipstr
, inet_ntoa(domain
->dcaddr
.sin_addr
));
855 if ((ret
= get_ldap_seq( ipstr
, LDAP_PORT
, seq
)) == 0) {
856 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
857 "number for Domain (%s) from DC (%s)\n",
858 domain
->name
, ipstr
));
863 #endif /* HAVE_LDAP */
865 /* find the sequence number for a domain */
866 static NTSTATUS
sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
872 BOOL got_seq_num
= False
;
873 struct rpc_pipe_client
*cli
;
875 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain
->name
));
877 if ( !winbindd_can_contact_domain( domain
) ) {
878 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
884 *seq
= DOM_SEQUENCE_NONE
;
886 if (!(mem_ctx
= talloc_init("sequence_number[rpc]")))
887 return NT_STATUS_NO_MEMORY
;
890 if ( domain
->active_directory
)
894 DEBUG(8,("using get_ldap_seq() to retrieve the "
895 "sequence number\n"));
897 res
= get_ldap_sequence_number( domain
, seq
);
900 result
= NT_STATUS_OK
;
901 DEBUG(10,("domain_sequence_number: LDAP for "
903 domain
->name
, *seq
));
907 DEBUG(10,("domain_sequence_number: failed to get LDAP "
908 "sequence number for domain %s\n",
911 #endif /* HAVE_LDAP */
913 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
914 if (!NT_STATUS_IS_OK(result
)) {
918 /* Query domain info */
920 result
= rpccli_samr_query_dom_info(cli
, mem_ctx
, &dom_pol
, 8, &ctr
);
922 if (NT_STATUS_IS_OK(result
)) {
923 *seq
= ctr
.info
.inf8
.seq_num
;
928 /* retry with info-level 2 in case the dc does not support info-level 8
929 * (like all older samba2 and samba3 dc's - Guenther */
931 result
= rpccli_samr_query_dom_info(cli
, mem_ctx
, &dom_pol
, 2, &ctr
);
933 if (NT_STATUS_IS_OK(result
)) {
934 *seq
= ctr
.info
.inf2
.seq_num
;
940 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
941 domain
->name
, (unsigned)*seq
));
943 DEBUG(10,("domain_sequence_number: failed to get sequence "
944 "number (%u) for domain %s\n",
945 (unsigned)*seq
, domain
->name
));
950 talloc_destroy(mem_ctx
);
955 /* get a list of trusted domains */
956 static NTSTATUS
trusted_domains(struct winbindd_domain
*domain
,
963 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
965 struct rpc_pipe_client
*cli
;
966 POLICY_HND lsa_policy
;
968 DEBUG(3,("rpc: trusted_domains\n"));
975 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
976 if (!NT_STATUS_IS_OK(result
))
979 result
= STATUS_MORE_ENTRIES
;
981 while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
982 uint32 start_idx
, num
;
987 result
= rpccli_lsa_enum_trust_dom(cli
, mem_ctx
,
988 &lsa_policy
, &enum_ctx
,
992 if (!NT_STATUS_IS_OK(result
) &&
993 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
))
996 start_idx
= *num_domains
;
998 *names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *names
,
999 char *, *num_domains
);
1000 *dom_sids
= TALLOC_REALLOC_ARRAY(mem_ctx
, *dom_sids
,
1001 DOM_SID
, *num_domains
);
1002 *alt_names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *alt_names
,
1003 char *, *num_domains
);
1004 if ((*names
== NULL
) || (*dom_sids
== NULL
) ||
1005 (*alt_names
== NULL
))
1006 return NT_STATUS_NO_MEMORY
;
1008 for (i
=0; i
<num
; i
++) {
1009 (*names
)[start_idx
+i
] = tmp_names
[i
];
1010 (*dom_sids
)[start_idx
+i
] = tmp_sids
[i
];
1011 (*alt_names
)[start_idx
+i
] = talloc_strdup(mem_ctx
, "");
1017 /* find the lockout policy for a domain */
1018 NTSTATUS
msrpc_lockout_policy(struct winbindd_domain
*domain
,
1019 TALLOC_CTX
*mem_ctx
,
1020 SAM_UNK_INFO_12
*lockout_policy
)
1023 struct rpc_pipe_client
*cli
;
1027 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain
->name
));
1029 if ( !winbindd_can_contact_domain( domain
) ) {
1030 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1032 return NT_STATUS_NOT_SUPPORTED
;
1035 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1036 if (!NT_STATUS_IS_OK(result
)) {
1040 result
= rpccli_samr_query_dom_info(cli
, mem_ctx
, &dom_pol
, 12, &ctr
);
1041 if (!NT_STATUS_IS_OK(result
)) {
1045 *lockout_policy
= ctr
.info
.inf12
;
1047 DEBUG(10,("msrpc_lockout_policy: bad_attempt_lockout %d\n",
1048 ctr
.info
.inf12
.bad_attempt_lockout
));
1055 /* find the password policy for a domain */
1056 NTSTATUS
msrpc_password_policy(struct winbindd_domain
*domain
,
1057 TALLOC_CTX
*mem_ctx
,
1058 SAM_UNK_INFO_1
*password_policy
)
1061 struct rpc_pipe_client
*cli
;
1065 DEBUG(10,("rpc: fetch password policy for %s\n", domain
->name
));
1067 if ( !winbindd_can_contact_domain( domain
) ) {
1068 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1070 return NT_STATUS_NOT_SUPPORTED
;
1073 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1074 if (!NT_STATUS_IS_OK(result
)) {
1078 result
= rpccli_samr_query_dom_info(cli
, mem_ctx
, &dom_pol
, 1, &ctr
);
1079 if (!NT_STATUS_IS_OK(result
)) {
1083 *password_policy
= ctr
.info
.inf1
;
1085 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1086 ctr
.info
.inf1
.min_length_password
));
1094 /* the rpc backend methods are exposed via this structure */
1095 struct winbindd_methods msrpc_methods
= {
1102 msrpc_rids_to_names
,
1105 msrpc_lookup_useraliases
,
1108 msrpc_lockout_policy
,
1109 msrpc_password_policy
,