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