source: branches/samba-3.2.x/source/winbindd/winbindd_rpc.c

Last change on this file was 335, checked in by Herwig Bauernfeind, 16 years ago

Update 3.2 to 3.2.14 (final)

File size: 30.7 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3
4 Winbind rpc backend functions
5
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)
10
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.
15
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.
20
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/>.
23*/
24
25#include "includes.h"
26#include "winbindd.h"
27
28#undef DBGC_CLASS
29#define DBGC_CLASS DBGC_WINBIND
30
31
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
34 application. */
35static NTSTATUS query_user_list(struct winbindd_domain *domain,
36 TALLOC_CTX *mem_ctx,
37 uint32 *num_entries,
38 WINBIND_USERINFO **info)
39{
40 NTSTATUS result;
41 POLICY_HND dom_pol;
42 unsigned int i, start_idx;
43 uint32 loop_count;
44 struct rpc_pipe_client *cli;
45
46 DEBUG(3,("rpc: query_user_list\n"));
47
48 *num_entries = 0;
49 *info = NULL;
50
51 if ( !winbindd_can_contact_domain( domain ) ) {
52 DEBUG(10,("query_user_list: No incoming trust for domain %s\n",
53 domain->name));
54 return NT_STATUS_OK;
55 }
56
57 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
58 if (!NT_STATUS_IS_OK(result))
59 return result;
60
61 i = start_idx = 0;
62 loop_count = 0;
63
64 do {
65 uint32 num_dom_users, j;
66 uint32 max_entries, max_size;
67 uint32_t total_size, returned_size;
68
69 union samr_DispInfo disp_info;
70
71 /* this next bit is copied from net_user_list_internal() */
72
73 get_query_dispinfo_params(loop_count, &max_entries,
74 &max_size);
75
76 result = rpccli_samr_QueryDisplayInfo(cli, mem_ctx,
77 &dom_pol,
78 1,
79 start_idx,
80 max_entries,
81 max_size,
82 &total_size,
83 &returned_size,
84 &disp_info);
85 num_dom_users = disp_info.info1.count;
86 start_idx += disp_info.info1.count;
87 loop_count++;
88
89 *num_entries += num_dom_users;
90
91 *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info, WINBIND_USERINFO,
92 *num_entries);
93
94 if (!(*info)) {
95 return NT_STATUS_NO_MEMORY;
96 }
97
98 for (j = 0; j < num_dom_users; i++, j++) {
99
100 uint32_t rid = disp_info.info1.entries[j].rid;
101
102 (*info)[i].acct_name = talloc_strdup(mem_ctx,
103 disp_info.info1.entries[j].account_name.string);
104 (*info)[i].full_name = talloc_strdup(mem_ctx,
105 disp_info.info1.entries[j].full_name.string);
106 (*info)[i].homedir = NULL;
107 (*info)[i].shell = NULL;
108 sid_compose(&(*info)[i].user_sid, &domain->sid, rid);
109
110 /* For the moment we set the primary group for
111 every user to be the Domain Users group.
112 There are serious problems with determining
113 the actual primary group for large domains.
114 This should really be made into a 'winbind
115 force group' smb.conf parameter or
116 something like that. */
117
118 sid_compose(&(*info)[i].group_sid, &domain->sid,
119 DOMAIN_GROUP_RID_USERS);
120 }
121
122 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
123
124 return result;
125}
126
127/* list all domain groups */
128static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
129 TALLOC_CTX *mem_ctx,
130 uint32 *num_entries,
131 struct acct_info **info)
132{
133 POLICY_HND dom_pol;
134 NTSTATUS status;
135 uint32 start = 0;
136 struct rpc_pipe_client *cli;
137
138 *num_entries = 0;
139 *info = NULL;
140
141 DEBUG(3,("rpc: enum_dom_groups\n"));
142
143 if ( !winbindd_can_contact_domain( domain ) ) {
144 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
145 domain->name));
146 return NT_STATUS_OK;
147 }
148
149 status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
150 if (!NT_STATUS_IS_OK(status))
151 return status;
152
153 do {
154 struct samr_SamArray *sam_array = NULL;
155 uint32 count = 0;
156 TALLOC_CTX *mem_ctx2;
157 int g;
158
159 mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
160
161 /* start is updated by this call. */
162 status = rpccli_samr_EnumDomainGroups(cli, mem_ctx2,
163 &dom_pol,
164 &start,
165 &sam_array,
166 0xFFFF, /* buffer size? */
167 &count);
168
169 if (!NT_STATUS_IS_OK(status) &&
170 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
171 talloc_destroy(mem_ctx2);
172 break;
173 }
174
175 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
176 struct acct_info,
177 (*num_entries) + count);
178 if (! *info) {
179 talloc_destroy(mem_ctx2);
180 return NT_STATUS_NO_MEMORY;
181 }
182
183 for (g=0; g < count; g++) {
184
185 fstrcpy((*info)[*num_entries + g].acct_name,
186 sam_array->entries[g].name.string);
187 (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
188 }
189
190 (*num_entries) += count;
191 talloc_destroy(mem_ctx2);
192 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
193
194 return NT_STATUS_OK;
195}
196
197/* List all domain groups */
198
199static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
200 TALLOC_CTX *mem_ctx,
201 uint32 *num_entries,
202 struct acct_info **info)
203{
204 POLICY_HND dom_pol;
205 NTSTATUS result;
206 struct rpc_pipe_client *cli;
207
208 *num_entries = 0;
209 *info = NULL;
210
211 DEBUG(3,("rpc: enum_local_groups\n"));
212
213 if ( !winbindd_can_contact_domain( domain ) ) {
214 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
215 domain->name));
216 return NT_STATUS_OK;
217 }
218
219 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
220 if (!NT_STATUS_IS_OK(result))
221 return result;
222
223 do {
224 struct samr_SamArray *sam_array = NULL;
225 uint32 count = 0, start = *num_entries;
226 TALLOC_CTX *mem_ctx2;
227 int g;
228
229 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
230
231 result = rpccli_samr_EnumDomainAliases(cli, mem_ctx2,
232 &dom_pol,
233 &start,
234 &sam_array,
235 0xFFFF, /* buffer size? */
236 &count);
237 if (!NT_STATUS_IS_OK(result) &&
238 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
239 {
240 talloc_destroy(mem_ctx2);
241 return result;
242 }
243
244 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
245 struct acct_info,
246 (*num_entries) + count);
247 if (! *info) {
248 talloc_destroy(mem_ctx2);
249 return NT_STATUS_NO_MEMORY;
250 }
251
252 for (g=0; g < count; g++) {
253
254 fstrcpy((*info)[*num_entries + g].acct_name,
255 sam_array->entries[g].name.string);
256 (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
257 }
258
259 (*num_entries) += count;
260 talloc_destroy(mem_ctx2);
261
262 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
263
264 return NT_STATUS_OK;
265}
266
267/* convert a single name to a sid in a domain */
268static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
269 TALLOC_CTX *mem_ctx,
270 enum winbindd_cmd original_cmd,
271 const char *domain_name,
272 const char *name,
273 DOM_SID *sid,
274 enum lsa_SidType *type)
275{
276 NTSTATUS result;
277 DOM_SID *sids = NULL;
278 enum lsa_SidType *types = NULL;
279 char *full_name = NULL;
280 struct rpc_pipe_client *cli;
281 POLICY_HND lsa_policy;
282 unsigned int orig_timeout;
283
284 if (name == NULL || *name=='\0') {
285 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
286 } else if (domain_name == NULL || *domain_name == '\0') {
287 full_name = talloc_asprintf(mem_ctx, "%s", name);
288 } else {
289 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
290 }
291 if (!full_name) {
292 DEBUG(0, ("talloc_asprintf failed!\n"));
293 return NT_STATUS_NO_MEMORY;
294 }
295
296 DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
297
298 ws_name_return( full_name, WB_REPLACE_CHAR );
299
300 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", full_name?full_name:"", domain_name ));
301
302 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
303 if (!NT_STATUS_IS_OK(result))
304 return result;
305
306 /*
307 * This call can take a long time
308 * allow the server to time out.
309 * 35 seconds should do it.
310 */
311 orig_timeout = cli_set_timeout(cli->cli, 35000);
312
313 result = rpccli_lsa_lookup_names(cli, mem_ctx, &lsa_policy, 1,
314 (const char**) &full_name, NULL, 1, &sids, &types);
315
316 /* And restore our original timeout. */
317 cli_set_timeout(cli->cli, orig_timeout);
318
319 if (!NT_STATUS_IS_OK(result))
320 return result;
321
322 /* Return rid and type if lookup successful */
323
324 sid_copy(sid, &sids[0]);
325 *type = types[0];
326
327 return NT_STATUS_OK;
328}
329
330/*
331 convert a domain SID to a user or group name
332*/
333static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
334 TALLOC_CTX *mem_ctx,
335 const DOM_SID *sid,
336 char **domain_name,
337 char **name,
338 enum lsa_SidType *type)
339{
340 char **domains;
341 char **names;
342 enum lsa_SidType *types = NULL;
343 NTSTATUS result;
344 struct rpc_pipe_client *cli;
345 POLICY_HND lsa_policy;
346 unsigned int orig_timeout;
347
348 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
349 domain->name ));
350
351 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
352 if (!NT_STATUS_IS_OK(result)) {
353 DEBUG(2,("msrpc_sid_to_name: cm_connect_lsa() failed (%s)\n",
354 nt_errstr(result)));
355 return result;
356 }
357
358
359 /*
360 * This call can take a long time
361 * allow the server to time out.
362 * 35 seconds should do it.
363 */
364 orig_timeout = cli_set_timeout(cli->cli, 35000);
365
366 result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy,
367 1, sid, &domains, &names, &types);
368
369 /* And restore our original timeout. */
370 cli_set_timeout(cli->cli, orig_timeout);
371
372 if (!NT_STATUS_IS_OK(result)) {
373 DEBUG(2,("msrpc_sid_to_name: rpccli_lsa_lookup_sids() failed (%s)\n",
374 nt_errstr(result)));
375 return result;
376 }
377
378 *type = (enum lsa_SidType)types[0];
379 *domain_name = domains[0];
380 *name = names[0];
381
382 ws_name_replace( *name, WB_REPLACE_CHAR );
383
384 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
385 return NT_STATUS_OK;
386}
387
388static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
389 TALLOC_CTX *mem_ctx,
390 const DOM_SID *sid,
391 uint32 *rids,
392 size_t num_rids,
393 char **domain_name,
394 char ***names,
395 enum lsa_SidType **types)
396{
397 char **domains;
398 NTSTATUS result;
399 struct rpc_pipe_client *cli;
400 POLICY_HND lsa_policy;
401 DOM_SID *sids;
402 size_t i;
403 char **ret_names;
404 unsigned int orig_timeout;
405
406 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name ));
407
408 if (num_rids) {
409 sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids);
410 if (sids == NULL) {
411 return NT_STATUS_NO_MEMORY;
412 }
413 } else {
414 sids = NULL;
415 }
416
417 for (i=0; i<num_rids; i++) {
418 if (!sid_compose(&sids[i], sid, rids[i])) {
419 return NT_STATUS_INTERNAL_ERROR;
420 }
421 }
422
423 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
424 if (!NT_STATUS_IS_OK(result)) {
425 return result;
426 }
427
428 /*
429 * This call can take a long time
430 * allow the server to time out.
431 * 35 seconds should do it.
432 */
433 orig_timeout = cli_set_timeout(cli->cli, 35000);
434
435 result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy,
436 num_rids, sids, &domains,
437 names, types);
438
439 /* And restore our original timeout. */
440 cli_set_timeout(cli->cli, orig_timeout);
441
442 if (!NT_STATUS_IS_OK(result) &&
443 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
444 return result;
445 }
446
447 ret_names = *names;
448 for (i=0; i<num_rids; i++) {
449 if ((*types)[i] != SID_NAME_UNKNOWN) {
450 ws_name_replace( ret_names[i], WB_REPLACE_CHAR );
451 *domain_name = domains[i];
452 }
453 }
454
455 return result;
456}
457
458/* Lookup user information from a rid or username. */
459static NTSTATUS query_user(struct winbindd_domain *domain,
460 TALLOC_CTX *mem_ctx,
461 const DOM_SID *user_sid,
462 WINBIND_USERINFO *user_info)
463{
464 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
465 POLICY_HND dom_pol, user_pol;
466 union samr_UserInfo *info = NULL;
467 uint32 user_rid;
468 struct netr_SamInfo3 *user;
469 struct rpc_pipe_client *cli;
470
471 DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid)));
472
473 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
474 return NT_STATUS_UNSUCCESSFUL;
475
476 user_info->homedir = NULL;
477 user_info->shell = NULL;
478 user_info->primary_gid = (gid_t)-1;
479
480 /* try netsamlogon cache first */
481
482 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
483 {
484
485 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
486 sid_string_dbg(user_sid)));
487
488 sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
489 sid_compose(&user_info->group_sid, &domain->sid,
490 user->base.primary_gid);
491
492 user_info->acct_name = talloc_strdup(mem_ctx,
493 user->base.account_name.string);
494 user_info->full_name = talloc_strdup(mem_ctx,
495 user->base.full_name.string);
496
497 TALLOC_FREE(user);
498
499 return NT_STATUS_OK;
500 }
501
502 if ( !winbindd_can_contact_domain( domain ) ) {
503 DEBUG(10,("query_user: No incoming trust for domain %s\n",
504 domain->name));
505 return NT_STATUS_OK;
506 }
507
508 if ( !winbindd_can_contact_domain( domain ) ) {
509 DEBUG(10,("query_user: No incoming trust for domain %s\n",
510 domain->name));
511 return NT_STATUS_OK;
512 }
513
514 if ( !winbindd_can_contact_domain( domain ) ) {
515 DEBUG(10,("query_user: No incoming trust for domain %s\n",
516 domain->name));
517 return NT_STATUS_OK;
518 }
519
520 /* no cache; hit the wire */
521
522 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
523 if (!NT_STATUS_IS_OK(result))
524 return result;
525
526 /* Get user handle */
527 result = rpccli_samr_OpenUser(cli, mem_ctx,
528 &dom_pol,
529 SEC_RIGHTS_MAXIMUM_ALLOWED,
530 user_rid,
531 &user_pol);
532
533 if (!NT_STATUS_IS_OK(result))
534 return result;
535
536 /* Get user info */
537 result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
538 &user_pol,
539 0x15,
540 &info);
541
542 rpccli_samr_Close(cli, mem_ctx, &user_pol);
543
544 if (!NT_STATUS_IS_OK(result))
545 return result;
546
547 sid_compose(&user_info->user_sid, &domain->sid, user_rid);
548 sid_compose(&user_info->group_sid, &domain->sid,
549 info->info21.primary_gid);
550 user_info->acct_name = talloc_strdup(mem_ctx,
551 info->info21.account_name.string);
552 user_info->full_name = talloc_strdup(mem_ctx,
553 info->info21.full_name.string);
554 user_info->homedir = NULL;
555 user_info->shell = NULL;
556 user_info->primary_gid = (gid_t)-1;
557
558 return NT_STATUS_OK;
559}
560
561/* Lookup groups a user is a member of. I wish Unix had a call like this! */
562static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
563 TALLOC_CTX *mem_ctx,
564 const DOM_SID *user_sid,
565 uint32 *num_groups, DOM_SID **user_grpsids)
566{
567 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
568 POLICY_HND dom_pol, user_pol;
569 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
570 struct samr_RidWithAttributeArray *rid_array = NULL;
571 unsigned int i;
572 uint32 user_rid;
573 struct rpc_pipe_client *cli;
574
575 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid)));
576
577 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
578 return NT_STATUS_UNSUCCESSFUL;
579
580 *num_groups = 0;
581 *user_grpsids = NULL;
582
583 /* so lets see if we have a cached user_info_3 */
584 result = lookup_usergroups_cached(domain, mem_ctx, user_sid,
585 num_groups, user_grpsids);
586
587 if (NT_STATUS_IS_OK(result)) {
588 return NT_STATUS_OK;
589 }
590
591 if ( !winbindd_can_contact_domain( domain ) ) {
592 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
593 domain->name));
594
595 /* Tell the cache manager not to remember this one */
596
597 return NT_STATUS_SYNCHRONIZATION_REQUIRED;
598 }
599
600 /* no cache; hit the wire */
601
602 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
603 if (!NT_STATUS_IS_OK(result))
604 return result;
605
606 /* Get user handle */
607 result = rpccli_samr_OpenUser(cli, mem_ctx,
608 &dom_pol,
609 des_access,
610 user_rid,
611 &user_pol);
612
613 if (!NT_STATUS_IS_OK(result))
614 return result;
615
616 /* Query user rids */
617 result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
618 &user_pol,
619 &rid_array);
620 *num_groups = rid_array->count;
621
622 rpccli_samr_Close(cli, mem_ctx, &user_pol);
623
624 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
625 return result;
626
627 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
628 if (!(*user_grpsids))
629 return NT_STATUS_NO_MEMORY;
630
631 for (i=0;i<(*num_groups);i++) {
632 sid_copy(&((*user_grpsids)[i]), &domain->sid);
633 sid_append_rid(&((*user_grpsids)[i]),
634 rid_array->rids[i].rid);
635 }
636
637 return NT_STATUS_OK;
638}
639
640static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
641 TALLOC_CTX *mem_ctx,
642 uint32 num_sids, const DOM_SID *sids,
643 uint32 *num_aliases,
644 uint32 **alias_rids)
645{
646 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
647 POLICY_HND dom_pol;
648 uint32 num_query_sids = 0;
649 int i;
650 struct rpc_pipe_client *cli;
651 struct samr_Ids alias_rids_query;
652 int rangesize = MAX_SAM_ENTRIES_W2K;
653 uint32 total_sids = 0;
654 int num_queries = 1;
655
656 *num_aliases = 0;
657 *alias_rids = NULL;
658
659 DEBUG(3,("rpc: lookup_useraliases\n"));
660
661 if ( !winbindd_can_contact_domain( domain ) ) {
662 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
663 domain->name));
664 return NT_STATUS_OK;
665 }
666
667 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
668 if (!NT_STATUS_IS_OK(result))
669 return result;
670
671 do {
672 /* prepare query */
673 struct lsa_SidArray sid_array;
674
675 ZERO_STRUCT(sid_array);
676
677 num_query_sids = MIN(num_sids - total_sids, rangesize);
678
679 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
680 num_queries, num_query_sids));
681
682 if (num_query_sids) {
683 sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
684 if (sid_array.sids == NULL) {
685 return NT_STATUS_NO_MEMORY;
686 }
687 } else {
688 sid_array.sids = NULL;
689 }
690
691 for (i=0; i<num_query_sids; i++) {
692 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]);
693 if (!sid_array.sids[i].sid) {
694 TALLOC_FREE(sid_array.sids);
695 return NT_STATUS_NO_MEMORY;
696 }
697 }
698 sid_array.num_sids = num_query_sids;
699
700 /* do request */
701 result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
702 &dom_pol,
703 &sid_array,
704 &alias_rids_query);
705
706 if (!NT_STATUS_IS_OK(result)) {
707 *num_aliases = 0;
708 *alias_rids = NULL;
709 TALLOC_FREE(sid_array.sids);
710 goto done;
711 }
712
713 /* process output */
714
715 for (i=0; i<alias_rids_query.count; i++) {
716 size_t na = *num_aliases;
717 if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],
718 alias_rids, &na)) {
719 return NT_STATUS_NO_MEMORY;
720 }
721 *num_aliases = na;
722 }
723
724 TALLOC_FREE(sid_array.sids);
725
726 num_queries++;
727
728 } while (total_sids < num_sids);
729
730 done:
731 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
732 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
733
734 return result;
735}
736
737
738/* Lookup group membership given a rid. */
739static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
740 TALLOC_CTX *mem_ctx,
741 const DOM_SID *group_sid, uint32 *num_names,
742 DOM_SID **sid_mem, char ***names,
743 uint32 **name_types)
744{
745 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
746 uint32 i, total_names = 0;
747 POLICY_HND dom_pol, group_pol;
748 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
749 uint32 *rid_mem = NULL;
750 uint32 group_rid;
751 unsigned int j, r;
752 struct rpc_pipe_client *cli;
753 unsigned int orig_timeout;
754 struct samr_RidTypeArray *rids = NULL;
755
756 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
757 sid_string_dbg(group_sid)));
758
759 if ( !winbindd_can_contact_domain( domain ) ) {
760 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
761 domain->name));
762 return NT_STATUS_OK;
763 }
764
765 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
766 return NT_STATUS_UNSUCCESSFUL;
767
768 *num_names = 0;
769
770 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
771 if (!NT_STATUS_IS_OK(result))
772 return result;
773
774 result = rpccli_samr_OpenGroup(cli, mem_ctx,
775 &dom_pol,
776 des_access,
777 group_rid,
778 &group_pol);
779
780 if (!NT_STATUS_IS_OK(result))
781 return result;
782
783 /* Step #1: Get a list of user rids that are the members of the
784 group. */
785
786 /* This call can take a long time - allow the server to time out.
787 35 seconds should do it. */
788
789 orig_timeout = cli_set_timeout(cli->cli, 35000);
790
791 result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
792 &group_pol,
793 &rids);
794
795 /* And restore our original timeout. */
796 cli_set_timeout(cli->cli, orig_timeout);
797
798 rpccli_samr_Close(cli, mem_ctx, &group_pol);
799
800 if (!NT_STATUS_IS_OK(result))
801 return result;
802
803 *num_names = rids->count;
804 rid_mem = rids->rids;
805
806 if (!*num_names) {
807 names = NULL;
808 name_types = NULL;
809 sid_mem = NULL;
810 return NT_STATUS_OK;
811 }
812
813 /* Step #2: Convert list of rids into list of usernames. Do this
814 in bunches of ~1000 to avoid crashing NT4. It looks like there
815 is a buffer overflow or something like that lurking around
816 somewhere. */
817
818#define MAX_LOOKUP_RIDS 900
819
820 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
821 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
822 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
823
824 for (j=0;j<(*num_names);j++)
825 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
826
827 if (*num_names>0 && (!*names || !*name_types))
828 return NT_STATUS_NO_MEMORY;
829
830 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
831 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
832 struct lsa_Strings tmp_names;
833 struct samr_Ids tmp_types;
834
835 /* Lookup a chunk of rids */
836
837 result = rpccli_samr_LookupRids(cli, mem_ctx,
838 &dom_pol,
839 num_lookup_rids,
840 &rid_mem[i],
841 &tmp_names,
842 &tmp_types);
843
844 /* see if we have a real error (and yes the
845 STATUS_SOME_UNMAPPED is the one returned from 2k) */
846
847 if (!NT_STATUS_IS_OK(result) &&
848 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
849 return result;
850
851 /* Copy result into array. The talloc system will take
852 care of freeing the temporary arrays later on. */
853
854 if (tmp_names.count != tmp_types.count) {
855 return NT_STATUS_UNSUCCESSFUL;
856 }
857
858 for (r=0; r<tmp_names.count; r++) {
859 if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
860 continue;
861 }
862 (*names)[total_names] = fill_domain_username_talloc(
863 mem_ctx, domain->name,
864 tmp_names.names[r].string, true);
865 (*name_types)[total_names] = tmp_types.ids[r];
866 total_names += 1;
867 }
868 }
869
870 *num_names = total_names;
871
872 return NT_STATUS_OK;
873}
874
875#ifdef HAVE_LDAP
876
877#include <ldap.h>
878
879static int get_ldap_seq(const char *server, int port, uint32 *seq)
880{
881 int ret = -1;
882 struct timeval to;
883 const char *attrs[] = {"highestCommittedUSN", NULL};
884 LDAPMessage *res = NULL;
885 char **values = NULL;
886 LDAP *ldp = NULL;
887
888 *seq = DOM_SEQUENCE_NONE;
889
890 /*
891 * Parameterised (5) second timeout on open. This is needed as the
892 * search timeout doesn't seem to apply to doing an open as well. JRA.
893 */
894
895 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
896 if (ldp == NULL)
897 return -1;
898
899 /* Timeout if no response within 20 seconds. */
900 to.tv_sec = 10;
901 to.tv_usec = 0;
902
903 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
904 CONST_DISCARD(char **, attrs), 0, &to, &res))
905 goto done;
906
907 if (ldap_count_entries(ldp, res) != 1)
908 goto done;
909
910 values = ldap_get_values(ldp, res, "highestCommittedUSN");
911 if (!values || !values[0])
912 goto done;
913
914 *seq = atoi(values[0]);
915 ret = 0;
916
917 done:
918
919 if (values)
920 ldap_value_free(values);
921 if (res)
922 ldap_msgfree(res);
923 if (ldp)
924 ldap_unbind(ldp);
925 return ret;
926}
927
928/**********************************************************************
929 Get the sequence number for a Windows AD native mode domain using
930 LDAP queries.
931**********************************************************************/
932
933static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
934{
935 int ret = -1;
936 char addr[INET6_ADDRSTRLEN];
937
938 print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
939 if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
940 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
941 "number for Domain (%s) from DC (%s)\n",
942 domain->name, addr));
943 }
944 return ret;
945}
946
947#endif /* HAVE_LDAP */
948
949/* find the sequence number for a domain */
950static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
951{
952 TALLOC_CTX *mem_ctx;
953 union samr_DomainInfo *info = NULL;
954 NTSTATUS result;
955 POLICY_HND dom_pol;
956 bool got_seq_num = False;
957 struct rpc_pipe_client *cli;
958
959 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
960
961 if ( !winbindd_can_contact_domain( domain ) ) {
962 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
963 domain->name));
964 *seq = time(NULL);
965 return NT_STATUS_OK;
966 }
967
968 *seq = DOM_SEQUENCE_NONE;
969
970 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
971 return NT_STATUS_NO_MEMORY;
972
973#ifdef HAVE_LDAP
974 if ( domain->active_directory )
975 {
976 int res;
977
978 DEBUG(8,("using get_ldap_seq() to retrieve the "
979 "sequence number\n"));
980
981 res = get_ldap_sequence_number( domain, seq );
982 if (res == 0)
983 {
984 result = NT_STATUS_OK;
985 DEBUG(10,("domain_sequence_number: LDAP for "
986 "domain %s is %u\n",
987 domain->name, *seq));
988 goto done;
989 }
990
991 DEBUG(10,("domain_sequence_number: failed to get LDAP "
992 "sequence number for domain %s\n",
993 domain->name ));
994 }
995#endif /* HAVE_LDAP */
996
997 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
998 if (!NT_STATUS_IS_OK(result)) {
999 goto done;
1000 }
1001
1002 /* Query domain info */
1003
1004 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1005 &dom_pol,
1006 8,
1007 &info);
1008
1009 if (NT_STATUS_IS_OK(result)) {
1010 *seq = info->info8.sequence_num;
1011 got_seq_num = True;
1012 goto seq_num;
1013 }
1014
1015 /* retry with info-level 2 in case the dc does not support info-level 8
1016 * (like all older samba2 and samba3 dc's) - Guenther */
1017
1018 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1019 &dom_pol,
1020 2,
1021 &info);
1022
1023 if (NT_STATUS_IS_OK(result)) {
1024 *seq = info->info2.sequence_num;
1025 got_seq_num = True;
1026 }
1027
1028 seq_num:
1029 if (got_seq_num) {
1030 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1031 domain->name, (unsigned)*seq));
1032 } else {
1033 DEBUG(10,("domain_sequence_number: failed to get sequence "
1034 "number (%u) for domain %s\n",
1035 (unsigned)*seq, domain->name ));
1036 }
1037
1038 done:
1039
1040 talloc_destroy(mem_ctx);
1041
1042 return result;
1043}
1044
1045/* get a list of trusted domains */
1046static NTSTATUS trusted_domains(struct winbindd_domain *domain,
1047 TALLOC_CTX *mem_ctx,
1048 uint32 *num_domains,
1049 char ***names,
1050 char ***alt_names,
1051 DOM_SID **dom_sids)
1052{
1053 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1054 uint32 enum_ctx = 0;
1055 struct rpc_pipe_client *cli;
1056 POLICY_HND lsa_policy;
1057
1058 DEBUG(3,("rpc: trusted_domains\n"));
1059
1060 *num_domains = 0;
1061 *names = NULL;
1062 *alt_names = NULL;
1063 *dom_sids = NULL;
1064
1065 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1066 if (!NT_STATUS_IS_OK(result))
1067 return result;
1068
1069 result = STATUS_MORE_ENTRIES;
1070
1071 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1072 uint32 start_idx;
1073 int i;
1074 struct lsa_DomainList dom_list;
1075
1076 result = rpccli_lsa_EnumTrustDom(cli, mem_ctx,
1077 &lsa_policy,
1078 &enum_ctx,
1079 &dom_list,
1080 (uint32_t)-1);
1081
1082 if (!NT_STATUS_IS_OK(result) &&
1083 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
1084 break;
1085
1086 start_idx = *num_domains;
1087 *num_domains += dom_list.count;
1088 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
1089 char *, *num_domains);
1090 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
1091 DOM_SID, *num_domains);
1092 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,
1093 char *, *num_domains);
1094 if ((*names == NULL) || (*dom_sids == NULL) ||
1095 (*alt_names == NULL))
1096 return NT_STATUS_NO_MEMORY;
1097
1098 for (i=0; i<dom_list.count; i++) {
1099 (*names)[start_idx+i] = CONST_DISCARD(char *, dom_list.domains[i].name.string);
1100 (*dom_sids)[start_idx+i] = *dom_list.domains[i].sid;
1101 (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
1102 }
1103 }
1104 return result;
1105}
1106
1107/* find the lockout policy for a domain */
1108static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
1109 TALLOC_CTX *mem_ctx,
1110 struct samr_DomInfo12 *lockout_policy)
1111{
1112 NTSTATUS result;
1113 struct rpc_pipe_client *cli;
1114 POLICY_HND dom_pol;
1115 union samr_DomainInfo *info = NULL;
1116
1117 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
1118
1119 if ( !winbindd_can_contact_domain( domain ) ) {
1120 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1121 domain->name));
1122 return NT_STATUS_NOT_SUPPORTED;
1123 }
1124
1125 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1126 if (!NT_STATUS_IS_OK(result)) {
1127 goto done;
1128 }
1129
1130 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1131 &dom_pol,
1132 12,
1133 &info);
1134 if (!NT_STATUS_IS_OK(result)) {
1135 goto done;
1136 }
1137
1138 *lockout_policy = info->info12;
1139
1140 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1141 info->info12.lockout_threshold));
1142
1143 done:
1144
1145 return result;
1146}
1147
1148/* find the password policy for a domain */
1149static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1150 TALLOC_CTX *mem_ctx,
1151 struct samr_DomInfo1 *password_policy)
1152{
1153 NTSTATUS result;
1154 struct rpc_pipe_client *cli;
1155 POLICY_HND dom_pol;
1156 union samr_DomainInfo *info = NULL;
1157
1158 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
1159
1160 if ( !winbindd_can_contact_domain( domain ) ) {
1161 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1162 domain->name));
1163 return NT_STATUS_NOT_SUPPORTED;
1164 }
1165
1166 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1167 if (!NT_STATUS_IS_OK(result)) {
1168 goto done;
1169 }
1170
1171 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1172 &dom_pol,
1173 1,
1174 &info);
1175 if (!NT_STATUS_IS_OK(result)) {
1176 goto done;
1177 }
1178
1179 *password_policy = info->info1;
1180
1181 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1182 info->info1.min_password_length));
1183
1184 done:
1185
1186 return result;
1187}
1188
1189
1190/* the rpc backend methods are exposed via this structure */
1191struct winbindd_methods msrpc_methods = {
1192 False,
1193 query_user_list,
1194 enum_dom_groups,
1195 enum_local_groups,
1196 msrpc_name_to_sid,
1197 msrpc_sid_to_name,
1198 msrpc_rids_to_names,
1199 query_user,
1200 lookup_usergroups,
1201 msrpc_lookup_useraliases,
1202 lookup_groupmem,
1203 sequence_number,
1204 msrpc_lockout_policy,
1205 msrpc_password_policy,
1206 trusted_domains,
1207};
Note: See TracBrowser for help on using the repository browser.