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