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