s3-rpc_client: add and use rpc_client/rpc_client.h.
[samba.git] / source3 / winbindd / winbindd_rpc.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 "rpc_client/rpc_client.h"
31 #include "librpc/gen_ndr/ndr_samr_c.h"
32 #include "librpc/gen_ndr/srv_samr.h"
33 #include "librpc/gen_ndr/ndr_lsa_c.h"
34 #include "librpc/gen_ndr/srv_lsa.h"
35 #include "rpc_client/cli_samr.h"
36 #include "rpc_client/cli_lsarpc.h"
37 #include "../libcli/security/security.h"
38
39 /* Query display info for a domain */
40 NTSTATUS rpc_query_user_list(TALLOC_CTX *mem_ctx,
41                              struct rpc_pipe_client *samr_pipe,
42                              struct policy_handle *samr_policy,
43                              const struct dom_sid *domain_sid,
44                              uint32_t *pnum_info,
45                              struct wbint_userinfo **pinfo)
46 {
47         struct wbint_userinfo *info = NULL;
48         uint32_t num_info = 0;
49         uint32_t loop_count = 0;
50         uint32_t start_idx = 0;
51         uint32_t i = 0;
52         NTSTATUS status, result;
53         struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
54
55         *pnum_info = 0;
56
57         do {
58                 uint32_t j;
59                 uint32_t num_dom_users;
60                 uint32_t max_entries, max_size;
61                 uint32_t total_size, returned_size;
62                 union samr_DispInfo disp_info;
63
64                 dcerpc_get_query_dispinfo_params(loop_count,
65                                                  &max_entries,
66                                                  &max_size);
67
68                 status = dcerpc_samr_QueryDisplayInfo(b,
69                                                       mem_ctx,
70                                                       samr_policy,
71                                                       1, /* level */
72                                                       start_idx,
73                                                       max_entries,
74                                                       max_size,
75                                                       &total_size,
76                                                       &returned_size,
77                                                       &disp_info,
78                                                       &result);
79                 if (!NT_STATUS_IS_OK(status)) {
80                         return status;
81                 }
82                 if (!NT_STATUS_IS_OK(result)) {
83                         if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
84                                 return result;
85                         }
86                 }
87
88                 /* increment required start query values */
89                 start_idx += disp_info.info1.count;
90                 loop_count++;
91                 num_dom_users = disp_info.info1.count;
92
93                 num_info += num_dom_users;
94
95                 info = TALLOC_REALLOC_ARRAY(mem_ctx,
96                                             info,
97                                             struct wbint_userinfo,
98                                             num_info);
99                 if (info == NULL) {
100                         return NT_STATUS_NO_MEMORY;
101                 }
102
103                 for (j = 0; j < num_dom_users; i++, j++) {
104                         uint32_t rid = disp_info.info1.entries[j].rid;
105                         struct samr_DispEntryGeneral *src;
106                         struct wbint_userinfo *dst;
107
108                         src = &(disp_info.info1.entries[j]);
109                         dst = &(info[i]);
110
111                         dst->acct_name = talloc_strdup(info,
112                                                        src->account_name.string);
113                         if (dst->acct_name == NULL) {
114                                 return NT_STATUS_NO_MEMORY;
115                         }
116
117                         dst->full_name = talloc_strdup(info, src->full_name.string);
118                         if ((src->full_name.string != NULL) &&
119                             (dst->full_name == NULL))
120                         {
121                                 return NT_STATUS_NO_MEMORY;
122                         }
123
124                         dst->homedir = NULL;
125                         dst->shell = NULL;
126
127                         sid_compose(&dst->user_sid, domain_sid, rid);
128
129                         /* For the moment we set the primary group for
130                            every user to be the Domain Users group.
131                            There are serious problems with determining
132                            the actual primary group for large domains.
133                            This should really be made into a 'winbind
134                            force group' smb.conf parameter or
135                            something like that. */
136                         sid_compose(&dst->group_sid, domain_sid,
137                                     DOMAIN_RID_USERS);
138                 }
139         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
140
141         *pnum_info = num_info;
142         *pinfo = info;
143
144         return NT_STATUS_OK;
145 }
146
147 /* List all domain groups */
148 NTSTATUS rpc_enum_dom_groups(TALLOC_CTX *mem_ctx,
149                              struct rpc_pipe_client *samr_pipe,
150                              struct policy_handle *samr_policy,
151                              uint32_t *pnum_info,
152                              struct wb_acct_info **pinfo)
153 {
154         struct wb_acct_info *info = NULL;
155         uint32_t start = 0;
156         uint32_t num_info = 0;
157         NTSTATUS status, result;
158         struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
159
160         *pnum_info = 0;
161
162         do {
163                 struct samr_SamArray *sam_array = NULL;
164                 uint32_t count = 0;
165                 uint32_t g;
166
167                 /* start is updated by this call. */
168                 status = dcerpc_samr_EnumDomainGroups(b,
169                                                       mem_ctx,
170                                                       samr_policy,
171                                                       &start,
172                                                       &sam_array,
173                                                       0xFFFF, /* buffer size? */
174                                                       &count,
175                                                       &result);
176                 if (!NT_STATUS_IS_OK(status)) {
177                         return status;
178                 }
179                 if (!NT_STATUS_IS_OK(result)) {
180                         if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
181                                 DEBUG(2,("query_user_list: failed to enum domain groups: %s\n",
182                                          nt_errstr(result)));
183                                 return result;
184                         }
185                 }
186
187                 info = TALLOC_REALLOC_ARRAY(mem_ctx,
188                                             info,
189                                             struct wb_acct_info,
190                                             num_info + count);
191                 if (info == NULL) {
192                         return NT_STATUS_NO_MEMORY;
193                 }
194
195                 for (g = 0; g < count; g++) {
196                         fstrcpy(info[num_info + g].acct_name,
197                                 sam_array->entries[g].name.string);
198
199                         info[num_info + g].rid = sam_array->entries[g].idx;
200                 }
201
202                 num_info += count;
203         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
204
205         *pnum_info = num_info;
206         *pinfo = info;
207
208         return NT_STATUS_OK;
209 }
210
211 NTSTATUS rpc_enum_local_groups(TALLOC_CTX *mem_ctx,
212                                struct rpc_pipe_client *samr_pipe,
213                                struct policy_handle *samr_policy,
214                                uint32_t *pnum_info,
215                                struct wb_acct_info **pinfo)
216 {
217         struct wb_acct_info *info = NULL;
218         uint32_t num_info = 0;
219         NTSTATUS status, result;
220         struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
221
222         *pnum_info = 0;
223
224         do {
225                 struct samr_SamArray *sam_array = NULL;
226                 uint32_t count = 0;
227                 uint32_t start = num_info;
228                 uint32_t g;
229
230                 status = dcerpc_samr_EnumDomainAliases(b,
231                                                        mem_ctx,
232                                                        samr_policy,
233                                                        &start,
234                                                        &sam_array,
235                                                        0xFFFF, /* buffer size? */
236                                                        &count,
237                                                        &result);
238                 if (!NT_STATUS_IS_OK(status)) {
239                         return status;
240                 }
241                 if (!NT_STATUS_IS_OK(result)) {
242                         if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
243                                 return result;
244                         }
245                 }
246
247                 info = TALLOC_REALLOC_ARRAY(mem_ctx,
248                                             info,
249                                             struct wb_acct_info,
250                                             num_info + count);
251                 if (info == NULL) {
252                         return  NT_STATUS_NO_MEMORY;
253                 }
254
255                 for (g = 0; g < count; g++) {
256                         fstrcpy(info[num_info + g].acct_name,
257                                 sam_array->entries[g].name.string);
258                         info[num_info + g].rid = sam_array->entries[g].idx;
259                 }
260
261                 num_info += count;
262         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
263
264         *pnum_info = num_info;
265         *pinfo = info;
266
267         return NT_STATUS_OK;
268 }
269
270 /* convert a single name to a sid in a domain */
271 NTSTATUS rpc_name_to_sid(TALLOC_CTX *mem_ctx,
272                          struct rpc_pipe_client *lsa_pipe,
273                          struct policy_handle *lsa_policy,
274                          const char *domain_name,
275                          const char *name,
276                          uint32_t flags,
277                          struct dom_sid *sid,
278                          enum lsa_SidType *type)
279 {
280         enum lsa_SidType *types = NULL;
281         struct dom_sid *sids = NULL;
282         char *full_name = NULL;
283         char *mapped_name = NULL;
284         NTSTATUS status;
285
286         if (name == NULL || name[0] == '\0') {
287                 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
288         } else if (domain_name == NULL || domain_name[0] == '\0') {
289                 full_name = talloc_asprintf(mem_ctx, "%s", name);
290         } else {
291                 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
292         }
293
294         if (full_name == NULL) {
295                 return NT_STATUS_NO_MEMORY;
296         }
297
298         status = normalize_name_unmap(mem_ctx, full_name, &mapped_name);
299         /* Reset the full_name pointer if we mapped anything */
300         if (NT_STATUS_IS_OK(status) ||
301             NT_STATUS_EQUAL(status, NT_STATUS_FILE_RENAMED)) {
302                 full_name = mapped_name;
303         }
304
305         DEBUG(3,("name_to_sid: %s for domain %s\n",
306                  full_name ? full_name : "", domain_name ));
307
308         /*
309          * We don't run into deadlocks here, cause winbind_off() is
310          * called in the main function.
311          */
312         status = rpccli_lsa_lookup_names(lsa_pipe,
313                                          mem_ctx,
314                                          lsa_policy,
315                                          1, /* num_names */
316                                          (const char **) &full_name,
317                                          NULL, /* domains */
318                                          1, /* level */
319                                          &sids,
320                                          &types);
321         if (!NT_STATUS_IS_OK(status)) {
322                 DEBUG(2,("name_to_sid: failed to lookup name: %s\n",
323                         nt_errstr(status)));
324                 return status;
325         }
326
327         sid_copy(sid, &sids[0]);
328         *type = types[0];
329
330         return NT_STATUS_OK;
331 }
332
333 /* Convert a domain SID to a user or group name */
334 NTSTATUS rpc_sid_to_name(TALLOC_CTX *mem_ctx,
335                          struct rpc_pipe_client *lsa_pipe,
336                          struct policy_handle *lsa_policy,
337                          struct winbindd_domain *domain,
338                          const struct dom_sid *sid,
339                          char **pdomain_name,
340                          char **pname,
341                          enum lsa_SidType *ptype)
342 {
343         char *mapped_name = NULL;
344         char **domains = NULL;
345         char **names = NULL;
346         enum lsa_SidType *types = NULL;
347         NTSTATUS map_status;
348         NTSTATUS status;
349
350         status = rpccli_lsa_lookup_sids(lsa_pipe,
351                                         mem_ctx,
352                                         lsa_policy,
353                                         1, /* num_sids */
354                                         sid,
355                                         &domains,
356                                         &names,
357                                         &types);
358         if (!NT_STATUS_IS_OK(status)) {
359                 DEBUG(2,("sid_to_name: failed to lookup sids: %s\n",
360                         nt_errstr(status)));
361                 return status;
362         }
363
364         *ptype = (enum lsa_SidType) types[0];
365
366         map_status = normalize_name_map(mem_ctx,
367                                         domain,
368                                         *pname,
369                                         &mapped_name);
370         if (NT_STATUS_IS_OK(map_status) ||
371             NT_STATUS_EQUAL(map_status, NT_STATUS_FILE_RENAMED)) {
372                 *pname = talloc_strdup(mem_ctx, mapped_name);
373                 DEBUG(5,("returning mapped name -- %s\n", *pname));
374         } else {
375                 *pname = talloc_strdup(mem_ctx, names[0]);
376         }
377         if (*pname == NULL) {
378                 return NT_STATUS_NO_MEMORY;
379         }
380
381         *pdomain_name = talloc_strdup(mem_ctx, domains[0]);
382         if (*pdomain_name == NULL) {
383                 return NT_STATUS_NO_MEMORY;
384         }
385
386         return NT_STATUS_OK;
387 }
388
389 /* Convert a bunch of rids to user or group names */
390 NTSTATUS rpc_rids_to_names(TALLOC_CTX *mem_ctx,
391                            struct rpc_pipe_client *lsa_pipe,
392                            struct policy_handle *lsa_policy,
393                            struct winbindd_domain *domain,
394                            const struct dom_sid *sid,
395                            uint32_t *rids,
396                            size_t num_rids,
397                            char **pdomain_name,
398                            char ***pnames,
399                            enum lsa_SidType **ptypes)
400 {
401         enum lsa_SidType *types = NULL;
402         char *domain_name = NULL;
403         char **domains = NULL;
404         char **names = NULL;
405         struct dom_sid *sids;
406         size_t i;
407         NTSTATUS status;
408
409         if (num_rids > 0) {
410                 sids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_rids);
411                 if (sids == NULL) {
412                         return NT_STATUS_NO_MEMORY;
413                 }
414         } else {
415                 sids = NULL;
416         }
417
418         for (i = 0; i < num_rids; i++) {
419                 if (!sid_compose(&sids[i], sid, rids[i])) {
420                         return NT_STATUS_INTERNAL_ERROR;
421                 }
422         }
423
424         status = rpccli_lsa_lookup_sids(lsa_pipe,
425                                         mem_ctx,
426                                         lsa_policy,
427                                         num_rids,
428                                         sids,
429                                         &domains,
430                                         &names,
431                                         &types);
432         if (!NT_STATUS_IS_OK(status) &&
433             !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
434                 DEBUG(2,("rids_to_names: failed to lookup sids: %s\n",
435                         nt_errstr(status)));
436                 return status;
437         }
438
439         for (i = 0; i < num_rids; i++) {
440                 char *mapped_name = NULL;
441                 NTSTATUS map_status;
442
443                 if (types[i] != SID_NAME_UNKNOWN) {
444                         map_status = normalize_name_map(mem_ctx,
445                                                         domain,
446                                                         names[i],
447                                                         &mapped_name);
448                         if (NT_STATUS_IS_OK(map_status) ||
449                             NT_STATUS_EQUAL(map_status, NT_STATUS_FILE_RENAMED)) {
450                                 TALLOC_FREE(names[i]);
451                                 names[i] = talloc_strdup(names, mapped_name);
452                                 if (names[i] == NULL) {
453                                         return NT_STATUS_NO_MEMORY;
454                                 }
455                         }
456
457                         domain_name = domains[i];
458                 }
459         }
460
461         *pdomain_name = domain_name;
462         *ptypes = types;
463         *pnames = names;
464
465         return NT_STATUS_OK;
466 }
467
468 /* Lookup user information from a rid or username. */
469 NTSTATUS rpc_query_user(TALLOC_CTX *mem_ctx,
470                         struct rpc_pipe_client *samr_pipe,
471                         struct policy_handle *samr_policy,
472                         const struct dom_sid *domain_sid,
473                         const struct dom_sid *user_sid,
474                         struct wbint_userinfo *user_info)
475 {
476         struct policy_handle user_policy;
477         union samr_UserInfo *info = NULL;
478         uint32_t user_rid;
479         NTSTATUS status, result;
480         struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
481
482         if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
483                 return NT_STATUS_UNSUCCESSFUL;
484         }
485
486         /* Get user handle */
487         status = dcerpc_samr_OpenUser(b,
488                                       mem_ctx,
489                                       samr_policy,
490                                       SEC_FLAG_MAXIMUM_ALLOWED,
491                                       user_rid,
492                                       &user_policy,
493                                       &result);
494         if (!NT_STATUS_IS_OK(status)) {
495                 return status;
496         }
497         if (!NT_STATUS_IS_OK(result)) {
498                 return result;
499         }
500
501         /* Get user info */
502         status = dcerpc_samr_QueryUserInfo(b,
503                                            mem_ctx,
504                                            &user_policy,
505                                            0x15,
506                                            &info,
507                                            &result);
508         {
509                 NTSTATUS _result;
510                 dcerpc_samr_Close(b, mem_ctx, &user_policy, &_result);
511         }
512         if (!NT_STATUS_IS_OK(status)) {
513                 return status;
514         }
515         if (!NT_STATUS_IS_OK(result)) {
516                 return result;
517         }
518
519         sid_compose(&user_info->user_sid, domain_sid, user_rid);
520         sid_compose(&user_info->group_sid, domain_sid,
521                     info->info21.primary_gid);
522
523         user_info->acct_name = talloc_strdup(user_info,
524                                         info->info21.account_name.string);
525         if (user_info->acct_name == NULL) {
526                 return NT_STATUS_NO_MEMORY;
527         }
528
529         user_info->full_name = talloc_strdup(user_info,
530                                         info->info21.full_name.string);
531         if ((info->info21.full_name.string != NULL) &&
532             (user_info->acct_name == NULL))
533         {
534                 return NT_STATUS_NO_MEMORY;
535         }
536
537         user_info->homedir = NULL;
538         user_info->shell = NULL;
539         user_info->primary_gid = (gid_t)-1;
540
541         return NT_STATUS_OK;
542 }
543
544 /* Lookup groups a user is a member of. */
545 NTSTATUS rpc_lookup_usergroups(TALLOC_CTX *mem_ctx,
546                                struct rpc_pipe_client *samr_pipe,
547                                struct policy_handle *samr_policy,
548                                const struct dom_sid *domain_sid,
549                                const struct dom_sid *user_sid,
550                                uint32_t *pnum_groups,
551                                struct dom_sid **puser_grpsids)
552 {
553         struct policy_handle user_policy;
554         struct samr_RidWithAttributeArray *rid_array = NULL;
555         struct dom_sid *user_grpsids = NULL;
556         uint32_t num_groups = 0, i;
557         uint32_t user_rid;
558         NTSTATUS status, result;
559         struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
560
561         if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
562                 return NT_STATUS_UNSUCCESSFUL;
563         }
564
565         /* Get user handle */
566         status = dcerpc_samr_OpenUser(b,
567                                       mem_ctx,
568                                       samr_policy,
569                                       SEC_FLAG_MAXIMUM_ALLOWED,
570                                       user_rid,
571                                       &user_policy,
572                                       &result);
573         if (!NT_STATUS_IS_OK(status)) {
574                 return status;
575         }
576         if (!NT_STATUS_IS_OK(result)) {
577                 return result;
578         }
579
580         /* Query user rids */
581         status = dcerpc_samr_GetGroupsForUser(b,
582                                               mem_ctx,
583                                               &user_policy,
584                                               &rid_array,
585                                               &result);
586         num_groups = rid_array->count;
587
588         {
589                 NTSTATUS _result;
590                 dcerpc_samr_Close(b, mem_ctx, &user_policy, &_result);
591         }
592
593         if (!NT_STATUS_IS_OK(status)) {
594                 return status;
595         }
596         if (!NT_STATUS_IS_OK(result) || num_groups == 0) {
597                 return result;
598         }
599
600         user_grpsids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_groups);
601         if (user_grpsids == NULL) {
602                 status = NT_STATUS_NO_MEMORY;
603                 return status;
604         }
605
606         for (i = 0; i < num_groups; i++) {
607                 sid_compose(&(user_grpsids[i]), domain_sid,
608                             rid_array->rids[i].rid);
609         }
610
611         *pnum_groups = num_groups;
612
613         *puser_grpsids = user_grpsids;
614
615         return NT_STATUS_OK;
616 }
617
618 NTSTATUS rpc_lookup_useraliases(TALLOC_CTX *mem_ctx,
619                                 struct rpc_pipe_client *samr_pipe,
620                                 struct policy_handle *samr_policy,
621                                 uint32_t num_sids,
622                                 const struct dom_sid *sids,
623                                 uint32_t *pnum_aliases,
624                                 uint32_t **palias_rids)
625 {
626 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
627         uint32_t num_query_sids = 0;
628         uint32_t num_queries = 1;
629         uint32_t num_aliases = 0;
630         uint32_t total_sids = 0;
631         uint32_t *alias_rids = NULL;
632         uint32_t rangesize = MAX_SAM_ENTRIES_W2K;
633         uint32_t i;
634         struct samr_Ids alias_rids_query;
635         NTSTATUS status, result;
636         struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
637
638         do {
639                 /* prepare query */
640                 struct lsa_SidArray sid_array;
641
642                 ZERO_STRUCT(sid_array);
643
644                 num_query_sids = MIN(num_sids - total_sids, rangesize);
645
646                 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
647                         num_queries, num_query_sids));
648
649                 if (num_query_sids) {
650                         sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
651                         if (sid_array.sids == NULL) {
652                                 return NT_STATUS_NO_MEMORY;
653                         }
654                 } else {
655                         sid_array.sids = NULL;
656                 }
657
658                 for (i = 0; i < num_query_sids; i++) {
659                         sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[total_sids++]);
660                         if (sid_array.sids[i].sid == NULL) {
661                                 return NT_STATUS_NO_MEMORY;
662                         }
663                 }
664                 sid_array.num_sids = num_query_sids;
665
666                 /* do request */
667                 status = dcerpc_samr_GetAliasMembership(b,
668                                                         mem_ctx,
669                                                         samr_policy,
670                                                         &sid_array,
671                                                         &alias_rids_query,
672                                                         &result);
673                 if (!NT_STATUS_IS_OK(status)) {
674                         return status;
675                 }
676                 if (!NT_STATUS_IS_OK(result)) {
677                         return result;
678                 }
679
680                 /* process output */
681                 for (i = 0; i < alias_rids_query.count; i++) {
682                         size_t na = num_aliases;
683
684                         if (!add_rid_to_array_unique(mem_ctx,
685                                                      alias_rids_query.ids[i],
686                                                      &alias_rids,
687                                                      &na)) {
688                                         return NT_STATUS_NO_MEMORY;
689                                 }
690                                 num_aliases = na;
691                 }
692
693                 num_queries++;
694
695         } while (total_sids < num_sids);
696
697         DEBUG(10,("rpc: rpc_lookup_useraliases: got %d aliases in %d queries "
698                   "(rangesize: %d)\n", num_aliases, num_queries, rangesize));
699
700         *pnum_aliases = num_aliases;
701         *palias_rids = alias_rids;
702
703         return NT_STATUS_OK;
704 #undef MAX_SAM_ENTRIES_W2K
705 }
706
707 /* Lookup group membership given a rid.   */
708 NTSTATUS rpc_lookup_groupmem(TALLOC_CTX *mem_ctx,
709                              struct rpc_pipe_client *samr_pipe,
710                              struct policy_handle *samr_policy,
711                              const char *domain_name,
712                              const struct dom_sid *domain_sid,
713                              const struct dom_sid *group_sid,
714                              enum lsa_SidType type,
715                              uint32_t *pnum_names,
716                              struct dom_sid **psid_mem,
717                              char ***pnames,
718                              uint32_t **pname_types)
719 {
720         struct policy_handle group_policy;
721         uint32_t group_rid;
722         uint32_t *rid_mem = NULL;
723
724         uint32_t num_names = 0;
725         uint32_t total_names = 0;
726         struct dom_sid *sid_mem = NULL;
727         char **names = NULL;
728         uint32_t *name_types = NULL;
729
730         struct lsa_Strings tmp_names;
731         struct samr_Ids tmp_types;
732
733         uint32_t j, r;
734         NTSTATUS status, result;
735         struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
736
737         if (!sid_peek_check_rid(domain_sid, group_sid, &group_rid)) {
738                 return NT_STATUS_UNSUCCESSFUL;
739         }
740
741         switch(type) {
742         case SID_NAME_DOM_GRP:
743         {
744                 struct samr_RidAttrArray *rids = NULL;
745
746                 status = dcerpc_samr_OpenGroup(b,
747                                                mem_ctx,
748                                                samr_policy,
749                                                SEC_FLAG_MAXIMUM_ALLOWED,
750                                                group_rid,
751                                                &group_policy,
752                                                &result);
753                 if (!NT_STATUS_IS_OK(status)) {
754                         return status;
755                 }
756                 if (!NT_STATUS_IS_OK(result)) {
757                         return result;
758                 }
759
760                 /*
761                  * Step #1: Get a list of user rids that are the members of the group.
762                  */
763                 status = dcerpc_samr_QueryGroupMember(b,
764                                                       mem_ctx,
765                                                       &group_policy,
766                                                       &rids,
767                                                       &result);
768                 {
769                         NTSTATUS _result;
770                         dcerpc_samr_Close(b, mem_ctx, &group_policy, &_result);
771                 }
772
773                 if (!NT_STATUS_IS_OK(status)) {
774                         return status;
775                 }
776                 if (!NT_STATUS_IS_OK(result)) {
777                         return result;
778                 }
779
780
781                 if (rids == NULL || rids->count == 0) {
782                         pnum_names = 0;
783                         pnames = NULL;
784                         pname_types = NULL;
785                         psid_mem = NULL;
786
787                         return NT_STATUS_OK;
788                 }
789
790                 num_names = rids->count;
791                 rid_mem = rids->rids;
792
793                 break;
794         }
795         case SID_NAME_WKN_GRP:
796         case SID_NAME_ALIAS:
797         {
798                 struct lsa_SidArray sid_array;
799                 struct lsa_SidPtr sid_ptr;
800                 struct samr_Ids rids_query;
801
802                 sid_ptr.sid = dom_sid_dup(mem_ctx, group_sid);
803                 if (sid_ptr.sid == NULL) {
804                         return NT_STATUS_NO_MEMORY;
805                 }
806
807                 sid_array.num_sids = 1;
808                 sid_array.sids = &sid_ptr;
809
810                 status = dcerpc_samr_GetAliasMembership(b,
811                                                         mem_ctx,
812                                                         samr_policy,
813                                                         &sid_array,
814                                                         &rids_query,
815                                                         &result);
816                 if (!NT_STATUS_IS_OK(status)) {
817                         return status;
818                 }
819                 if (!NT_STATUS_IS_OK(result)) {
820                         return result;
821                 }
822
823                 if (rids_query.count == 0) {
824                         pnum_names = 0;
825                         pnames = NULL;
826                         pname_types = NULL;
827                         psid_mem = NULL;
828
829                         return NT_STATUS_OK;
830                 }
831
832                 num_names = rids_query.count;
833                 rid_mem = rids_query.ids;
834
835                 break;
836         }
837         default:
838                 return NT_STATUS_UNSUCCESSFUL;
839         }
840
841         /*
842          * Step #2: Convert list of rids into list of usernames.
843          */
844         if (num_names > 0) {
845                 names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_names);
846                 name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32_t, num_names);
847                 sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_names);
848                 if (names == NULL || name_types == NULL || sid_mem == NULL) {
849                         return NT_STATUS_NO_MEMORY;
850                 }
851         }
852
853         for (j = 0; j < num_names; j++) {
854                 sid_compose(&sid_mem[j], domain_sid, rid_mem[j]);
855         }
856
857         status = dcerpc_samr_LookupRids(b,
858                                         mem_ctx,
859                                         samr_policy,
860                                         num_names,
861                                         rid_mem,
862                                         &tmp_names,
863                                         &tmp_types,
864                                         &result);
865         if (!NT_STATUS_IS_OK(status)) {
866                 return status;
867         }
868
869         if (!NT_STATUS_IS_OK(result)) {
870                 if (!NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
871                         return result;
872                 }
873         }
874
875         /* Copy result into array.  The talloc system will take
876            care of freeing the temporary arrays later on. */
877         if (tmp_names.count != tmp_types.count) {
878                 return NT_STATUS_UNSUCCESSFUL;
879         }
880
881         for (r = 0; r < tmp_names.count; r++) {
882                 if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
883                         continue;
884                 }
885                 names[total_names] = fill_domain_username_talloc(names,
886                                                                  domain_name,
887                                                                  tmp_names.names[r].string,
888                                                                  true);
889                 if (names[total_names] == NULL) {
890                         return NT_STATUS_NO_MEMORY;
891                 }
892                 name_types[total_names] = tmp_types.ids[r];
893                 total_names++;
894         }
895
896         *pnum_names = total_names;
897         *pnames = names;
898         *pname_types = name_types;
899         *psid_mem = sid_mem;
900
901         return NT_STATUS_OK;
902 }
903
904 /* Find the sequence number for a domain */
905 NTSTATUS rpc_sequence_number(TALLOC_CTX *mem_ctx,
906                              struct rpc_pipe_client *samr_pipe,
907                              struct policy_handle *samr_policy,
908                              const char *domain_name,
909                              uint32_t *pseq)
910 {
911         union samr_DomainInfo *info = NULL;
912         bool got_seq_num = false;
913         NTSTATUS status, result;
914         struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
915
916         /* query domain info */
917         status = dcerpc_samr_QueryDomainInfo(b,
918                                              mem_ctx,
919                                              samr_policy,
920                                              8,
921                                              &info,
922                                              &result);
923         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
924                 *pseq = info->info8.sequence_num;
925                 got_seq_num = true;
926                 goto seq_num;
927         }
928
929         /* retry with info-level 2 in case the dc does not support info-level 8
930          * (like all older samba2 and samba3 dc's) - Guenther */
931         status = dcerpc_samr_QueryDomainInfo(b,
932                                              mem_ctx,
933                                              samr_policy,
934                                              2,
935                                              &info,
936                                              &result);
937         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
938                 *pseq = info->general.sequence_num;
939                 got_seq_num = true;
940                 goto seq_num;
941         }
942
943         if (!NT_STATUS_IS_OK(status)) {
944                 goto seq_num;
945         }
946
947         status = result;
948
949 seq_num:
950         if (got_seq_num) {
951                 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
952                           domain_name, (unsigned) *pseq));
953         } else {
954                 DEBUG(10,("domain_sequence_number: failed to get sequence "
955                           "number (%u) for domain %s\n",
956                           (unsigned) *pseq, domain_name ));
957                 status = NT_STATUS_OK;
958         }
959
960         return status;
961 }
962
963 /* Get a list of trusted domains */
964 NTSTATUS rpc_trusted_domains(TALLOC_CTX *mem_ctx,
965                              struct rpc_pipe_client *lsa_pipe,
966                              struct policy_handle *lsa_policy,
967                              uint32_t *pnum_trusts,
968                              struct netr_DomainTrust **ptrusts)
969 {
970         struct netr_DomainTrust *array = NULL;
971         uint32_t enum_ctx = 0;
972         uint32_t count = 0;
973         NTSTATUS status, result;
974         struct dcerpc_binding_handle *b = lsa_pipe->binding_handle;
975
976         do {
977                 struct lsa_DomainList dom_list;
978                 uint32_t start_idx;
979                 uint32_t i;
980
981                 /*
982                  * We don't run into deadlocks here, cause winbind_off() is
983                  * called in the main function.
984                  */
985                 status = dcerpc_lsa_EnumTrustDom(b,
986                                                  mem_ctx,
987                                                  lsa_policy,
988                                                  &enum_ctx,
989                                                  &dom_list,
990                                                  (uint32_t) -1,
991                                                  &result);
992                 if (!NT_STATUS_IS_OK(status)) {
993                         return status;
994                 }
995                 if (!NT_STATUS_IS_OK(result)) {
996                         if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
997                                 return result;
998                         }
999                 }
1000
1001                 start_idx = count;
1002                 count += dom_list.count;
1003
1004                 array = talloc_realloc(mem_ctx,
1005                                        array,
1006                                        struct netr_DomainTrust,
1007                                        count);
1008                 if (array == NULL) {
1009                         return NT_STATUS_NO_MEMORY;
1010                 }
1011
1012                 for (i = 0; i < dom_list.count; i++) {
1013                         struct netr_DomainTrust *trust = &array[i];
1014                         struct dom_sid *sid;
1015
1016                         ZERO_STRUCTP(trust);
1017
1018                         trust->netbios_name = talloc_move(array,
1019                                                           &dom_list.domains[i].name.string);
1020                         trust->dns_name = NULL;
1021
1022                         sid = talloc(array, struct dom_sid);
1023                         if (sid == NULL) {
1024                                 return NT_STATUS_NO_MEMORY;
1025                         }
1026                         sid_copy(sid, dom_list.domains[i].sid);
1027                         trust->sid = sid;
1028                 }
1029         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1030
1031         *pnum_trusts = count;
1032         *ptrusts = array;
1033
1034         return NT_STATUS_OK;
1035 }