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