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