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