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
9 Copyright (C) Guenther Deschner 2008 (pidl conversion)
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include "../librpc/gen_ndr/cli_samr.h"
28 #include "../librpc/gen_ndr/cli_lsa.h"
31 #define DBGC_CLASS DBGC_WINBIND
34 /* Query display info for a domain. This returns enough information plus a
35 bit extra to give an overview of domain users for the User Manager
37 static NTSTATUS
query_user_list(struct winbindd_domain
*domain
,
40 struct wbint_userinfo
**info
)
43 struct policy_handle dom_pol
;
44 unsigned int i
, start_idx
;
46 struct rpc_pipe_client
*cli
;
48 DEBUG(3,("rpc: query_user_list\n"));
53 if ( !winbindd_can_contact_domain( domain
) ) {
54 DEBUG(10,("query_user_list: No incoming trust for domain %s\n",
59 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
60 if (!NT_STATUS_IS_OK(result
))
67 uint32 num_dom_users
, j
;
68 uint32 max_entries
, max_size
;
69 uint32_t total_size
, returned_size
;
71 union samr_DispInfo disp_info
;
73 /* this next bit is copied from net_user_list_internal() */
75 get_query_dispinfo_params(loop_count
, &max_entries
,
78 result
= rpccli_samr_QueryDisplayInfo(cli
, mem_ctx
,
88 if (!NT_STATUS_IS_OK(result
)) {
89 if (!NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
94 num_dom_users
= disp_info
.info1
.count
;
95 start_idx
+= disp_info
.info1
.count
;
98 *num_entries
+= num_dom_users
;
100 *info
= TALLOC_REALLOC_ARRAY(mem_ctx
, *info
,
101 struct wbint_userinfo
,
105 return NT_STATUS_NO_MEMORY
;
108 for (j
= 0; j
< num_dom_users
; i
++, j
++) {
110 uint32_t rid
= disp_info
.info1
.entries
[j
].rid
;
112 (*info
)[i
].acct_name
= talloc_strdup(mem_ctx
,
113 disp_info
.info1
.entries
[j
].account_name
.string
);
114 (*info
)[i
].full_name
= talloc_strdup(mem_ctx
,
115 disp_info
.info1
.entries
[j
].full_name
.string
);
116 (*info
)[i
].homedir
= NULL
;
117 (*info
)[i
].shell
= NULL
;
118 sid_compose(&(*info
)[i
].user_sid
, &domain
->sid
, rid
);
120 /* For the moment we set the primary group for
121 every user to be the Domain Users group.
122 There are serious problems with determining
123 the actual primary group for large domains.
124 This should really be made into a 'winbind
125 force group' smb.conf parameter or
126 something like that. */
128 sid_compose(&(*info
)[i
].group_sid
, &domain
->sid
,
129 DOMAIN_GROUP_RID_USERS
);
132 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
137 /* list all domain groups */
138 static NTSTATUS
enum_dom_groups(struct winbindd_domain
*domain
,
141 struct acct_info
**info
)
143 struct policy_handle dom_pol
;
146 struct rpc_pipe_client
*cli
;
151 DEBUG(3,("rpc: enum_dom_groups\n"));
153 if ( !winbindd_can_contact_domain( domain
) ) {
154 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
159 status
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
160 if (!NT_STATUS_IS_OK(status
))
164 struct samr_SamArray
*sam_array
= NULL
;
166 TALLOC_CTX
*mem_ctx2
;
169 mem_ctx2
= talloc_init("enum_dom_groups[rpc]");
171 /* start is updated by this call. */
172 status
= rpccli_samr_EnumDomainGroups(cli
, mem_ctx2
,
176 0xFFFF, /* buffer size? */
179 if (!NT_STATUS_IS_OK(status
) &&
180 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
181 talloc_destroy(mem_ctx2
);
185 (*info
) = TALLOC_REALLOC_ARRAY(mem_ctx
, *info
,
187 (*num_entries
) + count
);
189 talloc_destroy(mem_ctx2
);
190 return NT_STATUS_NO_MEMORY
;
193 for (g
=0; g
< count
; g
++) {
195 fstrcpy((*info
)[*num_entries
+ g
].acct_name
,
196 sam_array
->entries
[g
].name
.string
);
197 (*info
)[*num_entries
+ g
].rid
= sam_array
->entries
[g
].idx
;
200 (*num_entries
) += count
;
201 talloc_destroy(mem_ctx2
);
202 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
207 /* List all domain groups */
209 static NTSTATUS
enum_local_groups(struct winbindd_domain
*domain
,
212 struct acct_info
**info
)
214 struct policy_handle dom_pol
;
216 struct rpc_pipe_client
*cli
;
221 DEBUG(3,("rpc: enum_local_groups\n"));
223 if ( !winbindd_can_contact_domain( domain
) ) {
224 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
229 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
230 if (!NT_STATUS_IS_OK(result
))
234 struct samr_SamArray
*sam_array
= NULL
;
235 uint32 count
= 0, start
= *num_entries
;
236 TALLOC_CTX
*mem_ctx2
;
239 mem_ctx2
= talloc_init("enum_dom_local_groups[rpc]");
241 result
= rpccli_samr_EnumDomainAliases(cli
, mem_ctx2
,
245 0xFFFF, /* buffer size? */
247 if (!NT_STATUS_IS_OK(result
) &&
248 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
) )
250 talloc_destroy(mem_ctx2
);
254 (*info
) = TALLOC_REALLOC_ARRAY(mem_ctx
, *info
,
256 (*num_entries
) + count
);
258 talloc_destroy(mem_ctx2
);
259 return NT_STATUS_NO_MEMORY
;
262 for (g
=0; g
< count
; g
++) {
264 fstrcpy((*info
)[*num_entries
+ g
].acct_name
,
265 sam_array
->entries
[g
].name
.string
);
266 (*info
)[*num_entries
+ g
].rid
= sam_array
->entries
[g
].idx
;
269 (*num_entries
) += count
;
270 talloc_destroy(mem_ctx2
);
272 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
277 /* convert a single name to a sid in a domain */
278 static NTSTATUS
msrpc_name_to_sid(struct winbindd_domain
*domain
,
280 const char *domain_name
,
284 enum lsa_SidType
*type
)
287 DOM_SID
*sids
= NULL
;
288 enum lsa_SidType
*types
= NULL
;
289 char *full_name
= NULL
;
290 NTSTATUS name_map_status
= NT_STATUS_UNSUCCESSFUL
;
291 char *mapped_name
= NULL
;
293 if (name
== NULL
|| *name
=='\0') {
294 full_name
= talloc_asprintf(mem_ctx
, "%s", domain_name
);
295 } else if (domain_name
== NULL
|| *domain_name
== '\0') {
296 full_name
= talloc_asprintf(mem_ctx
, "%s", name
);
298 full_name
= talloc_asprintf(mem_ctx
, "%s\\%s", domain_name
, name
);
301 DEBUG(0, ("talloc_asprintf failed!\n"));
302 return NT_STATUS_NO_MEMORY
;
305 DEBUG(3,("rpc: name_to_sid name=%s\n", full_name
));
307 name_map_status
= normalize_name_unmap(mem_ctx
, full_name
,
310 /* Reset the full_name pointer if we mapped anytthing */
312 if (NT_STATUS_IS_OK(name_map_status
) ||
313 NT_STATUS_EQUAL(name_map_status
, NT_STATUS_FILE_RENAMED
))
315 full_name
= mapped_name
;
318 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
319 full_name
?full_name
:"", domain_name
));
321 result
= winbindd_lookup_names(mem_ctx
, domain
, 1,
322 (const char **)&full_name
, NULL
,
324 if (!NT_STATUS_IS_OK(result
))
327 /* Return rid and type if lookup successful */
329 sid_copy(sid
, &sids
[0]);
336 convert a domain SID to a user or group name
338 static NTSTATUS
msrpc_sid_to_name(struct winbindd_domain
*domain
,
343 enum lsa_SidType
*type
)
347 enum lsa_SidType
*types
= NULL
;
349 NTSTATUS name_map_status
= NT_STATUS_UNSUCCESSFUL
;
350 char *mapped_name
= NULL
;
352 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid
),
355 result
= winbindd_lookup_sids(mem_ctx
,
362 if (!NT_STATUS_IS_OK(result
)) {
363 DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n",
369 *type
= (enum lsa_SidType
)types
[0];
370 *domain_name
= domains
[0];
373 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains
[0], *name
));
375 name_map_status
= normalize_name_map(mem_ctx
, domain
, *name
,
377 if (NT_STATUS_IS_OK(name_map_status
) ||
378 NT_STATUS_EQUAL(name_map_status
, NT_STATUS_FILE_RENAMED
))
381 DEBUG(5,("returning mapped name -- %s\n", *name
));
387 static NTSTATUS
msrpc_rids_to_names(struct winbindd_domain
*domain
,
394 enum lsa_SidType
**types
)
402 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain
->name
));
405 sids
= TALLOC_ARRAY(mem_ctx
, DOM_SID
, num_rids
);
407 return NT_STATUS_NO_MEMORY
;
413 for (i
=0; i
<num_rids
; i
++) {
414 if (!sid_compose(&sids
[i
], sid
, rids
[i
])) {
415 return NT_STATUS_INTERNAL_ERROR
;
419 result
= winbindd_lookup_sids(mem_ctx
,
427 if (!NT_STATUS_IS_OK(result
) &&
428 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
433 for (i
=0; i
<num_rids
; i
++) {
434 NTSTATUS name_map_status
= NT_STATUS_UNSUCCESSFUL
;
435 char *mapped_name
= NULL
;
437 if ((*types
)[i
] != SID_NAME_UNKNOWN
) {
438 name_map_status
= normalize_name_map(mem_ctx
,
442 if (NT_STATUS_IS_OK(name_map_status
) ||
443 NT_STATUS_EQUAL(name_map_status
, NT_STATUS_FILE_RENAMED
))
445 ret_names
[i
] = mapped_name
;
448 *domain_name
= domains
[i
];
455 /* Lookup user information from a rid or username. */
456 static NTSTATUS
query_user(struct winbindd_domain
*domain
,
458 const DOM_SID
*user_sid
,
459 struct wbint_userinfo
*user_info
)
461 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
462 struct policy_handle dom_pol
, user_pol
;
463 union samr_UserInfo
*info
= NULL
;
465 struct netr_SamInfo3
*user
;
466 struct rpc_pipe_client
*cli
;
468 DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid
)));
470 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
471 return NT_STATUS_UNSUCCESSFUL
;
473 user_info
->homedir
= NULL
;
474 user_info
->shell
= NULL
;
475 user_info
->primary_gid
= (gid_t
)-1;
477 /* try netsamlogon cache first */
479 if ( (user
= netsamlogon_cache_get( mem_ctx
, user_sid
)) != NULL
)
482 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
483 sid_string_dbg(user_sid
)));
485 sid_compose(&user_info
->user_sid
, &domain
->sid
, user
->base
.rid
);
486 sid_compose(&user_info
->group_sid
, &domain
->sid
,
487 user
->base
.primary_gid
);
489 user_info
->acct_name
= talloc_strdup(mem_ctx
,
490 user
->base
.account_name
.string
);
491 user_info
->full_name
= talloc_strdup(mem_ctx
,
492 user
->base
.full_name
.string
);
499 if ( !winbindd_can_contact_domain( domain
) ) {
500 DEBUG(10,("query_user: No incoming trust for domain %s\n",
505 /* no cache; hit the wire */
507 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
508 if (!NT_STATUS_IS_OK(result
))
511 /* Get user handle */
512 result
= rpccli_samr_OpenUser(cli
, mem_ctx
,
514 SEC_FLAG_MAXIMUM_ALLOWED
,
518 if (!NT_STATUS_IS_OK(result
))
522 result
= rpccli_samr_QueryUserInfo(cli
, mem_ctx
,
527 rpccli_samr_Close(cli
, mem_ctx
, &user_pol
);
529 if (!NT_STATUS_IS_OK(result
))
532 sid_compose(&user_info
->user_sid
, &domain
->sid
, user_rid
);
533 sid_compose(&user_info
->group_sid
, &domain
->sid
,
534 info
->info21
.primary_gid
);
535 user_info
->acct_name
= talloc_strdup(mem_ctx
,
536 info
->info21
.account_name
.string
);
537 user_info
->full_name
= talloc_strdup(mem_ctx
,
538 info
->info21
.full_name
.string
);
539 user_info
->homedir
= NULL
;
540 user_info
->shell
= NULL
;
541 user_info
->primary_gid
= (gid_t
)-1;
546 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
547 static NTSTATUS
lookup_usergroups(struct winbindd_domain
*domain
,
549 const DOM_SID
*user_sid
,
550 uint32
*num_groups
, DOM_SID
**user_grpsids
)
552 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
553 struct policy_handle dom_pol
, user_pol
;
554 uint32 des_access
= SEC_FLAG_MAXIMUM_ALLOWED
;
555 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
558 struct rpc_pipe_client
*cli
;
560 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid
)));
562 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
563 return NT_STATUS_UNSUCCESSFUL
;
566 *user_grpsids
= NULL
;
568 /* so lets see if we have a cached user_info_3 */
569 result
= lookup_usergroups_cached(domain
, mem_ctx
, user_sid
,
570 num_groups
, user_grpsids
);
572 if (NT_STATUS_IS_OK(result
)) {
576 if ( !winbindd_can_contact_domain( domain
) ) {
577 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
580 /* Tell the cache manager not to remember this one */
582 return NT_STATUS_SYNCHRONIZATION_REQUIRED
;
585 /* no cache; hit the wire */
587 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
588 if (!NT_STATUS_IS_OK(result
))
591 /* Get user handle */
592 result
= rpccli_samr_OpenUser(cli
, mem_ctx
,
598 if (!NT_STATUS_IS_OK(result
))
601 /* Query user rids */
602 result
= rpccli_samr_GetGroupsForUser(cli
, mem_ctx
,
605 *num_groups
= rid_array
->count
;
607 rpccli_samr_Close(cli
, mem_ctx
, &user_pol
);
609 if (!NT_STATUS_IS_OK(result
) || (*num_groups
) == 0)
612 (*user_grpsids
) = TALLOC_ARRAY(mem_ctx
, DOM_SID
, *num_groups
);
613 if (!(*user_grpsids
))
614 return NT_STATUS_NO_MEMORY
;
616 for (i
=0;i
<(*num_groups
);i
++) {
617 sid_copy(&((*user_grpsids
)[i
]), &domain
->sid
);
618 sid_append_rid(&((*user_grpsids
)[i
]),
619 rid_array
->rids
[i
].rid
);
625 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
627 static NTSTATUS
msrpc_lookup_useraliases(struct winbindd_domain
*domain
,
629 uint32 num_sids
, const DOM_SID
*sids
,
633 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
634 struct policy_handle dom_pol
;
635 uint32 num_query_sids
= 0;
637 struct rpc_pipe_client
*cli
;
638 struct samr_Ids alias_rids_query
;
639 int rangesize
= MAX_SAM_ENTRIES_W2K
;
640 uint32 total_sids
= 0;
646 DEBUG(3,("rpc: lookup_useraliases\n"));
648 if ( !winbindd_can_contact_domain( domain
) ) {
649 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
654 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
655 if (!NT_STATUS_IS_OK(result
))
660 struct lsa_SidArray sid_array
;
662 ZERO_STRUCT(sid_array
);
664 num_query_sids
= MIN(num_sids
- total_sids
, rangesize
);
666 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
667 num_queries
, num_query_sids
));
669 if (num_query_sids
) {
670 sid_array
.sids
= TALLOC_ZERO_ARRAY(mem_ctx
, struct lsa_SidPtr
, num_query_sids
);
671 if (sid_array
.sids
== NULL
) {
672 return NT_STATUS_NO_MEMORY
;
675 sid_array
.sids
= NULL
;
678 for (i
=0; i
<num_query_sids
; i
++) {
679 sid_array
.sids
[i
].sid
= sid_dup_talloc(mem_ctx
, &sids
[total_sids
++]);
680 if (!sid_array
.sids
[i
].sid
) {
681 TALLOC_FREE(sid_array
.sids
);
682 return NT_STATUS_NO_MEMORY
;
685 sid_array
.num_sids
= num_query_sids
;
688 result
= rpccli_samr_GetAliasMembership(cli
, mem_ctx
,
693 if (!NT_STATUS_IS_OK(result
)) {
696 TALLOC_FREE(sid_array
.sids
);
702 for (i
=0; i
<alias_rids_query
.count
; i
++) {
703 size_t na
= *num_aliases
;
704 if (!add_rid_to_array_unique(mem_ctx
, alias_rids_query
.ids
[i
],
706 return NT_STATUS_NO_MEMORY
;
711 TALLOC_FREE(sid_array
.sids
);
715 } while (total_sids
< num_sids
);
718 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
719 "(rangesize: %d)\n", *num_aliases
, num_queries
, rangesize
));
725 /* Lookup group membership given a rid. */
726 static NTSTATUS
lookup_groupmem(struct winbindd_domain
*domain
,
728 const DOM_SID
*group_sid
,
729 enum lsa_SidType type
,
731 DOM_SID
**sid_mem
, char ***names
,
734 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
735 uint32 i
, total_names
= 0;
736 struct policy_handle dom_pol
, group_pol
;
737 uint32 des_access
= SEC_FLAG_MAXIMUM_ALLOWED
;
738 uint32
*rid_mem
= NULL
;
741 struct rpc_pipe_client
*cli
;
742 unsigned int orig_timeout
;
743 struct samr_RidTypeArray
*rids
= NULL
;
745 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain
->name
,
746 sid_string_dbg(group_sid
)));
748 if ( !winbindd_can_contact_domain( domain
) ) {
749 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
754 if (!sid_peek_check_rid(&domain
->sid
, group_sid
, &group_rid
))
755 return NT_STATUS_UNSUCCESSFUL
;
759 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
760 if (!NT_STATUS_IS_OK(result
))
763 result
= rpccli_samr_OpenGroup(cli
, mem_ctx
,
769 if (!NT_STATUS_IS_OK(result
))
772 /* Step #1: Get a list of user rids that are the members of the
775 /* This call can take a long time - allow the server to time out.
776 35 seconds should do it. */
778 orig_timeout
= rpccli_set_timeout(cli
, 35000);
780 result
= rpccli_samr_QueryGroupMember(cli
, mem_ctx
,
784 /* And restore our original timeout. */
785 rpccli_set_timeout(cli
, orig_timeout
);
787 rpccli_samr_Close(cli
, mem_ctx
, &group_pol
);
789 if (!NT_STATUS_IS_OK(result
))
792 if (!rids
|| !rids
->count
) {
799 *num_names
= rids
->count
;
800 rid_mem
= rids
->rids
;
802 /* Step #2: Convert list of rids into list of usernames. Do this
803 in bunches of ~1000 to avoid crashing NT4. It looks like there
804 is a buffer overflow or something like that lurking around
807 #define MAX_LOOKUP_RIDS 900
809 *names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, *num_names
);
810 *name_types
= TALLOC_ZERO_ARRAY(mem_ctx
, uint32
, *num_names
);
811 *sid_mem
= TALLOC_ZERO_ARRAY(mem_ctx
, DOM_SID
, *num_names
);
813 for (j
=0;j
<(*num_names
);j
++)
814 sid_compose(&(*sid_mem
)[j
], &domain
->sid
, rid_mem
[j
]);
816 if (*num_names
>0 && (!*names
|| !*name_types
))
817 return NT_STATUS_NO_MEMORY
;
819 for (i
= 0; i
< *num_names
; i
+= MAX_LOOKUP_RIDS
) {
820 int num_lookup_rids
= MIN(*num_names
- i
, MAX_LOOKUP_RIDS
);
821 struct lsa_Strings tmp_names
;
822 struct samr_Ids tmp_types
;
824 /* Lookup a chunk of rids */
826 result
= rpccli_samr_LookupRids(cli
, mem_ctx
,
833 /* see if we have a real error (and yes the
834 STATUS_SOME_UNMAPPED is the one returned from 2k) */
836 if (!NT_STATUS_IS_OK(result
) &&
837 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
))
840 /* Copy result into array. The talloc system will take
841 care of freeing the temporary arrays later on. */
843 if (tmp_names
.count
!= tmp_types
.count
) {
844 return NT_STATUS_UNSUCCESSFUL
;
847 for (r
=0; r
<tmp_names
.count
; r
++) {
848 if (tmp_types
.ids
[r
] == SID_NAME_UNKNOWN
) {
851 (*names
)[total_names
] = fill_domain_username_talloc(
852 mem_ctx
, domain
->name
,
853 tmp_names
.names
[r
].string
, true);
854 (*name_types
)[total_names
] = tmp_types
.ids
[r
];
859 *num_names
= total_names
;
868 static int get_ldap_seq(const char *server
, int port
, uint32
*seq
)
872 const char *attrs
[] = {"highestCommittedUSN", NULL
};
873 LDAPMessage
*res
= NULL
;
874 char **values
= NULL
;
877 *seq
= DOM_SEQUENCE_NONE
;
880 * Parameterised (5) second timeout on open. This is needed as the
881 * search timeout doesn't seem to apply to doing an open as well. JRA.
884 ldp
= ldap_open_with_timeout(server
, port
, lp_ldap_timeout());
888 /* Timeout if no response within 20 seconds. */
892 if (ldap_search_st(ldp
, "", LDAP_SCOPE_BASE
, "(objectclass=*)",
893 CONST_DISCARD(char **, attrs
), 0, &to
, &res
))
896 if (ldap_count_entries(ldp
, res
) != 1)
899 values
= ldap_get_values(ldp
, res
, "highestCommittedUSN");
900 if (!values
|| !values
[0])
903 *seq
= atoi(values
[0]);
909 ldap_value_free(values
);
917 /**********************************************************************
918 Get the sequence number for a Windows AD native mode domain using
920 **********************************************************************/
922 static int get_ldap_sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
925 char addr
[INET6_ADDRSTRLEN
];
927 print_sockaddr(addr
, sizeof(addr
), &domain
->dcaddr
);
928 if ((ret
= get_ldap_seq(addr
, LDAP_PORT
, seq
)) == 0) {
929 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
930 "number for Domain (%s) from DC (%s)\n",
931 domain
->name
, addr
));
936 #endif /* HAVE_LDAP */
938 /* find the sequence number for a domain */
939 static NTSTATUS
sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
942 union samr_DomainInfo
*info
= NULL
;
944 struct policy_handle dom_pol
;
945 bool got_seq_num
= False
;
946 struct rpc_pipe_client
*cli
;
948 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain
->name
));
950 if ( !winbindd_can_contact_domain( domain
) ) {
951 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
957 *seq
= DOM_SEQUENCE_NONE
;
959 if (!(mem_ctx
= talloc_init("sequence_number[rpc]")))
960 return NT_STATUS_NO_MEMORY
;
963 if ( domain
->active_directory
)
967 DEBUG(8,("using get_ldap_seq() to retrieve the "
968 "sequence number\n"));
970 res
= get_ldap_sequence_number( domain
, seq
);
973 result
= NT_STATUS_OK
;
974 DEBUG(10,("domain_sequence_number: LDAP for "
976 domain
->name
, *seq
));
980 DEBUG(10,("domain_sequence_number: failed to get LDAP "
981 "sequence number for domain %s\n",
984 #endif /* HAVE_LDAP */
986 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
987 if (!NT_STATUS_IS_OK(result
)) {
991 /* Query domain info */
993 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
998 if (NT_STATUS_IS_OK(result
)) {
999 *seq
= info
->info8
.sequence_num
;
1004 /* retry with info-level 2 in case the dc does not support info-level 8
1005 * (like all older samba2 and samba3 dc's) - Guenther */
1007 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1012 if (NT_STATUS_IS_OK(result
)) {
1013 *seq
= info
->general
.sequence_num
;
1019 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1020 domain
->name
, (unsigned)*seq
));
1022 DEBUG(10,("domain_sequence_number: failed to get sequence "
1023 "number (%u) for domain %s\n",
1024 (unsigned)*seq
, domain
->name
));
1029 talloc_destroy(mem_ctx
);
1034 /* get a list of trusted domains */
1035 static NTSTATUS
trusted_domains(struct winbindd_domain
*domain
,
1036 TALLOC_CTX
*mem_ctx
,
1037 struct netr_DomainTrustList
*trusts
)
1039 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1040 uint32 enum_ctx
= 0;
1041 struct rpc_pipe_client
*cli
;
1042 struct policy_handle lsa_policy
;
1044 DEBUG(3,("rpc: trusted_domains\n"));
1046 ZERO_STRUCTP(trusts
);
1048 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
1049 if (!NT_STATUS_IS_OK(result
))
1052 result
= STATUS_MORE_ENTRIES
;
1054 while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
1057 struct lsa_DomainList dom_list
;
1059 result
= rpccli_lsa_EnumTrustDom(cli
, mem_ctx
,
1065 if (!NT_STATUS_IS_OK(result
) &&
1066 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
))
1069 start_idx
= trusts
->count
;
1070 trusts
->count
+= dom_list
.count
;
1072 trusts
->array
= talloc_realloc(
1073 mem_ctx
, trusts
->array
, struct netr_DomainTrust
,
1075 if (trusts
->array
== NULL
) {
1076 return NT_STATUS_NO_MEMORY
;
1079 for (i
=0; i
<dom_list
.count
; i
++) {
1080 struct netr_DomainTrust
*trust
= &trusts
->array
[i
];
1081 struct dom_sid
*sid
;
1083 ZERO_STRUCTP(trust
);
1085 trust
->netbios_name
= talloc_move(
1087 &dom_list
.domains
[i
].name
.string
);
1088 trust
->dns_name
= NULL
;
1090 sid
= talloc(trusts
->array
, struct dom_sid
);
1092 return NT_STATUS_NO_MEMORY
;
1094 sid_copy(sid
, dom_list
.domains
[i
].sid
);
1101 /* find the lockout policy for a domain */
1102 static NTSTATUS
msrpc_lockout_policy(struct winbindd_domain
*domain
,
1103 TALLOC_CTX
*mem_ctx
,
1104 struct samr_DomInfo12
*lockout_policy
)
1107 struct rpc_pipe_client
*cli
;
1108 struct policy_handle dom_pol
;
1109 union samr_DomainInfo
*info
= NULL
;
1111 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain
->name
));
1113 if ( !winbindd_can_contact_domain( domain
) ) {
1114 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1116 return NT_STATUS_NOT_SUPPORTED
;
1119 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1120 if (!NT_STATUS_IS_OK(result
)) {
1124 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1128 if (!NT_STATUS_IS_OK(result
)) {
1132 *lockout_policy
= info
->info12
;
1134 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1135 info
->info12
.lockout_threshold
));
1142 /* find the password policy for a domain */
1143 static NTSTATUS
msrpc_password_policy(struct winbindd_domain
*domain
,
1144 TALLOC_CTX
*mem_ctx
,
1145 struct samr_DomInfo1
*password_policy
)
1148 struct rpc_pipe_client
*cli
;
1149 struct policy_handle dom_pol
;
1150 union samr_DomainInfo
*info
= NULL
;
1152 DEBUG(10,("rpc: fetch password policy for %s\n", domain
->name
));
1154 if ( !winbindd_can_contact_domain( domain
) ) {
1155 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1157 return NT_STATUS_NOT_SUPPORTED
;
1160 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1161 if (!NT_STATUS_IS_OK(result
)) {
1165 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1169 if (!NT_STATUS_IS_OK(result
)) {
1173 *password_policy
= info
->info1
;
1175 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1176 info
->info1
.min_password_length
));
1183 typedef NTSTATUS (*lookup_sids_fn_t
)(struct rpc_pipe_client
*cli
,
1184 TALLOC_CTX
*mem_ctx
,
1185 struct policy_handle
*pol
,
1187 const DOM_SID
*sids
,
1190 enum lsa_SidType
**ptypes
);
1192 NTSTATUS
winbindd_lookup_sids(TALLOC_CTX
*mem_ctx
,
1193 struct winbindd_domain
*domain
,
1195 const struct dom_sid
*sids
,
1198 enum lsa_SidType
**types
)
1201 struct rpc_pipe_client
*cli
= NULL
;
1202 struct policy_handle lsa_policy
;
1203 unsigned int orig_timeout
;
1204 lookup_sids_fn_t lookup_sids_fn
= rpccli_lsa_lookup_sids
;
1206 if (domain
->can_do_ncacn_ip_tcp
) {
1207 status
= cm_connect_lsa_tcp(domain
, mem_ctx
, &cli
);
1208 if (NT_STATUS_IS_OK(status
)) {
1209 lookup_sids_fn
= rpccli_lsa_lookup_sids3
;
1212 domain
->can_do_ncacn_ip_tcp
= false;
1214 status
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
1216 if (!NT_STATUS_IS_OK(status
)) {
1222 * This call can take a long time
1223 * allow the server to time out.
1224 * 35 seconds should do it.
1226 orig_timeout
= rpccli_set_timeout(cli
, 35000);
1228 status
= lookup_sids_fn(cli
,
1237 /* And restore our original timeout. */
1238 rpccli_set_timeout(cli
, orig_timeout
);
1240 if (NT_STATUS_V(status
) == DCERPC_FAULT_ACCESS_DENIED
||
1241 NT_STATUS_V(status
) == DCERPC_FAULT_SEC_PKG_ERROR
) {
1243 * This can happen if the schannel key is not
1244 * valid anymore, we need to invalidate the
1245 * all connections to the dc and reestablish
1246 * a netlogon connection first.
1248 invalidate_cm_connection(&domain
->conn
);
1249 status
= NT_STATUS_ACCESS_DENIED
;
1252 if (!NT_STATUS_IS_OK(status
)) {
1259 typedef NTSTATUS (*lookup_names_fn_t
)(struct rpc_pipe_client
*cli
,
1260 TALLOC_CTX
*mem_ctx
,
1261 struct policy_handle
*pol
,
1264 const char ***dom_names
,
1266 struct dom_sid
**sids
,
1267 enum lsa_SidType
**types
);
1269 NTSTATUS
winbindd_lookup_names(TALLOC_CTX
*mem_ctx
,
1270 struct winbindd_domain
*domain
,
1273 const char ***domains
,
1274 struct dom_sid
**sids
,
1275 enum lsa_SidType
**types
)
1278 struct rpc_pipe_client
*cli
= NULL
;
1279 struct policy_handle lsa_policy
;
1280 unsigned int orig_timeout
= 0;
1281 lookup_names_fn_t lookup_names_fn
= rpccli_lsa_lookup_names
;
1283 if (domain
->can_do_ncacn_ip_tcp
) {
1284 status
= cm_connect_lsa_tcp(domain
, mem_ctx
, &cli
);
1285 if (NT_STATUS_IS_OK(status
)) {
1286 lookup_names_fn
= rpccli_lsa_lookup_names4
;
1289 domain
->can_do_ncacn_ip_tcp
= false;
1291 status
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
1293 if (!NT_STATUS_IS_OK(status
)) {
1300 * This call can take a long time
1301 * allow the server to time out.
1302 * 35 seconds should do it.
1304 orig_timeout
= rpccli_set_timeout(cli
, 35000);
1306 status
= lookup_names_fn(cli
,
1310 (const char **) names
,
1316 /* And restore our original timeout. */
1317 rpccli_set_timeout(cli
, orig_timeout
);
1319 if (NT_STATUS_V(status
) == DCERPC_FAULT_ACCESS_DENIED
||
1320 NT_STATUS_V(status
) == DCERPC_FAULT_SEC_PKG_ERROR
) {
1322 * This can happen if the schannel key is not
1323 * valid anymore, we need to invalidate the
1324 * all connections to the dc and reestablish
1325 * a netlogon connection first.
1327 invalidate_cm_connection(&domain
->conn
);
1328 status
= NT_STATUS_ACCESS_DENIED
;
1331 if (!NT_STATUS_IS_OK(status
)) {
1338 /* the rpc backend methods are exposed via this structure */
1339 struct winbindd_methods msrpc_methods
= {
1346 msrpc_rids_to_names
,
1349 msrpc_lookup_useraliases
,
1352 msrpc_lockout_policy
,
1353 msrpc_password_policy
,