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