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