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