s3: Fix a bogus uninitialized variable warning
[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_GROUP_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 NT_STATUS_OK;
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 NT_STATUS_OK;
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_copy(&((*user_grpsids)[i]), &domain->sid);
616                 sid_append_rid(&((*user_grpsids)[i]),
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         *num_names = rids->count;
791         rid_mem = rids->rids;
792
793         if (!*num_names) {
794                 names = NULL;
795                 name_types = NULL;
796                 sid_mem = NULL;
797                 return NT_STATUS_OK;
798         }
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                                 uint32 *num_domains,
1036                                 char ***names,
1037                                 char ***alt_names,
1038                                 DOM_SID **dom_sids)
1039 {
1040         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1041         uint32 enum_ctx = 0;
1042         struct rpc_pipe_client *cli;
1043         struct policy_handle lsa_policy;
1044
1045         DEBUG(3,("rpc: trusted_domains\n"));
1046
1047         *num_domains = 0;
1048         *names = NULL;
1049         *alt_names = NULL;
1050         *dom_sids = NULL;
1051
1052         result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1053         if (!NT_STATUS_IS_OK(result))
1054                 return result;
1055
1056         result = STATUS_MORE_ENTRIES;
1057
1058         while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1059                 uint32 start_idx;
1060                 int i;
1061                 struct lsa_DomainList dom_list;
1062
1063                 result = rpccli_lsa_EnumTrustDom(cli, mem_ctx,
1064                                                  &lsa_policy,
1065                                                  &enum_ctx,
1066                                                  &dom_list,
1067                                                  (uint32_t)-1);
1068
1069                 if (!NT_STATUS_IS_OK(result) &&
1070                     !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
1071                         break;
1072
1073                 start_idx = *num_domains;
1074                 *num_domains += dom_list.count;
1075                 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
1076                                               char *, *num_domains);
1077                 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
1078                                                  DOM_SID, *num_domains);
1079                 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,
1080                                                  char *, *num_domains);
1081                 if ((*names == NULL) || (*dom_sids == NULL) ||
1082                     (*alt_names == NULL))
1083                         return NT_STATUS_NO_MEMORY;
1084
1085                 for (i=0; i<dom_list.count; i++) {
1086                         (*names)[start_idx+i] = CONST_DISCARD(char *, dom_list.domains[i].name.string);
1087                         (*dom_sids)[start_idx+i] = *dom_list.domains[i].sid;
1088                         (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
1089                 }
1090         }
1091         return result;
1092 }
1093
1094 /* find the lockout policy for a domain */
1095 static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
1096                                      TALLOC_CTX *mem_ctx,
1097                                      struct samr_DomInfo12 *lockout_policy)
1098 {
1099         NTSTATUS result;
1100         struct rpc_pipe_client *cli;
1101         struct policy_handle dom_pol;
1102         union samr_DomainInfo *info = NULL;
1103
1104         DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
1105
1106         if ( !winbindd_can_contact_domain( domain ) ) {
1107                 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1108                           domain->name));
1109                 return NT_STATUS_NOT_SUPPORTED;
1110         }
1111
1112         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1113         if (!NT_STATUS_IS_OK(result)) {
1114                 goto done;
1115         }
1116
1117         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1118                                              &dom_pol,
1119                                              12,
1120                                              &info);
1121         if (!NT_STATUS_IS_OK(result)) {
1122                 goto done;
1123         }
1124
1125         *lockout_policy = info->info12;
1126
1127         DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1128                 info->info12.lockout_threshold));
1129
1130   done:
1131
1132         return result;
1133 }
1134
1135 /* find the password policy for a domain */
1136 static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1137                                       TALLOC_CTX *mem_ctx,
1138                                       struct samr_DomInfo1 *password_policy)
1139 {
1140         NTSTATUS result;
1141         struct rpc_pipe_client *cli;
1142         struct policy_handle dom_pol;
1143         union samr_DomainInfo *info = NULL;
1144
1145         DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
1146
1147         if ( !winbindd_can_contact_domain( domain ) ) {
1148                 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1149                           domain->name));
1150                 return NT_STATUS_NOT_SUPPORTED;
1151         }
1152
1153         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1154         if (!NT_STATUS_IS_OK(result)) {
1155                 goto done;
1156         }
1157
1158         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1159                                              &dom_pol,
1160                                              1,
1161                                              &info);
1162         if (!NT_STATUS_IS_OK(result)) {
1163                 goto done;
1164         }
1165
1166         *password_policy = info->info1;
1167
1168         DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1169                 info->info1.min_password_length));
1170
1171   done:
1172
1173         return result;
1174 }
1175
1176 typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli,
1177                                      TALLOC_CTX *mem_ctx,
1178                                      struct policy_handle *pol,
1179                                      int num_sids,
1180                                      const DOM_SID *sids,
1181                                      char ***pdomains,
1182                                      char ***pnames,
1183                                      enum lsa_SidType **ptypes);
1184
1185 NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
1186                               struct winbindd_domain *domain,
1187                               uint32_t num_sids,
1188                               const struct dom_sid *sids,
1189                               char ***domains,
1190                               char ***names,
1191                               enum lsa_SidType **types)
1192 {
1193         NTSTATUS status;
1194         struct rpc_pipe_client *cli = NULL;
1195         struct policy_handle lsa_policy;
1196         unsigned int orig_timeout;
1197         lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;
1198
1199         if (domain->can_do_ncacn_ip_tcp) {
1200                 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1201                 if (NT_STATUS_IS_OK(status)) {
1202                         lookup_sids_fn = rpccli_lsa_lookup_sids3;
1203                         goto lookup;
1204                 }
1205                 domain->can_do_ncacn_ip_tcp = false;
1206         }
1207         status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1208
1209         if (!NT_STATUS_IS_OK(status)) {
1210                 return status;
1211         }
1212
1213  lookup:
1214         /*
1215          * This call can take a long time
1216          * allow the server to time out.
1217          * 35 seconds should do it.
1218          */
1219         orig_timeout = rpccli_set_timeout(cli, 35000);
1220
1221         status = lookup_sids_fn(cli,
1222                                 mem_ctx,
1223                                 &lsa_policy,
1224                                 num_sids,
1225                                 sids,
1226                                 domains,
1227                                 names,
1228                                 types);
1229
1230         /* And restore our original timeout. */
1231         rpccli_set_timeout(cli, orig_timeout);
1232
1233         if (!NT_STATUS_IS_OK(status)) {
1234                 return status;
1235         }
1236
1237         return status;
1238 }
1239
1240 typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
1241                                       TALLOC_CTX *mem_ctx,
1242                                       struct policy_handle *pol,
1243                                       int num_names,
1244                                       const char **names,
1245                                       const char ***dom_names,
1246                                       int level,
1247                                       struct dom_sid **sids,
1248                                       enum lsa_SidType **types);
1249
1250 NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
1251                                struct winbindd_domain *domain,
1252                                uint32_t num_names,
1253                                const char **names,
1254                                const char ***domains,
1255                                struct dom_sid **sids,
1256                                enum lsa_SidType **types)
1257 {
1258         NTSTATUS status;
1259         struct rpc_pipe_client *cli = NULL;
1260         struct policy_handle lsa_policy;
1261         unsigned int orig_timeout = 0;
1262         lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names;
1263
1264         if (domain->can_do_ncacn_ip_tcp) {
1265                 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1266                 if (NT_STATUS_IS_OK(status)) {
1267                         lookup_names_fn = rpccli_lsa_lookup_names4;
1268                         goto lookup;
1269                 }
1270                 domain->can_do_ncacn_ip_tcp = false;
1271         }
1272         status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1273
1274         if (!NT_STATUS_IS_OK(status)) {
1275                 return status;
1276         }
1277
1278  lookup:
1279
1280         /*
1281          * This call can take a long time
1282          * allow the server to time out.
1283          * 35 seconds should do it.
1284          * NB
1285          * only do this when the undelying transport is named pipe.
1286          */
1287         if (cli->transport->transport == NCACN_NP) {
1288                 orig_timeout = rpccli_set_timeout(cli, 35000);
1289         }
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         if (cli->transport->transport == NCACN_NP) {
1303                 rpccli_set_timeout(cli, orig_timeout);
1304         }
1305
1306         if (!NT_STATUS_IS_OK(status)) {
1307                 return status;
1308         }
1309
1310         return status;
1311 }
1312
1313 /* the rpc backend methods are exposed via this structure */
1314 struct winbindd_methods msrpc_methods = {
1315         False,
1316         query_user_list,
1317         enum_dom_groups,
1318         enum_local_groups,
1319         msrpc_name_to_sid,
1320         msrpc_sid_to_name,
1321         msrpc_rids_to_names,
1322         query_user,
1323         lookup_usergroups,
1324         msrpc_lookup_useraliases,
1325         lookup_groupmem,
1326         sequence_number,
1327         msrpc_lockout_policy,
1328         msrpc_password_policy,
1329         trusted_domains,
1330 };