source: vendor/3.6.0/source3/winbindd/winbindd_samr.c

Last change on this file was 740, checked in by Silvan Scherrer, 13 years ago

Samba Server: update vendor to 3.6.0

File size: 26.5 KB
Line 
1/*
2 * Unix SMB/CIFS implementation.
3 *
4 * Winbind rpc backend functions
5 *
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>
11 *
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.
16 *
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.
21 *
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/>.
24 */
25
26#include "includes.h"
27#include "winbindd.h"
28#include "winbindd_rpc.h"
29#include "rpc_client/rpc_client.h"
30#include "../librpc/gen_ndr/ndr_samr_c.h"
31#include "rpc_client/cli_samr.h"
32#include "../librpc/gen_ndr/ndr_lsa_c.h"
33#include "rpc_client/cli_lsarpc.h"
34#include "rpc_server/rpc_ncacn_np.h"
35#include "../libcli/security/security.h"
36#include "passdb/machine_sid.h"
37#include "auth.h"
38
39#undef DBGC_CLASS
40#define DBGC_CLASS DBGC_WINBIND
41
42static NTSTATUS open_internal_samr_pipe(TALLOC_CTX *mem_ctx,
43 struct rpc_pipe_client **samr_pipe)
44{
45 struct rpc_pipe_client *cli = NULL;
46 struct auth_serversupplied_info *session_info = NULL;
47 NTSTATUS status;
48
49 if (session_info == NULL) {
50 status = make_session_info_system(mem_ctx, &session_info);
51 if (!NT_STATUS_IS_OK(status)) {
52 DEBUG(0, ("open_samr_pipe: Could not create auth_serversupplied_info: %s\n",
53 nt_errstr(status)));
54 return status;
55 }
56 }
57
58 /* create a samr connection */
59 status = rpc_pipe_open_interface(mem_ctx,
60 &ndr_table_samr.syntax_id,
61 session_info,
62 NULL,
63 winbind_messaging_context(),
64 &cli);
65 if (!NT_STATUS_IS_OK(status)) {
66 DEBUG(0, ("open_samr_pipe: Could not connect to samr_pipe: %s\n",
67 nt_errstr(status)));
68 return status;
69 }
70
71 if (samr_pipe) {
72 *samr_pipe = cli;
73 }
74
75 return NT_STATUS_OK;
76}
77
78NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
79 struct winbindd_domain *domain,
80 struct rpc_pipe_client **samr_pipe,
81 struct policy_handle *samr_domain_hnd)
82{
83 NTSTATUS status, result;
84 struct policy_handle samr_connect_hnd;
85 struct dcerpc_binding_handle *b;
86
87 status = open_internal_samr_pipe(mem_ctx, samr_pipe);
88 if (!NT_STATUS_IS_OK(status)) {
89 return status;
90 }
91
92 b = (*samr_pipe)->binding_handle;
93
94 status = dcerpc_samr_Connect2(b, mem_ctx,
95 (*samr_pipe)->desthost,
96 SEC_FLAG_MAXIMUM_ALLOWED,
97 &samr_connect_hnd,
98 &result);
99 if (!NT_STATUS_IS_OK(status)) {
100 return status;
101 }
102 if (!NT_STATUS_IS_OK(result)) {
103 return result;
104 }
105
106 status = dcerpc_samr_OpenDomain(b, mem_ctx,
107 &samr_connect_hnd,
108 SEC_FLAG_MAXIMUM_ALLOWED,
109 &domain->sid,
110 samr_domain_hnd,
111 &result);
112 if (!NT_STATUS_IS_OK(status)) {
113 return status;
114 }
115
116 return result;
117}
118
119static NTSTATUS open_internal_lsa_pipe(TALLOC_CTX *mem_ctx,
120 struct rpc_pipe_client **lsa_pipe)
121{
122 struct rpc_pipe_client *cli = NULL;
123 struct auth_serversupplied_info *session_info = NULL;
124 NTSTATUS status;
125
126 if (session_info == NULL) {
127 status = make_session_info_system(mem_ctx, &session_info);
128 if (!NT_STATUS_IS_OK(status)) {
129 DEBUG(0, ("open_lsa_pipe: Could not create auth_serversupplied_info: %s\n",
130 nt_errstr(status)));
131 return status;
132 }
133 }
134
135 /* create a lsa connection */
136 status = rpc_pipe_open_interface(mem_ctx,
137 &ndr_table_lsarpc.syntax_id,
138 session_info,
139 NULL,
140 winbind_messaging_context(),
141 &cli);
142 if (!NT_STATUS_IS_OK(status)) {
143 DEBUG(0, ("open_lsa_pipe: Could not connect to lsa_pipe: %s\n",
144 nt_errstr(status)));
145 return status;
146 }
147
148 if (lsa_pipe) {
149 *lsa_pipe = cli;
150 }
151
152 return NT_STATUS_OK;
153}
154
155static NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
156 struct rpc_pipe_client **lsa_pipe,
157 struct policy_handle *lsa_hnd)
158{
159 NTSTATUS status;
160
161 status = open_internal_lsa_pipe(mem_ctx, lsa_pipe);
162 if (!NT_STATUS_IS_OK(status)) {
163 return status;
164 }
165
166 status = rpccli_lsa_open_policy((*lsa_pipe),
167 mem_ctx,
168 true,
169 SEC_FLAG_MAXIMUM_ALLOWED,
170 lsa_hnd);
171
172 return status;
173}
174
175/*********************************************************************
176 SAM specific functions.
177*********************************************************************/
178
179/* List all domain groups */
180static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
181 TALLOC_CTX *mem_ctx,
182 uint32_t *pnum_info,
183 struct wb_acct_info **pinfo)
184{
185 struct rpc_pipe_client *samr_pipe;
186 struct policy_handle dom_pol;
187 struct wb_acct_info *info = NULL;
188 uint32_t num_info = 0;
189 TALLOC_CTX *tmp_ctx;
190 NTSTATUS status, result;
191 struct dcerpc_binding_handle *b = NULL;
192
193 DEBUG(3,("sam_enum_dom_groups\n"));
194
195 ZERO_STRUCT(dom_pol);
196
197 if (pnum_info) {
198 *pnum_info = 0;
199 }
200
201 tmp_ctx = talloc_stackframe();
202 if (tmp_ctx == NULL) {
203 return NT_STATUS_NO_MEMORY;
204 }
205
206 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
207 if (!NT_STATUS_IS_OK(status)) {
208 goto error;
209 }
210
211 b = samr_pipe->binding_handle;
212
213 status = rpc_enum_dom_groups(tmp_ctx,
214 samr_pipe,
215 &dom_pol,
216 &num_info,
217 &info);
218 if (!NT_STATUS_IS_OK(status)) {
219 goto error;
220 }
221
222 if (pnum_info) {
223 *pnum_info = num_info;
224 }
225
226 if (pinfo) {
227 *pinfo = talloc_move(mem_ctx, &info);
228 }
229
230error:
231 if (b && is_valid_policy_hnd(&dom_pol)) {
232 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
233 }
234 TALLOC_FREE(tmp_ctx);
235 return status;
236}
237
238/* Query display info for a domain */
239static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
240 TALLOC_CTX *mem_ctx,
241 uint32_t *pnum_info,
242 struct wbint_userinfo **pinfo)
243{
244 struct rpc_pipe_client *samr_pipe = NULL;
245 struct policy_handle dom_pol;
246 struct wbint_userinfo *info = NULL;
247 uint32_t num_info = 0;
248 TALLOC_CTX *tmp_ctx;
249 NTSTATUS status, result;
250 struct dcerpc_binding_handle *b = NULL;
251
252 DEBUG(3,("samr_query_user_list\n"));
253
254 ZERO_STRUCT(dom_pol);
255
256 if (pnum_info) {
257 *pnum_info = 0;
258 }
259
260 tmp_ctx = talloc_stackframe();
261 if (tmp_ctx == NULL) {
262 return NT_STATUS_NO_MEMORY;
263 }
264
265 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
266 if (!NT_STATUS_IS_OK(status)) {
267 goto done;
268 }
269
270 b = samr_pipe->binding_handle;
271
272 status = rpc_query_user_list(tmp_ctx,
273 samr_pipe,
274 &dom_pol,
275 &domain->sid,
276 &num_info,
277 &info);
278 if (!NT_STATUS_IS_OK(status)) {
279 goto done;
280 }
281
282 if (pnum_info) {
283 *pnum_info = num_info;
284 }
285
286 if (pinfo) {
287 *pinfo = talloc_move(mem_ctx, &info);
288 }
289
290done:
291 if (b && is_valid_policy_hnd(&dom_pol)) {
292 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
293 }
294
295 TALLOC_FREE(tmp_ctx);
296 return status;
297}
298
299/* Lookup user information from a rid or username. */
300static NTSTATUS sam_query_user(struct winbindd_domain *domain,
301 TALLOC_CTX *mem_ctx,
302 const struct dom_sid *user_sid,
303 struct wbint_userinfo *user_info)
304{
305 struct rpc_pipe_client *samr_pipe;
306 struct policy_handle dom_pol;
307 TALLOC_CTX *tmp_ctx;
308 NTSTATUS status, result;
309 struct dcerpc_binding_handle *b = NULL;
310
311 DEBUG(3,("sam_query_user\n"));
312
313 ZERO_STRUCT(dom_pol);
314
315 /* Paranoia check */
316 if (!sid_check_is_in_our_domain(user_sid)) {
317 return NT_STATUS_NO_SUCH_USER;
318 }
319
320 if (user_info) {
321 user_info->homedir = NULL;
322 user_info->shell = NULL;
323 user_info->primary_gid = (gid_t) -1;
324 }
325
326 tmp_ctx = talloc_stackframe();
327 if (tmp_ctx == NULL) {
328 return NT_STATUS_NO_MEMORY;
329 }
330
331 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
332 if (!NT_STATUS_IS_OK(status)) {
333 goto done;
334 }
335
336 b = samr_pipe->binding_handle;
337
338 status = rpc_query_user(tmp_ctx,
339 samr_pipe,
340 &dom_pol,
341 &domain->sid,
342 user_sid,
343 user_info);
344
345done:
346 if (b && is_valid_policy_hnd(&dom_pol)) {
347 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
348 }
349
350 TALLOC_FREE(tmp_ctx);
351 return status;
352}
353
354/* get a list of trusted domains - builtin domain */
355static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
356 TALLOC_CTX *mem_ctx,
357 struct netr_DomainTrustList *ptrust_list)
358{
359 struct rpc_pipe_client *lsa_pipe;
360 struct policy_handle lsa_policy;
361 struct netr_DomainTrust *trusts = NULL;
362 uint32_t num_trusts = 0;
363 TALLOC_CTX *tmp_ctx;
364 NTSTATUS status, result;
365 struct dcerpc_binding_handle *b = NULL;
366
367 DEBUG(3,("samr: trusted domains\n"));
368
369 ZERO_STRUCT(lsa_policy);
370
371 if (ptrust_list) {
372 ZERO_STRUCTP(ptrust_list);
373 }
374
375 tmp_ctx = talloc_stackframe();
376 if (tmp_ctx == NULL) {
377 return NT_STATUS_NO_MEMORY;
378 }
379
380 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
381 if (!NT_STATUS_IS_OK(status)) {
382 goto done;
383 }
384
385 b = lsa_pipe->binding_handle;
386
387 status = rpc_trusted_domains(tmp_ctx,
388 lsa_pipe,
389 &lsa_policy,
390 &num_trusts,
391 &trusts);
392 if (!NT_STATUS_IS_OK(status)) {
393 goto done;
394 }
395
396 if (ptrust_list) {
397 ptrust_list->count = num_trusts;
398 ptrust_list->array = talloc_move(mem_ctx, &trusts);
399 }
400
401done:
402 if (b && is_valid_policy_hnd(&lsa_policy)) {
403 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
404 }
405
406 TALLOC_FREE(tmp_ctx);
407 return status;
408}
409
410/* Lookup group membership given a rid. */
411static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
412 TALLOC_CTX *mem_ctx,
413 const struct dom_sid *group_sid,
414 enum lsa_SidType type,
415 uint32_t *pnum_names,
416 struct dom_sid **psid_mem,
417 char ***pnames,
418 uint32_t **pname_types)
419{
420 struct rpc_pipe_client *samr_pipe;
421 struct policy_handle dom_pol;
422
423 uint32_t num_names = 0;
424 struct dom_sid *sid_mem = NULL;
425 char **names = NULL;
426 uint32_t *name_types = NULL;
427
428 TALLOC_CTX *tmp_ctx;
429 NTSTATUS status, result;
430 struct dcerpc_binding_handle *b = NULL;
431
432 DEBUG(3,("sam_lookup_groupmem\n"));
433
434 ZERO_STRUCT(dom_pol);
435
436 /* Paranoia check */
437 if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
438 /* There's no groups, only aliases in BUILTIN */
439 return NT_STATUS_NO_SUCH_GROUP;
440 }
441
442 if (pnum_names) {
443 pnum_names = 0;
444 }
445
446 tmp_ctx = talloc_stackframe();
447 if (tmp_ctx == NULL) {
448 return NT_STATUS_NO_MEMORY;
449 }
450
451 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
452 if (!NT_STATUS_IS_OK(status)) {
453 goto done;
454 }
455
456 b = samr_pipe->binding_handle;
457
458 status = rpc_lookup_groupmem(tmp_ctx,
459 samr_pipe,
460 &dom_pol,
461 domain->name,
462 &domain->sid,
463 group_sid,
464 type,
465 &num_names,
466 &sid_mem,
467 &names,
468 &name_types);
469
470 if (pnum_names) {
471 *pnum_names = num_names;
472 }
473
474 if (pnames) {
475 *pnames = talloc_move(mem_ctx, &names);
476 }
477
478 if (pname_types) {
479 *pname_types = talloc_move(mem_ctx, &name_types);
480 }
481
482 if (psid_mem) {
483 *psid_mem = talloc_move(mem_ctx, &sid_mem);
484 }
485
486done:
487 if (b && is_valid_policy_hnd(&dom_pol)) {
488 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
489 }
490
491 TALLOC_FREE(tmp_ctx);
492 return status;
493}
494
495/*********************************************************************
496 BUILTIN specific functions.
497*********************************************************************/
498
499/* List all domain groups */
500static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
501 TALLOC_CTX *mem_ctx,
502 uint32 *num_entries,
503 struct wb_acct_info **info)
504{
505 /* BUILTIN doesn't have domain groups */
506 *num_entries = 0;
507 *info = NULL;
508 return NT_STATUS_OK;
509}
510
511/* Query display info for a domain */
512static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
513 TALLOC_CTX *mem_ctx,
514 uint32 *num_entries,
515 struct wbint_userinfo **info)
516{
517 /* We don't have users */
518 *num_entries = 0;
519 *info = NULL;
520 return NT_STATUS_OK;
521}
522
523/* Lookup user information from a rid or username. */
524static NTSTATUS builtin_query_user(struct winbindd_domain *domain,
525 TALLOC_CTX *mem_ctx,
526 const struct dom_sid *user_sid,
527 struct wbint_userinfo *user_info)
528{
529 return NT_STATUS_NO_SUCH_USER;
530}
531
532/* get a list of trusted domains - builtin domain */
533static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
534 TALLOC_CTX *mem_ctx,
535 struct netr_DomainTrustList *trusts)
536{
537 ZERO_STRUCTP(trusts);
538 return NT_STATUS_OK;
539}
540
541/*********************************************************************
542 COMMON functions.
543*********************************************************************/
544
545/* List all local groups (aliases) */
546static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
547 TALLOC_CTX *mem_ctx,
548 uint32_t *pnum_info,
549 struct wb_acct_info **pinfo)
550{
551 struct rpc_pipe_client *samr_pipe;
552 struct policy_handle dom_pol;
553 struct wb_acct_info *info = NULL;
554 uint32_t num_info = 0;
555 TALLOC_CTX *tmp_ctx;
556 NTSTATUS status, result;
557 struct dcerpc_binding_handle *b = NULL;
558
559 DEBUG(3,("samr: enum local groups\n"));
560
561 ZERO_STRUCT(dom_pol);
562
563 if (pnum_info) {
564 *pnum_info = 0;
565 }
566
567 tmp_ctx = talloc_stackframe();
568 if (tmp_ctx == NULL) {
569 return NT_STATUS_NO_MEMORY;
570 }
571
572 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
573 if (!NT_STATUS_IS_OK(status)) {
574 goto done;
575 }
576
577 b = samr_pipe->binding_handle;
578
579 status = rpc_enum_local_groups(mem_ctx,
580 samr_pipe,
581 &dom_pol,
582 &num_info,
583 &info);
584 if (!NT_STATUS_IS_OK(status)) {
585 goto done;
586 }
587
588 if (pnum_info) {
589 *pnum_info = num_info;
590 }
591
592 if (pinfo) {
593 *pinfo = talloc_move(mem_ctx, &info);
594 }
595
596done:
597 if (b && is_valid_policy_hnd(&dom_pol)) {
598 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
599 }
600
601 TALLOC_FREE(tmp_ctx);
602 return status;
603}
604
605/* convert a single name to a sid in a domain */
606static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
607 TALLOC_CTX *mem_ctx,
608 const char *domain_name,
609 const char *name,
610 uint32_t flags,
611 struct dom_sid *psid,
612 enum lsa_SidType *ptype)
613{
614 struct rpc_pipe_client *lsa_pipe;
615 struct policy_handle lsa_policy;
616 struct dom_sid sid;
617 enum lsa_SidType type;
618 TALLOC_CTX *tmp_ctx;
619 NTSTATUS status, result;
620 struct dcerpc_binding_handle *b = NULL;
621
622 DEBUG(3,("sam_name_to_sid\n"));
623
624 ZERO_STRUCT(lsa_policy);
625
626 tmp_ctx = talloc_stackframe();
627 if (tmp_ctx == NULL) {
628 return NT_STATUS_NO_MEMORY;
629 }
630
631 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
632 if (!NT_STATUS_IS_OK(status)) {
633 goto done;
634 }
635
636 b = lsa_pipe->binding_handle;
637
638 status = rpc_name_to_sid(tmp_ctx,
639 lsa_pipe,
640 &lsa_policy,
641 domain_name,
642 name,
643 flags,
644 &sid,
645 &type);
646 if (!NT_STATUS_IS_OK(status)) {
647 goto done;
648 }
649
650 if (psid) {
651 sid_copy(psid, &sid);
652 }
653 if (ptype) {
654 *ptype = type;
655 }
656
657done:
658 if (b && is_valid_policy_hnd(&lsa_policy)) {
659 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
660 }
661
662 TALLOC_FREE(tmp_ctx);
663 return status;
664}
665
666/* convert a domain SID to a user or group name */
667static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
668 TALLOC_CTX *mem_ctx,
669 const struct dom_sid *sid,
670 char **pdomain_name,
671 char **pname,
672 enum lsa_SidType *ptype)
673{
674 struct rpc_pipe_client *lsa_pipe;
675 struct policy_handle lsa_policy;
676 char *domain_name = NULL;
677 char *name = NULL;
678 enum lsa_SidType type;
679 TALLOC_CTX *tmp_ctx;
680 NTSTATUS status, result;
681 struct dcerpc_binding_handle *b = NULL;
682
683 DEBUG(3,("sam_sid_to_name\n"));
684
685 ZERO_STRUCT(lsa_policy);
686
687 /* Paranoia check */
688 if (!sid_check_is_in_builtin(sid) &&
689 !sid_check_is_in_our_domain(sid) &&
690 !sid_check_is_in_unix_users(sid) &&
691 !sid_check_is_unix_users(sid) &&
692 !sid_check_is_in_unix_groups(sid) &&
693 !sid_check_is_unix_groups(sid) &&
694 !sid_check_is_in_wellknown_domain(sid)) {
695 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
696 "lookup SID %s\n", sid_string_dbg(sid)));
697 return NT_STATUS_NONE_MAPPED;
698 }
699
700 tmp_ctx = talloc_stackframe();
701 if (tmp_ctx == NULL) {
702 return NT_STATUS_NO_MEMORY;
703 }
704
705 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
706 if (!NT_STATUS_IS_OK(status)) {
707 goto done;
708 }
709
710 b = lsa_pipe->binding_handle;
711
712 status = rpc_sid_to_name(tmp_ctx,
713 lsa_pipe,
714 &lsa_policy,
715 domain,
716 sid,
717 &domain_name,
718 &name,
719 &type);
720
721 if (ptype) {
722 *ptype = type;
723 }
724
725 if (pname) {
726 *pname = talloc_move(mem_ctx, &name);
727 }
728
729 if (pdomain_name) {
730 *pdomain_name = talloc_move(mem_ctx, &domain_name);
731 }
732
733done:
734 if (b && is_valid_policy_hnd(&lsa_policy)) {
735 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
736 }
737
738 TALLOC_FREE(tmp_ctx);
739 return status;
740}
741
742static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
743 TALLOC_CTX *mem_ctx,
744 const struct dom_sid *domain_sid,
745 uint32 *rids,
746 size_t num_rids,
747 char **pdomain_name,
748 char ***pnames,
749 enum lsa_SidType **ptypes)
750{
751 struct rpc_pipe_client *lsa_pipe;
752 struct policy_handle lsa_policy;
753 enum lsa_SidType *types = NULL;
754 char *domain_name = NULL;
755 char **names = NULL;
756 TALLOC_CTX *tmp_ctx;
757 NTSTATUS status, result;
758 struct dcerpc_binding_handle *b = NULL;
759
760 DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
761
762 ZERO_STRUCT(lsa_policy);
763
764 /* Paranoia check */
765 if (!sid_check_is_builtin(domain_sid) &&
766 !sid_check_is_domain(domain_sid) &&
767 !sid_check_is_unix_users(domain_sid) &&
768 !sid_check_is_unix_groups(domain_sid) &&
769 !sid_check_is_in_wellknown_domain(domain_sid)) {
770 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
771 "lookup SID %s\n", sid_string_dbg(domain_sid)));
772 return NT_STATUS_NONE_MAPPED;
773 }
774
775 tmp_ctx = talloc_stackframe();
776 if (tmp_ctx == NULL) {
777 return NT_STATUS_NO_MEMORY;
778 }
779
780 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
781 if (!NT_STATUS_IS_OK(status)) {
782 goto done;
783 }
784
785 b = lsa_pipe->binding_handle;
786
787 status = rpc_rids_to_names(tmp_ctx,
788 lsa_pipe,
789 &lsa_policy,
790 domain,
791 domain_sid,
792 rids,
793 num_rids,
794 &domain_name,
795 &names,
796 &types);
797 if (!NT_STATUS_IS_OK(status)) {
798 goto done;
799 }
800
801 if (pdomain_name) {
802 *pdomain_name = talloc_move(mem_ctx, &domain_name);
803 }
804
805 if (ptypes) {
806 *ptypes = talloc_move(mem_ctx, &types);
807 }
808
809 if (pnames) {
810 *pnames = talloc_move(mem_ctx, &names);
811 }
812
813done:
814 if (b && is_valid_policy_hnd(&lsa_policy)) {
815 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
816 }
817
818 TALLOC_FREE(tmp_ctx);
819 return status;
820}
821
822static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
823 TALLOC_CTX *mem_ctx,
824 struct samr_DomInfo12 *lockout_policy)
825{
826 struct rpc_pipe_client *samr_pipe;
827 struct policy_handle dom_pol;
828 union samr_DomainInfo *info = NULL;
829 TALLOC_CTX *tmp_ctx;
830 NTSTATUS status, result;
831 struct dcerpc_binding_handle *b = NULL;
832
833 DEBUG(3,("sam_lockout_policy\n"));
834
835 ZERO_STRUCT(dom_pol);
836
837 tmp_ctx = talloc_stackframe();
838 if (tmp_ctx == NULL) {
839 return NT_STATUS_NO_MEMORY;
840 }
841
842 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
843 if (!NT_STATUS_IS_OK(status)) {
844 goto error;
845 }
846
847 b = samr_pipe->binding_handle;
848
849 status = dcerpc_samr_QueryDomainInfo(b,
850 mem_ctx,
851 &dom_pol,
852 12,
853 &info,
854 &result);
855 if (!NT_STATUS_IS_OK(status)) {
856 goto error;
857 }
858 if (!NT_STATUS_IS_OK(result)) {
859 status = result;
860 goto error;
861 }
862
863 *lockout_policy = info->info12;
864
865error:
866 if (b && is_valid_policy_hnd(&dom_pol)) {
867 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
868 }
869
870 TALLOC_FREE(tmp_ctx);
871 return status;
872}
873
874static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
875 TALLOC_CTX *mem_ctx,
876 struct samr_DomInfo1 *passwd_policy)
877{
878 struct rpc_pipe_client *samr_pipe;
879 struct policy_handle dom_pol;
880 union samr_DomainInfo *info = NULL;
881 TALLOC_CTX *tmp_ctx;
882 NTSTATUS status, result;
883 struct dcerpc_binding_handle *b = NULL;
884
885 DEBUG(3,("sam_password_policy\n"));
886
887 ZERO_STRUCT(dom_pol);
888
889 tmp_ctx = talloc_stackframe();
890 if (tmp_ctx == NULL) {
891 return NT_STATUS_NO_MEMORY;
892 }
893
894 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
895 if (!NT_STATUS_IS_OK(status)) {
896 goto error;
897 }
898
899 b = samr_pipe->binding_handle;
900
901 status = dcerpc_samr_QueryDomainInfo(b,
902 mem_ctx,
903 &dom_pol,
904 1,
905 &info,
906 &result);
907 if (!NT_STATUS_IS_OK(status)) {
908 goto error;
909 }
910 if (!NT_STATUS_IS_OK(result)) {
911 status = result;
912 goto error;
913 }
914
915 *passwd_policy = info->info1;
916
917error:
918 if (b && is_valid_policy_hnd(&dom_pol)) {
919 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
920 }
921
922 TALLOC_FREE(tmp_ctx);
923 return status;
924}
925
926/* Lookup groups a user is a member of. */
927static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
928 TALLOC_CTX *mem_ctx,
929 const struct dom_sid *user_sid,
930 uint32_t *pnum_groups,
931 struct dom_sid **puser_grpsids)
932{
933 struct rpc_pipe_client *samr_pipe;
934 struct policy_handle dom_pol;
935 struct dom_sid *user_grpsids = NULL;
936 uint32_t num_groups = 0;
937 TALLOC_CTX *tmp_ctx;
938 NTSTATUS status, result;
939 struct dcerpc_binding_handle *b = NULL;
940
941 DEBUG(3,("sam_lookup_usergroups\n"));
942
943 ZERO_STRUCT(dom_pol);
944
945 if (pnum_groups) {
946 *pnum_groups = 0;
947 }
948
949 tmp_ctx = talloc_stackframe();
950 if (tmp_ctx == NULL) {
951 return NT_STATUS_NO_MEMORY;
952 }
953
954 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
955 if (!NT_STATUS_IS_OK(status)) {
956 goto done;
957 }
958
959 b = samr_pipe->binding_handle;
960
961 status = rpc_lookup_usergroups(tmp_ctx,
962 samr_pipe,
963 &dom_pol,
964 &domain->sid,
965 user_sid,
966 &num_groups,
967 &user_grpsids);
968 if (!NT_STATUS_IS_OK(status)) {
969 goto done;
970 }
971
972 if (pnum_groups) {
973 *pnum_groups = num_groups;
974 }
975
976 if (puser_grpsids) {
977 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
978 }
979
980done:
981 if (b && is_valid_policy_hnd(&dom_pol)) {
982 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
983 }
984
985 TALLOC_FREE(tmp_ctx);
986 return status;
987}
988
989static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
990 TALLOC_CTX *mem_ctx,
991 uint32_t num_sids,
992 const struct dom_sid *sids,
993 uint32_t *pnum_aliases,
994 uint32_t **palias_rids)
995{
996 struct rpc_pipe_client *samr_pipe;
997 struct policy_handle dom_pol;
998 uint32_t num_aliases = 0;
999 uint32_t *alias_rids = NULL;
1000 TALLOC_CTX *tmp_ctx;
1001 NTSTATUS status, result;
1002 struct dcerpc_binding_handle *b = NULL;
1003
1004 DEBUG(3,("sam_lookup_useraliases\n"));
1005
1006 ZERO_STRUCT(dom_pol);
1007
1008 if (pnum_aliases) {
1009 *pnum_aliases = 0;
1010 }
1011
1012 tmp_ctx = talloc_stackframe();
1013 if (tmp_ctx == NULL) {
1014 return NT_STATUS_NO_MEMORY;
1015 }
1016
1017 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
1018 if (!NT_STATUS_IS_OK(status)) {
1019 goto done;
1020 }
1021
1022 b = samr_pipe->binding_handle;
1023
1024 status = rpc_lookup_useraliases(tmp_ctx,
1025 samr_pipe,
1026 &dom_pol,
1027 num_sids,
1028 sids,
1029 &num_aliases,
1030 &alias_rids);
1031 if (!NT_STATUS_IS_OK(status)) {
1032 goto done;
1033 }
1034
1035 if (pnum_aliases) {
1036 *pnum_aliases = num_aliases;
1037 }
1038
1039 if (palias_rids) {
1040 *palias_rids = talloc_move(mem_ctx, &alias_rids);
1041 }
1042
1043done:
1044 if (b && is_valid_policy_hnd(&dom_pol)) {
1045 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
1046 }
1047
1048 TALLOC_FREE(tmp_ctx);
1049 return status;
1050}
1051
1052/* find the sequence number for a domain */
1053static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
1054 uint32_t *pseq)
1055{
1056 struct rpc_pipe_client *samr_pipe;
1057 struct policy_handle dom_pol;
1058 uint32_t seq;
1059 TALLOC_CTX *tmp_ctx;
1060 NTSTATUS status, result;
1061 struct dcerpc_binding_handle *b = NULL;
1062
1063 DEBUG(3,("samr: sequence number\n"));
1064
1065 ZERO_STRUCT(dom_pol);
1066
1067 if (pseq) {
1068 *pseq = DOM_SEQUENCE_NONE;
1069 }
1070
1071 tmp_ctx = talloc_stackframe();
1072 if (tmp_ctx == NULL) {
1073 return NT_STATUS_NO_MEMORY;
1074 }
1075
1076 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
1077 if (!NT_STATUS_IS_OK(status)) {
1078 goto done;
1079 }
1080
1081 b = samr_pipe->binding_handle;
1082
1083 status = rpc_sequence_number(tmp_ctx,
1084 samr_pipe,
1085 &dom_pol,
1086 domain->name,
1087 &seq);
1088 if (!NT_STATUS_IS_OK(status)) {
1089 goto done;
1090 }
1091
1092 if (pseq) {
1093 *pseq = seq;
1094 }
1095done:
1096 if (b && is_valid_policy_hnd(&dom_pol)) {
1097 dcerpc_samr_Close(b, tmp_ctx, &dom_pol, &result);
1098 }
1099
1100 TALLOC_FREE(tmp_ctx);
1101 return status;
1102}
1103
1104/* the rpc backend methods are exposed via this structure */
1105struct winbindd_methods builtin_passdb_methods = {
1106 .consistent = false,
1107
1108 .query_user_list = builtin_query_user_list,
1109 .enum_dom_groups = builtin_enum_dom_groups,
1110 .enum_local_groups = sam_enum_local_groups,
1111 .name_to_sid = sam_name_to_sid,
1112 .sid_to_name = sam_sid_to_name,
1113 .rids_to_names = sam_rids_to_names,
1114 .query_user = builtin_query_user,
1115 .lookup_usergroups = sam_lookup_usergroups,
1116 .lookup_useraliases = sam_lookup_useraliases,
1117 .lookup_groupmem = sam_lookup_groupmem,
1118 .sequence_number = sam_sequence_number,
1119 .lockout_policy = sam_lockout_policy,
1120 .password_policy = sam_password_policy,
1121 .trusted_domains = builtin_trusted_domains
1122};
1123
1124/* the rpc backend methods are exposed via this structure */
1125struct winbindd_methods sam_passdb_methods = {
1126 .consistent = false,
1127
1128 .query_user_list = sam_query_user_list,
1129 .enum_dom_groups = sam_enum_dom_groups,
1130 .enum_local_groups = sam_enum_local_groups,
1131 .name_to_sid = sam_name_to_sid,
1132 .sid_to_name = sam_sid_to_name,
1133 .rids_to_names = sam_rids_to_names,
1134 .query_user = sam_query_user,
1135 .lookup_usergroups = sam_lookup_usergroups,
1136 .lookup_useraliases = sam_lookup_useraliases,
1137 .lookup_groupmem = sam_lookup_groupmem,
1138 .sequence_number = sam_sequence_number,
1139 .lockout_policy = sam_lockout_policy,
1140 .password_policy = sam_password_policy,
1141 .trusted_domains = sam_trusted_domains
1142};
Note: See TracBrowser for help on using the repository browser.