s3-lsa: Fix _lsa_DeleteObject to handle trusted domain objects.
[ambi/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         case LSA_HANDLE_TRUST_TYPE:
2192                 if (!pdb_del_trusteddom_pw(info->name)) {
2193                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2194                 }
2195                 status = NT_STATUS_OK;
2196                 break;
2197         default:
2198                 return NT_STATUS_INVALID_HANDLE;
2199         }
2200
2201         close_policy_hnd(p, r->in.handle);
2202         ZERO_STRUCTP(r->out.handle);
2203
2204         return status;
2205 }
2206
2207 /***************************************************************************
2208  _lsa_EnumPrivs
2209  ***************************************************************************/
2210
2211 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2212                         struct lsa_EnumPrivs *r)
2213 {
2214         struct lsa_info *handle;
2215         uint32 i;
2216         uint32 enum_context = *r->in.resume_handle;
2217         int num_privs = num_privileges_in_short_list();
2218         struct lsa_PrivEntry *entries = NULL;
2219
2220         /* remember that the enum_context starts at 0 and not 1 */
2221
2222         if ( enum_context >= num_privs )
2223                 return NT_STATUS_NO_MORE_ENTRIES;
2224
2225         DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2226                 enum_context, num_privs));
2227
2228         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2229                 return NT_STATUS_INVALID_HANDLE;
2230
2231         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2232                 return NT_STATUS_INVALID_HANDLE;
2233         }
2234
2235         /* check if the user has enough rights
2236            I don't know if it's the right one. not documented.  */
2237
2238         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2239                 return NT_STATUS_ACCESS_DENIED;
2240
2241         if (num_privs) {
2242                 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2243                 if (!entries) {
2244                         return NT_STATUS_NO_MEMORY;
2245                 }
2246         } else {
2247                 entries = NULL;
2248         }
2249
2250         for (i = 0; i < num_privs; i++) {
2251                 if( i < enum_context) {
2252
2253                         init_lsa_StringLarge(&entries[i].name, NULL);
2254
2255                         entries[i].luid.low = 0;
2256                         entries[i].luid.high = 0;
2257                 } else {
2258
2259                         init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2260
2261                         entries[i].luid.low = sec_privilege_from_index(i);
2262                         entries[i].luid.high = 0;
2263                 }
2264         }
2265
2266         enum_context = num_privs;
2267
2268         *r->out.resume_handle = enum_context;
2269         r->out.privs->count = num_privs;
2270         r->out.privs->privs = entries;
2271
2272         return NT_STATUS_OK;
2273 }
2274
2275 /***************************************************************************
2276  _lsa_LookupPrivDisplayName
2277  ***************************************************************************/
2278
2279 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2280                                     struct lsa_LookupPrivDisplayName *r)
2281 {
2282         struct lsa_info *handle;
2283         const char *description;
2284         struct lsa_StringLarge *lsa_name;
2285
2286         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2287                 return NT_STATUS_INVALID_HANDLE;
2288
2289         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2290                 return NT_STATUS_INVALID_HANDLE;
2291         }
2292
2293         /* check if the user has enough rights */
2294
2295         /*
2296          * I don't know if it's the right one. not documented.
2297          */
2298         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2299                 return NT_STATUS_ACCESS_DENIED;
2300
2301         DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2302
2303         description = get_privilege_dispname(r->in.name->string);
2304         if (!description) {
2305                 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2306                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2307         }
2308
2309         DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2310
2311         lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2312         if (!lsa_name) {
2313                 return NT_STATUS_NO_MEMORY;
2314         }
2315
2316         init_lsa_StringLarge(lsa_name, description);
2317
2318         *r->out.returned_language_id = r->in.language_id;
2319         *r->out.disp_name = lsa_name;
2320
2321         return NT_STATUS_OK;
2322 }
2323
2324 /***************************************************************************
2325  _lsa_EnumAccounts
2326  ***************************************************************************/
2327
2328 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2329                            struct lsa_EnumAccounts *r)
2330 {
2331         struct lsa_info *handle;
2332         struct dom_sid *sid_list;
2333         int i, j, num_entries;
2334         NTSTATUS status;
2335         struct lsa_SidPtr *sids = NULL;
2336
2337         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2338                 return NT_STATUS_INVALID_HANDLE;
2339
2340         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2341                 return NT_STATUS_INVALID_HANDLE;
2342         }
2343
2344         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2345                 return NT_STATUS_ACCESS_DENIED;
2346
2347         sid_list = NULL;
2348         num_entries = 0;
2349
2350         /* The only way we can currently find out all the SIDs that have been
2351            privileged is to scan all privileges */
2352
2353         status = privilege_enumerate_accounts(&sid_list, &num_entries);
2354         if (!NT_STATUS_IS_OK(status)) {
2355                 return status;
2356         }
2357
2358         if (*r->in.resume_handle >= num_entries) {
2359                 return NT_STATUS_NO_MORE_ENTRIES;
2360         }
2361
2362         if (num_entries - *r->in.resume_handle) {
2363                 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2364                                          num_entries - *r->in.resume_handle);
2365                 if (!sids) {
2366                         talloc_free(sid_list);
2367                         return NT_STATUS_NO_MEMORY;
2368                 }
2369
2370                 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2371                         sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2372                         if (!sids[j].sid) {
2373                                 talloc_free(sid_list);
2374                                 return NT_STATUS_NO_MEMORY;
2375                         }
2376                 }
2377         }
2378
2379         talloc_free(sid_list);
2380
2381         *r->out.resume_handle = num_entries;
2382         r->out.sids->num_sids = num_entries;
2383         r->out.sids->sids = sids;
2384
2385         return NT_STATUS_OK;
2386 }
2387
2388 /***************************************************************************
2389  _lsa_GetUserName
2390  ***************************************************************************/
2391
2392 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2393                           struct lsa_GetUserName *r)
2394 {
2395         const char *username, *domname;
2396         struct lsa_String *account_name = NULL;
2397         struct lsa_String *authority_name = NULL;
2398
2399         if (r->in.account_name &&
2400            *r->in.account_name) {
2401                 return NT_STATUS_INVALID_PARAMETER;
2402         }
2403
2404         if (r->in.authority_name &&
2405            *r->in.authority_name) {
2406                 return NT_STATUS_INVALID_PARAMETER;
2407         }
2408
2409         if (security_session_user_level(p->session_info, NULL) < SECURITY_USER) {
2410                 /*
2411                  * I'm 99% sure this is not the right place to do this,
2412                  * global_sid_Anonymous should probably be put into the token
2413                  * instead of the guest id -- vl
2414                  */
2415                 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2416                                 &domname, &username, NULL)) {
2417                         return NT_STATUS_NO_MEMORY;
2418                 }
2419         } else {
2420                 username = p->session_info->unix_info->sanitized_username;
2421                 domname = p->session_info->info->domain_name;
2422         }
2423
2424         account_name = talloc(p->mem_ctx, struct lsa_String);
2425         if (!account_name) {
2426                 return NT_STATUS_NO_MEMORY;
2427         }
2428         init_lsa_String(account_name, username);
2429
2430         if (r->out.authority_name) {
2431                 authority_name = talloc(p->mem_ctx, struct lsa_String);
2432                 if (!authority_name) {
2433                         return NT_STATUS_NO_MEMORY;
2434                 }
2435                 init_lsa_String(authority_name, domname);
2436         }
2437
2438         *r->out.account_name = account_name;
2439         if (r->out.authority_name) {
2440                 *r->out.authority_name = authority_name;
2441         }
2442
2443         return NT_STATUS_OK;
2444 }
2445
2446 /***************************************************************************
2447  _lsa_CreateAccount
2448  ***************************************************************************/
2449
2450 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2451                             struct lsa_CreateAccount *r)
2452 {
2453         NTSTATUS status;
2454         struct lsa_info *handle;
2455         uint32_t acc_granted;
2456         struct security_descriptor *psd;
2457         size_t sd_size;
2458
2459         /* find the connection policy handle. */
2460         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2461                 return NT_STATUS_INVALID_HANDLE;
2462
2463         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2464                 return NT_STATUS_INVALID_HANDLE;
2465         }
2466
2467         /* check if the user has enough rights */
2468
2469         if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2470                 return NT_STATUS_ACCESS_DENIED;
2471         }
2472
2473         /* Work out max allowed. */
2474         map_max_allowed_access(p->session_info->security_token,
2475                                p->session_info->unix_token,
2476                                &r->in.access_mask);
2477
2478         /* map the generic bits to the lsa policy ones */
2479         se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2480
2481         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2482                                     &lsa_account_mapping,
2483                                     r->in.sid, LSA_POLICY_ALL_ACCESS);
2484         if (!NT_STATUS_IS_OK(status)) {
2485                 return status;
2486         }
2487
2488         status = access_check_object(psd, p->session_info->security_token,
2489                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2490                                      &acc_granted, "_lsa_CreateAccount");
2491         if (!NT_STATUS_IS_OK(status)) {
2492                 return status;
2493         }
2494
2495         if ( is_privileged_sid( r->in.sid ) )
2496                 return NT_STATUS_OBJECT_NAME_COLLISION;
2497
2498         status = create_lsa_policy_handle(p->mem_ctx, p,
2499                                           LSA_HANDLE_ACCOUNT_TYPE,
2500                                           acc_granted,
2501                                           r->in.sid,
2502                                           NULL,
2503                                           psd,
2504                                           r->out.acct_handle);
2505         if (!NT_STATUS_IS_OK(status)) {
2506                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2507         }
2508
2509         return privilege_create_account(r->in.sid);
2510 }
2511
2512 /***************************************************************************
2513  _lsa_OpenAccount
2514  ***************************************************************************/
2515
2516 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2517                           struct lsa_OpenAccount *r)
2518 {
2519         struct lsa_info *handle;
2520         struct security_descriptor *psd = NULL;
2521         size_t sd_size;
2522         uint32_t des_access = r->in.access_mask;
2523         uint32_t acc_granted;
2524         NTSTATUS status;
2525
2526         /* find the connection policy handle. */
2527         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2528                 return NT_STATUS_INVALID_HANDLE;
2529
2530         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2531                 return NT_STATUS_INVALID_HANDLE;
2532         }
2533
2534         /* des_access is for the account here, not the policy
2535          * handle - so don't check against policy handle. */
2536
2537         /* Work out max allowed. */
2538         map_max_allowed_access(p->session_info->security_token,
2539                                p->session_info->unix_token,
2540                                &des_access);
2541
2542         /* map the generic bits to the lsa account ones */
2543         se_map_generic(&des_access, &lsa_account_mapping);
2544
2545         /* get the generic lsa account SD until we store it */
2546         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2547                                 &lsa_account_mapping,
2548                                 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2549         if (!NT_STATUS_IS_OK(status)) {
2550                 return status;
2551         }
2552
2553         status = access_check_object(psd, p->session_info->security_token,
2554                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2555                                      &acc_granted, "_lsa_OpenAccount" );
2556         if (!NT_STATUS_IS_OK(status)) {
2557                 return status;
2558         }
2559
2560         /* TODO: Fis the parsing routine before reenabling this check! */
2561         #if 0
2562         if (!lookup_sid(&handle->sid, dom_name, name, &type))
2563                 return NT_STATUS_ACCESS_DENIED;
2564         #endif
2565
2566         status = create_lsa_policy_handle(p->mem_ctx, p,
2567                                           LSA_HANDLE_ACCOUNT_TYPE,
2568                                           acc_granted,
2569                                           r->in.sid,
2570                                           NULL,
2571                                           psd,
2572                                           r->out.acct_handle);
2573         if (!NT_STATUS_IS_OK(status)) {
2574                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2575         }
2576
2577         return NT_STATUS_OK;
2578 }
2579
2580 /***************************************************************************
2581  _lsa_EnumPrivsAccount
2582  For a given SID, enumerate all the privilege this account has.
2583  ***************************************************************************/
2584
2585 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2586                                struct lsa_EnumPrivsAccount *r)
2587 {
2588         NTSTATUS status = NT_STATUS_OK;
2589         struct lsa_info *info=NULL;
2590         PRIVILEGE_SET *privileges;
2591         struct lsa_PrivilegeSet *priv_set = NULL;
2592
2593         /* find the connection policy handle. */
2594         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2595                 return NT_STATUS_INVALID_HANDLE;
2596
2597         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2598                 return NT_STATUS_INVALID_HANDLE;
2599         }
2600
2601         if (!(info->access & LSA_ACCOUNT_VIEW))
2602                 return NT_STATUS_ACCESS_DENIED;
2603
2604         status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2605         if (!NT_STATUS_IS_OK(status)) {
2606                 return status;
2607         }
2608
2609         *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2610         if (!priv_set) {
2611                 return NT_STATUS_NO_MEMORY;
2612         }
2613
2614         DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2615                   sid_string_dbg(&info->sid),
2616                   privileges->count));
2617
2618         priv_set->count = privileges->count;
2619         priv_set->unknown = 0;
2620         priv_set->set = talloc_move(priv_set, &privileges->set);
2621
2622         return status;
2623 }
2624
2625 /***************************************************************************
2626  _lsa_GetSystemAccessAccount
2627  ***************************************************************************/
2628
2629 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2630                                      struct lsa_GetSystemAccessAccount *r)
2631 {
2632         NTSTATUS status;
2633         struct lsa_info *info = NULL;
2634         struct lsa_EnumPrivsAccount e;
2635         struct lsa_PrivilegeSet *privset;
2636
2637         /* find the connection policy handle. */
2638
2639         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2640                 return NT_STATUS_INVALID_HANDLE;
2641
2642         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2643                 return NT_STATUS_INVALID_HANDLE;
2644         }
2645
2646         if (!(info->access & LSA_ACCOUNT_VIEW))
2647                 return NT_STATUS_ACCESS_DENIED;
2648
2649         privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2650         if (!privset) {
2651                 return NT_STATUS_NO_MEMORY;
2652         }
2653
2654         e.in.handle = r->in.handle;
2655         e.out.privs = &privset;
2656
2657         status = _lsa_EnumPrivsAccount(p, &e);
2658         if (!NT_STATUS_IS_OK(status)) {
2659                 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2660                         "failed to call _lsa_EnumPrivsAccount(): %s\n",
2661                         nt_errstr(status)));
2662                 return status;
2663         }
2664
2665         /* Samba4 would iterate over the privset to merge the policy mode bits,
2666          * not sure samba3 can do the same here, so just return what we did in
2667          * the past - gd */
2668
2669         /*
2670           0x01 -> Log on locally
2671           0x02 -> Access this computer from network
2672           0x04 -> Log on as a batch job
2673           0x10 -> Log on as a service
2674
2675           they can be ORed together
2676         */
2677
2678         *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2679                               LSA_POLICY_MODE_NETWORK;
2680
2681         return NT_STATUS_OK;
2682 }
2683
2684 /***************************************************************************
2685   update the systemaccount information
2686  ***************************************************************************/
2687
2688 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2689                                      struct lsa_SetSystemAccessAccount *r)
2690 {
2691         struct lsa_info *info=NULL;
2692         GROUP_MAP map;
2693
2694         /* find the connection policy handle. */
2695         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2696                 return NT_STATUS_INVALID_HANDLE;
2697
2698         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2699                 return NT_STATUS_INVALID_HANDLE;
2700         }
2701
2702         if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2703                 return NT_STATUS_ACCESS_DENIED;
2704         }
2705
2706         if (!pdb_getgrsid(&map, info->sid))
2707                 return NT_STATUS_NO_SUCH_GROUP;
2708
2709         return pdb_update_group_mapping_entry(&map);
2710 }
2711
2712 /***************************************************************************
2713  _lsa_AddPrivilegesToAccount
2714  For a given SID, add some privileges.
2715  ***************************************************************************/
2716
2717 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
2718                                      struct lsa_AddPrivilegesToAccount *r)
2719 {
2720         struct lsa_info *info = NULL;
2721         struct lsa_PrivilegeSet *set = NULL;
2722
2723         /* find the connection policy handle. */
2724         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2725                 return NT_STATUS_INVALID_HANDLE;
2726
2727         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2728                 return NT_STATUS_INVALID_HANDLE;
2729         }
2730
2731         if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2732                 return NT_STATUS_ACCESS_DENIED;
2733         }
2734
2735         set = r->in.privs;
2736
2737         if ( !grant_privilege_set( &info->sid, set ) ) {
2738                 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
2739                          sid_string_dbg(&info->sid) ));
2740                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2741         }
2742
2743         return NT_STATUS_OK;
2744 }
2745
2746 /***************************************************************************
2747  _lsa_RemovePrivilegesFromAccount
2748  For a given SID, remove some privileges.
2749  ***************************************************************************/
2750
2751 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2752                                           struct lsa_RemovePrivilegesFromAccount *r)
2753 {
2754         struct lsa_info *info = NULL;
2755         struct lsa_PrivilegeSet *set = NULL;
2756
2757         /* find the connection policy handle. */
2758         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2759                 return NT_STATUS_INVALID_HANDLE;
2760
2761         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2762                 return NT_STATUS_INVALID_HANDLE;
2763         }
2764
2765         if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2766                 return NT_STATUS_ACCESS_DENIED;
2767         }
2768
2769         set = r->in.privs;
2770
2771         if ( !revoke_privilege_set( &info->sid, set) ) {
2772                 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2773                          sid_string_dbg(&info->sid) ));
2774                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2775         }
2776
2777         return NT_STATUS_OK;
2778 }
2779
2780 /***************************************************************************
2781  _lsa_LookupPrivName
2782  ***************************************************************************/
2783
2784 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
2785                              struct lsa_LookupPrivName *r)
2786 {
2787         struct lsa_info *info = NULL;
2788         const char *name;
2789         struct lsa_StringLarge *lsa_name;
2790
2791         /* find the connection policy handle. */
2792         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2793                 return NT_STATUS_INVALID_HANDLE;
2794         }
2795
2796         if (info->type != LSA_HANDLE_POLICY_TYPE) {
2797                 return NT_STATUS_INVALID_HANDLE;
2798         }
2799
2800         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2801                 return NT_STATUS_ACCESS_DENIED;
2802         }
2803
2804         if (r->in.luid->high != 0) {
2805                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2806         }
2807
2808         name = sec_privilege_name(r->in.luid->low);
2809         if (!name) {
2810                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2811         }
2812
2813         lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2814         if (!lsa_name) {
2815                 return NT_STATUS_NO_MEMORY;
2816         }
2817
2818         lsa_name->string = talloc_strdup(lsa_name, name);
2819         if (!lsa_name->string) {
2820                 TALLOC_FREE(lsa_name);
2821                 return NT_STATUS_NO_MEMORY;
2822         }
2823
2824         *r->out.name = lsa_name;
2825
2826         return NT_STATUS_OK;
2827 }
2828
2829 /***************************************************************************
2830  _lsa_QuerySecurity
2831  ***************************************************************************/
2832
2833 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
2834                             struct lsa_QuerySecurity *r)
2835 {
2836         struct lsa_info *handle=NULL;
2837         struct security_descriptor *psd = NULL;
2838         size_t sd_size = 0;
2839         NTSTATUS status;
2840
2841         /* find the connection policy handle. */
2842         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2843                 return NT_STATUS_INVALID_HANDLE;
2844
2845         switch (handle->type) {
2846         case LSA_HANDLE_POLICY_TYPE:
2847         case LSA_HANDLE_ACCOUNT_TYPE:
2848         case LSA_HANDLE_TRUST_TYPE:
2849                 psd = handle->sd;
2850                 sd_size = ndr_size_security_descriptor(psd, 0);
2851                 status = NT_STATUS_OK;
2852                 break;
2853         default:
2854                 status = NT_STATUS_INVALID_HANDLE;
2855                 break;
2856         }
2857
2858         if (!NT_STATUS_IS_OK(status)) {
2859                 return status;
2860         }
2861
2862         *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2863         if (!*r->out.sdbuf) {
2864                 return NT_STATUS_NO_MEMORY;
2865         }
2866
2867         return status;
2868 }
2869
2870 /***************************************************************************
2871  _lsa_AddAccountRights
2872  ***************************************************************************/
2873
2874 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
2875                                struct lsa_AddAccountRights *r)
2876 {
2877         struct lsa_info *info = NULL;
2878         int i = 0;
2879         uint32_t acc_granted = 0;
2880         struct security_descriptor *psd = NULL;
2881         size_t sd_size;
2882         struct dom_sid sid;
2883         NTSTATUS status;
2884
2885         /* find the connection policy handle. */
2886         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2887                 return NT_STATUS_INVALID_HANDLE;
2888
2889         if (info->type != LSA_HANDLE_POLICY_TYPE) {
2890                 return NT_STATUS_INVALID_HANDLE;
2891         }
2892
2893         /* get the generic lsa account SD for this SID until we store it */
2894         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2895                                 &lsa_account_mapping,
2896                                 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2897         if (!NT_STATUS_IS_OK(status)) {
2898                 return status;
2899         }
2900
2901         /*
2902          * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2903          * on the policy handle. If it does, ask for
2904          * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2905          * on the account sid. We don't check here so just use the latter. JRA.
2906          */
2907
2908         status = access_check_object(psd, p->session_info->security_token,
2909                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2910                                      LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2911                                      &acc_granted, "_lsa_AddAccountRights" );
2912         if (!NT_STATUS_IS_OK(status)) {
2913                 return status;
2914         }
2915
2916         /* according to an NT4 PDC, you can add privileges to SIDs even without
2917            call_lsa_create_account() first.  And you can use any arbitrary SID. */
2918
2919         sid_copy( &sid, r->in.sid );
2920
2921         for ( i=0; i < r->in.rights->count; i++ ) {
2922
2923                 const char *privname = r->in.rights->names[i].string;
2924
2925                 /* only try to add non-null strings */
2926
2927                 if ( !privname )
2928                         continue;
2929
2930                 if ( !grant_privilege_by_name( &sid, privname ) ) {
2931                         DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2932                                 privname ));
2933                         return NT_STATUS_NO_SUCH_PRIVILEGE;
2934                 }
2935         }
2936
2937         return NT_STATUS_OK;
2938 }
2939
2940 /***************************************************************************
2941  _lsa_RemoveAccountRights
2942  ***************************************************************************/
2943
2944 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
2945                                   struct lsa_RemoveAccountRights *r)
2946 {
2947         struct lsa_info *info = NULL;
2948         int i = 0;
2949         struct security_descriptor *psd = NULL;
2950         size_t sd_size;
2951         struct dom_sid sid;
2952         const char *privname = NULL;
2953         uint32_t acc_granted = 0;
2954         NTSTATUS status;
2955
2956         /* find the connection policy handle. */
2957         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2958                 return NT_STATUS_INVALID_HANDLE;
2959
2960         if (info->type != LSA_HANDLE_POLICY_TYPE) {
2961                 return NT_STATUS_INVALID_HANDLE;
2962         }
2963
2964         /* get the generic lsa account SD for this SID until we store it */
2965         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2966                                 &lsa_account_mapping,
2967                                 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2968         if (!NT_STATUS_IS_OK(status)) {
2969                 return status;
2970         }
2971
2972         /*
2973          * From the MS DOCs. We need
2974          * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2975          * and DELETE on the account sid.
2976          */
2977
2978         status = access_check_object(psd, p->session_info->security_token,
2979                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2980                                      LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2981                                      LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
2982                                      &acc_granted, "_lsa_RemoveAccountRights");
2983         if (!NT_STATUS_IS_OK(status)) {
2984                 return status;
2985         }
2986
2987         sid_copy( &sid, r->in.sid );
2988
2989         if ( r->in.remove_all ) {
2990                 if ( !revoke_all_privileges( &sid ) )
2991                         return NT_STATUS_ACCESS_DENIED;
2992
2993                 return NT_STATUS_OK;
2994         }
2995
2996         for ( i=0; i < r->in.rights->count; i++ ) {
2997
2998                 privname = r->in.rights->names[i].string;
2999
3000                 /* only try to add non-null strings */
3001
3002                 if ( !privname )
3003                         continue;
3004
3005                 if ( !revoke_privilege_by_name( &sid, privname ) ) {
3006                         DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3007                                 privname ));
3008                         return NT_STATUS_NO_SUCH_PRIVILEGE;
3009                 }
3010         }
3011
3012         return NT_STATUS_OK;
3013 }
3014
3015 /*******************************************************************
3016 ********************************************************************/
3017
3018 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3019                                    struct lsa_RightSet *r,
3020                                    PRIVILEGE_SET *privileges)
3021 {
3022         uint32 i;
3023         const char *privname;
3024         const char **privname_array = NULL;
3025         int num_priv = 0;
3026
3027         for (i=0; i<privileges->count; i++) {
3028                 if (privileges->set[i].luid.high) {
3029                         continue;
3030                 }
3031                 privname = sec_privilege_name(privileges->set[i].luid.low);
3032                 if (privname) {
3033                         if (!add_string_to_array(mem_ctx, privname,
3034                                                  &privname_array, &num_priv)) {
3035                                 return NT_STATUS_NO_MEMORY;
3036                         }
3037                 }
3038         }
3039
3040         if (num_priv) {
3041
3042                 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3043                                              num_priv);
3044                 if (!r->names) {
3045                         return NT_STATUS_NO_MEMORY;
3046                 }
3047
3048                 for (i=0; i<num_priv; i++) {
3049                         init_lsa_StringLarge(&r->names[i], privname_array[i]);
3050                 }
3051
3052                 r->count = num_priv;
3053         }
3054
3055         return NT_STATUS_OK;
3056 }
3057
3058 /***************************************************************************
3059  _lsa_EnumAccountRights
3060  ***************************************************************************/
3061
3062 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3063                                 struct lsa_EnumAccountRights *r)
3064 {
3065         NTSTATUS status;
3066         struct lsa_info *info = NULL;
3067         PRIVILEGE_SET *privileges;
3068
3069         /* find the connection policy handle. */
3070
3071         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3072                 return NT_STATUS_INVALID_HANDLE;
3073
3074         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3075                 return NT_STATUS_INVALID_HANDLE;
3076         }
3077
3078         if (!(info->access & LSA_ACCOUNT_VIEW)) {
3079                 return NT_STATUS_ACCESS_DENIED;
3080         }
3081
3082         /* according to an NT4 PDC, you can add privileges to SIDs even without
3083            call_lsa_create_account() first.  And you can use any arbitrary SID. */
3084
3085         /* according to MS-LSAD 3.1.4.5.10 it is required to return
3086          * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3087          * the lsa database */
3088
3089         status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3090         if (!NT_STATUS_IS_OK(status)) {
3091                 return status;
3092         }
3093
3094         DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3095                   sid_string_dbg(r->in.sid), privileges->count));
3096
3097         status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3098
3099         return status;
3100 }
3101
3102 /***************************************************************************
3103  _lsa_LookupPrivValue
3104  ***************************************************************************/
3105
3106 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3107                               struct lsa_LookupPrivValue *r)
3108 {
3109         struct lsa_info *info = NULL;
3110         const char *name = NULL;
3111
3112         /* find the connection policy handle. */
3113
3114         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3115                 return NT_STATUS_INVALID_HANDLE;
3116
3117         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3118                 return NT_STATUS_INVALID_HANDLE;
3119         }
3120
3121         if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3122                 return NT_STATUS_ACCESS_DENIED;
3123
3124         name = r->in.name->string;
3125
3126         DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3127
3128         r->out.luid->low = sec_privilege_id(name);
3129         r->out.luid->high = 0;
3130         if (r->out.luid->low == SEC_PRIV_INVALID) {
3131                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3132         }
3133         return NT_STATUS_OK;
3134 }
3135
3136 /***************************************************************************
3137  _lsa_EnumAccountsWithUserRight
3138  ***************************************************************************/
3139
3140 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3141                                         struct lsa_EnumAccountsWithUserRight *r)
3142 {
3143         NTSTATUS status;
3144         struct lsa_info *info = NULL;
3145         struct dom_sid *sids = NULL;
3146         int num_sids = 0;
3147         uint32_t i;
3148         enum sec_privilege privilege;
3149
3150         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3151                 return NT_STATUS_INVALID_HANDLE;
3152         }
3153
3154         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3155                 return NT_STATUS_INVALID_HANDLE;
3156         }
3157
3158         if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3159                 return NT_STATUS_ACCESS_DENIED;
3160         }
3161
3162         if (!r->in.name || !r->in.name->string) {
3163                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3164         }
3165
3166         privilege = sec_privilege_id(r->in.name->string);
3167         if (privilege == SEC_PRIV_INVALID) {
3168                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3169         }
3170
3171         status = privilege_enum_sids(privilege, p->mem_ctx,
3172                                      &sids, &num_sids);
3173         if (!NT_STATUS_IS_OK(status)) {
3174                 return status;
3175         }
3176
3177         r->out.sids->num_sids = num_sids;
3178         r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3179                                          r->out.sids->num_sids);
3180
3181         for (i=0; i < r->out.sids->num_sids; i++) {
3182                 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3183                                                           &sids[i]);
3184                 if (!r->out.sids->sids[i].sid) {
3185                         TALLOC_FREE(r->out.sids->sids);
3186                         r->out.sids->num_sids = 0;
3187                         return NT_STATUS_NO_MEMORY;
3188                 }
3189         }
3190
3191         return NT_STATUS_OK;
3192 }
3193
3194 /***************************************************************************
3195  _lsa_Delete
3196  ***************************************************************************/
3197
3198 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3199                      struct lsa_Delete *r)
3200 {
3201         return NT_STATUS_NOT_SUPPORTED;
3202 }
3203
3204 /*
3205  * From here on the server routines are just dummy ones to make smbd link with
3206  * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3207  * pulling the server stubs across one by one.
3208  */
3209
3210 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3211 {
3212         p->rng_fault_state = True;
3213         return NT_STATUS_NOT_IMPLEMENTED;
3214 }
3215
3216 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3217                              struct lsa_ChangePassword *r)
3218 {
3219         p->rng_fault_state = True;
3220         return NT_STATUS_NOT_IMPLEMENTED;
3221 }
3222
3223 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3224 {
3225         p->rng_fault_state = True;
3226         return NT_STATUS_NOT_IMPLEMENTED;
3227 }
3228
3229 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3230 {
3231         p->rng_fault_state = True;
3232         return NT_STATUS_NOT_IMPLEMENTED;
3233 }
3234
3235 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3236                                   struct lsa_GetQuotasForAccount *r)
3237 {
3238         p->rng_fault_state = True;
3239         return NT_STATUS_NOT_IMPLEMENTED;
3240 }
3241
3242 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3243                                   struct lsa_SetQuotasForAccount *r)
3244 {
3245         p->rng_fault_state = True;
3246         return NT_STATUS_NOT_IMPLEMENTED;
3247 }
3248
3249 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3250                                           struct lsa_SetInformationTrustedDomain *r)
3251 {
3252         p->rng_fault_state = True;
3253         return NT_STATUS_NOT_IMPLEMENTED;
3254 }
3255
3256 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
3257 {
3258         p->rng_fault_state = True;
3259         return NT_STATUS_NOT_IMPLEMENTED;
3260 }
3261
3262 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3263                                    struct lsa_SetTrustedDomainInfo *r)
3264 {
3265         p->rng_fault_state = True;
3266         return NT_STATUS_NOT_IMPLEMENTED;
3267 }
3268
3269 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3270                                struct lsa_StorePrivateData *r)
3271 {
3272         p->rng_fault_state = True;
3273         return NT_STATUS_NOT_IMPLEMENTED;
3274 }
3275
3276 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3277                                   struct lsa_RetrievePrivateData *r)
3278 {
3279         p->rng_fault_state = True;
3280         return NT_STATUS_NOT_IMPLEMENTED;
3281 }
3282
3283 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3284                              struct lsa_SetInfoPolicy2 *r)
3285 {
3286         p->rng_fault_state = True;
3287         return NT_STATUS_NOT_IMPLEMENTED;
3288 }
3289
3290 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3291                                          struct lsa_SetTrustedDomainInfoByName *r)
3292 {
3293         p->rng_fault_state = True;
3294         return NT_STATUS_NOT_IMPLEMENTED;
3295 }
3296
3297 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3298                                    struct lsa_EnumTrustedDomainsEx *r)
3299 {
3300         struct lsa_info *info;
3301         uint32_t count;
3302         struct pdb_trusted_domain **domains;
3303         struct lsa_TrustDomainInfoInfoEx *entries;
3304         int i;
3305         NTSTATUS nt_status;
3306
3307         /* bail out early if pdb backend is not capable of ex trusted domains,
3308          * if we dont do that, the client might not call
3309          * _lsa_EnumTrustedDomains() afterwards - gd */
3310
3311         if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3312                 p->rng_fault_state = True;
3313                 return NT_STATUS_NOT_IMPLEMENTED;
3314         }
3315
3316         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3317                 return NT_STATUS_INVALID_HANDLE;
3318
3319         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3320                 return NT_STATUS_INVALID_HANDLE;
3321         }
3322
3323         /* check if the user has enough rights */
3324         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3325                 return NT_STATUS_ACCESS_DENIED;
3326
3327         become_root();
3328         nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3329         unbecome_root();
3330
3331         if (!NT_STATUS_IS_OK(nt_status)) {
3332                 return nt_status;
3333         }
3334
3335         entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3336                                     count);
3337         if (!entries) {
3338                 return NT_STATUS_NO_MEMORY;
3339         }
3340
3341         for (i=0; i<count; i++) {
3342                 init_lsa_StringLarge(&entries[i].netbios_name,
3343                                      domains[i]->netbios_name);
3344                 entries[i].sid = &domains[i]->security_identifier;
3345         }
3346
3347         if (*r->in.resume_handle >= count) {
3348                 *r->out.resume_handle = -1;
3349                 TALLOC_FREE(entries);
3350                 return NT_STATUS_NO_MORE_ENTRIES;
3351         }
3352
3353         /* return the rest, limit by max_size. Note that we
3354            use the w2k3 element size value of 60 */
3355         r->out.domains->count = count - *r->in.resume_handle;
3356         r->out.domains->count = MIN(r->out.domains->count,
3357                                     (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3358
3359         r->out.domains->domains = entries + *r->in.resume_handle;
3360
3361         if (r->out.domains->count < count - *r->in.resume_handle) {
3362                 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3363                 return STATUS_MORE_ENTRIES;
3364         }
3365
3366         /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3367          * always be larger than the previous input resume handle, in
3368          * particular when hitting the last query it is vital to set the
3369          * resume handle correctly to avoid infinite client loops, as
3370          * seen e.g. with Windows XP SP3 when resume handle is 0 and
3371          * status is NT_STATUS_OK - gd */
3372
3373         *r->out.resume_handle = (uint32_t)-1;
3374
3375         return NT_STATUS_OK;
3376 }
3377
3378 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3379                                            struct lsa_QueryDomainInformationPolicy *r)
3380 {
3381         p->rng_fault_state = True;
3382         return NT_STATUS_NOT_IMPLEMENTED;
3383 }
3384
3385 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3386                                          struct lsa_SetDomainInformationPolicy *r)
3387 {
3388         p->rng_fault_state = True;
3389         return NT_STATUS_NOT_IMPLEMENTED;
3390 }
3391
3392 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3393 {
3394         p->rng_fault_state = True;
3395         return NT_STATUS_NOT_IMPLEMENTED;
3396 }
3397
3398 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3399 {
3400         p->rng_fault_state = True;
3401         return NT_STATUS_NOT_IMPLEMENTED;
3402 }
3403
3404 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3405 {
3406         p->rng_fault_state = True;
3407         return NT_STATUS_NOT_IMPLEMENTED;
3408 }
3409
3410 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3411 {
3412         p->rng_fault_state = True;
3413         return NT_STATUS_NOT_IMPLEMENTED;
3414 }
3415
3416 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3417                                           struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3418 {
3419         p->rng_fault_state = True;
3420         return NT_STATUS_NOT_IMPLEMENTED;
3421 }
3422
3423 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3424                                          struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3425 {
3426         p->rng_fault_state = True;
3427         return NT_STATUS_NOT_IMPLEMENTED;
3428 }
3429
3430 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3431 {
3432         p->rng_fault_state = True;
3433         return NT_STATUS_NOT_IMPLEMENTED;
3434 }
3435
3436 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3437                                  struct lsa_CREDRGETTARGETINFO *r)
3438 {
3439         p->rng_fault_state = True;
3440         return NT_STATUS_NOT_IMPLEMENTED;
3441 }
3442
3443 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3444                                  struct lsa_CREDRPROFILELOADED *r)
3445 {
3446         p->rng_fault_state = True;
3447         return NT_STATUS_NOT_IMPLEMENTED;
3448 }
3449
3450 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3451                                    struct lsa_CREDRGETSESSIONTYPES *r)
3452 {
3453         p->rng_fault_state = True;
3454         return NT_STATUS_NOT_IMPLEMENTED;
3455 }
3456
3457 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3458                                      struct lsa_LSARREGISTERAUDITEVENT *r)
3459 {
3460         p->rng_fault_state = True;
3461         return NT_STATUS_NOT_IMPLEMENTED;
3462 }
3463
3464 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3465                                 struct lsa_LSARGENAUDITEVENT *r)
3466 {
3467         p->rng_fault_state = True;
3468         return NT_STATUS_NOT_IMPLEMENTED;
3469 }
3470
3471 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3472                                        struct lsa_LSARUNREGISTERAUDITEVENT *r)
3473 {
3474         p->rng_fault_state = True;
3475         return NT_STATUS_NOT_IMPLEMENTED;
3476 }
3477
3478 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3479                                               struct lsa_lsaRQueryForestTrustInformation *r)
3480 {
3481         p->rng_fault_state = True;
3482         return NT_STATUS_NOT_IMPLEMENTED;
3483 }
3484
3485 #define DNS_CMP_MATCH 0
3486 #define DNS_CMP_FIRST_IS_CHILD 1
3487 #define DNS_CMP_SECOND_IS_CHILD 2
3488 #define DNS_CMP_NO_MATCH 3
3489
3490 /* this function assumes names are well formed DNS names.
3491  * it doesn't validate them */
3492 static int dns_cmp(const char *s1, size_t l1,
3493                    const char *s2, size_t l2)
3494 {
3495         const char *p1, *p2;
3496         size_t t1, t2;
3497         int cret;
3498
3499         if (l1 == l2) {
3500                 if (strcasecmp_m(s1, s2) == 0) {
3501                         return DNS_CMP_MATCH;
3502                 }
3503                 return DNS_CMP_NO_MATCH;
3504         }
3505
3506         if (l1 > l2) {
3507                 p1 = s1;
3508                 p2 = s2;
3509                 t1 = l1;
3510                 t2 = l2;
3511                 cret = DNS_CMP_FIRST_IS_CHILD;
3512         } else {
3513                 p1 = s2;
3514                 p2 = s1;
3515                 t1 = l2;
3516                 t2 = l1;
3517                 cret = DNS_CMP_SECOND_IS_CHILD;
3518         }
3519
3520         if (p1[t1 - t2 - 1] != '.') {
3521                 return DNS_CMP_NO_MATCH;
3522         }
3523
3524         if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
3525                 return cret;
3526         }
3527
3528         return DNS_CMP_NO_MATCH;
3529 }
3530
3531 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3532                              struct lsa_ForestTrustInformation *lfti,
3533                              struct ForestTrustInfo *fti)
3534 {
3535         struct lsa_ForestTrustRecord *lrec;
3536         struct ForestTrustInfoRecord *rec;
3537         struct lsa_StringLarge *tln;
3538         struct lsa_ForestTrustDomainInfo *info;
3539         uint32_t i;
3540
3541         fti->version = 1;
3542         fti->count = lfti->count;
3543         fti->records = talloc_array(mem_ctx,
3544                                     struct ForestTrustInfoRecordArmor,
3545                                     fti->count);
3546         if (!fti->records) {
3547                 return NT_STATUS_NO_MEMORY;
3548         }
3549         for (i = 0; i < fti->count; i++) {
3550                 lrec = lfti->entries[i];
3551                 rec = &fti->records[i].record;
3552
3553                 rec->flags = lrec->flags;
3554                 rec->timestamp = lrec->time;
3555                 rec->type = lrec->type;
3556
3557                 switch (lrec->type) {
3558                 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
3559                 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3560                         tln = &lrec->forest_trust_data.top_level_name;
3561                         rec->data.name.string =
3562                                 talloc_strdup(mem_ctx, tln->string);
3563                         if (!rec->data.name.string) {
3564                                 return NT_STATUS_NO_MEMORY;
3565                         }
3566                         rec->data.name.size = strlen(rec->data.name.string);
3567                         break;
3568                 case LSA_FOREST_TRUST_DOMAIN_INFO:
3569                         info = &lrec->forest_trust_data.domain_info;
3570                         rec->data.info.sid = *info->domain_sid;
3571                         rec->data.info.dns_name.string =
3572                                 talloc_strdup(mem_ctx,
3573                                             info->dns_domain_name.string);
3574                         if (!rec->data.info.dns_name.string) {
3575                                 return NT_STATUS_NO_MEMORY;
3576                         }
3577                         rec->data.info.dns_name.size =
3578                                 strlen(rec->data.info.dns_name.string);
3579                         rec->data.info.netbios_name.string =
3580                                 talloc_strdup(mem_ctx,
3581                                             info->netbios_domain_name.string);
3582                         if (!rec->data.info.netbios_name.string) {
3583                                 return NT_STATUS_NO_MEMORY;
3584                         }
3585                         rec->data.info.netbios_name.size =
3586                                 strlen(rec->data.info.netbios_name.string);
3587                         break;
3588                 default:
3589                         return NT_STATUS_INVALID_DOMAIN_STATE;
3590                 }
3591         }
3592
3593         return NT_STATUS_OK;
3594 }
3595
3596 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3597                               uint32_t index, uint32_t collision_type,
3598                               uint32_t conflict_type, const char *tdo_name);
3599
3600 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
3601                               const char *tdo_name,
3602                               struct ForestTrustInfo *tdo_fti,
3603                               struct ForestTrustInfo *new_fti,
3604                               struct lsa_ForestTrustCollisionInfo *c_info)
3605 {
3606         struct ForestTrustInfoRecord *nrec;
3607         struct ForestTrustInfoRecord *trec;
3608         const char *dns_name;
3609         const char *nb_name = NULL;
3610         struct dom_sid *sid = NULL;
3611         const char *tname = NULL;
3612         size_t dns_len = 0;
3613         size_t nb_len;
3614         size_t tlen = 0;
3615         NTSTATUS nt_status;
3616         uint32_t new_fti_idx;
3617         uint32_t i;
3618         /* use always TDO type, until we understand when Xref can be used */
3619         uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
3620         bool tln_conflict;
3621         bool sid_conflict;
3622         bool nb_conflict;
3623         bool exclusion;
3624         bool ex_rule = false;
3625         int ret;
3626
3627         for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
3628
3629                 nrec = &new_fti->records[new_fti_idx].record;
3630                 dns_name = NULL;
3631                 tln_conflict = false;
3632                 sid_conflict = false;
3633                 nb_conflict = false;
3634                 exclusion = false;
3635
3636                 switch (nrec->type) {
3637                 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3638                         /* exclusions do not conflict by definition */
3639                         break;
3640
3641                 case FOREST_TRUST_TOP_LEVEL_NAME:
3642                         dns_name = nrec->data.name.string;
3643                         dns_len = nrec->data.name.size;
3644                         break;
3645
3646                 case LSA_FOREST_TRUST_DOMAIN_INFO:
3647                         dns_name = nrec->data.info.dns_name.string;
3648                         dns_len = nrec->data.info.dns_name.size;
3649                         nb_name = nrec->data.info.netbios_name.string;
3650                         nb_len = nrec->data.info.netbios_name.size;
3651                         sid = &nrec->data.info.sid;
3652                         break;
3653                 }
3654
3655                 if (!dns_name) continue;
3656
3657                 /* check if this is already taken and not excluded */
3658                 for (i = 0; i < tdo_fti->count; i++) {
3659                         trec = &tdo_fti->records[i].record;
3660
3661                         switch (trec->type) {
3662                         case FOREST_TRUST_TOP_LEVEL_NAME:
3663                                 ex_rule = false;
3664                                 tname = trec->data.name.string;
3665                                 tlen = trec->data.name.size;
3666                                 break;
3667                         case FOREST_TRUST_TOP_LEVEL_NAME_EX:
3668                                 ex_rule = true;
3669                                 tname = trec->data.name.string;
3670                                 tlen = trec->data.name.size;
3671                                 break;
3672                         case FOREST_TRUST_DOMAIN_INFO:
3673                                 ex_rule = false;
3674                                 tname = trec->data.info.dns_name.string;
3675                                 tlen = trec->data.info.dns_name.size;
3676                                 break;
3677                         default:
3678                                 return NT_STATUS_INVALID_PARAMETER;
3679                         }
3680                         ret = dns_cmp(dns_name, dns_len, tname, tlen);
3681                         switch (ret) {
3682                         case DNS_CMP_MATCH:
3683                                 /* if it matches exclusion,
3684                                  * it doesn't conflict */
3685                                 if (ex_rule) {
3686                                         exclusion = true;
3687                                         break;
3688                                 }
3689                                 /* fall through */
3690                         case DNS_CMP_FIRST_IS_CHILD:
3691                         case DNS_CMP_SECOND_IS_CHILD:
3692                                 tln_conflict = true;
3693                                 /* fall through */
3694                         default:
3695                                 break;
3696                         }
3697
3698                         /* explicit exclusion, no dns name conflict here */
3699                         if (exclusion) {
3700                                 tln_conflict = false;
3701                         }
3702
3703                         if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
3704                                 continue;
3705                         }
3706
3707                         /* also test for domain info */
3708                         if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
3709                             dom_sid_compare(&trec->data.info.sid, sid) == 0) {
3710                                 sid_conflict = true;
3711                         }
3712                         if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
3713                             strcasecmp_m(trec->data.info.netbios_name.string,
3714                                        nb_name) == 0) {
3715                                 nb_conflict = true;
3716                         }
3717                 }
3718
3719                 if (tln_conflict) {
3720                         nt_status = add_collision(c_info, new_fti_idx,
3721                                                   collision_type,
3722                                                   LSA_TLN_DISABLED_CONFLICT,
3723                                                   tdo_name);
3724                 }
3725                 if (sid_conflict) {
3726                         nt_status = add_collision(c_info, new_fti_idx,
3727                                                   collision_type,
3728                                                   LSA_SID_DISABLED_CONFLICT,
3729                                                   tdo_name);
3730                 }
3731                 if (nb_conflict) {
3732                         nt_status = add_collision(c_info, new_fti_idx,
3733                                                   collision_type,
3734                                                   LSA_NB_DISABLED_CONFLICT,
3735                                                   tdo_name);
3736                 }
3737         }
3738
3739         return NT_STATUS_OK;
3740 }
3741
3742 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3743                               uint32_t idx, uint32_t collision_type,
3744                               uint32_t conflict_type, const char *tdo_name)
3745 {
3746         struct lsa_ForestTrustCollisionRecord **es;
3747         uint32_t i = c_info->count;
3748
3749         es = talloc_realloc(c_info, c_info->entries,
3750                             struct lsa_ForestTrustCollisionRecord *, i + 1);
3751         if (!es) {
3752                 return NT_STATUS_NO_MEMORY;
3753         }
3754         c_info->entries = es;
3755         c_info->count = i + 1;
3756
3757         es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
3758         if (!es[i]) {
3759                 return NT_STATUS_NO_MEMORY;
3760         }
3761
3762         es[i]->index = idx;
3763         es[i]->type = collision_type;
3764         es[i]->flags.flags = conflict_type;
3765         es[i]->name.string = talloc_strdup(es[i], tdo_name);
3766         if (!es[i]->name.string) {
3767                 return NT_STATUS_NO_MEMORY;
3768         }
3769         es[i]->name.size = strlen(es[i]->name.string);
3770
3771         return NT_STATUS_OK;
3772 }
3773
3774 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3775                             struct pdb_trusted_domain *td,
3776                             struct ForestTrustInfo *info)
3777 {
3778         enum ndr_err_code ndr_err;
3779
3780         if (td->trust_forest_trust_info.length == 0 ||
3781             td->trust_forest_trust_info.data == NULL) {
3782                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3783         }
3784         ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
3785                                            info,
3786                                            (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
3787         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3788                 return NT_STATUS_INVALID_DOMAIN_STATE;
3789         }
3790
3791         return NT_STATUS_OK;
3792 }
3793
3794 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
3795                             struct ForestTrustInfo *fti)
3796 {
3797         struct ForestTrustDataDomainInfo *info;
3798         struct ForestTrustInfoRecord *rec;
3799
3800         fti->version = 1;
3801         fti->count = 2;
3802         fti->records = talloc_array(fti,
3803                                     struct ForestTrustInfoRecordArmor, 2);
3804         if (!fti->records) {
3805                 return NT_STATUS_NO_MEMORY;
3806         }
3807
3808         /* TLN info */
3809         rec = &fti->records[0].record;
3810
3811         rec->flags = 0;
3812         rec->timestamp = 0;
3813         rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
3814
3815         rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
3816         if (!rec->data.name.string) {
3817                 return NT_STATUS_NO_MEMORY;
3818         }
3819         rec->data.name.size = strlen(rec->data.name.string);
3820
3821         /* DOMAIN info */
3822         rec = &fti->records[1].record;
3823
3824         rec->flags = 0;
3825         rec->timestamp = 0;
3826         rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
3827
3828         info = &rec->data.info;
3829
3830         info->sid = dom_info->sid;
3831         info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
3832         if (!info->dns_name.string) {
3833                 return NT_STATUS_NO_MEMORY;
3834         }
3835         info->dns_name.size = strlen(info->dns_name.string);
3836         info->netbios_name.string = talloc_strdup(fti, dom_info->name);
3837         if (!info->netbios_name.string) {
3838                 return NT_STATUS_NO_MEMORY;
3839         }
3840         info->netbios_name.size = strlen(info->netbios_name.string);
3841
3842         return NT_STATUS_OK;
3843 }
3844
3845 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
3846                                             struct lsa_lsaRSetForestTrustInformation *r)
3847 {
3848         NTSTATUS status;
3849         int i;
3850         int j;
3851         struct lsa_info *handle;
3852         uint32_t num_domains;
3853         struct pdb_trusted_domain **domains;
3854         struct ForestTrustInfo *nfti;
3855         struct ForestTrustInfo *fti;
3856         struct lsa_ForestTrustCollisionInfo *c_info;
3857         struct pdb_domain_info *dom_info;
3858         enum ndr_err_code ndr_err;
3859
3860         if (!IS_DC) {
3861                 return NT_STATUS_NOT_SUPPORTED;
3862         }
3863
3864         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
3865                 return NT_STATUS_INVALID_HANDLE;
3866         }
3867
3868         if (handle->type != LSA_HANDLE_TRUST_TYPE) {
3869                 return NT_STATUS_INVALID_HANDLE;
3870         }
3871
3872         if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
3873                 return NT_STATUS_ACCESS_DENIED;
3874         }
3875
3876         status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
3877         if (!NT_STATUS_IS_OK(status)) {
3878                 return status;
3879         }
3880         if (num_domains == 0) {
3881                 return NT_STATUS_NO_SUCH_DOMAIN;
3882         }
3883
3884         for (i = 0; i < num_domains; i++) {
3885                 if (domains[i]->domain_name == NULL) {
3886                         return NT_STATUS_INVALID_DOMAIN_STATE;
3887                 }
3888                 if (strcasecmp_m(domains[i]->domain_name,
3889                                r->in.trusted_domain_name->string) == 0) {
3890                         break;
3891                 }
3892         }
3893         if (i >= num_domains) {
3894                 return NT_STATUS_NO_SUCH_DOMAIN;
3895         }
3896
3897         if (!(domains[i]->trust_attributes &
3898               LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
3899                 return NT_STATUS_INVALID_PARAMETER;
3900         }
3901
3902         if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
3903                 return NT_STATUS_INVALID_PARAMETER;
3904         }
3905
3906         /* The following section until COPY_END is a copy from
3907          * source4/rpmc_server/lsa/scesrc_lsa.c */
3908         nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
3909         if (!nfti) {
3910                 return NT_STATUS_NO_MEMORY;
3911         }
3912
3913         status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
3914         if (!NT_STATUS_IS_OK(status)) {
3915                 return status;
3916         }
3917
3918         c_info = talloc_zero(r->out.collision_info,
3919                              struct lsa_ForestTrustCollisionInfo);
3920         if (!c_info) {
3921                 return NT_STATUS_NO_MEMORY;
3922         }
3923
3924         /* first check own info, then other domains */
3925         fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3926         if (!fti) {
3927                 return NT_STATUS_NO_MEMORY;
3928         }
3929
3930         dom_info = pdb_get_domain_info(p->mem_ctx);
3931
3932         status = own_ft_info(dom_info, fti);
3933         if (!NT_STATUS_IS_OK(status)) {
3934                 return status;
3935         }
3936
3937         status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
3938         if (!NT_STATUS_IS_OK(status)) {
3939                 return status;
3940         }
3941
3942         for (j = 0; j < num_domains; j++) {
3943                 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3944                 if (!fti) {
3945                         return NT_STATUS_NO_MEMORY;
3946                 }
3947
3948                 status = get_ft_info(p->mem_ctx, domains[j], fti);
3949                 if (!NT_STATUS_IS_OK(status)) {
3950                         if (NT_STATUS_EQUAL(status,
3951                             NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3952                                 continue;
3953                         }
3954                         return status;
3955                 }
3956
3957                 if (domains[j]->domain_name == NULL) {
3958                         return NT_STATUS_INVALID_DOMAIN_STATE;
3959                 }
3960
3961                 status = check_ft_info(c_info, domains[j]->domain_name,
3962                                        fti, nfti, c_info);
3963                 if (!NT_STATUS_IS_OK(status)) {
3964                         return status;
3965                 }
3966         }
3967
3968         *r->out.collision_info = c_info;
3969
3970         if (r->in.check_only != 0) {
3971                 return NT_STATUS_OK;
3972         }
3973
3974         /* COPY_END */
3975
3976         ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
3977                                        p->mem_ctx, nfti,
3978                                        (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
3979         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3980                 return NT_STATUS_INVALID_PARAMETER;
3981         }
3982
3983         status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
3984         if (!NT_STATUS_IS_OK(status)) {
3985                 return status;
3986         }
3987
3988         return NT_STATUS_OK;
3989 }
3990
3991 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
3992                           struct lsa_CREDRRENAME *r)
3993 {
3994         p->rng_fault_state = True;
3995         return NT_STATUS_NOT_IMPLEMENTED;
3996 }
3997
3998 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
3999                                 struct lsa_LSAROPENPOLICYSCE *r)
4000 {
4001         p->rng_fault_state = True;
4002         return NT_STATUS_NOT_IMPLEMENTED;
4003 }
4004
4005 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4006                                                  struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4007 {
4008         p->rng_fault_state = True;
4009         return NT_STATUS_NOT_IMPLEMENTED;
4010 }
4011
4012 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4013                                                    struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4014 {
4015         p->rng_fault_state = True;
4016         return NT_STATUS_NOT_IMPLEMENTED;
4017 }
4018
4019 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4020                                          struct lsa_LSARADTREPORTSECURITYEVENT *r)
4021 {
4022         p->rng_fault_state = True;
4023         return NT_STATUS_NOT_IMPLEMENTED;
4024 }