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/>.
2
* Unix SMB/CIFS implementation.
4
* Winbind rpc backend functions
6
* Copyright (c) 2000-2003 Tim Potter
7
* Copyright (c) 2001 Andrew Tridgell
8
* Copyright (c) 2005 Volker Lendecke
9
* Copyright (c) 2008 Guenther Deschner (pidl conversion)
10
* Copyright (c) 2010 Andreas Schneider <asn@samba.org>
12
* This program is free software; you can redistribute it and/or modify
13
* it under the terms of the GNU General Public License as published by
14
* the Free Software Foundation; either version 3 of the License, or
15
* (at your option) any later version.
17
* This program is distributed in the hope that it will be useful,
18
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
* GNU General Public License for more details.
22
* You should have received a copy of the GNU General Public License
23
* along with this program. If not, see <http://www.gnu.org/licenses/>.
25
26
#include "includes.h"
26
27
#include "winbindd.h"
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)
28
#include "winbindd_rpc.h"
29
#include "rpc_client/rpc_client.h"
30
#include "librpc/gen_ndr/ndr_samr_c.h"
31
#include "librpc/gen_ndr/ndr_lsa_c.h"
32
#include "rpc_client/cli_samr.h"
33
#include "rpc_client/cli_lsarpc.h"
34
#include "../libcli/security/security.h"
36
/* Query display info for a domain */
37
NTSTATUS rpc_query_user_list(TALLOC_CTX *mem_ctx,
38
struct rpc_pipe_client *samr_pipe,
39
struct policy_handle *samr_policy,
40
const struct dom_sid *domain_sid,
42
struct wbint_userinfo **pinfo)
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))
44
struct wbint_userinfo *info = NULL;
45
uint32_t num_info = 0;
46
uint32_t loop_count = 0;
47
uint32_t start_idx = 0;
49
NTSTATUS status, result;
50
struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
67
uint32 num_dom_users, j;
68
uint32 max_entries, max_size;
56
uint32_t num_dom_users;
57
uint32_t max_entries, max_size;
69
58
uint32_t total_size, returned_size;
71
59
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,
61
dcerpc_get_query_dispinfo_params(loop_count,
65
status = dcerpc_samr_QueryDisplayInfo(b,
76
if (!NT_STATUS_IS_OK(status)) {
88
79
if (!NT_STATUS_IS_OK(result)) {
89
if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
80
if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
94
num_dom_users = disp_info.info1.count;
85
/* increment required start query values */
95
86
start_idx += disp_info.info1.count;
98
*num_entries += num_dom_users;
100
*info = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
101
struct wbint_userinfo,
88
num_dom_users = disp_info.info1.count;
90
num_info += num_dom_users;
92
info = TALLOC_REALLOC_ARRAY(mem_ctx,
94
struct wbint_userinfo,
105
97
return NT_STATUS_NO_MEMORY;
108
100
for (j = 0; j < num_dom_users; i++, j++) {
110
101
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);
102
struct samr_DispEntryGeneral *src;
103
struct wbint_userinfo *dst;
105
src = &(disp_info.info1.entries[j]);
108
dst->acct_name = talloc_strdup(info,
109
src->account_name.string);
110
if (dst->acct_name == NULL) {
111
return NT_STATUS_NO_MEMORY;
114
dst->full_name = talloc_strdup(info, src->full_name.string);
115
if ((src->full_name.string != NULL) &&
116
(dst->full_name == NULL))
118
return NT_STATUS_NO_MEMORY;
124
sid_compose(&dst->user_sid, domain_sid, rid);
120
126
/* For the moment we set the primary group for
121
127
every user to be the Domain Users group.
124
130
This should really be made into a 'winbind
125
131
force group' smb.conf parameter or
126
132
something like that. */
128
sid_compose(&(*info)[i].group_sid, &domain->sid,
129
DOMAIN_GROUP_RID_USERS);
133
sid_compose(&dst->group_sid, domain_sid,
132
136
} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
138
*pnum_info = num_info;
137
/* list all domain groups */
138
static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
141
struct acct_info **info)
144
/* List all domain groups */
145
NTSTATUS rpc_enum_dom_groups(TALLOC_CTX *mem_ctx,
146
struct rpc_pipe_client *samr_pipe,
147
struct policy_handle *samr_policy,
149
struct wb_acct_info **pinfo)
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))
151
struct wb_acct_info *info = NULL;
153
uint32_t num_info = 0;
154
NTSTATUS status, result;
155
struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
164
160
struct samr_SamArray *sam_array = NULL;
166
TALLOC_CTX *mem_ctx2;
169
mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
171
164
/* start is updated by this call. */
172
status = rpccli_samr_EnumDomainGroups(cli, mem_ctx2,
165
status = dcerpc_samr_EnumDomainGroups(b,
176
170
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);
173
if (!NT_STATUS_IS_OK(status)) {
176
if (!NT_STATUS_IS_OK(result)) {
177
if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
178
DEBUG(2,("query_user_list: failed to enum domain groups: %s\n",
184
info = TALLOC_REALLOC_ARRAY(mem_ctx,
190
189
return NT_STATUS_NO_MEMORY;
193
for (g=0; g < count; g++) {
195
fstrcpy((*info)[*num_entries + g].acct_name,
192
for (g = 0; g < count; g++) {
193
fstrcpy(info[num_info + g].acct_name,
196
194
sam_array->entries[g].name.string);
197
(*info)[*num_entries + g].rid = sam_array->entries[g].idx;
196
info[num_info + 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));
200
} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
202
*pnum_info = num_info;
207
/* List all domain groups */
209
static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
212
struct acct_info **info)
208
NTSTATUS rpc_enum_local_groups(TALLOC_CTX *mem_ctx,
209
struct rpc_pipe_client *samr_pipe,
210
struct policy_handle *samr_policy,
212
struct wb_acct_info **pinfo)
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))
214
struct wb_acct_info *info = NULL;
215
uint32_t num_info = 0;
216
NTSTATUS status, result;
217
struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
234
222
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,
224
uint32_t start = num_info;
227
status = dcerpc_samr_EnumDomainAliases(b,
245
232
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,
235
if (!NT_STATUS_IS_OK(status)) {
238
if (!NT_STATUS_IS_OK(result)) {
239
if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
244
info = TALLOC_REALLOC_ARRAY(mem_ctx,
249
return NT_STATUS_NO_MEMORY;
252
for (g = 0; g < count; g++) {
253
fstrcpy(info[num_info + g].acct_name,
265
254
sam_array->entries[g].name.string);
266
(*info)[*num_entries + g].rid = sam_array->entries[g].idx;
255
info[num_info + g].rid = sam_array->entries[g].idx;
269
(*num_entries) += count;
270
talloc_destroy(mem_ctx2);
272
259
} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
261
*pnum_info = num_info;
277
267
/* 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)
268
NTSTATUS rpc_name_to_sid(TALLOC_CTX *mem_ctx,
269
struct rpc_pipe_client *lsa_pipe,
270
struct policy_handle *lsa_policy,
271
const char *domain_name,
275
enum lsa_SidType *type)
287
DOM_SID *sids = NULL;
288
277
enum lsa_SidType *types = NULL;
278
struct dom_sid *sids = NULL;
289
279
char *full_name = NULL;
290
NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
291
280
char *mapped_name = NULL;
293
if (name == NULL || *name=='\0') {
283
if (name == NULL || name[0] == '\0') {
294
284
full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
295
} else if (domain_name == NULL || *domain_name == '\0') {
285
} else if (domain_name == NULL || domain_name[0] == '\0') {
296
286
full_name = talloc_asprintf(mem_ctx, "%s", name);
298
288
full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
301
DEBUG(0, ("talloc_asprintf failed!\n"));
291
if (full_name == NULL) {
302
292
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))
295
status = normalize_name_unmap(mem_ctx, full_name, &mapped_name);
296
/* Reset the full_name pointer if we mapped anything */
297
if (NT_STATUS_IS_OK(status) ||
298
NT_STATUS_EQUAL(status, NT_STATUS_FILE_RENAMED)) {
315
299
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 */
302
DEBUG(3,("name_to_sid: %s for domain %s\n",
303
full_name ? full_name : "", domain_name ));
306
* We don't run into deadlocks here, cause winbind_off() is
307
* called in the main function.
309
status = rpccli_lsa_lookup_names(lsa_pipe,
313
(const char **) &full_name,
318
if (!NT_STATUS_IS_OK(status)) {
319
DEBUG(2,("name_to_sid: failed to lookup name: %s\n",
329
324
sid_copy(sid, &sids[0]);
330
325
*type = types[0];
413
for (i=0; i<num_rids; i++) {
415
for (i = 0; i < num_rids; i++) {
414
416
if (!sid_compose(&sids[i], sid, rids[i])) {
415
417
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)) {
421
status = rpccli_lsa_lookup_sids(lsa_pipe,
429
if (!NT_STATUS_IS_OK(status) &&
430
!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
431
DEBUG(2,("rids_to_names: failed to lookup sids: %s\n",
433
for (i=0; i<num_rids; i++) {
434
NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
436
for (i = 0; i < num_rids; i++) {
435
437
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;
440
if (types[i] != SID_NAME_UNKNOWN) {
441
map_status = normalize_name_map(mem_ctx,
445
if (NT_STATUS_IS_OK(map_status) ||
446
NT_STATUS_EQUAL(map_status, NT_STATUS_FILE_RENAMED)) {
447
TALLOC_FREE(names[i]);
448
names[i] = talloc_strdup(names, mapped_name);
449
if (names[i] == NULL) {
450
return NT_STATUS_NO_MEMORY;
448
*domain_name = domains[i];
454
domain_name = domains[i];
458
*pdomain_name = domain_name;
455
465
/* 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)
466
NTSTATUS rpc_query_user(TALLOC_CTX *mem_ctx,
467
struct rpc_pipe_client *samr_pipe,
468
struct policy_handle *samr_policy,
469
const struct dom_sid *domain_sid,
470
const struct dom_sid *user_sid,
471
struct wbint_userinfo *user_info)
461
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
462
struct policy_handle dom_pol, user_pol;
473
struct policy_handle user_policy;
463
474
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))
476
NTSTATUS status, result;
477
struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
479
if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
471
480
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
483
/* Get user handle */
512
result = rpccli_samr_OpenUser(cli, mem_ctx,
484
status = dcerpc_samr_OpenUser(b,
514
487
SEC_FLAG_MAXIMUM_ALLOWED,
518
if (!NT_STATUS_IS_OK(result))
491
if (!NT_STATUS_IS_OK(status)) {
494
if (!NT_STATUS_IS_OK(result)) {
521
498
/* Get user info */
522
result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
499
status = dcerpc_samr_QueryUserInfo(b,
527
rpccli_samr_Close(cli, mem_ctx, &user_pol);
529
if (!NT_STATUS_IS_OK(result))
507
dcerpc_samr_Close(b, mem_ctx, &user_policy, &_result);
509
if (!NT_STATUS_IS_OK(status)) {
512
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,
516
sid_compose(&user_info->user_sid, domain_sid, user_rid);
517
sid_compose(&user_info->group_sid, domain_sid,
534
518
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);
520
user_info->acct_name = talloc_strdup(user_info,
521
info->info21.account_name.string);
522
if (user_info->acct_name == NULL) {
523
return NT_STATUS_NO_MEMORY;
526
user_info->full_name = talloc_strdup(user_info,
527
info->info21.full_name.string);
528
if ((info->info21.full_name.string != NULL) &&
529
(user_info->acct_name == NULL))
531
return NT_STATUS_NO_MEMORY;
539
534
user_info->homedir = NULL;
540
535
user_info->shell = NULL;
541
536
user_info->primary_gid = (gid_t)-1;
543
538
return NT_STATUS_OK;
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)
541
/* Lookup groups a user is a member of. */
542
NTSTATUS rpc_lookup_usergroups(TALLOC_CTX *mem_ctx,
543
struct rpc_pipe_client *samr_pipe,
544
struct policy_handle *samr_policy,
545
const struct dom_sid *domain_sid,
546
const struct dom_sid *user_sid,
547
uint32_t *pnum_groups,
548
struct dom_sid **puser_grpsids)
552
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
553
struct policy_handle dom_pol, user_pol;
554
uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
550
struct policy_handle user_policy;
555
551
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))
552
struct dom_sid *user_grpsids = NULL;
553
uint32_t num_groups = 0, i;
555
NTSTATUS status, result;
556
struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
558
if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
563
559
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
562
/* Get user handle */
592
result = rpccli_samr_OpenUser(cli, mem_ctx,
563
status = dcerpc_samr_OpenUser(b,
566
SEC_FLAG_MAXIMUM_ALLOWED,
598
if (!NT_STATUS_IS_OK(result))
570
if (!NT_STATUS_IS_OK(status)) {
573
if (!NT_STATUS_IS_OK(result)) {
601
577
/* 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)
578
status = dcerpc_samr_GetGroupsForUser(b,
583
num_groups = rid_array->count;
587
dcerpc_samr_Close(b, mem_ctx, &user_policy, &_result);
590
if (!NT_STATUS_IS_OK(status)) {
593
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);
597
user_grpsids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_groups);
598
if (user_grpsids == NULL) {
599
status = NT_STATUS_NO_MEMORY;
603
for (i = 0; i < num_groups; i++) {
604
sid_compose(&(user_grpsids[i]), domain_sid,
605
rid_array->rids[i].rid);
608
*pnum_groups = num_groups;
610
*puser_grpsids = user_grpsids;
622
612
return NT_STATUS_OK;
615
NTSTATUS rpc_lookup_useraliases(TALLOC_CTX *mem_ctx,
616
struct rpc_pipe_client *samr_pipe,
617
struct policy_handle *samr_policy,
619
const struct dom_sid *sids,
620
uint32_t *pnum_aliases,
621
uint32_t **palias_rids)
625
623
#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;
624
uint32_t num_query_sids = 0;
625
uint32_t num_queries = 1;
626
uint32_t num_aliases = 0;
627
uint32_t total_sids = 0;
628
uint32_t *alias_rids = NULL;
629
uint32_t rangesize = MAX_SAM_ENTRIES_W2K;
638
631
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))
632
NTSTATUS status, result;
633
struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
659
636
/* prepare query */
675
652
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);
655
for (i = 0; i < num_query_sids; i++) {
656
sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[total_sids++]);
657
if (sid_array.sids[i].sid == NULL) {
682
658
return NT_STATUS_NO_MEMORY;
685
661
sid_array.num_sids = num_query_sids;
688
result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
664
status = dcerpc_samr_GetAliasMembership(b,
670
if (!NT_STATUS_IS_OK(status)) {
693
673
if (!NT_STATUS_IS_OK(result)) {
696
TALLOC_FREE(sid_array.sids);
700
677
/* process output */
678
for (i = 0; i < alias_rids_query.count; i++) {
679
size_t na = num_aliases;
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;
681
if (!add_rid_to_array_unique(mem_ctx,
682
alias_rids_query.ids[i],
685
return NT_STATUS_NO_MEMORY;
711
TALLOC_FREE(sid_array.sids);
715
692
} 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));
694
DEBUG(10,("rpc: rpc_lookup_useraliases: got %d aliases in %d queries "
695
"(rangesize: %d)\n", num_aliases, num_queries, rangesize));
697
*pnum_aliases = num_aliases;
698
*palias_rids = alias_rids;
701
#undef MAX_SAM_ENTRIES_W2K
725
704
/* 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;
705
NTSTATUS rpc_lookup_groupmem(TALLOC_CTX *mem_ctx,
706
struct rpc_pipe_client *samr_pipe,
707
struct policy_handle *samr_policy,
708
const char *domain_name,
709
const struct dom_sid *domain_sid,
710
const struct dom_sid *group_sid,
711
enum lsa_SidType type,
712
uint32_t *pnum_names,
713
struct dom_sid **psid_mem,
715
uint32_t **pname_types)
717
struct policy_handle group_policy;
719
uint32_t *rid_mem = NULL;
721
uint32_t num_names = 0;
722
uint32_t total_names = 0;
723
struct dom_sid *sid_mem = NULL;
725
uint32_t *name_types = NULL;
727
struct lsa_Strings tmp_names;
728
struct samr_Ids tmp_types;
731
NTSTATUS status, result;
732
struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
734
if (!sid_peek_check_rid(domain_sid, group_sid, &group_rid)) {
735
return NT_STATUS_UNSUCCESSFUL;
739
case SID_NAME_DOM_GRP:
741
struct samr_RidAttrArray *rids = NULL;
743
status = dcerpc_samr_OpenGroup(b,
746
SEC_FLAG_MAXIMUM_ALLOWED,
750
if (!NT_STATUS_IS_OK(status)) {
753
if (!NT_STATUS_IS_OK(result)) {
758
* Step #1: Get a list of user rids that are the members of the group.
760
status = dcerpc_samr_QueryGroupMember(b,
767
dcerpc_samr_Close(b, mem_ctx, &group_policy, &_result);
770
if (!NT_STATUS_IS_OK(status)) {
773
if (!NT_STATUS_IS_OK(result)) {
778
if (rids == NULL || rids->count == 0) {
787
num_names = rids->count;
788
rid_mem = rids->rids;
792
case SID_NAME_WKN_GRP:
795
struct lsa_SidArray sid_array;
796
struct lsa_SidPtr sid_ptr;
797
struct samr_Ids rids_query;
799
sid_ptr.sid = dom_sid_dup(mem_ctx, group_sid);
800
if (sid_ptr.sid == NULL) {
801
return NT_STATUS_NO_MEMORY;
804
sid_array.num_sids = 1;
805
sid_array.sids = &sid_ptr;
807
status = dcerpc_samr_GetAliasMembership(b,
813
if (!NT_STATUS_IS_OK(status)) {
816
if (!NT_STATUS_IS_OK(result)) {
820
if (rids_query.count == 0) {
829
num_names = rids_query.count;
830
rid_mem = rids_query.ids;
835
return NT_STATUS_UNSUCCESSFUL;
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.
839
* Step #2: Convert list of rids into list of usernames.
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)
842
names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_names);
843
name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32_t, num_names);
844
sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_names);
845
if (names == NULL || name_types == NULL || sid_mem == NULL) {
846
return NT_STATUS_NO_MEMORY;
850
for (j = 0; j < num_names; j++) {
851
sid_compose(&sid_mem[j], domain_sid, rid_mem[j]);
854
status = dcerpc_samr_LookupRids(b,
862
if (!NT_STATUS_IS_OK(status)) {
866
if (!NT_STATUS_IS_OK(result)) {
867
if (!NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
872
/* Copy result into array. The talloc system will take
873
care of freeing the temporary arrays later on. */
874
if (tmp_names.count != tmp_types.count) {
875
return NT_STATUS_UNSUCCESSFUL;
878
for (r = 0; r < tmp_names.count; r++) {
879
if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
882
names[total_names] = fill_domain_username_talloc(names,
884
tmp_names.names[r].string,
886
if (names[total_names] == NULL) {
887
return NT_STATUS_NO_MEMORY;
889
name_types[total_names] = tmp_types.ids[r];
893
*pnum_names = total_names;
895
*pname_types = name_types;
901
/* Find the sequence number for a domain */
902
NTSTATUS rpc_sequence_number(TALLOC_CTX *mem_ctx,
903
struct rpc_pipe_client *samr_pipe,
904
struct policy_handle *samr_policy,
905
const char *domain_name,
942
908
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,
909
bool got_seq_num = false;
910
NTSTATUS status, result;
911
struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
913
/* query domain info */
914
status = dcerpc_samr_QueryDomainInfo(b,
998
if (NT_STATUS_IS_OK(result)) {
999
*seq = info->info8.sequence_num;
920
if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
921
*pseq = info->info8.sequence_num;
1004
926
/* retry with info-level 2 in case the dc does not support info-level 8
1005
927
* (like all older samba2 and samba3 dc's) - Guenther */
1007
result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
928
status = dcerpc_samr_QueryDomainInfo(b,
1012
if (NT_STATUS_IS_OK(result)) {
1013
*seq = info->general.sequence_num;
934
if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
935
*pseq = info->general.sequence_num;
940
if (!NT_STATUS_IS_OK(status)) {
1018
947
if (got_seq_num) {
1019
948
DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1020
domain->name, (unsigned)*seq));
949
domain_name, (unsigned) *pseq));
1022
951
DEBUG(10,("domain_sequence_number: failed to get sequence "
1023
952
"number (%u) for domain %s\n",
1024
(unsigned)*seq, domain->name ));
953
(unsigned) *pseq, domain_name ));
954
status = NT_STATUS_OK;
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)
960
/* Get a list of trusted domains */
961
NTSTATUS rpc_trusted_domains(TALLOC_CTX *mem_ctx,
962
struct rpc_pipe_client *lsa_pipe,
963
struct policy_handle *lsa_policy,
964
uint32_t *pnum_trusts,
965
struct netr_DomainTrust **ptrusts)
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)) {
967
struct netr_DomainTrust *array = NULL;
968
uint32_t enum_ctx = 0;
970
NTSTATUS status, result;
971
struct dcerpc_binding_handle *b = lsa_pipe->binding_handle;
1057
974
struct lsa_DomainList dom_list;
1059
result = rpccli_lsa_EnumTrustDom(cli, mem_ctx,
979
* We don't run into deadlocks here, cause winbind_off() is
980
* called in the main function.
982
status = dcerpc_lsa_EnumTrustDom(b,
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) {
989
if (!NT_STATUS_IS_OK(status)) {
992
if (!NT_STATUS_IS_OK(result)) {
993
if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
999
count += dom_list.count;
1001
array = talloc_realloc(mem_ctx,
1003
struct netr_DomainTrust,
1005
if (array == NULL) {
1076
1006
return NT_STATUS_NO_MEMORY;
1079
for (i=0; i<dom_list.count; i++) {
1080
struct netr_DomainTrust *trust = &trusts->array[i];
1009
for (i = 0; i < dom_list.count; i++) {
1010
struct netr_DomainTrust *trust = &array[i];
1081
1011
struct dom_sid *sid;
1083
1013
ZERO_STRUCTP(trust);
1085
trust->netbios_name = talloc_move(
1087
&dom_list.domains[i].name.string);
1015
trust->netbios_name = talloc_move(array,
1016
&dom_list.domains[i].name.string);
1088
1017
trust->dns_name = NULL;
1090
sid = talloc(trusts->array, struct dom_sid);
1019
sid = talloc(array, struct dom_sid);
1091
1020
if (sid == NULL) {
1092
1021
return NT_STATUS_NO_MEMORY;
1094
1023
sid_copy(sid, dom_list.domains[i].sid);
1095
1024
trust->sid = 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,
1026
} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1028
*pnum_trusts = count;
1031
return NT_STATUS_OK;
1034
static NTSTATUS rpc_try_lookup_sids3(TALLOC_CTX *mem_ctx,
1035
struct winbindd_domain *domain,
1036
struct lsa_SidArray *sids,
1037
struct lsa_RefDomainList **pdomains,
1038
struct lsa_TransNameArray **pnames)
1040
struct lsa_TransNameArray2 lsa_names2;
1041
struct lsa_TransNameArray *names;
1043
struct rpc_pipe_client *cli;
1044
NTSTATUS status, result;
1046
status = cm_connect_lsa_tcp(domain, talloc_tos(), &cli);
1047
if (!NT_STATUS_IS_OK(status)) {
1048
domain->can_do_ncacn_ip_tcp = false;
1052
ZERO_STRUCT(lsa_names2);
1053
status = dcerpc_lsa_LookupSids3(cli->binding_handle,
1058
LSA_LOOKUP_NAMES_ALL,
1060
LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES,
1061
LSA_CLIENT_REVISION_2,
1063
if (!NT_STATUS_IS_OK(status)) {
1066
if (NT_STATUS_IS_ERR(result)) {
1069
names = TALLOC_ZERO_P(mem_ctx, struct lsa_TransNameArray);
1070
if (names == NULL) {
1071
return NT_STATUS_NO_MEMORY;
1073
names->count = lsa_names2.count;
1074
names->names = talloc_array(names, struct lsa_TranslatedName,
1076
if (names->names == NULL) {
1077
return NT_STATUS_NO_MEMORY;
1079
for (i=0; i<names->count; i++) {
1080
names->names[i].sid_type = lsa_names2.names[i].sid_type;
1081
names->names[i].name.string = talloc_move(
1082
names->names, &lsa_names2.names[i].name.string);
1083
names->names[i].sid_index = lsa_names2.names[i].sid_index;
1089
NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx,
1090
struct winbindd_domain *domain,
1091
struct lsa_SidArray *sids,
1092
struct lsa_RefDomainList **pdomains,
1093
struct lsa_TransNameArray **pnames)
1095
struct lsa_TransNameArray *names;
1096
struct rpc_pipe_client *cli = NULL;
1097
struct policy_handle lsa_policy;
1099
NTSTATUS status, result;
1101
if (domain->can_do_ncacn_ip_tcp) {
1102
status = rpc_try_lookup_sids3(mem_ctx, domain, sids,
1104
if (!NT_STATUS_IS_ERR(status)) {
1109
status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1110
if (!NT_STATUS_IS_OK(status)) {
1114
names = TALLOC_ZERO_P(mem_ctx, struct lsa_TransNameArray);
1115
if (names == NULL) {
1116
return NT_STATUS_NO_MEMORY;
1118
status = dcerpc_lsa_LookupSids(cli->binding_handle, mem_ctx,
1119
&lsa_policy, sids, pdomains,
1120
names, LSA_LOOKUP_NAMES_ALL,
1122
if (!NT_STATUS_IS_OK(status)) {
1125
if (NT_STATUS_IS_ERR(result)) {