s3-ipasam: Add aliases for trusted domain user
[samba.git] / source3 / rpc_server / lsa / srv_lsa_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Jeremy Allison                    2001, 2006.
8  *  Copyright (C) Rafal Szczesniak                  2002,
9  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
10  *  Copyright (C) Simo Sorce                        2003.
11  *  Copyright (C) Gerald (Jerry) Carter             2005.
12  *  Copyright (C) Volker Lendecke                   2005.
13  *  Copyright (C) Guenther Deschner                 2008.
14  *  Copyright (C) Andrew Bartlett                   2010.
15  *
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License as published by
18  *  the Free Software Foundation; either version 3 of the License, or
19  *  (at your option) any later version.
20  *
21  *  This program is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *  GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License
27  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
28  */
29
30 /* This is the implementation of the lsa server code. */
31
32 #include "includes.h"
33 #include "../librpc/gen_ndr/srv_lsa.h"
34 #include "secrets.h"
35 #include "../librpc/gen_ndr/netlogon.h"
36 #include "rpc_client/init_lsa.h"
37 #include "../libcli/security/security.h"
38 #include "../libcli/security/dom_sid.h"
39 #include "../librpc/gen_ndr/drsblobs.h"
40 #include "../librpc/gen_ndr/ndr_drsblobs.h"
41 #include "../lib/crypto/arcfour.h"
42 #include "../libcli/security/dom_sid.h"
43
44 #undef DBGC_CLASS
45 #define DBGC_CLASS DBGC_RPC_SRV
46
47 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
48
49 enum lsa_handle_type {
50         LSA_HANDLE_POLICY_TYPE = 1,
51         LSA_HANDLE_ACCOUNT_TYPE = 2,
52         LSA_HANDLE_TRUST_TYPE = 3};
53
54 struct lsa_info {
55         struct dom_sid sid;
56         const char *name;
57         uint32 access;
58         enum lsa_handle_type type;
59         struct security_descriptor *sd;
60 };
61
62 const struct generic_mapping lsa_account_mapping = {
63         LSA_ACCOUNT_READ,
64         LSA_ACCOUNT_WRITE,
65         LSA_ACCOUNT_EXECUTE,
66         LSA_ACCOUNT_ALL_ACCESS
67 };
68
69 const struct generic_mapping lsa_policy_mapping = {
70         LSA_POLICY_READ,
71         LSA_POLICY_WRITE,
72         LSA_POLICY_EXECUTE,
73         LSA_POLICY_ALL_ACCESS
74 };
75
76 const struct generic_mapping lsa_secret_mapping = {
77         LSA_SECRET_READ,
78         LSA_SECRET_WRITE,
79         LSA_SECRET_EXECUTE,
80         LSA_SECRET_ALL_ACCESS
81 };
82
83 const struct generic_mapping lsa_trusted_domain_mapping = {
84         LSA_TRUSTED_DOMAIN_READ,
85         LSA_TRUSTED_DOMAIN_WRITE,
86         LSA_TRUSTED_DOMAIN_EXECUTE,
87         LSA_TRUSTED_DOMAIN_ALL_ACCESS
88 };
89
90 /***************************************************************************
91  init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
92 ***************************************************************************/
93
94 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
95                                     struct lsa_RefDomainList *ref,
96                                     const char *dom_name,
97                                     struct dom_sid *dom_sid)
98 {
99         int num = 0;
100
101         if (dom_name != NULL) {
102                 for (num = 0; num < ref->count; num++) {
103                         if (dom_sid_equal(dom_sid, ref->domains[num].sid)) {
104                                 return num;
105                         }
106                 }
107         } else {
108                 num = ref->count;
109         }
110
111         if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
112                 /* index not found, already at maximum domain limit */
113                 return -1;
114         }
115
116         ref->count = num + 1;
117         ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
118
119         ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains,
120                                             struct lsa_DomainInfo, ref->count);
121         if (!ref->domains) {
122                 return -1;
123         }
124
125         ZERO_STRUCT(ref->domains[num]);
126
127         init_lsa_StringLarge(&ref->domains[num].name, dom_name);
128         ref->domains[num].sid = dom_sid_dup(mem_ctx, dom_sid);
129         if (!ref->domains[num].sid) {
130                 return -1;
131         }
132
133         return num;
134 }
135
136
137 /***************************************************************************
138  initialize a lsa_DomainInfo structure.
139  ***************************************************************************/
140
141 static void init_dom_query_3(struct lsa_DomainInfo *r,
142                              const char *name,
143                              struct dom_sid *sid)
144 {
145         init_lsa_StringLarge(&r->name, name);
146         r->sid = sid;
147 }
148
149 /***************************************************************************
150  initialize a lsa_DomainInfo structure.
151  ***************************************************************************/
152
153 static void init_dom_query_5(struct lsa_DomainInfo *r,
154                              const char *name,
155                              struct dom_sid *sid)
156 {
157         init_lsa_StringLarge(&r->name, name);
158         r->sid = sid;
159 }
160
161 /***************************************************************************
162  lookup_lsa_rids. Must be called as root for lookup_name to work.
163  ***************************************************************************/
164
165 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
166                                 struct lsa_RefDomainList *ref,
167                                 struct lsa_TranslatedSid *prid,
168                                 uint32_t num_entries,
169                                 struct lsa_String *name,
170                                 int flags,
171                                 uint32_t *pmapped_count)
172 {
173         uint32 mapped_count, i;
174
175         SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
176
177         mapped_count = 0;
178         *pmapped_count = 0;
179
180         for (i = 0; i < num_entries; i++) {
181                 struct dom_sid sid;
182                 uint32 rid;
183                 int dom_idx;
184                 const char *full_name;
185                 const char *domain;
186                 enum lsa_SidType type = SID_NAME_UNKNOWN;
187
188                 /* Split name into domain and user component */
189
190                 /* follow w2k8 behavior and return the builtin domain when no
191                  * input has been passed in */
192
193                 if (name[i].string) {
194                         full_name = name[i].string;
195                 } else {
196                         full_name = "BUILTIN";
197                 }
198
199                 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
200
201                 /* We can ignore the result of lookup_name, it will not touch
202                    "type" if it's not successful */
203
204                 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
205                             &sid, &type);
206
207                 switch (type) {
208                 case SID_NAME_USER:
209                 case SID_NAME_DOM_GRP:
210                 case SID_NAME_DOMAIN:
211                 case SID_NAME_ALIAS:
212                 case SID_NAME_WKN_GRP:
213                         DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
214                         /* Leave these unchanged */
215                         break;
216                 default:
217                         /* Don't hand out anything but the list above */
218                         DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
219                         type = SID_NAME_UNKNOWN;
220                         break;
221                 }
222
223                 rid = 0;
224                 dom_idx = -1;
225
226                 if (type != SID_NAME_UNKNOWN) {
227                         if (type == SID_NAME_DOMAIN) {
228                                 rid = (uint32_t)-1;
229                         } else {
230                                 sid_split_rid(&sid, &rid);
231                         }
232                         dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
233                         mapped_count++;
234                 }
235
236                 prid[i].sid_type        = type;
237                 prid[i].rid             = rid;
238                 prid[i].sid_index       = dom_idx;
239         }
240
241         *pmapped_count = mapped_count;
242         return NT_STATUS_OK;
243 }
244
245 /***************************************************************************
246  lookup_lsa_sids. Must be called as root for lookup_name to work.
247  ***************************************************************************/
248
249 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
250                                 struct lsa_RefDomainList *ref,
251                                 struct lsa_TranslatedSid3 *trans_sids,
252                                 uint32_t num_entries,
253                                 struct lsa_String *name,
254                                 int flags,
255                                 uint32 *pmapped_count)
256 {
257         uint32 mapped_count, i;
258
259         SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
260
261         mapped_count = 0;
262         *pmapped_count = 0;
263
264         for (i = 0; i < num_entries; i++) {
265                 struct dom_sid sid;
266                 uint32 rid;
267                 int dom_idx;
268                 const char *full_name;
269                 const char *domain;
270                 enum lsa_SidType type = SID_NAME_UNKNOWN;
271
272                 ZERO_STRUCT(sid);
273
274                 /* Split name into domain and user component */
275
276                 full_name = name[i].string;
277                 if (full_name == NULL) {
278                         return NT_STATUS_NO_MEMORY;
279                 }
280
281                 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
282
283                 /* We can ignore the result of lookup_name, it will not touch
284                    "type" if it's not successful */
285
286                 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
287                             &sid, &type);
288
289                 switch (type) {
290                 case SID_NAME_USER:
291                 case SID_NAME_DOM_GRP:
292                 case SID_NAME_DOMAIN:
293                 case SID_NAME_ALIAS:
294                 case SID_NAME_WKN_GRP:
295                         DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
296                         /* Leave these unchanged */
297                         break;
298                 default:
299                         /* Don't hand out anything but the list above */
300                         DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
301                         type = SID_NAME_UNKNOWN;
302                         break;
303                 }
304
305                 rid = 0;
306                 dom_idx = -1;
307
308                 if (type != SID_NAME_UNKNOWN) {
309                         struct dom_sid domain_sid;
310                         sid_copy(&domain_sid, &sid);
311                         sid_split_rid(&domain_sid, &rid);
312                         dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
313                         mapped_count++;
314                 }
315
316                 /* Initialize the lsa_TranslatedSid3 return. */
317                 trans_sids[i].sid_type = type;
318                 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
319                 trans_sids[i].sid_index = dom_idx;
320         }
321
322         *pmapped_count = mapped_count;
323         return NT_STATUS_OK;
324 }
325
326 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
327                                         const struct generic_mapping *map,
328                                         struct dom_sid *sid, uint32_t sid_access)
329 {
330         struct dom_sid adm_sid;
331         struct security_ace ace[5];
332         size_t i = 0;
333
334         struct security_acl *psa = NULL;
335
336         /* READ|EXECUTE access for Everyone */
337
338         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
339                         map->generic_execute | map->generic_read, 0);
340
341         /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
342
343         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
344                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
345         init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
346                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
347
348         /* Add Full Access for Domain Admins */
349         sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
350         init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
351                         map->generic_all, 0);
352
353         /* If we have a sid, give it some special access */
354
355         if (sid) {
356                 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
357                         sid_access, 0);
358         }
359
360         if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
361                 return NT_STATUS_NO_MEMORY;
362
363         if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
364                                 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
365                                 psa, sd_size)) == NULL)
366                 return NT_STATUS_NO_MEMORY;
367
368         return NT_STATUS_OK;
369 }
370
371 /***************************************************************************
372  ***************************************************************************/
373
374 static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
375                                          struct pipes_struct *p,
376                                          enum lsa_handle_type type,
377                                          uint32_t acc_granted,
378                                          struct dom_sid *sid,
379                                          const char *name,
380                                          const struct security_descriptor *sd,
381                                          struct policy_handle *handle)
382 {
383         struct lsa_info *info;
384
385         ZERO_STRUCTP(handle);
386
387         info = talloc_zero(mem_ctx, struct lsa_info);
388         if (!info) {
389                 return NT_STATUS_NO_MEMORY;
390         }
391
392         info->type = type;
393         info->access = acc_granted;
394
395         if (sid) {
396                 sid_copy(&info->sid, sid);
397         }
398
399         info->name = talloc_strdup(info, name);
400
401         if (sd) {
402                 info->sd = dup_sec_desc(info, sd);
403                 if (!info->sd) {
404                         talloc_free(info);
405                         return NT_STATUS_NO_MEMORY;
406                 }
407         }
408
409         if (!create_policy_hnd(p, handle, info)) {
410                 talloc_free(info);
411                 ZERO_STRUCTP(handle);
412                 return NT_STATUS_NO_MEMORY;
413         }
414
415         return NT_STATUS_OK;
416 }
417
418 /***************************************************************************
419  _lsa_OpenPolicy2
420  ***************************************************************************/
421
422 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
423                           struct lsa_OpenPolicy2 *r)
424 {
425         struct security_descriptor *psd = NULL;
426         size_t sd_size;
427         uint32 des_access = r->in.access_mask;
428         uint32 acc_granted;
429         NTSTATUS status;
430
431         /* Work out max allowed. */
432         map_max_allowed_access(p->server_info->security_token,
433                                &p->server_info->utok,
434                                &des_access);
435
436         /* map the generic bits to the lsa policy ones */
437         se_map_generic(&des_access, &lsa_policy_mapping);
438
439         /* get the generic lsa policy SD until we store it */
440         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
441                         NULL, 0);
442         if (!NT_STATUS_IS_OK(status)) {
443                 return status;
444         }
445
446         status = access_check_object(psd, p->server_info->security_token,
447                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
448                                      &acc_granted, "_lsa_OpenPolicy2" );
449         if (!NT_STATUS_IS_OK(status)) {
450                 return status;
451         }
452
453         status = create_lsa_policy_handle(p->mem_ctx, p,
454                                           LSA_HANDLE_POLICY_TYPE,
455                                           acc_granted,
456                                           get_global_sam_sid(),
457                                           NULL,
458                                           psd,
459                                           r->out.handle);
460         if (!NT_STATUS_IS_OK(status)) {
461                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
462         }
463
464         return NT_STATUS_OK;
465 }
466
467 /***************************************************************************
468  _lsa_OpenPolicy
469  ***************************************************************************/
470
471 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
472                          struct lsa_OpenPolicy *r)
473 {
474         struct lsa_OpenPolicy2 o;
475
476         o.in.system_name        = NULL; /* should be ignored */
477         o.in.attr               = r->in.attr;
478         o.in.access_mask        = r->in.access_mask;
479
480         o.out.handle            = r->out.handle;
481
482         return _lsa_OpenPolicy2(p, &o);
483 }
484
485 /***************************************************************************
486  _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
487  ufff, done :)  mimir
488  ***************************************************************************/
489
490 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
491                            struct lsa_EnumTrustDom *r)
492 {
493         struct lsa_info *info;
494         uint32_t count;
495         struct trustdom_info **domains;
496         struct lsa_DomainInfo *entries;
497         int i;
498         NTSTATUS nt_status;
499
500         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
501                 return NT_STATUS_INVALID_HANDLE;
502
503         if (info->type != LSA_HANDLE_POLICY_TYPE) {
504                 return NT_STATUS_INVALID_HANDLE;
505         }
506
507         /* check if the user has enough rights */
508         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
509                 return NT_STATUS_ACCESS_DENIED;
510
511         become_root();
512         nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
513         unbecome_root();
514
515         if (!NT_STATUS_IS_OK(nt_status)) {
516                 return nt_status;
517         }
518
519         entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo, count);
520         if (!entries) {
521                 return NT_STATUS_NO_MEMORY;
522         }
523
524         for (i=0; i<count; i++) {
525                 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
526                 entries[i].sid = &domains[i]->sid;
527         }
528
529         if (*r->in.resume_handle >= count) {
530                 *r->out.resume_handle = -1;
531                 TALLOC_FREE(entries);
532                 return NT_STATUS_NO_MORE_ENTRIES;
533         }
534
535         /* return the rest, limit by max_size. Note that we
536            use the w2k3 element size value of 60 */
537         r->out.domains->count = count - *r->in.resume_handle;
538         r->out.domains->count = MIN(r->out.domains->count,
539                                  1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
540
541         r->out.domains->domains = entries + *r->in.resume_handle;
542
543         if (r->out.domains->count < count - *r->in.resume_handle) {
544                 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
545                 return STATUS_MORE_ENTRIES;
546         }
547
548         /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
549          * always be larger than the previous input resume handle, in
550          * particular when hitting the last query it is vital to set the
551          * resume handle correctly to avoid infinite client loops, as
552          * seen e.g. with Windows XP SP3 when resume handle is 0 and
553          * status is NT_STATUS_OK - gd */
554
555         *r->out.resume_handle = (uint32_t)-1;
556
557         return NT_STATUS_OK;
558 }
559
560 #define LSA_AUDIT_NUM_CATEGORIES_NT4    7
561 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K  9
562 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
563
564 /***************************************************************************
565  _lsa_QueryInfoPolicy
566  ***************************************************************************/
567
568 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
569                               struct lsa_QueryInfoPolicy *r)
570 {
571         NTSTATUS status = NT_STATUS_OK;
572         struct lsa_info *handle;
573         struct dom_sid domain_sid;
574         const char *name;
575         struct dom_sid *sid = NULL;
576         union lsa_PolicyInformation *info = NULL;
577         uint32_t acc_required = 0;
578
579         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
580                 return NT_STATUS_INVALID_HANDLE;
581
582         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
583                 return NT_STATUS_INVALID_HANDLE;
584         }
585
586         switch (r->in.level) {
587         case LSA_POLICY_INFO_AUDIT_LOG:
588         case LSA_POLICY_INFO_AUDIT_EVENTS:
589                 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
590                 break;
591         case LSA_POLICY_INFO_DOMAIN:
592                 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
593                 break;
594         case LSA_POLICY_INFO_PD:
595                 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
596                 break;
597         case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
598                 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
599                 break;
600         case LSA_POLICY_INFO_ROLE:
601         case LSA_POLICY_INFO_REPLICA:
602                 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
603                 break;
604         case LSA_POLICY_INFO_QUOTA:
605                 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
606                 break;
607         case LSA_POLICY_INFO_MOD:
608         case LSA_POLICY_INFO_AUDIT_FULL_SET:
609                 /* according to MS-LSAD 3.1.4.4.3 */
610                 return NT_STATUS_INVALID_PARAMETER;
611         case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
612                 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
613                 break;
614         case LSA_POLICY_INFO_DNS:
615         case LSA_POLICY_INFO_DNS_INT:
616         case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
617                 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
618                 break;
619         default:
620                 break;
621         }
622
623         if (!(handle->access & acc_required)) {
624                 /* return NT_STATUS_ACCESS_DENIED; */
625         }
626
627         info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
628         if (!info) {
629                 return NT_STATUS_NO_MEMORY;
630         }
631
632         switch (r->in.level) {
633         /* according to MS-LSAD 3.1.4.4.3 */
634         case LSA_POLICY_INFO_MOD:
635         case LSA_POLICY_INFO_AUDIT_FULL_SET:
636         case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
637                 return NT_STATUS_INVALID_PARAMETER;
638         case LSA_POLICY_INFO_AUDIT_LOG:
639                 info->audit_log.percent_full            = 0;
640                 info->audit_log.maximum_log_size        = 0;
641                 info->audit_log.retention_time          = 0;
642                 info->audit_log.shutdown_in_progress    = 0;
643                 info->audit_log.time_to_shutdown        = 0;
644                 info->audit_log.next_audit_record       = 0;
645                 status = NT_STATUS_OK;
646                 break;
647         case LSA_POLICY_INFO_PD:
648                 info->pd.name.string                    = NULL;
649                 status = NT_STATUS_OK;
650                 break;
651         case LSA_POLICY_INFO_REPLICA:
652                 info->replica.source.string             = NULL;
653                 info->replica.account.string            = NULL;
654                 status = NT_STATUS_OK;
655                 break;
656         case LSA_POLICY_INFO_QUOTA:
657                 info->quota.paged_pool                  = 0;
658                 info->quota.non_paged_pool              = 0;
659                 info->quota.min_wss                     = 0;
660                 info->quota.max_wss                     = 0;
661                 info->quota.pagefile                    = 0;
662                 info->quota.unknown                     = 0;
663                 status = NT_STATUS_OK;
664                 break;
665         case LSA_POLICY_INFO_AUDIT_EVENTS:
666                 {
667
668                 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
669
670                 /* check if the user has enough rights */
671                 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
672                         DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
673                         return NT_STATUS_ACCESS_DENIED;
674                 }
675
676                 /* fake info: We audit everything. ;) */
677
678                 info->audit_events.auditing_mode = true;
679                 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
680                 info->audit_events.settings = TALLOC_ZERO_ARRAY(p->mem_ctx,
681                                                                 enum lsa_PolicyAuditPolicy,
682                                                                 info->audit_events.count);
683                 if (!info->audit_events.settings) {
684                         return NT_STATUS_NO_MEMORY;
685                 }
686
687                 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
688                 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
689                 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
690                 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
691                 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
692                 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
693                 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
694
695                 break;
696                 }
697         case LSA_POLICY_INFO_DOMAIN:
698                 /* check if the user has enough rights */
699                 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
700                         return NT_STATUS_ACCESS_DENIED;
701
702                 /* Request PolicyPrimaryDomainInformation. */
703                 switch (lp_server_role()) {
704                         case ROLE_DOMAIN_PDC:
705                         case ROLE_DOMAIN_BDC:
706                                 name = get_global_sam_name();
707                                 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
708                                 if (!sid) {
709                                         return NT_STATUS_NO_MEMORY;
710                                 }
711                                 break;
712                         case ROLE_DOMAIN_MEMBER:
713                                 name = lp_workgroup();
714                                 /* We need to return the Domain SID here. */
715                                 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
716                                         sid = dom_sid_dup(p->mem_ctx, &domain_sid);
717                                         if (!sid) {
718                                                 return NT_STATUS_NO_MEMORY;
719                                         }
720                                 } else {
721                                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
722                                 }
723                                 break;
724                         case ROLE_STANDALONE:
725                                 name = lp_workgroup();
726                                 sid = NULL;
727                                 break;
728                         default:
729                                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
730                 }
731                 init_dom_query_3(&info->domain, name, sid);
732                 break;
733         case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
734                 /* check if the user has enough rights */
735                 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
736                         return NT_STATUS_ACCESS_DENIED;
737
738                 /* Request PolicyAccountDomainInformation. */
739                 name = get_global_sam_name();
740                 sid = get_global_sam_sid();
741
742                 init_dom_query_5(&info->account_domain, name, sid);
743                 break;
744         case LSA_POLICY_INFO_ROLE:
745                 /* check if the user has enough rights */
746                 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
747                         return NT_STATUS_ACCESS_DENIED;
748
749                 switch (lp_server_role()) {
750                         case ROLE_DOMAIN_BDC:
751                                 /*
752                                  * only a BDC is a backup controller
753                                  * of the domain, it controls.
754                                  */
755                                 info->role.role = LSA_ROLE_BACKUP;
756                                 break;
757                         default:
758                                 /*
759                                  * any other role is a primary
760                                  * of the domain, it controls.
761                                  */
762                                 info->role.role = LSA_ROLE_PRIMARY;
763                                 break;
764                 }
765                 break;
766         case LSA_POLICY_INFO_DNS:
767         case LSA_POLICY_INFO_DNS_INT: {
768                 struct pdb_domain_info *dominfo;
769
770                 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
771                         DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
772                                    "without ADS passdb backend\n"));
773                         status = NT_STATUS_INVALID_INFO_CLASS;
774                         break;
775                 }
776
777                 dominfo = pdb_get_domain_info(info);
778                 if (dominfo == NULL) {
779                         status = NT_STATUS_NO_MEMORY;
780                         break;
781                 }
782
783                 init_lsa_StringLarge(&info->dns.name,
784                                      dominfo->name);
785                 init_lsa_StringLarge(&info->dns.dns_domain,
786                                      dominfo->dns_domain);
787                 init_lsa_StringLarge(&info->dns.dns_forest,
788                                      dominfo->dns_forest);
789                 info->dns.domain_guid = dominfo->guid;
790                 info->dns.sid = &dominfo->sid;
791                 break;
792         }
793         default:
794                 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
795                         r->in.level));
796                 status = NT_STATUS_INVALID_INFO_CLASS;
797                 break;
798         }
799
800         *r->out.info = info;
801
802         return status;
803 }
804
805 /***************************************************************************
806  _lsa_QueryInfoPolicy2
807  ***************************************************************************/
808
809 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
810                                struct lsa_QueryInfoPolicy2 *r2)
811 {
812         struct lsa_QueryInfoPolicy r;
813
814         if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
815                 p->rng_fault_state = True;
816                 return NT_STATUS_NOT_IMPLEMENTED;
817         }
818
819         ZERO_STRUCT(r);
820         r.in.handle = r2->in.handle;
821         r.in.level = r2->in.level;
822         r.out.info = r2->out.info;
823
824         return _lsa_QueryInfoPolicy(p, &r);
825 }
826
827 /***************************************************************************
828  _lsa_lookup_sids_internal
829  ***************************************************************************/
830
831 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
832                                           TALLOC_CTX *mem_ctx,
833                                           uint16_t level,                       /* input */
834                                           int num_sids,                         /* input */
835                                           struct lsa_SidPtr *sid,               /* input */
836                                           struct lsa_RefDomainList **pp_ref,    /* input/output */
837                                           struct lsa_TranslatedName2 **pp_names,/* input/output */
838                                           uint32_t *pp_mapped_count)            /* input/output */
839 {
840         NTSTATUS status;
841         int i;
842         const struct dom_sid **sids = NULL;
843         struct lsa_RefDomainList *ref = NULL;
844         uint32 mapped_count = 0;
845         struct lsa_dom_info *dom_infos = NULL;
846         struct lsa_name_info *name_infos = NULL;
847         struct lsa_TranslatedName2 *names = NULL;
848
849         *pp_mapped_count = 0;
850         *pp_names = NULL;
851         *pp_ref = NULL;
852
853         if (num_sids == 0) {
854                 return NT_STATUS_OK;
855         }
856
857         sids = TALLOC_ARRAY(p->mem_ctx, const struct dom_sid *, num_sids);
858         ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
859
860         if (sids == NULL || ref == NULL) {
861                 return NT_STATUS_NO_MEMORY;
862         }
863
864         for (i=0; i<num_sids; i++) {
865                 sids[i] = sid[i].sid;
866         }
867
868         status = lookup_sids(p->mem_ctx, num_sids, sids, level,
869                                   &dom_infos, &name_infos);
870
871         if (!NT_STATUS_IS_OK(status)) {
872                 return status;
873         }
874
875         names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
876         if (names == NULL) {
877                 return NT_STATUS_NO_MEMORY;
878         }
879
880         for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
881
882                 if (!dom_infos[i].valid) {
883                         break;
884                 }
885
886                 if (init_lsa_ref_domain_list(mem_ctx, ref,
887                                              dom_infos[i].name,
888                                              &dom_infos[i].sid) != i) {
889                         DEBUG(0, ("Domain %s mentioned twice??\n",
890                                   dom_infos[i].name));
891                         return NT_STATUS_INTERNAL_ERROR;
892                 }
893         }
894
895         for (i=0; i<num_sids; i++) {
896                 struct lsa_name_info *name = &name_infos[i];
897
898                 if (name->type == SID_NAME_UNKNOWN) {
899                         fstring tmp;
900                         name->dom_idx = -1;
901                         /* Unknown sids should return the string
902                          * representation of the SID. Windows 2003 behaves
903                          * rather erratic here, in many cases it returns the
904                          * RID as 8 bytes hex, in others it returns the full
905                          * SID. We (Jerry/VL) could not figure out which the
906                          * hard cases are, so leave it with the SID.  */
907                         name->name = talloc_asprintf(p->mem_ctx, "%s",
908                                                      sid_to_fstring(tmp,
909                                                                     sids[i]));
910                         if (name->name == NULL) {
911                                 return NT_STATUS_NO_MEMORY;
912                         }
913                 } else {
914                         mapped_count += 1;
915                 }
916
917                 names[i].sid_type       = name->type;
918                 names[i].name.string    = name->name;
919                 names[i].sid_index      = name->dom_idx;
920                 names[i].unknown        = 0;
921         }
922
923         status = NT_STATUS_NONE_MAPPED;
924         if (mapped_count > 0) {
925                 status = (mapped_count < num_sids) ?
926                         STATUS_SOME_UNMAPPED : NT_STATUS_OK;
927         }
928
929         DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
930                    num_sids, mapped_count, nt_errstr(status)));
931
932         *pp_mapped_count = mapped_count;
933         *pp_names = names;
934         *pp_ref = ref;
935
936         return status;
937 }
938
939 /***************************************************************************
940  _lsa_LookupSids
941  ***************************************************************************/
942
943 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
944                          struct lsa_LookupSids *r)
945 {
946         NTSTATUS status;
947         struct lsa_info *handle;
948         int num_sids = r->in.sids->num_sids;
949         uint32 mapped_count = 0;
950         struct lsa_RefDomainList *domains = NULL;
951         struct lsa_TranslatedName *names_out = NULL;
952         struct lsa_TranslatedName2 *names = NULL;
953         int i;
954
955         if ((r->in.level < 1) || (r->in.level > 6)) {
956                 return NT_STATUS_INVALID_PARAMETER;
957         }
958
959         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
960                 return NT_STATUS_INVALID_HANDLE;
961         }
962
963         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
964                 return NT_STATUS_INVALID_HANDLE;
965         }
966
967         /* check if the user has enough rights */
968         if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
969                 return NT_STATUS_ACCESS_DENIED;
970         }
971
972         if (num_sids >  MAX_LOOKUP_SIDS) {
973                 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
974                          MAX_LOOKUP_SIDS, num_sids));
975                 return NT_STATUS_NONE_MAPPED;
976         }
977
978         status = _lsa_lookup_sids_internal(p,
979                                            p->mem_ctx,
980                                            r->in.level,
981                                            num_sids,
982                                            r->in.sids->sids,
983                                            &domains,
984                                            &names,
985                                            &mapped_count);
986
987         /* Only return here when there is a real error.
988            NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
989            the requested sids could be resolved. Older versions of XP (pre SP3)
990            rely that we return with the string representations of those SIDs in
991            that case. If we don't, XP crashes - Guenther
992            */
993
994         if (NT_STATUS_IS_ERR(status) &&
995             !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
996                 return status;
997         }
998
999         /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
1000         names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
1001                                  num_sids);
1002         if (!names_out) {
1003                 return NT_STATUS_NO_MEMORY;
1004         }
1005
1006         for (i=0; i<num_sids; i++) {
1007                 names_out[i].sid_type = names[i].sid_type;
1008                 names_out[i].name = names[i].name;
1009                 names_out[i].sid_index = names[i].sid_index;
1010         }
1011
1012         *r->out.domains = domains;
1013         r->out.names->count = num_sids;
1014         r->out.names->names = names_out;
1015         *r->out.count = mapped_count;
1016
1017         return status;
1018 }
1019
1020 /***************************************************************************
1021  _lsa_LookupSids2
1022  ***************************************************************************/
1023
1024 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1025                           struct lsa_LookupSids2 *r)
1026 {
1027         NTSTATUS status;
1028         struct lsa_info *handle;
1029         int num_sids = r->in.sids->num_sids;
1030         uint32 mapped_count = 0;
1031         struct lsa_RefDomainList *domains = NULL;
1032         struct lsa_TranslatedName2 *names = NULL;
1033         bool check_policy = true;
1034
1035         switch (p->opnum) {
1036                 case NDR_LSA_LOOKUPSIDS3:
1037                         check_policy = false;
1038                         break;
1039                 case NDR_LSA_LOOKUPSIDS2:
1040                 default:
1041                         check_policy = true;
1042         }
1043
1044         if ((r->in.level < 1) || (r->in.level > 6)) {
1045                 return NT_STATUS_INVALID_PARAMETER;
1046         }
1047
1048         if (check_policy) {
1049                 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1050                         return NT_STATUS_INVALID_HANDLE;
1051                 }
1052
1053                 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1054                         return NT_STATUS_INVALID_HANDLE;
1055                 }
1056
1057                 /* check if the user has enough rights */
1058                 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1059                         return NT_STATUS_ACCESS_DENIED;
1060                 }
1061         }
1062
1063         if (num_sids >  MAX_LOOKUP_SIDS) {
1064                 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1065                          MAX_LOOKUP_SIDS, num_sids));
1066                 return NT_STATUS_NONE_MAPPED;
1067         }
1068
1069         status = _lsa_lookup_sids_internal(p,
1070                                            p->mem_ctx,
1071                                            r->in.level,
1072                                            num_sids,
1073                                            r->in.sids->sids,
1074                                            &domains,
1075                                            &names,
1076                                            &mapped_count);
1077
1078         *r->out.domains = domains;
1079         r->out.names->count = num_sids;
1080         r->out.names->names = names;
1081         *r->out.count = mapped_count;
1082
1083         return status;
1084 }
1085
1086 /***************************************************************************
1087  _lsa_LookupSids3
1088  ***************************************************************************/
1089
1090 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1091                           struct lsa_LookupSids3 *r)
1092 {
1093         struct lsa_LookupSids2 q;
1094
1095         /* No policy handle on this call. Restrict to crypto connections. */
1096         if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1097                 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1098                         get_remote_machine_name() ));
1099                 return NT_STATUS_INVALID_PARAMETER;
1100         }
1101
1102         q.in.handle             = NULL;
1103         q.in.sids               = r->in.sids;
1104         q.in.level              = r->in.level;
1105         q.in.lookup_options     = r->in.lookup_options;
1106         q.in.client_revision    = r->in.client_revision;
1107         q.in.names              = r->in.names;
1108         q.in.count              = r->in.count;
1109
1110         q.out.domains           = r->out.domains;
1111         q.out.names             = r->out.names;
1112         q.out.count             = r->out.count;
1113
1114         return _lsa_LookupSids2(p, &q);
1115 }
1116
1117 /***************************************************************************
1118  ***************************************************************************/
1119
1120 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1121 {
1122         int flags;
1123
1124         switch (level) {
1125                 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1126                         flags = LOOKUP_NAME_ALL;
1127                         break;
1128                 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1129                         flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1130                         break;
1131                 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1132                         flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1133                         break;
1134                 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1135                 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1136                 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1137                 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1138                 default:
1139                         flags = LOOKUP_NAME_NONE;
1140                         break;
1141         }
1142
1143         return flags;
1144 }
1145
1146 /***************************************************************************
1147  _lsa_LookupNames
1148  ***************************************************************************/
1149
1150 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1151                           struct lsa_LookupNames *r)
1152 {
1153         NTSTATUS status = NT_STATUS_NONE_MAPPED;
1154         struct lsa_info *handle;
1155         struct lsa_String *names = r->in.names;
1156         uint32 num_entries = r->in.num_names;
1157         struct lsa_RefDomainList *domains = NULL;
1158         struct lsa_TranslatedSid *rids = NULL;
1159         uint32 mapped_count = 0;
1160         int flags = 0;
1161
1162         if (num_entries >  MAX_LOOKUP_SIDS) {
1163                 num_entries = MAX_LOOKUP_SIDS;
1164                 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1165                         num_entries));
1166         }
1167
1168         flags = lsa_lookup_level_to_flags(r->in.level);
1169
1170         domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1171         if (!domains) {
1172                 return NT_STATUS_NO_MEMORY;
1173         }
1174
1175         if (num_entries) {
1176                 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
1177                                          num_entries);
1178                 if (!rids) {
1179                         return NT_STATUS_NO_MEMORY;
1180                 }
1181         } else {
1182                 rids = NULL;
1183         }
1184
1185         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1186                 status = NT_STATUS_INVALID_HANDLE;
1187                 goto done;
1188         }
1189
1190         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1191                 return NT_STATUS_INVALID_HANDLE;
1192         }
1193
1194         /* check if the user has enough rights */
1195         if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1196                 status = NT_STATUS_ACCESS_DENIED;
1197                 goto done;
1198         }
1199
1200         /* set up the LSA Lookup RIDs response */
1201         become_root(); /* lookup_name can require root privs */
1202         status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1203                                  names, flags, &mapped_count);
1204         unbecome_root();
1205
1206 done:
1207
1208         if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1209                 if (mapped_count == 0) {
1210                         status = NT_STATUS_NONE_MAPPED;
1211                 } else if (mapped_count != num_entries) {
1212                         status = STATUS_SOME_UNMAPPED;
1213                 }
1214         }
1215
1216         *r->out.count = mapped_count;
1217         *r->out.domains = domains;
1218         r->out.sids->sids = rids;
1219         r->out.sids->count = num_entries;
1220
1221         return status;
1222 }
1223
1224 /***************************************************************************
1225  _lsa_LookupNames2
1226  ***************************************************************************/
1227
1228 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1229                            struct lsa_LookupNames2 *r)
1230 {
1231         NTSTATUS status;
1232         struct lsa_LookupNames q;
1233         struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1234         struct lsa_TransSidArray *sid_array = NULL;
1235         uint32_t i;
1236
1237         sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1238         if (!sid_array) {
1239                 return NT_STATUS_NO_MEMORY;
1240         }
1241
1242         q.in.handle             = r->in.handle;
1243         q.in.num_names          = r->in.num_names;
1244         q.in.names              = r->in.names;
1245         q.in.level              = r->in.level;
1246         q.in.sids               = sid_array;
1247         q.in.count              = r->in.count;
1248         /* we do not know what this is for */
1249         /*                      = r->in.unknown1; */
1250         /*                      = r->in.unknown2; */
1251
1252         q.out.domains           = r->out.domains;
1253         q.out.sids              = sid_array;
1254         q.out.count             = r->out.count;
1255
1256         status = _lsa_LookupNames(p, &q);
1257
1258         sid_array2->count = sid_array->count;
1259         sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1260         if (!sid_array2->sids) {
1261                 return NT_STATUS_NO_MEMORY;
1262         }
1263
1264         for (i=0; i<sid_array->count; i++) {
1265                 sid_array2->sids[i].sid_type  = sid_array->sids[i].sid_type;
1266                 sid_array2->sids[i].rid       = sid_array->sids[i].rid;
1267                 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1268                 sid_array2->sids[i].unknown   = 0;
1269         }
1270
1271         r->out.sids = sid_array2;
1272
1273         return status;
1274 }
1275
1276 /***************************************************************************
1277  _lsa_LookupNames3
1278  ***************************************************************************/
1279
1280 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1281                            struct lsa_LookupNames3 *r)
1282 {
1283         NTSTATUS status;
1284         struct lsa_info *handle;
1285         struct lsa_String *names = r->in.names;
1286         uint32 num_entries = r->in.num_names;
1287         struct lsa_RefDomainList *domains = NULL;
1288         struct lsa_TranslatedSid3 *trans_sids = NULL;
1289         uint32 mapped_count = 0;
1290         int flags = 0;
1291         bool check_policy = true;
1292
1293         switch (p->opnum) {
1294                 case NDR_LSA_LOOKUPNAMES4:
1295                         check_policy = false;
1296                         break;
1297                 case NDR_LSA_LOOKUPNAMES3:
1298                 default:
1299                         check_policy = true;
1300         }
1301
1302         if (num_entries >  MAX_LOOKUP_SIDS) {
1303                 num_entries = MAX_LOOKUP_SIDS;
1304                 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1305         }
1306
1307         /* Probably the lookup_level is some sort of bitmask. */
1308         if (r->in.level == 1) {
1309                 flags = LOOKUP_NAME_ALL;
1310         }
1311
1312         domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1313         if (!domains) {
1314                 return NT_STATUS_NO_MEMORY;
1315         }
1316
1317         if (num_entries) {
1318                 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1319                                                num_entries);
1320                 if (!trans_sids) {
1321                         return NT_STATUS_NO_MEMORY;
1322                 }
1323         } else {
1324                 trans_sids = NULL;
1325         }
1326
1327         if (check_policy) {
1328
1329                 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1330                         status = NT_STATUS_INVALID_HANDLE;
1331                         goto done;
1332                 }
1333
1334                 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1335                         return NT_STATUS_INVALID_HANDLE;
1336                 }
1337
1338                 /* check if the user has enough rights */
1339                 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1340                         status = NT_STATUS_ACCESS_DENIED;
1341                         goto done;
1342                 }
1343         }
1344
1345         /* set up the LSA Lookup SIDs response */
1346         become_root(); /* lookup_name can require root privs */
1347         status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1348                                  names, flags, &mapped_count);
1349         unbecome_root();
1350
1351 done:
1352
1353         if (NT_STATUS_IS_OK(status)) {
1354                 if (mapped_count == 0) {
1355                         status = NT_STATUS_NONE_MAPPED;
1356                 } else if (mapped_count != num_entries) {
1357                         status = STATUS_SOME_UNMAPPED;
1358                 }
1359         }
1360
1361         *r->out.count = mapped_count;
1362         *r->out.domains = domains;
1363         r->out.sids->sids = trans_sids;
1364         r->out.sids->count = num_entries;
1365
1366         return status;
1367 }
1368
1369 /***************************************************************************
1370  _lsa_LookupNames4
1371  ***************************************************************************/
1372
1373 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1374                            struct lsa_LookupNames4 *r)
1375 {
1376         struct lsa_LookupNames3 q;
1377
1378         /* No policy handle on this call. Restrict to crypto connections. */
1379         if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1380                 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1381                         get_remote_machine_name() ));
1382                 return NT_STATUS_INVALID_PARAMETER;
1383         }
1384
1385         q.in.handle             = NULL;
1386         q.in.num_names          = r->in.num_names;
1387         q.in.names              = r->in.names;
1388         q.in.level              = r->in.level;
1389         q.in.lookup_options     = r->in.lookup_options;
1390         q.in.client_revision    = r->in.client_revision;
1391         q.in.sids               = r->in.sids;
1392         q.in.count              = r->in.count;
1393
1394         q.out.domains           = r->out.domains;
1395         q.out.sids              = r->out.sids;
1396         q.out.count             = r->out.count;
1397
1398         return _lsa_LookupNames3(p, &q);
1399 }
1400
1401 /***************************************************************************
1402  _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1403  ***************************************************************************/
1404
1405 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1406 {
1407         if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1408                 return NT_STATUS_INVALID_HANDLE;
1409         }
1410
1411         close_policy_hnd(p, r->in.handle);
1412         ZERO_STRUCTP(r->out.handle);
1413         return NT_STATUS_OK;
1414 }
1415
1416 /***************************************************************************
1417  ***************************************************************************/
1418
1419 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1420                                                  const struct dom_sid *sid,
1421                                                  struct trustdom_info **info)
1422 {
1423         NTSTATUS status;
1424         uint32_t num_domains = 0;
1425         struct trustdom_info **domains = NULL;
1426         int i;
1427
1428         status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1429         if (!NT_STATUS_IS_OK(status)) {
1430                 return status;
1431         }
1432
1433         for (i=0; i < num_domains; i++) {
1434                 if (dom_sid_equal(&domains[i]->sid, sid)) {
1435                         break;
1436                 }
1437         }
1438
1439         if (i == num_domains) {
1440                 return NT_STATUS_INVALID_PARAMETER;
1441         }
1442
1443         *info = domains[i];
1444
1445         return NT_STATUS_OK;
1446 }
1447
1448 /***************************************************************************
1449  ***************************************************************************/
1450
1451 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1452                                                   const char *netbios_domain_name,
1453                                                   struct trustdom_info **info_p)
1454 {
1455         NTSTATUS status;
1456         struct trustdom_info *info;
1457         struct pdb_trusted_domain *td;
1458
1459         status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1460         if (!NT_STATUS_IS_OK(status)) {
1461                 return status;
1462         }
1463
1464         info = talloc(mem_ctx, struct trustdom_info);
1465         if (!info) {
1466                 return NT_STATUS_NO_MEMORY;
1467         }
1468
1469         info->name      = talloc_strdup(info, netbios_domain_name);
1470         NT_STATUS_HAVE_NO_MEMORY(info->name);
1471
1472         sid_copy(&info->sid, &td->security_identifier);
1473
1474         *info_p = info;
1475
1476         return NT_STATUS_OK;
1477 }
1478
1479 /***************************************************************************
1480  ***************************************************************************/
1481
1482 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p, struct lsa_OpenSecret *r)
1483 {
1484         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1485 }
1486
1487 /***************************************************************************
1488  _lsa_OpenTrustedDomain_base
1489  ***************************************************************************/
1490
1491 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1492                                             uint32_t access_mask,
1493                                             struct trustdom_info *info,
1494                                             struct policy_handle *handle)
1495 {
1496         struct security_descriptor *psd = NULL;
1497         size_t sd_size;
1498         uint32_t acc_granted;
1499         NTSTATUS status;
1500
1501         /* des_access is for the account here, not the policy
1502          * handle - so don't check against policy handle. */
1503
1504         /* Work out max allowed. */
1505         map_max_allowed_access(p->server_info->security_token,
1506                                &p->server_info->utok,
1507                                &access_mask);
1508
1509         /* map the generic bits to the lsa account ones */
1510         se_map_generic(&access_mask, &lsa_account_mapping);
1511
1512         /* get the generic lsa account SD until we store it */
1513         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1514                                     &lsa_trusted_domain_mapping,
1515                                     NULL, 0);
1516         if (!NT_STATUS_IS_OK(status)) {
1517                 return status;
1518         }
1519
1520         status = access_check_object(psd, p->server_info->security_token,
1521                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1522                                      access_mask, &acc_granted,
1523                                      "_lsa_OpenTrustedDomain");
1524         if (!NT_STATUS_IS_OK(status)) {
1525                 return status;
1526         }
1527
1528         status = create_lsa_policy_handle(p->mem_ctx, p,
1529                                           LSA_HANDLE_TRUST_TYPE,
1530                                           acc_granted,
1531                                           &info->sid,
1532                                           info->name,
1533                                           psd,
1534                                           handle);
1535         if (!NT_STATUS_IS_OK(status)) {
1536                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1537         }
1538
1539         return NT_STATUS_OK;
1540 }
1541
1542 /***************************************************************************
1543  _lsa_OpenTrustedDomain
1544  ***************************************************************************/
1545
1546 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1547                                 struct lsa_OpenTrustedDomain *r)
1548 {
1549         struct lsa_info *handle = NULL;
1550         struct trustdom_info *info;
1551         NTSTATUS status;
1552
1553         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1554                 return NT_STATUS_INVALID_HANDLE;
1555         }
1556
1557         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1558                 return NT_STATUS_INVALID_HANDLE;
1559         }
1560
1561         status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1562                                                   r->in.sid,
1563                                                   &info);
1564         if (!NT_STATUS_IS_OK(status)) {
1565                 return status;
1566         }
1567
1568         return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1569                                            r->out.trustdom_handle);
1570 }
1571
1572 /***************************************************************************
1573  _lsa_OpenTrustedDomainByName
1574  ***************************************************************************/
1575
1576 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1577                                       struct lsa_OpenTrustedDomainByName *r)
1578 {
1579         struct lsa_info *handle = NULL;
1580         struct trustdom_info *info;
1581         NTSTATUS status;
1582
1583         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1584                 return NT_STATUS_INVALID_HANDLE;
1585         }
1586
1587         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1588                 return NT_STATUS_INVALID_HANDLE;
1589         }
1590
1591         status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1592                                                    r->in.name.string,
1593                                                    &info);
1594         if (!NT_STATUS_IS_OK(status)) {
1595                 return status;
1596         }
1597
1598         return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1599                                            r->out.trustdom_handle);
1600 }
1601
1602 static NTSTATUS add_trusted_domain_user(TALLOC_CTX *mem_ctx,
1603                                         const char *netbios_name,
1604                                         const char *domain_name,
1605                                         struct trustDomainPasswords auth_struct)
1606 {
1607         NTSTATUS status;
1608         struct samu *sam_acct;
1609         char *acct_name;
1610         uint32_t rid;
1611         struct dom_sid user_sid;
1612         int i;
1613         char *dummy;
1614         size_t dummy_size;
1615
1616         sam_acct = samu_new(mem_ctx);
1617         if (sam_acct == NULL) {
1618                 return NT_STATUS_NO_MEMORY;
1619         }
1620
1621         acct_name = talloc_asprintf(mem_ctx, "%s$", netbios_name);
1622         if (acct_name == NULL) {
1623                 return NT_STATUS_NO_MEMORY;
1624         }
1625         if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1626                 return NT_STATUS_UNSUCCESSFUL;
1627         }
1628
1629         if (!pdb_set_domain(sam_acct, domain_name, PDB_SET)) {
1630                 return NT_STATUS_UNSUCCESSFUL;
1631         }
1632
1633         if (!pdb_set_acct_ctrl(sam_acct, ACB_DOMTRUST, PDB_SET)) {
1634                 return NT_STATUS_UNSUCCESSFUL;
1635         }
1636
1637         if (!pdb_new_rid(&rid)) {
1638                 return NT_STATUS_DS_NO_MORE_RIDS;
1639         }
1640         sid_compose(&user_sid, get_global_sam_sid(), rid);
1641         if (!pdb_set_user_sid(sam_acct, &user_sid, PDB_SET)) {
1642                 return NT_STATUS_UNSUCCESSFUL;
1643         }
1644
1645         for (i = 0; i < auth_struct.incoming.count; i++) {
1646                 switch (auth_struct.incoming.current.array[i].AuthType) {
1647                         case TRUST_AUTH_TYPE_CLEAR:
1648                                 if (!convert_string_talloc(mem_ctx,
1649                                                            CH_UTF16LE,
1650                                                            CH_UNIX,
1651                                                            auth_struct.incoming.current.array[i].AuthInfo.clear.password,
1652                                                            auth_struct.incoming.current.array[i].AuthInfo.clear.size,
1653                                                            &dummy,
1654                                                            &dummy_size,
1655                                                            false)) {
1656                                         return NT_STATUS_UNSUCCESSFUL;
1657                                 }
1658                                 if (!pdb_set_plaintext_passwd(sam_acct, dummy)) {
1659                                         return NT_STATUS_UNSUCCESSFUL;
1660                                 }
1661                                 break;
1662                         default:
1663                                 continue;
1664                 }
1665         }
1666
1667         status = pdb_add_sam_account(sam_acct);
1668         if (!NT_STATUS_IS_OK(status)) {
1669                 return status;
1670         }
1671
1672         return NT_STATUS_OK;
1673 }
1674
1675 /***************************************************************************
1676  _lsa_CreateTrustedDomainEx2
1677  ***************************************************************************/
1678
1679 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1680                                      struct lsa_CreateTrustedDomainEx2 *r)
1681 {
1682         struct lsa_info *policy;
1683         NTSTATUS status;
1684         uint32_t acc_granted;
1685         struct security_descriptor *psd;
1686         size_t sd_size;
1687         struct pdb_trusted_domain td;
1688         struct trustDomainPasswords auth_struct;
1689         enum ndr_err_code ndr_err;
1690         DATA_BLOB auth_blob;
1691
1692         if (!IS_DC) {
1693                 return NT_STATUS_NOT_SUPPORTED;
1694         }
1695
1696         if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1697                 return NT_STATUS_INVALID_HANDLE;
1698         }
1699
1700         if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1701                 return NT_STATUS_ACCESS_DENIED;
1702         }
1703
1704         if (p->server_info->utok.uid != sec_initial_uid() &&
1705             !nt_token_check_domain_rid(p->server_info->security_token, DOMAIN_RID_ADMINS)) {
1706                 return NT_STATUS_ACCESS_DENIED;
1707         }
1708
1709         /* Work out max allowed. */
1710         map_max_allowed_access(p->server_info->security_token,
1711                                &p->server_info->utok,
1712                                &r->in.access_mask);
1713
1714         /* map the generic bits to the lsa policy ones */
1715         se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1716
1717         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1718                                     &lsa_trusted_domain_mapping,
1719                                     NULL, 0);
1720         if (!NT_STATUS_IS_OK(status)) {
1721                 return status;
1722         }
1723
1724         status = access_check_object(psd, p->server_info->security_token,
1725                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1726                                      r->in.access_mask, &acc_granted,
1727                                      "_lsa_CreateTrustedDomainEx2");
1728         if (!NT_STATUS_IS_OK(status)) {
1729                 return status;
1730         }
1731
1732         ZERO_STRUCT(td);
1733
1734         td.domain_name = talloc_strdup(p->mem_ctx,
1735                                        r->in.info->domain_name.string);
1736         if (td.domain_name == NULL) {
1737                 return NT_STATUS_NO_MEMORY;
1738         }
1739         td.netbios_name = talloc_strdup(p->mem_ctx,
1740                                         r->in.info->netbios_name.string);
1741         if (td.netbios_name == NULL) {
1742                 return NT_STATUS_NO_MEMORY;
1743         }
1744         sid_copy(&td.security_identifier, r->in.info->sid);
1745         td.trust_direction = r->in.info->trust_direction;
1746         td.trust_type = r->in.info->trust_type;
1747         td.trust_attributes = r->in.info->trust_attributes;
1748
1749         if (r->in.auth_info->auth_blob.size != 0) {
1750                 auth_blob.length = r->in.auth_info->auth_blob.size;
1751                 auth_blob.data = r->in.auth_info->auth_blob.data;
1752
1753                 arcfour_crypt_blob(auth_blob.data, auth_blob.length,
1754                                    &p->server_info->user_session_key);
1755
1756                 ndr_err = ndr_pull_struct_blob(&auth_blob, p->mem_ctx,
1757                                                &auth_struct,
1758                                                (ndr_pull_flags_fn_t) ndr_pull_trustDomainPasswords);
1759                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1760                         return NT_STATUS_UNSUCCESSFUL;
1761                 }
1762
1763                 ndr_err = ndr_push_struct_blob(&td.trust_auth_incoming, p->mem_ctx,
1764                                                &auth_struct.incoming,
1765                                                (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1766                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1767                         return NT_STATUS_UNSUCCESSFUL;
1768                 }
1769
1770                 ndr_err = ndr_push_struct_blob(&td.trust_auth_outgoing, p->mem_ctx,
1771                                                &auth_struct.outgoing,
1772                                                (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1773                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1774                         return NT_STATUS_UNSUCCESSFUL;
1775                 }
1776         } else {
1777                 td.trust_auth_incoming.data = NULL;
1778                 td.trust_auth_incoming.length = 0;
1779                 td.trust_auth_outgoing.data = NULL;
1780                 td.trust_auth_outgoing.length = 0;
1781         }
1782
1783         status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1784         if (!NT_STATUS_IS_OK(status)) {
1785                 return status;
1786         }
1787
1788         if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1789                 status = add_trusted_domain_user(p->mem_ctx,
1790                                                  r->in.info->netbios_name.string,
1791                                                  r->in.info->domain_name.string,
1792                                                  auth_struct);
1793                 if (!NT_STATUS_IS_OK(status)) {
1794                         return status;
1795                 }
1796         }
1797
1798         status = create_lsa_policy_handle(p->mem_ctx, p,
1799                                           LSA_HANDLE_TRUST_TYPE,
1800                                           acc_granted,
1801                                           r->in.info->sid,
1802                                           r->in.info->netbios_name.string,
1803                                           psd,
1804                                           r->out.trustdom_handle);
1805         if (!NT_STATUS_IS_OK(status)) {
1806                 pdb_del_trusteddom_pw(r->in.info->netbios_name.string);
1807                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1808         }
1809
1810         return NT_STATUS_OK;
1811 }
1812
1813 /***************************************************************************
1814  _lsa_CreateTrustedDomainEx
1815  ***************************************************************************/
1816
1817 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1818                                     struct lsa_CreateTrustedDomainEx *r)
1819 {
1820         struct lsa_CreateTrustedDomainEx2 q;
1821
1822         q.in.policy_handle      = r->in.policy_handle;
1823         q.in.info               = r->in.info;
1824         q.in.auth_info          = r->in.auth_info;
1825         q.in.access_mask        = r->in.access_mask;
1826         q.out.trustdom_handle   = r->out.trustdom_handle;
1827
1828         return _lsa_CreateTrustedDomainEx2(p, &q);
1829 }
1830
1831 /***************************************************************************
1832  _lsa_CreateTrustedDomain
1833  ***************************************************************************/
1834
1835 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1836                                   struct lsa_CreateTrustedDomain *r)
1837 {
1838         struct lsa_CreateTrustedDomainEx2 c;
1839         struct lsa_TrustDomainInfoInfoEx info;
1840         struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1841
1842         ZERO_STRUCT(auth_info);
1843
1844         info.domain_name        = r->in.info->name;
1845         info.netbios_name       = r->in.info->name;
1846         info.sid                = r->in.info->sid;
1847         info.trust_direction    = LSA_TRUST_DIRECTION_OUTBOUND;
1848         info.trust_type         = LSA_TRUST_TYPE_DOWNLEVEL;
1849         info.trust_attributes   = 0;
1850
1851         c.in.policy_handle      = r->in.policy_handle;
1852         c.in.info               = &info;
1853         c.in.auth_info          = &auth_info;
1854         c.in.access_mask        = r->in.access_mask;
1855         c.out.trustdom_handle   = r->out.trustdom_handle;
1856
1857         return _lsa_CreateTrustedDomainEx2(p, &c);
1858 }
1859
1860 /***************************************************************************
1861  _lsa_DeleteTrustedDomain
1862  ***************************************************************************/
1863
1864 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1865                                   struct lsa_DeleteTrustedDomain *r)
1866 {
1867         NTSTATUS status;
1868         struct lsa_info *handle;
1869         struct pdb_trusted_domain *td;
1870         struct samu *sam_acct;
1871         char *acct_name;
1872
1873         /* find the connection policy handle. */
1874         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1875                 return NT_STATUS_INVALID_HANDLE;
1876         }
1877
1878         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1879                 return NT_STATUS_INVALID_HANDLE;
1880         }
1881
1882         if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1883                 return NT_STATUS_ACCESS_DENIED;
1884         }
1885
1886         status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1887         if (!NT_STATUS_IS_OK(status)) {
1888                 return status;
1889         }
1890
1891         if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1892                 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1893                            sid_string_tos(r->in.dom_sid)));
1894                 return NT_STATUS_UNSUCCESSFUL;
1895         }
1896
1897         if (td->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1898                 sam_acct = samu_new(p->mem_ctx);
1899                 if (sam_acct == NULL) {
1900                         return NT_STATUS_NO_MEMORY;
1901                 }
1902
1903                 acct_name = talloc_asprintf(p->mem_ctx, "%s$", td->netbios_name);
1904                 if (acct_name == NULL) {
1905                         return NT_STATUS_NO_MEMORY;
1906                 }
1907                 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1908                         return NT_STATUS_UNSUCCESSFUL;
1909                 }
1910                 status = pdb_delete_sam_account(sam_acct);
1911                 if (!NT_STATUS_IS_OK(status)) {
1912                         return status;
1913                 }
1914         }
1915
1916         status = pdb_del_trusted_domain(td->netbios_name);
1917         if (!NT_STATUS_IS_OK(status)) {
1918                 return status;
1919         }
1920
1921         return NT_STATUS_OK;
1922 }
1923
1924 /***************************************************************************
1925  _lsa_CloseTrustedDomainEx
1926  ***************************************************************************/
1927
1928 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1929                                    struct lsa_CloseTrustedDomainEx *r)
1930 {
1931         return NT_STATUS_NOT_IMPLEMENTED;
1932 }
1933
1934 /***************************************************************************
1935  _lsa_QueryTrustedDomainInfo
1936  ***************************************************************************/
1937
1938 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
1939                                      struct lsa_QueryTrustedDomainInfo *r)
1940 {
1941         NTSTATUS status;
1942         struct lsa_info *handle;
1943         union lsa_TrustedDomainInfo *info;
1944         struct pdb_trusted_domain *td;
1945         uint32_t acc_required;
1946
1947         /* find the connection policy handle. */
1948         if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
1949                 return NT_STATUS_INVALID_HANDLE;
1950         }
1951
1952         if (handle->type != LSA_HANDLE_TRUST_TYPE) {
1953                 return NT_STATUS_INVALID_HANDLE;
1954         }
1955
1956         switch (r->in.level) {
1957         case LSA_TRUSTED_DOMAIN_INFO_NAME:
1958                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1959                 break;
1960         case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1961                 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
1962                 break;
1963         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1964                 acc_required = LSA_TRUSTED_QUERY_POSIX;
1965                 break;
1966         case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
1967                 acc_required = LSA_TRUSTED_QUERY_AUTH;
1968                 break;
1969         case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1970                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1971                 break;
1972         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1973                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1974                 break;
1975         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1976                 acc_required = LSA_TRUSTED_QUERY_AUTH;
1977                 break;
1978         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1979                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1980                                LSA_TRUSTED_QUERY_POSIX |
1981                                LSA_TRUSTED_QUERY_AUTH;
1982                 break;
1983         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1984                 acc_required = LSA_TRUSTED_QUERY_AUTH;
1985                 break;
1986         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1987                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1988                                LSA_TRUSTED_QUERY_POSIX |
1989                                LSA_TRUSTED_QUERY_AUTH;
1990                 break;
1991         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1992                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1993                 break;
1994         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1995                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1996                                LSA_TRUSTED_QUERY_POSIX |
1997                                LSA_TRUSTED_QUERY_AUTH;
1998                 break;
1999         case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2000                 acc_required = LSA_TRUSTED_QUERY_POSIX;
2001                 break;
2002         default:
2003                 return NT_STATUS_INVALID_PARAMETER;
2004         }
2005
2006         if (!(handle->access & acc_required)) {
2007                 return NT_STATUS_ACCESS_DENIED;
2008         }
2009
2010         status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2011         if (!NT_STATUS_IS_OK(status)) {
2012                 return status;
2013         }
2014
2015         info = TALLOC_ZERO_P(p->mem_ctx, union lsa_TrustedDomainInfo);
2016         if (!info) {
2017                 return NT_STATUS_NO_MEMORY;
2018         }
2019
2020         switch (r->in.level) {
2021         case LSA_TRUSTED_DOMAIN_INFO_NAME:
2022                 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2023                 break;
2024         case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2025                 return NT_STATUS_INVALID_PARAMETER;
2026         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2027                 break;
2028         case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2029                 return NT_STATUS_INVALID_INFO_CLASS;
2030         case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2031                 return NT_STATUS_INVALID_PARAMETER;
2032         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2033                 init_lsa_StringLarge(&info->info_ex.domain_name, td->domain_name);
2034                 init_lsa_StringLarge(&info->info_ex.netbios_name, td->netbios_name);
2035                 info->info_ex.sid = dom_sid_dup(info, &td->security_identifier);
2036                 if (!info->info_ex.sid) {
2037                         return NT_STATUS_NO_MEMORY;
2038                 }
2039                 info->info_ex.trust_direction = td->trust_direction;
2040                 info->info_ex.trust_type = td->trust_type;
2041                 info->info_ex.trust_attributes = td->trust_attributes;
2042                 break;
2043         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2044                 return NT_STATUS_INVALID_INFO_CLASS;
2045         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2046                 break;
2047         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2048                 return NT_STATUS_INVALID_INFO_CLASS;
2049         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2050                 return NT_STATUS_INVALID_INFO_CLASS;
2051         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2052                 return NT_STATUS_INVALID_PARAMETER;
2053         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2054                 break;
2055         case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2056                 break;
2057         default:
2058                 return NT_STATUS_INVALID_PARAMETER;
2059         }
2060
2061         *r->out.info = info;
2062
2063         return NT_STATUS_OK;
2064 }
2065
2066 /***************************************************************************
2067  _lsa_QueryTrustedDomainInfoBySid
2068  ***************************************************************************/
2069
2070 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2071                                           struct lsa_QueryTrustedDomainInfoBySid *r)
2072 {
2073         NTSTATUS status;
2074         struct policy_handle trustdom_handle;
2075         struct lsa_OpenTrustedDomain o;
2076         struct lsa_QueryTrustedDomainInfo q;
2077         struct lsa_Close c;
2078
2079         o.in.handle             = r->in.handle;
2080         o.in.sid                = r->in.dom_sid;
2081         o.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
2082         o.out.trustdom_handle   = &trustdom_handle;
2083
2084         status = _lsa_OpenTrustedDomain(p, &o);
2085         if (!NT_STATUS_IS_OK(status)) {
2086                 return status;
2087         }
2088
2089         q.in.trustdom_handle    = &trustdom_handle;
2090         q.in.level              = r->in.level;
2091         q.out.info              = r->out.info;
2092
2093         status = _lsa_QueryTrustedDomainInfo(p, &q);
2094         if (!NT_STATUS_IS_OK(status)) {
2095                 return status;
2096         }
2097
2098         c.in.handle             = &trustdom_handle;
2099         c.out.handle            = &trustdom_handle;
2100
2101         return _lsa_Close(p, &c);
2102 }
2103
2104 /***************************************************************************
2105  _lsa_QueryTrustedDomainInfoByName
2106  ***************************************************************************/
2107
2108 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2109                                            struct lsa_QueryTrustedDomainInfoByName *r)
2110 {
2111         NTSTATUS status;
2112         struct policy_handle trustdom_handle;
2113         struct lsa_OpenTrustedDomainByName o;
2114         struct lsa_QueryTrustedDomainInfo q;
2115         struct lsa_Close c;
2116
2117         o.in.handle             = r->in.handle;
2118         o.in.name.string        = r->in.trusted_domain->string;
2119         o.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
2120         o.out.trustdom_handle   = &trustdom_handle;
2121
2122         status = _lsa_OpenTrustedDomainByName(p, &o);
2123         if (!NT_STATUS_IS_OK(status)) {
2124                 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2125                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2126                 }
2127                 return status;
2128         }
2129
2130         q.in.trustdom_handle    = &trustdom_handle;
2131         q.in.level              = r->in.level;
2132         q.out.info              = r->out.info;
2133
2134         status = _lsa_QueryTrustedDomainInfo(p, &q);
2135         if (!NT_STATUS_IS_OK(status)) {
2136                 return status;
2137         }
2138
2139         c.in.handle             = &trustdom_handle;
2140         c.out.handle            = &trustdom_handle;
2141
2142         return _lsa_Close(p, &c);
2143 }
2144
2145 /***************************************************************************
2146  ***************************************************************************/
2147
2148 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p, struct lsa_CreateSecret *r)
2149 {
2150         return NT_STATUS_ACCESS_DENIED;
2151 }
2152
2153 /***************************************************************************
2154  ***************************************************************************/
2155
2156 NTSTATUS _lsa_SetSecret(struct pipes_struct *p, struct lsa_SetSecret *r)
2157 {
2158         return NT_STATUS_ACCESS_DENIED;
2159 }
2160
2161 /***************************************************************************
2162  _lsa_DeleteObject
2163  ***************************************************************************/
2164
2165 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2166                            struct lsa_DeleteObject *r)
2167 {
2168         NTSTATUS status;
2169         struct lsa_info *info = NULL;
2170
2171         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2172                 return NT_STATUS_INVALID_HANDLE;
2173         }
2174
2175         if (!(info->access & SEC_STD_DELETE)) {
2176                 return NT_STATUS_ACCESS_DENIED;
2177         }
2178
2179         switch (info->type) {
2180         case LSA_HANDLE_ACCOUNT_TYPE:
2181                 status = privilege_delete_account(&info->sid);
2182                 if (!NT_STATUS_IS_OK(status)) {
2183                         DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2184                                 nt_errstr(status)));
2185                         return status;
2186                 }
2187                 break;
2188         default:
2189                 return NT_STATUS_INVALID_HANDLE;
2190         }
2191
2192         close_policy_hnd(p, r->in.handle);
2193         ZERO_STRUCTP(r->out.handle);
2194
2195         return status;
2196 }
2197
2198 /***************************************************************************
2199  _lsa_EnumPrivs
2200  ***************************************************************************/
2201
2202 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2203                         struct lsa_EnumPrivs *r)
2204 {
2205         struct lsa_info *handle;
2206         uint32 i;
2207         uint32 enum_context = *r->in.resume_handle;
2208         int num_privs = num_privileges_in_short_list();
2209         struct lsa_PrivEntry *entries = NULL;
2210
2211         /* remember that the enum_context starts at 0 and not 1 */
2212
2213         if ( enum_context >= num_privs )
2214                 return NT_STATUS_NO_MORE_ENTRIES;
2215
2216         DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2217                 enum_context, num_privs));
2218
2219         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2220                 return NT_STATUS_INVALID_HANDLE;
2221
2222         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2223                 return NT_STATUS_INVALID_HANDLE;
2224         }
2225
2226         /* check if the user has enough rights
2227            I don't know if it's the right one. not documented.  */
2228
2229         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2230                 return NT_STATUS_ACCESS_DENIED;
2231
2232         if (num_privs) {
2233                 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2234                 if (!entries) {
2235                         return NT_STATUS_NO_MEMORY;
2236                 }
2237         } else {
2238                 entries = NULL;
2239         }
2240
2241         for (i = 0; i < num_privs; i++) {
2242                 if( i < enum_context) {
2243
2244                         init_lsa_StringLarge(&entries[i].name, NULL);
2245
2246                         entries[i].luid.low = 0;
2247                         entries[i].luid.high = 0;
2248                 } else {
2249
2250                         init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2251
2252                         entries[i].luid.low = sec_privilege_from_index(i);
2253                         entries[i].luid.high = 0;
2254                 }
2255         }
2256
2257         enum_context = num_privs;
2258
2259         *r->out.resume_handle = enum_context;
2260         r->out.privs->count = num_privs;
2261         r->out.privs->privs = entries;
2262
2263         return NT_STATUS_OK;
2264 }
2265
2266 /***************************************************************************
2267  _lsa_LookupPrivDisplayName
2268  ***************************************************************************/
2269
2270 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2271                                     struct lsa_LookupPrivDisplayName *r)
2272 {
2273         struct lsa_info *handle;
2274         const char *description;
2275         struct lsa_StringLarge *lsa_name;
2276
2277         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2278                 return NT_STATUS_INVALID_HANDLE;
2279
2280         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2281                 return NT_STATUS_INVALID_HANDLE;
2282         }
2283
2284         /* check if the user has enough rights */
2285
2286         /*
2287          * I don't know if it's the right one. not documented.
2288          */
2289         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2290                 return NT_STATUS_ACCESS_DENIED;
2291
2292         DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2293
2294         description = get_privilege_dispname(r->in.name->string);
2295         if (!description) {
2296                 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2297                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2298         }
2299
2300         DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2301
2302         lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2303         if (!lsa_name) {
2304                 return NT_STATUS_NO_MEMORY;
2305         }
2306
2307         init_lsa_StringLarge(lsa_name, description);
2308
2309         *r->out.returned_language_id = r->in.language_id;
2310         *r->out.disp_name = lsa_name;
2311
2312         return NT_STATUS_OK;
2313 }
2314
2315 /***************************************************************************
2316  _lsa_EnumAccounts
2317  ***************************************************************************/
2318
2319 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2320                            struct lsa_EnumAccounts *r)
2321 {
2322         struct lsa_info *handle;
2323         struct dom_sid *sid_list;
2324         int i, j, num_entries;
2325         NTSTATUS status;
2326         struct lsa_SidPtr *sids = NULL;
2327
2328         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2329                 return NT_STATUS_INVALID_HANDLE;
2330
2331         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2332                 return NT_STATUS_INVALID_HANDLE;
2333         }
2334
2335         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2336                 return NT_STATUS_ACCESS_DENIED;
2337
2338         sid_list = NULL;
2339         num_entries = 0;
2340
2341         /* The only way we can currently find out all the SIDs that have been
2342            privileged is to scan all privileges */
2343
2344         status = privilege_enumerate_accounts(&sid_list, &num_entries);
2345         if (!NT_STATUS_IS_OK(status)) {
2346                 return status;
2347         }
2348
2349         if (*r->in.resume_handle >= num_entries) {
2350                 return NT_STATUS_NO_MORE_ENTRIES;
2351         }
2352
2353         if (num_entries - *r->in.resume_handle) {
2354                 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
2355                                          num_entries - *r->in.resume_handle);
2356                 if (!sids) {
2357                         talloc_free(sid_list);
2358                         return NT_STATUS_NO_MEMORY;
2359                 }
2360
2361                 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2362                         sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2363                         if (!sids[j].sid) {
2364                                 talloc_free(sid_list);
2365                                 return NT_STATUS_NO_MEMORY;
2366                         }
2367                 }
2368         }
2369
2370         talloc_free(sid_list);
2371
2372         *r->out.resume_handle = num_entries;
2373         r->out.sids->num_sids = num_entries;
2374         r->out.sids->sids = sids;
2375
2376         return NT_STATUS_OK;
2377 }
2378
2379 /***************************************************************************
2380  _lsa_GetUserName
2381  ***************************************************************************/
2382
2383 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2384                           struct lsa_GetUserName *r)
2385 {
2386         const char *username, *domname;
2387         struct lsa_String *account_name = NULL;
2388         struct lsa_String *authority_name = NULL;
2389
2390         if (r->in.account_name &&
2391            *r->in.account_name) {
2392                 return NT_STATUS_INVALID_PARAMETER;
2393         }
2394
2395         if (r->in.authority_name &&
2396            *r->in.authority_name) {
2397                 return NT_STATUS_INVALID_PARAMETER;
2398         }
2399
2400         if (p->server_info->guest) {
2401                 /*
2402                  * I'm 99% sure this is not the right place to do this,
2403                  * global_sid_Anonymous should probably be put into the token
2404                  * instead of the guest id -- vl
2405                  */
2406                 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2407                                 &domname, &username, NULL)) {
2408                         return NT_STATUS_NO_MEMORY;
2409                 }
2410         } else {
2411                 username = p->server_info->sanitized_username;
2412                 domname = p->server_info->info3->base.domain.string;
2413         }
2414
2415         account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2416         if (!account_name) {
2417                 return NT_STATUS_NO_MEMORY;
2418         }
2419         init_lsa_String(account_name, username);
2420
2421         if (r->out.authority_name) {
2422                 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2423                 if (!authority_name) {
2424                         return NT_STATUS_NO_MEMORY;
2425                 }
2426                 init_lsa_String(authority_name, domname);
2427         }
2428
2429         *r->out.account_name = account_name;
2430         if (r->out.authority_name) {
2431                 *r->out.authority_name = authority_name;
2432         }
2433
2434         return NT_STATUS_OK;
2435 }
2436
2437 /***************************************************************************
2438  _lsa_CreateAccount
2439  ***************************************************************************/
2440
2441 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2442                             struct lsa_CreateAccount *r)
2443 {
2444         NTSTATUS status;
2445         struct lsa_info *handle;
2446         uint32_t acc_granted;
2447         struct security_descriptor *psd;
2448         size_t sd_size;
2449
2450         /* find the connection policy handle. */
2451         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2452                 return NT_STATUS_INVALID_HANDLE;
2453
2454         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2455                 return NT_STATUS_INVALID_HANDLE;
2456         }
2457
2458         /* check if the user has enough rights */
2459
2460         if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2461                 return NT_STATUS_ACCESS_DENIED;
2462         }
2463
2464         /* Work out max allowed. */
2465         map_max_allowed_access(p->server_info->security_token,
2466                                &p->server_info->utok,
2467                                &r->in.access_mask);
2468
2469         /* map the generic bits to the lsa policy ones */
2470         se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2471
2472         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2473                                     &lsa_account_mapping,
2474                                     r->in.sid, LSA_POLICY_ALL_ACCESS);
2475         if (!NT_STATUS_IS_OK(status)) {
2476                 return status;
2477         }
2478
2479         status = access_check_object(psd, p->server_info->security_token,
2480                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2481                                      &acc_granted, "_lsa_CreateAccount");
2482         if (!NT_STATUS_IS_OK(status)) {
2483                 return status;
2484         }
2485
2486         if ( is_privileged_sid( r->in.sid ) )
2487                 return NT_STATUS_OBJECT_NAME_COLLISION;
2488
2489         status = create_lsa_policy_handle(p->mem_ctx, p,
2490                                           LSA_HANDLE_ACCOUNT_TYPE,
2491                                           acc_granted,
2492                                           r->in.sid,
2493                                           NULL,
2494                                           psd,
2495                                           r->out.acct_handle);
2496         if (!NT_STATUS_IS_OK(status)) {
2497                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2498         }
2499
2500         return privilege_create_account(r->in.sid);
2501 }
2502
2503 /***************************************************************************
2504  _lsa_OpenAccount
2505  ***************************************************************************/
2506
2507 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2508                           struct lsa_OpenAccount *r)
2509 {
2510         struct lsa_info *handle;
2511         struct security_descriptor *psd = NULL;
2512         size_t sd_size;
2513         uint32_t des_access = r->in.access_mask;
2514         uint32_t acc_granted;
2515         NTSTATUS status;
2516
2517         /* find the connection policy handle. */
2518         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2519                 return NT_STATUS_INVALID_HANDLE;
2520
2521         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2522                 return NT_STATUS_INVALID_HANDLE;
2523         }
2524
2525         /* des_access is for the account here, not the policy
2526          * handle - so don't check against policy handle. */
2527
2528         /* Work out max allowed. */
2529         map_max_allowed_access(p->server_info->security_token,
2530                                &p->server_info->utok,
2531                                &des_access);
2532
2533         /* map the generic bits to the lsa account ones */
2534         se_map_generic(&des_access, &lsa_account_mapping);
2535
2536         /* get the generic lsa account SD until we store it */
2537         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2538                                 &lsa_account_mapping,
2539                                 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2540         if (!NT_STATUS_IS_OK(status)) {
2541                 return status;
2542         }
2543
2544         status = access_check_object(psd, p->server_info->security_token,
2545                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2546                                      &acc_granted, "_lsa_OpenAccount" );
2547         if (!NT_STATUS_IS_OK(status)) {
2548                 return status;
2549         }
2550
2551         /* TODO: Fis the parsing routine before reenabling this check! */
2552         #if 0
2553         if (!lookup_sid(&handle->sid, dom_name, name, &type))
2554                 return NT_STATUS_ACCESS_DENIED;
2555         #endif
2556
2557         status = create_lsa_policy_handle(p->mem_ctx, p,
2558                                           LSA_HANDLE_ACCOUNT_TYPE,
2559                                           acc_granted,
2560                                           r->in.sid,
2561                                           NULL,
2562                                           psd,
2563                                           r->out.acct_handle);
2564         if (!NT_STATUS_IS_OK(status)) {
2565                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2566         }
2567
2568         return NT_STATUS_OK;
2569 }
2570
2571 /***************************************************************************
2572  _lsa_EnumPrivsAccount
2573  For a given SID, enumerate all the privilege this account has.
2574  ***************************************************************************/
2575
2576 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2577                                struct lsa_EnumPrivsAccount *r)
2578 {
2579         NTSTATUS status = NT_STATUS_OK;
2580         struct lsa_info *info=NULL;
2581         PRIVILEGE_SET *privileges;
2582         struct lsa_PrivilegeSet *priv_set = NULL;
2583
2584         /* find the connection policy handle. */
2585         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2586                 return NT_STATUS_INVALID_HANDLE;
2587
2588         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2589                 return NT_STATUS_INVALID_HANDLE;
2590         }
2591
2592         if (!(info->access & LSA_ACCOUNT_VIEW))
2593                 return NT_STATUS_ACCESS_DENIED;
2594
2595         status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2596         if (!NT_STATUS_IS_OK(status)) {
2597                 return status;
2598         }
2599
2600         *r->out.privs = priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
2601         if (!priv_set) {
2602                 return NT_STATUS_NO_MEMORY;
2603         }
2604
2605         DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2606                   sid_string_dbg(&info->sid),
2607                   privileges->count));
2608
2609         priv_set->count = privileges->count;
2610         priv_set->unknown = 0;
2611         priv_set->set = talloc_move(priv_set, &privileges->set);
2612
2613         return status;
2614 }
2615
2616 /***************************************************************************
2617  _lsa_GetSystemAccessAccount
2618  ***************************************************************************/
2619
2620 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2621                                      struct lsa_GetSystemAccessAccount *r)
2622 {
2623         NTSTATUS status;
2624         struct lsa_info *info = NULL;
2625         struct lsa_EnumPrivsAccount e;
2626         struct lsa_PrivilegeSet *privset;
2627
2628         /* find the connection policy handle. */
2629
2630         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2631                 return NT_STATUS_INVALID_HANDLE;
2632
2633         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2634                 return NT_STATUS_INVALID_HANDLE;
2635         }
2636
2637         if (!(info->access & LSA_ACCOUNT_VIEW))
2638                 return NT_STATUS_ACCESS_DENIED;
2639
2640         privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2641         if (!privset) {
2642                 return NT_STATUS_NO_MEMORY;
2643         }
2644
2645         e.in.handle = r->in.handle;
2646         e.out.privs = &privset;
2647
2648         status = _lsa_EnumPrivsAccount(p, &e);
2649         if (!NT_STATUS_IS_OK(status)) {
2650                 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2651                         "failed to call _lsa_EnumPrivsAccount(): %s\n",
2652                         nt_errstr(status)));
2653                 return status;
2654         }
2655
2656         /* Samba4 would iterate over the privset to merge the policy mode bits,
2657          * not sure samba3 can do the same here, so just return what we did in
2658          * the past - gd */
2659
2660         /*
2661           0x01 -> Log on locally
2662           0x02 -> Access this computer from network
2663           0x04 -> Log on as a batch job
2664           0x10 -> Log on as a service
2665
2666           they can be ORed together
2667         */
2668
2669         *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2670                               LSA_POLICY_MODE_NETWORK;
2671
2672         return NT_STATUS_OK;
2673 }
2674
2675 /***************************************************************************
2676   update the systemaccount information
2677  ***************************************************************************/
2678
2679 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2680                                      struct lsa_SetSystemAccessAccount *r)
2681 {
2682         struct lsa_info *info=NULL;
2683         GROUP_MAP map;
2684
2685         /* find the connection policy handle. */
2686         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2687                 return NT_STATUS_INVALID_HANDLE;
2688
2689         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2690                 return NT_STATUS_INVALID_HANDLE;
2691         }
2692
2693         if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2694                 return NT_STATUS_ACCESS_DENIED;
2695         }
2696
2697         if (!pdb_getgrsid(&map, info->sid))
2698                 return NT_STATUS_NO_SUCH_GROUP;
2699
2700         return pdb_update_group_mapping_entry(&map);
2701 }
2702
2703 /***************************************************************************
2704  _lsa_AddPrivilegesToAccount
2705  For a given SID, add some privileges.
2706  ***************************************************************************/
2707
2708 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
2709                                      struct lsa_AddPrivilegesToAccount *r)
2710 {
2711         struct lsa_info *info = NULL;
2712         struct lsa_PrivilegeSet *set = NULL;
2713
2714         /* find the connection policy handle. */
2715         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2716                 return NT_STATUS_INVALID_HANDLE;
2717
2718         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2719                 return NT_STATUS_INVALID_HANDLE;
2720         }
2721
2722         if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2723                 return NT_STATUS_ACCESS_DENIED;
2724         }
2725
2726         set = r->in.privs;
2727
2728         if ( !grant_privilege_set( &info->sid, set ) ) {
2729                 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
2730                          sid_string_dbg(&info->sid) ));
2731                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2732         }
2733
2734         return NT_STATUS_OK;
2735 }
2736
2737 /***************************************************************************
2738  _lsa_RemovePrivilegesFromAccount
2739  For a given SID, remove some privileges.
2740  ***************************************************************************/
2741
2742 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2743                                           struct lsa_RemovePrivilegesFromAccount *r)
2744 {
2745         struct lsa_info *info = NULL;
2746         struct lsa_PrivilegeSet *set = NULL;
2747
2748         /* find the connection policy handle. */
2749         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2750                 return NT_STATUS_INVALID_HANDLE;
2751
2752         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2753                 return NT_STATUS_INVALID_HANDLE;
2754         }
2755
2756         if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2757                 return NT_STATUS_ACCESS_DENIED;
2758         }
2759
2760         set = r->in.privs;
2761
2762         if ( !revoke_privilege_set( &info->sid, set) ) {
2763                 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2764                          sid_string_dbg(&info->sid) ));
2765                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2766         }
2767
2768         return NT_STATUS_OK;
2769 }
2770
2771 /***************************************************************************
2772  _lsa_LookupPrivName
2773  ***************************************************************************/
2774
2775 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
2776                              struct lsa_LookupPrivName *r)
2777 {
2778         struct lsa_info *info = NULL;
2779         const char *name;
2780         struct lsa_StringLarge *lsa_name;
2781
2782         /* find the connection policy handle. */
2783         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2784                 return NT_STATUS_INVALID_HANDLE;
2785         }
2786
2787         if (info->type != LSA_HANDLE_POLICY_TYPE) {
2788                 return NT_STATUS_INVALID_HANDLE;
2789         }
2790
2791         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2792                 return NT_STATUS_ACCESS_DENIED;
2793         }
2794
2795         if (r->in.luid->high != 0) {
2796                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2797         }
2798
2799         name = sec_privilege_name(r->in.luid->low);
2800         if (!name) {
2801                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2802         }
2803
2804         lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2805         if (!lsa_name) {
2806                 return NT_STATUS_NO_MEMORY;
2807         }
2808
2809         lsa_name->string = talloc_strdup(lsa_name, name);
2810         if (!lsa_name->string) {
2811                 TALLOC_FREE(lsa_name);
2812                 return NT_STATUS_NO_MEMORY;
2813         }
2814
2815         *r->out.name = lsa_name;
2816
2817         return NT_STATUS_OK;
2818 }
2819
2820 /***************************************************************************
2821  _lsa_QuerySecurity
2822  ***************************************************************************/
2823
2824 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
2825                             struct lsa_QuerySecurity *r)
2826 {
2827         struct lsa_info *handle=NULL;
2828         struct security_descriptor *psd = NULL;
2829         size_t sd_size;
2830         NTSTATUS status;
2831
2832         /* find the connection policy handle. */
2833         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2834                 return NT_STATUS_INVALID_HANDLE;
2835
2836         switch (handle->type) {
2837         case LSA_HANDLE_POLICY_TYPE:
2838                 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2839                                 &lsa_policy_mapping, NULL, 0);
2840                 break;
2841         case LSA_HANDLE_ACCOUNT_TYPE:
2842                 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2843                                 &lsa_account_mapping,
2844                                 &handle->sid, LSA_ACCOUNT_ALL_ACCESS);
2845                 break;
2846         default:
2847                 status = NT_STATUS_INVALID_HANDLE;
2848                 break;
2849         }
2850
2851         if (!NT_STATUS_IS_OK(status)) {
2852                 return status;
2853         }
2854
2855         *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2856         if (!*r->out.sdbuf) {
2857                 return NT_STATUS_NO_MEMORY;
2858         }
2859
2860         return status;
2861 }
2862
2863 /***************************************************************************
2864  _lsa_AddAccountRights
2865  ***************************************************************************/
2866
2867 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
2868                                struct lsa_AddAccountRights *r)
2869 {
2870         struct lsa_info *info = NULL;
2871         int i = 0;
2872         uint32_t acc_granted = 0;
2873         struct security_descriptor *psd = NULL;
2874         size_t sd_size;
2875         struct dom_sid sid;
2876         NTSTATUS status;
2877
2878         /* find the connection policy handle. */
2879         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2880                 return NT_STATUS_INVALID_HANDLE;
2881
2882         if (info->type != LSA_HANDLE_POLICY_TYPE) {
2883                 return NT_STATUS_INVALID_HANDLE;
2884         }
2885
2886         /* get the generic lsa account SD for this SID until we store it */
2887         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2888                                 &lsa_account_mapping,
2889                                 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2890         if (!NT_STATUS_IS_OK(status)) {
2891                 return status;
2892         }
2893
2894         /*
2895          * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2896          * on the policy handle. If it does, ask for
2897          * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2898          * on the account sid. We don't check here so just use the latter. JRA.
2899          */
2900
2901         status = access_check_object(psd, p->server_info->security_token,
2902                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2903                                      LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2904                                      &acc_granted, "_lsa_AddAccountRights" );
2905         if (!NT_STATUS_IS_OK(status)) {
2906                 return status;
2907         }
2908
2909         /* according to an NT4 PDC, you can add privileges to SIDs even without
2910            call_lsa_create_account() first.  And you can use any arbitrary SID. */
2911
2912         sid_copy( &sid, r->in.sid );
2913
2914         for ( i=0; i < r->in.rights->count; i++ ) {
2915
2916                 const char *privname = r->in.rights->names[i].string;
2917
2918                 /* only try to add non-null strings */
2919
2920                 if ( !privname )
2921                         continue;
2922
2923                 if ( !grant_privilege_by_name( &sid, privname ) ) {
2924                         DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2925                                 privname ));
2926                         return NT_STATUS_NO_SUCH_PRIVILEGE;
2927                 }
2928         }
2929
2930         return NT_STATUS_OK;
2931 }
2932
2933 /***************************************************************************
2934  _lsa_RemoveAccountRights
2935  ***************************************************************************/
2936
2937 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
2938                                   struct lsa_RemoveAccountRights *r)
2939 {
2940         struct lsa_info *info = NULL;
2941         int i = 0;
2942         struct security_descriptor *psd = NULL;
2943         size_t sd_size;
2944         struct dom_sid sid;
2945         const char *privname = NULL;
2946         uint32_t acc_granted = 0;
2947         NTSTATUS status;
2948
2949         /* find the connection policy handle. */
2950         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2951                 return NT_STATUS_INVALID_HANDLE;
2952
2953         if (info->type != LSA_HANDLE_POLICY_TYPE) {
2954                 return NT_STATUS_INVALID_HANDLE;
2955         }
2956
2957         /* get the generic lsa account SD for this SID until we store it */
2958         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2959                                 &lsa_account_mapping,
2960                                 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2961         if (!NT_STATUS_IS_OK(status)) {
2962                 return status;
2963         }
2964
2965         /*
2966          * From the MS DOCs. We need
2967          * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2968          * and DELETE on the account sid.
2969          */
2970
2971         status = access_check_object(psd, p->server_info->security_token,
2972                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2973                                      LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2974                                      LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
2975                                      &acc_granted, "_lsa_RemoveAccountRights");
2976         if (!NT_STATUS_IS_OK(status)) {
2977                 return status;
2978         }
2979
2980         sid_copy( &sid, r->in.sid );
2981
2982         if ( r->in.remove_all ) {
2983                 if ( !revoke_all_privileges( &sid ) )
2984                         return NT_STATUS_ACCESS_DENIED;
2985
2986                 return NT_STATUS_OK;
2987         }
2988
2989         for ( i=0; i < r->in.rights->count; i++ ) {
2990
2991                 privname = r->in.rights->names[i].string;
2992
2993                 /* only try to add non-null strings */
2994
2995                 if ( !privname )
2996                         continue;
2997
2998                 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2999                         DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3000                                 privname ));
3001                         return NT_STATUS_NO_SUCH_PRIVILEGE;
3002                 }
3003         }
3004
3005         return NT_STATUS_OK;
3006 }
3007
3008 /*******************************************************************
3009 ********************************************************************/
3010
3011 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3012                                    struct lsa_RightSet *r,
3013                                    PRIVILEGE_SET *privileges)
3014 {
3015         uint32 i;
3016         const char *privname;
3017         const char **privname_array = NULL;
3018         int num_priv = 0;
3019
3020         for (i=0; i<privileges->count; i++) {
3021                 if (privileges->set[i].luid.high) {
3022                         continue;
3023                 }
3024                 privname = sec_privilege_name(privileges->set[i].luid.low);
3025                 if (privname) {
3026                         if (!add_string_to_array(mem_ctx, privname,
3027                                                  &privname_array, &num_priv)) {
3028                                 return NT_STATUS_NO_MEMORY;
3029                         }
3030                 }
3031         }
3032
3033         if (num_priv) {
3034
3035                 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
3036                                              num_priv);
3037                 if (!r->names) {
3038                         return NT_STATUS_NO_MEMORY;
3039                 }
3040
3041                 for (i=0; i<num_priv; i++) {
3042                         init_lsa_StringLarge(&r->names[i], privname_array[i]);
3043                 }
3044
3045                 r->count = num_priv;
3046         }
3047
3048         return NT_STATUS_OK;
3049 }
3050
3051 /***************************************************************************
3052  _lsa_EnumAccountRights
3053  ***************************************************************************/
3054
3055 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3056                                 struct lsa_EnumAccountRights *r)
3057 {
3058         NTSTATUS status;
3059         struct lsa_info *info = NULL;
3060         PRIVILEGE_SET *privileges;
3061
3062         /* find the connection policy handle. */
3063
3064         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3065                 return NT_STATUS_INVALID_HANDLE;
3066
3067         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3068                 return NT_STATUS_INVALID_HANDLE;
3069         }
3070
3071         if (!(info->access & LSA_ACCOUNT_VIEW)) {
3072                 return NT_STATUS_ACCESS_DENIED;
3073         }
3074
3075         /* according to an NT4 PDC, you can add privileges to SIDs even without
3076            call_lsa_create_account() first.  And you can use any arbitrary SID. */
3077
3078         /* according to MS-LSAD 3.1.4.5.10 it is required to return
3079          * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3080          * the lsa database */
3081
3082         status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3083         if (!NT_STATUS_IS_OK(status)) {
3084                 return status;
3085         }
3086
3087         DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3088                   sid_string_dbg(r->in.sid), privileges->count));
3089
3090         status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3091
3092         return status;
3093 }
3094
3095 /***************************************************************************
3096  _lsa_LookupPrivValue
3097  ***************************************************************************/
3098
3099 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3100                               struct lsa_LookupPrivValue *r)
3101 {
3102         struct lsa_info *info = NULL;
3103         const char *name = NULL;
3104
3105         /* find the connection policy handle. */
3106
3107         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3108                 return NT_STATUS_INVALID_HANDLE;
3109
3110         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3111                 return NT_STATUS_INVALID_HANDLE;
3112         }
3113
3114         if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3115                 return NT_STATUS_ACCESS_DENIED;
3116
3117         name = r->in.name->string;
3118
3119         DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3120
3121         r->out.luid->low = sec_privilege_id(name);
3122         r->out.luid->high = 0;
3123         if (r->out.luid->low == SEC_PRIV_INVALID) {
3124                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3125         }
3126         return NT_STATUS_OK;
3127 }
3128
3129 /***************************************************************************
3130  _lsa_EnumAccountsWithUserRight
3131  ***************************************************************************/
3132
3133 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3134                                         struct lsa_EnumAccountsWithUserRight *r)
3135 {
3136         NTSTATUS status;
3137         struct lsa_info *info = NULL;
3138         struct dom_sid *sids = NULL;
3139         int num_sids = 0;
3140         uint32_t i;
3141         enum sec_privilege privilege;
3142
3143         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3144                 return NT_STATUS_INVALID_HANDLE;
3145         }
3146
3147         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3148                 return NT_STATUS_INVALID_HANDLE;
3149         }
3150
3151         if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3152                 return NT_STATUS_ACCESS_DENIED;
3153         }
3154
3155         if (!r->in.name || !r->in.name->string) {
3156                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3157         }
3158
3159         privilege = sec_privilege_id(r->in.name->string);
3160         if (privilege == SEC_PRIV_INVALID) {
3161                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3162         }
3163
3164         status = privilege_enum_sids(privilege, p->mem_ctx,
3165                                      &sids, &num_sids);
3166         if (!NT_STATUS_IS_OK(status)) {
3167                 return status;
3168         }
3169
3170         r->out.sids->num_sids = num_sids;
3171         r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3172                                          r->out.sids->num_sids);
3173
3174         for (i=0; i < r->out.sids->num_sids; i++) {
3175                 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3176                                                           &sids[i]);
3177                 if (!r->out.sids->sids[i].sid) {
3178                         TALLOC_FREE(r->out.sids->sids);
3179                         r->out.sids->num_sids = 0;
3180                         return NT_STATUS_NO_MEMORY;
3181                 }
3182         }
3183
3184         return NT_STATUS_OK;
3185 }
3186
3187 /***************************************************************************
3188  _lsa_Delete
3189  ***************************************************************************/
3190
3191 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3192                      struct lsa_Delete *r)
3193 {
3194         return NT_STATUS_NOT_SUPPORTED;
3195 }
3196
3197 /*
3198  * From here on the server routines are just dummy ones to make smbd link with
3199  * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3200  * pulling the server stubs across one by one.
3201  */
3202
3203 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3204 {
3205         p->rng_fault_state = True;
3206         return NT_STATUS_NOT_IMPLEMENTED;
3207 }
3208
3209 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3210                              struct lsa_ChangePassword *r)
3211 {
3212         p->rng_fault_state = True;
3213         return NT_STATUS_NOT_IMPLEMENTED;
3214 }
3215
3216 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3217 {
3218         p->rng_fault_state = True;
3219         return NT_STATUS_NOT_IMPLEMENTED;
3220 }
3221
3222 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3223 {
3224         p->rng_fault_state = True;
3225         return NT_STATUS_NOT_IMPLEMENTED;
3226 }
3227
3228 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3229                                   struct lsa_GetQuotasForAccount *r)
3230 {
3231         p->rng_fault_state = True;
3232         return NT_STATUS_NOT_IMPLEMENTED;
3233 }
3234
3235 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3236                                   struct lsa_SetQuotasForAccount *r)
3237 {
3238         p->rng_fault_state = True;
3239         return NT_STATUS_NOT_IMPLEMENTED;
3240 }
3241
3242 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3243                                           struct lsa_SetInformationTrustedDomain *r)
3244 {
3245         p->rng_fault_state = True;
3246         return NT_STATUS_NOT_IMPLEMENTED;
3247 }
3248
3249 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
3250 {
3251         p->rng_fault_state = True;
3252         return NT_STATUS_NOT_IMPLEMENTED;
3253 }
3254
3255 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3256                                    struct lsa_SetTrustedDomainInfo *r)
3257 {
3258         p->rng_fault_state = True;
3259         return NT_STATUS_NOT_IMPLEMENTED;
3260 }
3261
3262 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3263                                struct lsa_StorePrivateData *r)
3264 {
3265         p->rng_fault_state = True;
3266         return NT_STATUS_NOT_IMPLEMENTED;
3267 }
3268
3269 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3270                                   struct lsa_RetrievePrivateData *r)
3271 {
3272         p->rng_fault_state = True;
3273         return NT_STATUS_NOT_IMPLEMENTED;
3274 }
3275
3276 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3277                              struct lsa_SetInfoPolicy2 *r)
3278 {
3279         p->rng_fault_state = True;
3280         return NT_STATUS_NOT_IMPLEMENTED;
3281 }
3282
3283 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3284                                          struct lsa_SetTrustedDomainInfoByName *r)
3285 {
3286         p->rng_fault_state = True;
3287         return NT_STATUS_NOT_IMPLEMENTED;
3288 }
3289
3290 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3291                                    struct lsa_EnumTrustedDomainsEx *r)
3292 {
3293         struct lsa_info *info;
3294         uint32_t count;
3295         struct pdb_trusted_domain **domains;
3296         struct lsa_TrustDomainInfoInfoEx *entries;
3297         int i;
3298         NTSTATUS nt_status;
3299
3300         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3301                 return NT_STATUS_INVALID_HANDLE;
3302
3303         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3304                 return NT_STATUS_INVALID_HANDLE;
3305         }
3306
3307         /* check if the user has enough rights */
3308         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3309                 return NT_STATUS_ACCESS_DENIED;
3310
3311         become_root();
3312         nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3313         unbecome_root();
3314
3315         if (!NT_STATUS_IS_OK(nt_status)) {
3316                 return nt_status;
3317         }
3318
3319         entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3320                                     count);
3321         if (!entries) {
3322                 return NT_STATUS_NO_MEMORY;
3323         }
3324
3325         for (i=0; i<count; i++) {
3326                 init_lsa_StringLarge(&entries[i].netbios_name,
3327                                      domains[i]->netbios_name);
3328                 entries[i].sid = &domains[i]->security_identifier;
3329         }
3330
3331         if (*r->in.resume_handle >= count) {
3332                 *r->out.resume_handle = -1;
3333                 TALLOC_FREE(entries);
3334                 return NT_STATUS_NO_MORE_ENTRIES;
3335         }
3336
3337         /* return the rest, limit by max_size. Note that we
3338            use the w2k3 element size value of 60 */
3339         r->out.domains->count = count - *r->in.resume_handle;
3340         r->out.domains->count = MIN(r->out.domains->count,
3341                                     (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3342
3343         r->out.domains->domains = entries + *r->in.resume_handle;
3344
3345         if (r->out.domains->count < count - *r->in.resume_handle) {
3346                 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3347                 return STATUS_MORE_ENTRIES;
3348         }
3349
3350         /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3351          * always be larger than the previous input resume handle, in
3352          * particular when hitting the last query it is vital to set the
3353          * resume handle correctly to avoid infinite client loops, as
3354          * seen e.g. with Windows XP SP3 when resume handle is 0 and
3355          * status is NT_STATUS_OK - gd */
3356
3357         *r->out.resume_handle = (uint32_t)-1;
3358
3359         return NT_STATUS_OK;
3360 }
3361
3362 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3363                                            struct lsa_QueryDomainInformationPolicy *r)
3364 {
3365         p->rng_fault_state = True;
3366         return NT_STATUS_NOT_IMPLEMENTED;
3367 }
3368
3369 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3370                                          struct lsa_SetDomainInformationPolicy *r)
3371 {
3372         p->rng_fault_state = True;
3373         return NT_STATUS_NOT_IMPLEMENTED;
3374 }
3375
3376 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3377 {
3378         p->rng_fault_state = True;
3379         return NT_STATUS_NOT_IMPLEMENTED;
3380 }
3381
3382 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3383 {
3384         p->rng_fault_state = True;
3385         return NT_STATUS_NOT_IMPLEMENTED;
3386 }
3387
3388 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3389 {
3390         p->rng_fault_state = True;
3391         return NT_STATUS_NOT_IMPLEMENTED;
3392 }
3393
3394 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3395 {
3396         p->rng_fault_state = True;
3397         return NT_STATUS_NOT_IMPLEMENTED;
3398 }
3399
3400 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3401                                           struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3402 {
3403         p->rng_fault_state = True;
3404         return NT_STATUS_NOT_IMPLEMENTED;
3405 }
3406
3407 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3408                                          struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3409 {
3410         p->rng_fault_state = True;
3411         return NT_STATUS_NOT_IMPLEMENTED;
3412 }
3413
3414 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3415 {
3416         p->rng_fault_state = True;
3417         return NT_STATUS_NOT_IMPLEMENTED;
3418 }
3419
3420 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3421                                  struct lsa_CREDRGETTARGETINFO *r)
3422 {
3423         p->rng_fault_state = True;
3424         return NT_STATUS_NOT_IMPLEMENTED;
3425 }
3426
3427 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3428                                  struct lsa_CREDRPROFILELOADED *r)
3429 {
3430         p->rng_fault_state = True;
3431         return NT_STATUS_NOT_IMPLEMENTED;
3432 }
3433
3434 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3435                                    struct lsa_CREDRGETSESSIONTYPES *r)
3436 {
3437         p->rng_fault_state = True;
3438         return NT_STATUS_NOT_IMPLEMENTED;
3439 }
3440
3441 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3442                                      struct lsa_LSARREGISTERAUDITEVENT *r)
3443 {
3444         p->rng_fault_state = True;
3445         return NT_STATUS_NOT_IMPLEMENTED;
3446 }
3447
3448 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3449                                 struct lsa_LSARGENAUDITEVENT *r)
3450 {
3451         p->rng_fault_state = True;
3452         return NT_STATUS_NOT_IMPLEMENTED;
3453 }
3454
3455 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3456                                        struct lsa_LSARUNREGISTERAUDITEVENT *r)
3457 {
3458         p->rng_fault_state = True;
3459         return NT_STATUS_NOT_IMPLEMENTED;
3460 }
3461
3462 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3463                                               struct lsa_lsaRQueryForestTrustInformation *r)
3464 {
3465         p->rng_fault_state = True;
3466         return NT_STATUS_NOT_IMPLEMENTED;
3467 }
3468
3469 #define DNS_CMP_MATCH 0
3470 #define DNS_CMP_FIRST_IS_CHILD 1
3471 #define DNS_CMP_SECOND_IS_CHILD 2
3472 #define DNS_CMP_NO_MATCH 3
3473
3474 /* this function assumes names are well formed DNS names.
3475  * it doesn't validate them */
3476 static int dns_cmp(const char *s1, size_t l1,
3477                    const char *s2, size_t l2)
3478 {
3479         const char *p1, *p2;
3480         size_t t1, t2;
3481         int cret;
3482
3483         if (l1 == l2) {
3484                 if (StrCaseCmp(s1, s2) == 0) {
3485                         return DNS_CMP_MATCH;
3486                 }
3487                 return DNS_CMP_NO_MATCH;
3488         }
3489
3490         if (l1 > l2) {
3491                 p1 = s1;
3492                 p2 = s2;
3493                 t1 = l1;
3494                 t2 = l2;
3495                 cret = DNS_CMP_FIRST_IS_CHILD;
3496         } else {
3497                 p1 = s2;
3498                 p2 = s1;
3499                 t1 = l2;
3500                 t2 = l1;
3501                 cret = DNS_CMP_SECOND_IS_CHILD;
3502         }
3503
3504         if (p1[t1 - t2 - 1] != '.') {
3505                 return DNS_CMP_NO_MATCH;
3506         }
3507
3508         if (StrCaseCmp(&p1[t1 - t2], p2) == 0) {
3509                 return cret;
3510         }
3511
3512         return DNS_CMP_NO_MATCH;
3513 }
3514
3515 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3516                              struct lsa_ForestTrustInformation *lfti,
3517                              struct ForestTrustInfo *fti)
3518 {
3519         struct lsa_ForestTrustRecord *lrec;
3520         struct ForestTrustInfoRecord *rec;
3521         struct lsa_StringLarge *tln;
3522         struct lsa_ForestTrustDomainInfo *info;
3523         uint32_t i;
3524
3525         fti->version = 1;
3526         fti->count = lfti->count;
3527         fti->records = talloc_array(mem_ctx,
3528                                     struct ForestTrustInfoRecordArmor,
3529                                     fti->count);
3530         if (!fti->records) {
3531                 return NT_STATUS_NO_MEMORY;
3532         }
3533         for (i = 0; i < fti->count; i++) {
3534                 lrec = lfti->entries[i];
3535                 rec = &fti->records[i].record;
3536
3537                 rec->flags = lrec->flags;
3538                 rec->timestamp = lrec->time;
3539                 rec->type = lrec->type;
3540
3541                 switch (lrec->type) {
3542                 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
3543                 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3544                         tln = &lrec->forest_trust_data.top_level_name;
3545                         rec->data.name.string =
3546                                 talloc_strdup(mem_ctx, tln->string);
3547                         if (!rec->data.name.string) {
3548                                 return NT_STATUS_NO_MEMORY;
3549                         }
3550                         rec->data.name.size = strlen(rec->data.name.string);
3551                         break;
3552                 case LSA_FOREST_TRUST_DOMAIN_INFO:
3553                         info = &lrec->forest_trust_data.domain_info;
3554                         rec->data.info.sid = *info->domain_sid;
3555                         rec->data.info.dns_name.string =
3556                                 talloc_strdup(mem_ctx,
3557                                             info->dns_domain_name.string);
3558                         if (!rec->data.info.dns_name.string) {
3559                                 return NT_STATUS_NO_MEMORY;
3560                         }
3561                         rec->data.info.dns_name.size =
3562                                 strlen(rec->data.info.dns_name.string);
3563                         rec->data.info.netbios_name.string =
3564                                 talloc_strdup(mem_ctx,
3565                                             info->netbios_domain_name.string);
3566                         if (!rec->data.info.netbios_name.string) {
3567                                 return NT_STATUS_NO_MEMORY;
3568                         }
3569                         rec->data.info.netbios_name.size =
3570                                 strlen(rec->data.info.netbios_name.string);
3571                         break;
3572                 default:
3573                         return NT_STATUS_INVALID_DOMAIN_STATE;
3574                 }
3575         }
3576
3577         return NT_STATUS_OK;
3578 }
3579
3580 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3581                               uint32_t index, uint32_t collision_type,
3582                               uint32_t conflict_type, const char *tdo_name);
3583
3584 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
3585                               const char *tdo_name,
3586                               struct ForestTrustInfo *tdo_fti,
3587                               struct ForestTrustInfo *new_fti,
3588                               struct lsa_ForestTrustCollisionInfo *c_info)
3589 {
3590         struct ForestTrustInfoRecord *nrec;
3591         struct ForestTrustInfoRecord *trec;
3592         const char *dns_name;
3593         const char *nb_name = NULL;
3594         struct dom_sid *sid = NULL;
3595         const char *tname = NULL;
3596         size_t dns_len = 0;
3597         size_t nb_len;
3598         size_t tlen = 0;
3599         NTSTATUS nt_status;
3600         uint32_t new_fti_idx;
3601         uint32_t i;
3602         /* use always TDO type, until we understand when Xref can be used */
3603         uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
3604         bool tln_conflict;
3605         bool sid_conflict;
3606         bool nb_conflict;
3607         bool exclusion;
3608         bool ex_rule = false;
3609         int ret;
3610
3611         for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
3612
3613                 nrec = &new_fti->records[new_fti_idx].record;
3614                 dns_name = NULL;
3615                 tln_conflict = false;
3616                 sid_conflict = false;
3617                 nb_conflict = false;
3618                 exclusion = false;
3619
3620                 switch (nrec->type) {
3621                 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3622                         /* exclusions do not conflict by definition */
3623                         break;
3624
3625                 case FOREST_TRUST_TOP_LEVEL_NAME:
3626                         dns_name = nrec->data.name.string;
3627                         dns_len = nrec->data.name.size;
3628                         break;
3629
3630                 case LSA_FOREST_TRUST_DOMAIN_INFO:
3631                         dns_name = nrec->data.info.dns_name.string;
3632                         dns_len = nrec->data.info.dns_name.size;
3633                         nb_name = nrec->data.info.netbios_name.string;
3634                         nb_len = nrec->data.info.netbios_name.size;
3635                         sid = &nrec->data.info.sid;
3636                         break;
3637                 }
3638
3639                 if (!dns_name) continue;
3640
3641                 /* check if this is already taken and not excluded */
3642                 for (i = 0; i < tdo_fti->count; i++) {
3643                         trec = &tdo_fti->records[i].record;
3644
3645                         switch (trec->type) {
3646                         case FOREST_TRUST_TOP_LEVEL_NAME:
3647                                 ex_rule = false;
3648                                 tname = trec->data.name.string;
3649                                 tlen = trec->data.name.size;
3650                                 break;
3651                         case FOREST_TRUST_TOP_LEVEL_NAME_EX:
3652                                 ex_rule = true;
3653                                 tname = trec->data.name.string;
3654                                 tlen = trec->data.name.size;
3655                                 break;
3656                         case FOREST_TRUST_DOMAIN_INFO:
3657                                 ex_rule = false;
3658                                 tname = trec->data.info.dns_name.string;
3659                                 tlen = trec->data.info.dns_name.size;
3660                         }
3661                         ret = dns_cmp(dns_name, dns_len, tname, tlen);
3662                         switch (ret) {
3663                         case DNS_CMP_MATCH:
3664                                 /* if it matches exclusion,
3665                                  * it doesn't conflict */
3666                                 if (ex_rule) {
3667                                         exclusion = true;
3668                                         break;
3669                                 }
3670                                 /* fall through */
3671                         case DNS_CMP_FIRST_IS_CHILD:
3672                         case DNS_CMP_SECOND_IS_CHILD:
3673                                 tln_conflict = true;
3674                                 /* fall through */
3675                         default:
3676                                 break;
3677                         }
3678
3679                         /* explicit exclusion, no dns name conflict here */
3680                         if (exclusion) {
3681                                 tln_conflict = false;
3682                         }
3683
3684                         if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
3685                                 continue;
3686                         }
3687
3688                         /* also test for domain info */
3689                         if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
3690                             dom_sid_compare(&trec->data.info.sid, sid) == 0) {
3691                                 sid_conflict = true;
3692                         }
3693                         if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
3694                             StrCaseCmp(trec->data.info.netbios_name.string,
3695                                        nb_name) == 0) {
3696                                 nb_conflict = true;
3697                         }
3698                 }
3699
3700                 if (tln_conflict) {
3701                         nt_status = add_collision(c_info, new_fti_idx,
3702                                                   collision_type,
3703                                                   LSA_TLN_DISABLED_CONFLICT,
3704                                                   tdo_name);
3705                 }
3706                 if (sid_conflict) {
3707                         nt_status = add_collision(c_info, new_fti_idx,
3708                                                   collision_type,
3709                                                   LSA_SID_DISABLED_CONFLICT,
3710                                                   tdo_name);
3711                 }
3712                 if (nb_conflict) {
3713                         nt_status = add_collision(c_info, new_fti_idx,
3714                                                   collision_type,
3715                                                   LSA_NB_DISABLED_CONFLICT,
3716                                                   tdo_name);
3717                 }
3718         }
3719
3720         return NT_STATUS_OK;
3721 }
3722
3723 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3724                               uint32_t idx, uint32_t collision_type,
3725                               uint32_t conflict_type, const char *tdo_name)
3726 {
3727         struct lsa_ForestTrustCollisionRecord **es;
3728         uint32_t i = c_info->count;
3729
3730         es = talloc_realloc(c_info, c_info->entries,
3731                             struct lsa_ForestTrustCollisionRecord *, i + 1);
3732         if (!es) {
3733                 return NT_STATUS_NO_MEMORY;
3734         }
3735         c_info->entries = es;
3736         c_info->count = i + 1;
3737
3738         es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
3739         if (!es[i]) {
3740                 return NT_STATUS_NO_MEMORY;
3741         }
3742
3743         es[i]->index = idx;
3744         es[i]->type = collision_type;
3745         es[i]->flags.flags = conflict_type;
3746         es[i]->name.string = talloc_strdup(es[i], tdo_name);
3747         if (!es[i]->name.string) {
3748                 return NT_STATUS_NO_MEMORY;
3749         }
3750         es[i]->name.size = strlen(es[i]->name.string);
3751
3752         return NT_STATUS_OK;
3753 }
3754
3755 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3756                             struct pdb_trusted_domain *td,
3757                             struct ForestTrustInfo *info)
3758 {
3759         enum ndr_err_code ndr_err;
3760
3761         if (td->trust_forest_trust_info.length == 0 ||
3762             td->trust_forest_trust_info.data == NULL) {
3763                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3764         }
3765         ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
3766                                        &n