s3-lsarpc: Restrict lsa_LookupSids3 to ncacn_ip_tcp connections.
[mat/samba.git] / source3 / rpc_server / lsa / srv_lsa_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Jeremy Allison                    2001, 2006.
8  *  Copyright (C) Rafal Szczesniak                  2002,
9  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
10  *  Copyright (C) Simo Sorce                        2003.
11  *  Copyright (C) Gerald (Jerry) Carter             2005.
12  *  Copyright (C) Volker Lendecke                   2005.
13  *  Copyright (C) Guenther Deschner                 2008.
14  *  Copyright (C) Andrew Bartlett                   2010.
15  *
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License as published by
18  *  the Free Software Foundation; either version 3 of the License, or
19  *  (at your option) any later version.
20  *
21  *  This program is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *  GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License
27  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
28  */
29
30 /* This is the implementation of the lsa server code. */
31
32 #include "includes.h"
33 #include "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) {
410                 info->sd = dup_sec_desc(info, sd);
411                 if (!info->sd) {
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                 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1131                         get_remote_machine_name() ));
1132                 return NT_STATUS_INVALID_PARAMETER;
1133         }
1134
1135         q.in.handle             = NULL;
1136         q.in.sids               = r->in.sids;
1137         q.in.level              = r->in.level;
1138         q.in.lookup_options     = r->in.lookup_options;
1139         q.in.client_revision    = r->in.client_revision;
1140         q.in.names              = r->in.names;
1141         q.in.count              = r->in.count;
1142
1143         q.out.domains           = r->out.domains;
1144         q.out.names             = r->out.names;
1145         q.out.count             = r->out.count;
1146
1147         return _lsa_LookupSids_common(p, &q);
1148 }
1149
1150 /***************************************************************************
1151  ***************************************************************************/
1152
1153 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1154 {
1155         int flags;
1156
1157         switch (level) {
1158                 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1159                         flags = LOOKUP_NAME_ALL;
1160                         break;
1161                 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1162                         flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1163                         break;
1164                 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1165                         flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1166                         break;
1167                 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1168                 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1169                 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1170                 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1171                 default:
1172                         flags = LOOKUP_NAME_NONE;
1173                         break;
1174         }
1175
1176         return flags;
1177 }
1178
1179 /***************************************************************************
1180  _lsa_LookupNames
1181  ***************************************************************************/
1182
1183 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1184                           struct lsa_LookupNames *r)
1185 {
1186         NTSTATUS status = NT_STATUS_NONE_MAPPED;
1187         struct lsa_info *handle;
1188         struct lsa_String *names = r->in.names;
1189         uint32 num_entries = r->in.num_names;
1190         struct lsa_RefDomainList *domains = NULL;
1191         struct lsa_TranslatedSid *rids = NULL;
1192         uint32 mapped_count = 0;
1193         int flags = 0;
1194
1195         if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1196                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1197                 return NT_STATUS_ACCESS_DENIED;
1198         }
1199
1200         if (num_entries >  MAX_LOOKUP_SIDS) {
1201                 num_entries = MAX_LOOKUP_SIDS;
1202                 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1203                         num_entries));
1204         }
1205
1206         flags = lsa_lookup_level_to_flags(r->in.level);
1207
1208         domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1209         if (!domains) {
1210                 return NT_STATUS_NO_MEMORY;
1211         }
1212
1213         if (num_entries) {
1214                 rids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid,
1215                                          num_entries);
1216                 if (!rids) {
1217                         return NT_STATUS_NO_MEMORY;
1218                 }
1219         } else {
1220                 rids = NULL;
1221         }
1222
1223         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1224                 status = NT_STATUS_INVALID_HANDLE;
1225                 goto done;
1226         }
1227
1228         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1229                 return NT_STATUS_INVALID_HANDLE;
1230         }
1231
1232         /* check if the user has enough rights */
1233         if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1234                 status = NT_STATUS_ACCESS_DENIED;
1235                 goto done;
1236         }
1237
1238         /* set up the LSA Lookup RIDs response */
1239         become_root(); /* lookup_name can require root privs */
1240         status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1241                                  names, flags, &mapped_count);
1242         unbecome_root();
1243
1244 done:
1245
1246         if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1247                 if (mapped_count == 0) {
1248                         status = NT_STATUS_NONE_MAPPED;
1249                 } else if (mapped_count != num_entries) {
1250                         status = STATUS_SOME_UNMAPPED;
1251                 }
1252         }
1253
1254         *r->out.count = mapped_count;
1255         *r->out.domains = domains;
1256         r->out.sids->sids = rids;
1257         r->out.sids->count = num_entries;
1258
1259         return status;
1260 }
1261
1262 /***************************************************************************
1263  _lsa_LookupNames2
1264  ***************************************************************************/
1265
1266 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1267                            struct lsa_LookupNames2 *r)
1268 {
1269         NTSTATUS status;
1270         struct lsa_LookupNames q;
1271         struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1272         struct lsa_TransSidArray *sid_array = NULL;
1273         uint32_t i;
1274
1275         if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1276                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1277                 return NT_STATUS_ACCESS_DENIED;
1278         }
1279
1280         sid_array = talloc_zero(p->mem_ctx, struct lsa_TransSidArray);
1281         if (!sid_array) {
1282                 return NT_STATUS_NO_MEMORY;
1283         }
1284
1285         q.in.handle             = r->in.handle;
1286         q.in.num_names          = r->in.num_names;
1287         q.in.names              = r->in.names;
1288         q.in.level              = r->in.level;
1289         q.in.sids               = sid_array;
1290         q.in.count              = r->in.count;
1291         /* we do not know what this is for */
1292         /*                      = r->in.unknown1; */
1293         /*                      = r->in.unknown2; */
1294
1295         q.out.domains           = r->out.domains;
1296         q.out.sids              = sid_array;
1297         q.out.count             = r->out.count;
1298
1299         status = _lsa_LookupNames(p, &q);
1300
1301         sid_array2->count = sid_array->count;
1302         sid_array2->sids = talloc_array(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1303         if (!sid_array2->sids) {
1304                 return NT_STATUS_NO_MEMORY;
1305         }
1306
1307         for (i=0; i<sid_array->count; i++) {
1308                 sid_array2->sids[i].sid_type  = sid_array->sids[i].sid_type;
1309                 sid_array2->sids[i].rid       = sid_array->sids[i].rid;
1310                 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1311                 sid_array2->sids[i].unknown   = 0;
1312         }
1313
1314         r->out.sids = sid_array2;
1315
1316         return status;
1317 }
1318
1319 /***************************************************************************
1320  _lsa_LookupNames3
1321  ***************************************************************************/
1322
1323 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1324                            struct lsa_LookupNames3 *r)
1325 {
1326         NTSTATUS status;
1327         struct lsa_info *handle;
1328         struct lsa_String *names = r->in.names;
1329         uint32 num_entries = r->in.num_names;
1330         struct lsa_RefDomainList *domains = NULL;
1331         struct lsa_TranslatedSid3 *trans_sids = NULL;
1332         uint32 mapped_count = 0;
1333         int flags = 0;
1334         bool check_policy = true;
1335
1336         if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1337                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1338                 return NT_STATUS_ACCESS_DENIED;
1339         }
1340
1341         switch (p->opnum) {
1342                 case NDR_LSA_LOOKUPNAMES4:
1343                         check_policy = false;
1344                         break;
1345                 case NDR_LSA_LOOKUPNAMES3:
1346                 default:
1347                         check_policy = true;
1348         }
1349
1350         if (num_entries >  MAX_LOOKUP_SIDS) {
1351                 num_entries = MAX_LOOKUP_SIDS;
1352                 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1353         }
1354
1355         flags = lsa_lookup_level_to_flags(r->in.level);
1356
1357         domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1358         if (!domains) {
1359                 return NT_STATUS_NO_MEMORY;
1360         }
1361
1362         if (num_entries) {
1363                 trans_sids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid3,
1364                                                num_entries);
1365                 if (!trans_sids) {
1366                         return NT_STATUS_NO_MEMORY;
1367                 }
1368         } else {
1369                 trans_sids = NULL;
1370         }
1371
1372         if (check_policy) {
1373
1374                 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1375                         status = NT_STATUS_INVALID_HANDLE;
1376                         goto done;
1377                 }
1378
1379                 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1380                         return NT_STATUS_INVALID_HANDLE;
1381                 }
1382
1383                 /* check if the user has enough rights */
1384                 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1385                         status = NT_STATUS_ACCESS_DENIED;
1386                         goto done;
1387                 }
1388         }
1389
1390         /* set up the LSA Lookup SIDs response */
1391         become_root(); /* lookup_name can require root privs */
1392         status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1393                                  names, flags, &mapped_count);
1394         unbecome_root();
1395
1396 done:
1397
1398         if (NT_STATUS_IS_OK(status)) {
1399                 if (mapped_count == 0) {
1400                         status = NT_STATUS_NONE_MAPPED;
1401                 } else if (mapped_count != num_entries) {
1402                         status = STATUS_SOME_UNMAPPED;
1403                 }
1404         }
1405
1406         *r->out.count = mapped_count;
1407         *r->out.domains = domains;
1408         r->out.sids->sids = trans_sids;
1409         r->out.sids->count = num_entries;
1410
1411         return status;
1412 }
1413
1414 /***************************************************************************
1415  _lsa_LookupNames4
1416  ***************************************************************************/
1417
1418 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1419                            struct lsa_LookupNames4 *r)
1420 {
1421         struct lsa_LookupNames3 q;
1422
1423         /* No policy handle on this call. Restrict to crypto connections. */
1424         if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1425                 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1426                         get_remote_machine_name() ));
1427                 return NT_STATUS_INVALID_PARAMETER;
1428         }
1429
1430         q.in.handle             = NULL;
1431         q.in.num_names          = r->in.num_names;
1432         q.in.names              = r->in.names;
1433         q.in.level              = r->in.level;
1434         q.in.lookup_options     = r->in.lookup_options;
1435         q.in.client_revision    = r->in.client_revision;
1436         q.in.sids               = r->in.sids;
1437         q.in.count              = r->in.count;
1438
1439         q.out.domains           = r->out.domains;
1440         q.out.sids              = r->out.sids;
1441         q.out.count             = r->out.count;
1442
1443         return _lsa_LookupNames3(p, &q);
1444 }
1445
1446 /***************************************************************************
1447  _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1448  ***************************************************************************/
1449
1450 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1451 {
1452         if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1453                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1454                 return NT_STATUS_ACCESS_DENIED;
1455         }
1456
1457         if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1458                 return NT_STATUS_INVALID_HANDLE;
1459         }
1460
1461         close_policy_hnd(p, r->in.handle);
1462         ZERO_STRUCTP(r->out.handle);
1463         return NT_STATUS_OK;
1464 }
1465
1466 /***************************************************************************
1467  ***************************************************************************/
1468
1469 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1470                                                  const struct dom_sid *sid,
1471                                                  struct trustdom_info **info)
1472 {
1473         NTSTATUS status;
1474         uint32_t num_domains = 0;
1475         struct trustdom_info **domains = NULL;
1476         int i;
1477
1478         status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1479         if (!NT_STATUS_IS_OK(status)) {
1480                 return status;
1481         }
1482
1483         for (i=0; i < num_domains; i++) {
1484                 if (dom_sid_equal(&domains[i]->sid, sid)) {
1485                         break;
1486                 }
1487         }
1488
1489         if (i == num_domains) {
1490                 return NT_STATUS_INVALID_PARAMETER;
1491         }
1492
1493         *info = domains[i];
1494
1495         return NT_STATUS_OK;
1496 }
1497
1498 /***************************************************************************
1499  ***************************************************************************/
1500
1501 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1502                                                   const char *netbios_domain_name,
1503                                                   struct trustdom_info **info_p)
1504 {
1505         NTSTATUS status;
1506         struct trustdom_info *info;
1507         struct pdb_trusted_domain *td;
1508
1509         status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1510         if (!NT_STATUS_IS_OK(status)) {
1511                 return status;
1512         }
1513
1514         info = talloc(mem_ctx, struct trustdom_info);
1515         if (!info) {
1516                 return NT_STATUS_NO_MEMORY;
1517         }
1518
1519         info->name      = talloc_strdup(info, netbios_domain_name);
1520         NT_STATUS_HAVE_NO_MEMORY(info->name);
1521
1522         sid_copy(&info->sid, &td->security_identifier);
1523
1524         *info_p = info;
1525
1526         return NT_STATUS_OK;
1527 }
1528
1529 /***************************************************************************
1530  _lsa_OpenSecret
1531  ***************************************************************************/
1532
1533 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p,
1534                          struct lsa_OpenSecret *r)
1535 {
1536         struct lsa_info *handle;
1537         struct security_descriptor *psd;
1538         NTSTATUS status;
1539         uint32_t acc_granted;
1540
1541         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1542                 return NT_STATUS_INVALID_HANDLE;
1543         }
1544
1545         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1546                 return NT_STATUS_INVALID_HANDLE;
1547         }
1548
1549         if (!r->in.name.string) {
1550                 return NT_STATUS_INVALID_PARAMETER;
1551         }
1552
1553         /* Work out max allowed. */
1554         map_max_allowed_access(p->session_info->security_token,
1555                                p->session_info->unix_token,
1556                                &r->in.access_mask);
1557
1558         /* map the generic bits to the lsa policy ones */
1559         se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
1560
1561         status = pdb_get_secret(p->mem_ctx, r->in.name.string,
1562                                 NULL,
1563                                 NULL,
1564                                 NULL,
1565                                 NULL,
1566                                 &psd);
1567         if (!NT_STATUS_IS_OK(status)) {
1568                 return status;
1569         }
1570
1571         status = access_check_object(psd, p->session_info->security_token,
1572                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1573                                      r->in.access_mask,
1574                                      &acc_granted, "_lsa_OpenSecret");
1575         if (!NT_STATUS_IS_OK(status)) {
1576                 return status;
1577         }
1578
1579         status = create_lsa_policy_handle(p->mem_ctx, p,
1580                                           LSA_HANDLE_SECRET_TYPE,
1581                                           acc_granted,
1582                                           NULL,
1583                                           r->in.name.string,
1584                                           psd,
1585                                           r->out.sec_handle);
1586         if (!NT_STATUS_IS_OK(status)) {
1587                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1588         }
1589
1590         return NT_STATUS_OK;
1591 }
1592
1593 /***************************************************************************
1594  _lsa_OpenTrustedDomain_base
1595  ***************************************************************************/
1596
1597 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1598                                             uint32_t access_mask,
1599                                             struct trustdom_info *info,
1600                                             struct policy_handle *handle)
1601 {
1602         struct security_descriptor *psd = NULL;
1603         size_t sd_size;
1604         uint32_t acc_granted;
1605         NTSTATUS status;
1606
1607         /* des_access is for the account here, not the policy
1608          * handle - so don't check against policy handle. */
1609
1610         /* Work out max allowed. */
1611         map_max_allowed_access(p->session_info->security_token,
1612                                p->session_info->unix_token,
1613                                &access_mask);
1614
1615         /* map the generic bits to the lsa account ones */
1616         se_map_generic(&access_mask, &lsa_trusted_domain_mapping);
1617
1618         /* get the generic lsa account SD until we store it */
1619         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1620                                     &lsa_trusted_domain_mapping,
1621                                     NULL, 0);
1622         if (!NT_STATUS_IS_OK(status)) {
1623                 return status;
1624         }
1625
1626         status = access_check_object(psd, p->session_info->security_token,
1627                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1628                                      access_mask, &acc_granted,
1629                                      "_lsa_OpenTrustedDomain");
1630         if (!NT_STATUS_IS_OK(status)) {
1631                 return status;
1632         }
1633
1634         status = create_lsa_policy_handle(p->mem_ctx, p,
1635                                           LSA_HANDLE_TRUST_TYPE,
1636                                           acc_granted,
1637                                           &info->sid,
1638                                           info->name,
1639                                           psd,
1640                                           handle);
1641         if (!NT_STATUS_IS_OK(status)) {
1642                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1643         }
1644
1645         return NT_STATUS_OK;
1646 }
1647
1648 /***************************************************************************
1649  _lsa_OpenTrustedDomain
1650  ***************************************************************************/
1651
1652 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1653                                 struct lsa_OpenTrustedDomain *r)
1654 {
1655         struct lsa_info *handle = NULL;
1656         struct trustdom_info *info = NULL;
1657         NTSTATUS status;
1658
1659         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1660                 return NT_STATUS_INVALID_HANDLE;
1661         }
1662
1663         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1664                 return NT_STATUS_INVALID_HANDLE;
1665         }
1666
1667         status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1668                                                   r->in.sid,
1669                                                   &info);
1670         if (!NT_STATUS_IS_OK(status)) {
1671                 return status;
1672         }
1673
1674         return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1675                                            r->out.trustdom_handle);
1676 }
1677
1678 /***************************************************************************
1679  _lsa_OpenTrustedDomainByName
1680  ***************************************************************************/
1681
1682 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1683                                       struct lsa_OpenTrustedDomainByName *r)
1684 {
1685         struct lsa_info *handle = NULL;
1686         struct trustdom_info *info = NULL;
1687         NTSTATUS status;
1688
1689         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1690                 return NT_STATUS_INVALID_HANDLE;
1691         }
1692
1693         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1694                 return NT_STATUS_INVALID_HANDLE;
1695         }
1696
1697         status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1698                                                    r->in.name.string,
1699                                                    &info);
1700         if (!NT_STATUS_IS_OK(status)) {
1701                 return status;
1702         }
1703
1704         return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1705                                            r->out.trustdom_handle);
1706 }
1707
1708 static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p,
1709                                        TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
1710                                        struct trustDomainPasswords *auth_struct)
1711 {
1712         enum ndr_err_code ndr_err;
1713         DATA_BLOB lsession_key;
1714         NTSTATUS status;
1715
1716         status = session_extract_session_key(p->session_info, &lsession_key, KEY_USE_16BYTES);
1717         if (!NT_STATUS_IS_OK(status)) {
1718                 return NT_STATUS_INVALID_PARAMETER;
1719         }
1720
1721         arcfour_crypt_blob(auth_blob->data, auth_blob->length, &lsession_key);
1722         ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
1723                                        auth_struct,
1724                                        (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
1725         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1726                 return NT_STATUS_INVALID_PARAMETER;
1727         }
1728
1729         return NT_STATUS_OK;
1730 }
1731
1732 static NTSTATUS get_trustauth_inout_blob(TALLOC_CTX *mem_ctx,
1733                                          struct trustAuthInOutBlob *iopw,
1734                                          DATA_BLOB *trustauth_blob)
1735 {
1736         enum ndr_err_code ndr_err;
1737
1738         ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
1739                                        iopw,
1740                                        (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
1741         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1742                 return NT_STATUS_INVALID_PARAMETER;
1743         }
1744
1745         return NT_STATUS_OK;
1746 }
1747
1748 /***************************************************************************
1749  _lsa_CreateTrustedDomainEx2
1750  ***************************************************************************/
1751
1752 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1753                                      struct lsa_CreateTrustedDomainEx2 *r)
1754 {
1755         struct lsa_info *policy;
1756         NTSTATUS status;
1757         uint32_t acc_granted;
1758         struct security_descriptor *psd;
1759         size_t sd_size;
1760         struct pdb_trusted_domain td;
1761         struct trustDomainPasswords auth_struct;
1762         DATA_BLOB auth_blob;
1763
1764         if (!IS_DC) {
1765                 return NT_STATUS_NOT_SUPPORTED;
1766         }
1767
1768         if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1769                 return NT_STATUS_INVALID_HANDLE;
1770         }
1771
1772         if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1773                 return NT_STATUS_ACCESS_DENIED;
1774         }
1775
1776         if (p->session_info->unix_token->uid != sec_initial_uid() &&
1777             !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
1778                 return NT_STATUS_ACCESS_DENIED;
1779         }
1780
1781         /* Work out max allowed. */
1782         map_max_allowed_access(p->session_info->security_token,
1783                                p->session_info->unix_token,
1784                                &r->in.access_mask);
1785
1786         /* map the generic bits to the lsa policy ones */
1787         se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1788
1789         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1790                                     &lsa_trusted_domain_mapping,
1791                                     NULL, 0);
1792         if (!NT_STATUS_IS_OK(status)) {
1793                 return status;
1794         }
1795
1796         status = access_check_object(psd, p->session_info->security_token,
1797                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1798                                      r->in.access_mask, &acc_granted,
1799                                      "_lsa_CreateTrustedDomainEx2");
1800         if (!NT_STATUS_IS_OK(status)) {
1801                 return status;
1802         }
1803
1804         ZERO_STRUCT(td);
1805
1806         td.domain_name = talloc_strdup(p->mem_ctx,
1807                                        r->in.info->domain_name.string);
1808         if (td.domain_name == NULL) {
1809                 return NT_STATUS_NO_MEMORY;
1810         }
1811         td.netbios_name = talloc_strdup(p->mem_ctx,
1812                                         r->in.info->netbios_name.string);
1813         if (td.netbios_name == NULL) {
1814                 return NT_STATUS_NO_MEMORY;
1815         }
1816         sid_copy(&td.security_identifier, r->in.info->sid);
1817         td.trust_direction = r->in.info->trust_direction;
1818         td.trust_type = r->in.info->trust_type;
1819         td.trust_attributes = r->in.info->trust_attributes;
1820
1821         if (r->in.auth_info_internal->auth_blob.size != 0) {
1822                 auth_blob.length = r->in.auth_info_internal->auth_blob.size;
1823                 auth_blob.data = r->in.auth_info_internal->auth_blob.data;
1824
1825                 status = get_trustdom_auth_blob(p, p->mem_ctx, &auth_blob, &auth_struct);
1826                 if (!NT_STATUS_IS_OK(status)) {
1827                         return NT_STATUS_UNSUCCESSFUL;
1828                 }
1829
1830                 status = get_trustauth_inout_blob(p->mem_ctx, &auth_struct.incoming, &td.trust_auth_incoming);
1831                 if (!NT_STATUS_IS_OK(status)) {
1832                         return NT_STATUS_UNSUCCESSFUL;
1833                 }
1834
1835                 status = get_trustauth_inout_blob(p->mem_ctx, &auth_struct.outgoing, &td.trust_auth_outgoing);
1836                 if (!NT_STATUS_IS_OK(status)) {
1837                         return NT_STATUS_UNSUCCESSFUL;
1838                 }
1839         } else {
1840                 td.trust_auth_incoming.data = NULL;
1841                 td.trust_auth_incoming.length = 0;
1842                 td.trust_auth_outgoing.data = NULL;
1843                 td.trust_auth_outgoing.length = 0;
1844         }
1845
1846         status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1847         if (!NT_STATUS_IS_OK(status)) {
1848                 return status;
1849         }
1850
1851         status = create_lsa_policy_handle(p->mem_ctx, p,
1852                                           LSA_HANDLE_TRUST_TYPE,
1853                                           acc_granted,
1854                                           r->in.info->sid,
1855                                           r->in.info->netbios_name.string,
1856                                           psd,
1857                                           r->out.trustdom_handle);
1858         if (!NT_STATUS_IS_OK(status)) {
1859                 pdb_del_trusted_domain(r->in.info->netbios_name.string);
1860                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1861         }
1862
1863         return NT_STATUS_OK;
1864 }
1865
1866 /***************************************************************************
1867  _lsa_CreateTrustedDomainEx
1868  ***************************************************************************/
1869
1870 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1871                                     struct lsa_CreateTrustedDomainEx *r)
1872 {
1873         struct lsa_CreateTrustedDomainEx2 q;
1874         struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1875
1876         ZERO_STRUCT(auth_info);
1877
1878         q.in.policy_handle      = r->in.policy_handle;
1879         q.in.info               = r->in.info;
1880         q.in.auth_info_internal = &auth_info;
1881         q.in.access_mask        = r->in.access_mask;
1882         q.out.trustdom_handle   = r->out.trustdom_handle;
1883
1884         return _lsa_CreateTrustedDomainEx2(p, &q);
1885 }
1886
1887 /***************************************************************************
1888  _lsa_CreateTrustedDomain
1889  ***************************************************************************/
1890
1891 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1892                                   struct lsa_CreateTrustedDomain *r)
1893 {
1894         struct lsa_CreateTrustedDomainEx2 c;
1895         struct lsa_TrustDomainInfoInfoEx info;
1896         struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1897
1898         ZERO_STRUCT(auth_info);
1899
1900         info.domain_name        = r->in.info->name;
1901         info.netbios_name       = r->in.info->name;
1902         info.sid                = r->in.info->sid;
1903         info.trust_direction    = LSA_TRUST_DIRECTION_OUTBOUND;
1904         info.trust_type         = LSA_TRUST_TYPE_DOWNLEVEL;
1905         info.trust_attributes   = 0;
1906
1907         c.in.policy_handle      = r->in.policy_handle;
1908         c.in.info               = &info;
1909         c.in.auth_info_internal = &auth_info;
1910         c.in.access_mask        = r->in.access_mask;
1911         c.out.trustdom_handle   = r->out.trustdom_handle;
1912
1913         return _lsa_CreateTrustedDomainEx2(p, &c);
1914 }
1915
1916 /***************************************************************************
1917  _lsa_DeleteTrustedDomain
1918  ***************************************************************************/
1919
1920 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1921                                   struct lsa_DeleteTrustedDomain *r)
1922 {
1923         NTSTATUS status;
1924         struct lsa_info *handle;
1925         struct pdb_trusted_domain *td;
1926
1927         /* find the connection policy handle. */
1928         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1929                 return NT_STATUS_INVALID_HANDLE;
1930         }
1931
1932         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1933                 return NT_STATUS_INVALID_HANDLE;
1934         }
1935
1936         if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1937                 return NT_STATUS_ACCESS_DENIED;
1938         }
1939
1940         status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1941         if (!NT_STATUS_IS_OK(status)) {
1942                 return status;
1943         }
1944
1945         if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1946                 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1947                            sid_string_tos(r->in.dom_sid)));
1948                 return NT_STATUS_UNSUCCESSFUL;
1949         }
1950
1951         status = pdb_del_trusted_domain(td->netbios_name);
1952         if (!NT_STATUS_IS_OK(status)) {
1953                 return status;
1954         }
1955
1956         return NT_STATUS_OK;
1957 }
1958
1959 /***************************************************************************
1960  _lsa_CloseTrustedDomainEx
1961  ***************************************************************************/
1962
1963 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1964                                    struct lsa_CloseTrustedDomainEx *r)
1965 {
1966         return NT_STATUS_NOT_IMPLEMENTED;
1967 }
1968
1969 /***************************************************************************
1970  _lsa_QueryTrustedDomainInfo
1971  ***************************************************************************/
1972
1973 static NTSTATUS pdb_trusted_domain_2_info_ex(TALLOC_CTX *mem_ctx,
1974                                       struct pdb_trusted_domain *td,
1975                                       struct lsa_TrustDomainInfoInfoEx *info_ex)
1976 {
1977         if (td->domain_name == NULL ||
1978             td->netbios_name == NULL ||
1979             is_null_sid(&td->security_identifier)) {
1980                 return NT_STATUS_INVALID_PARAMETER;
1981         }
1982
1983         info_ex->domain_name.string = talloc_strdup(mem_ctx, td->domain_name);
1984         info_ex->netbios_name.string = talloc_strdup(mem_ctx, td->netbios_name);
1985         info_ex->sid = dom_sid_dup(mem_ctx, &td->security_identifier);
1986         if (info_ex->domain_name.string == NULL ||
1987             info_ex->netbios_name.string == NULL ||
1988             info_ex->sid == NULL) {
1989                 return NT_STATUS_NO_MEMORY;
1990         }
1991
1992         info_ex->trust_direction = td->trust_direction;
1993         info_ex->trust_type = td->trust_type;
1994         info_ex->trust_attributes = td->trust_attributes;
1995
1996         return NT_STATUS_OK;
1997 }
1998
1999 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
2000                                      struct lsa_QueryTrustedDomainInfo *r)
2001 {
2002         NTSTATUS status;
2003         struct lsa_info *handle;
2004         union lsa_TrustedDomainInfo *info;
2005         struct pdb_trusted_domain *td;
2006         uint32_t acc_required;
2007
2008         /* find the connection policy handle. */
2009         if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
2010                 return NT_STATUS_INVALID_HANDLE;
2011         }
2012
2013         if (handle->type != LSA_HANDLE_TRUST_TYPE) {
2014                 return NT_STATUS_INVALID_HANDLE;
2015         }
2016
2017         switch (r->in.level) {
2018         case LSA_TRUSTED_DOMAIN_INFO_NAME:
2019                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2020                 break;
2021         case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2022                 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
2023                 break;
2024         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2025                 acc_required = LSA_TRUSTED_QUERY_POSIX;
2026                 break;
2027         case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2028                 acc_required = LSA_TRUSTED_QUERY_AUTH;
2029                 break;
2030         case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2031                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2032                 break;
2033         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2034                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2035                 break;
2036         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2037                 acc_required = LSA_TRUSTED_QUERY_AUTH;
2038                 break;
2039         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2040                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2041                                LSA_TRUSTED_QUERY_POSIX |
2042                                LSA_TRUSTED_QUERY_AUTH;
2043                 break;
2044         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2045                 acc_required = LSA_TRUSTED_QUERY_AUTH;
2046                 break;
2047         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2048                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2049                                LSA_TRUSTED_QUERY_POSIX |
2050                                LSA_TRUSTED_QUERY_AUTH;
2051                 break;
2052         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2053                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2054                 break;
2055         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2056                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2057                                LSA_TRUSTED_QUERY_POSIX |
2058                                LSA_TRUSTED_QUERY_AUTH;
2059                 break;
2060         case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2061                 acc_required = LSA_TRUSTED_QUERY_POSIX;
2062                 break;
2063         default:
2064                 return NT_STATUS_INVALID_PARAMETER;
2065         }
2066
2067         if (!(handle->access & acc_required)) {
2068                 return NT_STATUS_ACCESS_DENIED;
2069         }
2070
2071         status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2072         if (!NT_STATUS_IS_OK(status)) {
2073                 return status;
2074         }
2075
2076         info = talloc_zero(p->mem_ctx, union lsa_TrustedDomainInfo);
2077         if (!info) {
2078                 return NT_STATUS_NO_MEMORY;
2079         }
2080
2081         switch (r->in.level) {
2082         case LSA_TRUSTED_DOMAIN_INFO_NAME:
2083                 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2084                 break;
2085         case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2086                 return NT_STATUS_INVALID_PARAMETER;
2087         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2088                 info->posix_offset.posix_offset = *td->trust_posix_offset;
2089                 break;
2090         case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2091                 return NT_STATUS_INVALID_INFO_CLASS;
2092         case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2093                 return NT_STATUS_INVALID_PARAMETER;
2094         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2095                 status = pdb_trusted_domain_2_info_ex(info, td, &info->info_ex);
2096                 if (!NT_STATUS_IS_OK(status)) {
2097                         return status;
2098                 }
2099                 break;
2100         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2101                 return NT_STATUS_INVALID_INFO_CLASS;
2102         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2103                 status = pdb_trusted_domain_2_info_ex(info, td,
2104                                                       &info->full_info.info_ex);
2105                 if (!NT_STATUS_IS_OK(status)) {
2106                         return status;
2107                 }
2108                 info->full_info.posix_offset.posix_offset = *td->trust_posix_offset;
2109                 status = auth_blob_2_auth_info(p->mem_ctx,
2110                                                     td->trust_auth_incoming,
2111                                                     td->trust_auth_outgoing,
2112                                                     &info->full_info.auth_info);
2113                 if (!NT_STATUS_IS_OK(status)) {
2114                         return status;
2115                 }
2116                 break;
2117         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2118                 return NT_STATUS_INVALID_INFO_CLASS;
2119         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2120                 return NT_STATUS_INVALID_INFO_CLASS;
2121         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2122                 return NT_STATUS_INVALID_PARAMETER;
2123         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2124                 info->full_info2_internal.posix_offset.posix_offset = *td->trust_posix_offset;
2125                 status = auth_blob_2_auth_info(p->mem_ctx,
2126                                           td->trust_auth_incoming,
2127                                           td->trust_auth_outgoing,
2128                                           &info->full_info2_internal.auth_info);
2129                 if (!NT_STATUS_IS_OK(status)) {
2130                         return status;
2131                 }
2132                 break;
2133         case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2134                 info->enc_types.enc_types = *td->supported_enc_type;
2135                 break;
2136         default:
2137                 return NT_STATUS_INVALID_PARAMETER;
2138         }
2139
2140         *r->out.info = info;
2141
2142         return NT_STATUS_OK;
2143 }
2144
2145 /***************************************************************************
2146  _lsa_QueryTrustedDomainInfoBySid
2147  ***************************************************************************/
2148
2149 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2150                                           struct lsa_QueryTrustedDomainInfoBySid *r)
2151 {
2152         NTSTATUS status;
2153         struct policy_handle trustdom_handle;
2154         struct lsa_OpenTrustedDomain o;
2155         struct lsa_QueryTrustedDomainInfo q;
2156         struct lsa_Close c;
2157
2158         o.in.handle             = r->in.handle;
2159         o.in.sid                = r->in.dom_sid;
2160         o.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
2161         o.out.trustdom_handle   = &trustdom_handle;
2162
2163         status = _lsa_OpenTrustedDomain(p, &o);
2164         if (!NT_STATUS_IS_OK(status)) {
2165                 return status;
2166         }
2167
2168         q.in.trustdom_handle    = &trustdom_handle;
2169         q.in.level              = r->in.level;
2170         q.out.info              = r->out.info;
2171
2172         status = _lsa_QueryTrustedDomainInfo(p, &q);
2173         if (!NT_STATUS_IS_OK(status)) {
2174                 return status;
2175         }
2176
2177         c.in.handle             = &trustdom_handle;
2178         c.out.handle            = &trustdom_handle;
2179
2180         return _lsa_Close(p, &c);
2181 }
2182
2183 /***************************************************************************
2184  _lsa_QueryTrustedDomainInfoByName
2185  ***************************************************************************/
2186
2187 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2188                                            struct lsa_QueryTrustedDomainInfoByName *r)
2189 {
2190         NTSTATUS status;
2191         struct policy_handle trustdom_handle;
2192         struct lsa_OpenTrustedDomainByName o;
2193         struct lsa_QueryTrustedDomainInfo q;
2194         struct lsa_Close c;
2195
2196         o.in.handle             = r->in.handle;
2197         o.in.name.string        = r->in.trusted_domain->string;
2198         o.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
2199         o.out.trustdom_handle   = &trustdom_handle;
2200
2201         status = _lsa_OpenTrustedDomainByName(p, &o);
2202         if (!NT_STATUS_IS_OK(status)) {
2203                 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2204                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2205                 }
2206                 return status;
2207         }
2208
2209         q.in.trustdom_handle    = &trustdom_handle;
2210         q.in.level              = r->in.level;
2211         q.out.info              = r->out.info;
2212
2213         status = _lsa_QueryTrustedDomainInfo(p, &q);
2214         if (!NT_STATUS_IS_OK(status)) {
2215                 return status;
2216         }
2217
2218         c.in.handle             = &trustdom_handle;
2219         c.out.handle            = &trustdom_handle;
2220
2221         return _lsa_Close(p, &c);
2222 }
2223
2224 /***************************************************************************
2225  _lsa_CreateSecret
2226  ***************************************************************************/
2227
2228 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p,
2229                            struct lsa_CreateSecret *r)
2230 {
2231         NTSTATUS status;
2232         struct lsa_info *handle;
2233         uint32_t acc_granted;
2234         struct security_descriptor *psd;
2235         size_t sd_size;
2236
2237         /* find the connection policy handle. */
2238         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
2239                 return NT_STATUS_INVALID_HANDLE;
2240         }
2241
2242         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2243                 return NT_STATUS_INVALID_HANDLE;
2244         }
2245
2246         /* check if the user has enough rights */
2247
2248         if (!(handle->access & LSA_POLICY_CREATE_SECRET)) {
2249                 return NT_STATUS_ACCESS_DENIED;
2250         }
2251
2252         /* Work out max allowed. */
2253         map_max_allowed_access(p->session_info->security_token,
2254                                p->session_info->unix_token,
2255                                &r->in.access_mask);
2256
2257         /* map the generic bits to the lsa policy ones */
2258         se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
2259
2260         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2261                                     &lsa_secret_mapping,
2262                                     NULL, 0);
2263         if (!NT_STATUS_IS_OK(status)) {
2264                 return status;
2265         }
2266
2267         status = access_check_object(psd, p->session_info->security_token,
2268                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2269                                      r->in.access_mask,
2270                                      &acc_granted, "_lsa_CreateSecret");
2271         if (!NT_STATUS_IS_OK(status)) {
2272                 return status;
2273         }
2274
2275         if (!r->in.name.string) {
2276                 return NT_STATUS_INVALID_PARAMETER;
2277         }
2278
2279         if (strlen(r->in.name.string) > 128) {
2280                 return NT_STATUS_NAME_TOO_LONG;
2281         }
2282
2283         status = pdb_get_secret(p->mem_ctx, r->in.name.string,
2284                                 NULL, NULL, NULL, NULL, NULL);
2285         if (NT_STATUS_IS_OK(status)) {
2286                 return NT_STATUS_OBJECT_NAME_COLLISION;
2287         }
2288
2289         status = pdb_set_secret(r->in.name.string, NULL, NULL, psd);
2290         if (!NT_STATUS_IS_OK(status)) {
2291                 return status;
2292         }
2293
2294         status = create_lsa_policy_handle(p->mem_ctx, p,
2295                                           LSA_HANDLE_SECRET_TYPE,
2296                                           acc_granted,
2297                                           NULL,
2298                                           r->in.name.string,
2299                                           psd,
2300                                           r->out.sec_handle);
2301         if (!NT_STATUS_IS_OK(status)) {
2302                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2303         }
2304
2305         return NT_STATUS_OK;
2306 }
2307
2308 /***************************************************************************
2309  _lsa_SetSecret
2310  ***************************************************************************/
2311
2312 NTSTATUS _lsa_SetSecret(struct pipes_struct *p,
2313                         struct lsa_SetSecret *r)
2314 {
2315         NTSTATUS status;
2316         struct lsa_info *info = NULL;
2317         DATA_BLOB blob_new, blob_old;
2318         DATA_BLOB cleartext_blob_new = data_blob_null;
2319         DATA_BLOB cleartext_blob_old = data_blob_null;
2320         DATA_BLOB *cleartext_blob_new_p = NULL;
2321         DATA_BLOB *cleartext_blob_old_p = NULL;
2322         DATA_BLOB session_key;
2323
2324         if (!find_policy_by_hnd(p, r->in.sec_handle, (void **)(void *)&info)) {
2325                 return NT_STATUS_INVALID_HANDLE;
2326         }
2327
2328         if (info->type != LSA_HANDLE_SECRET_TYPE) {
2329                 return NT_STATUS_INVALID_HANDLE;
2330         }
2331
2332         if (!(info->access & LSA_SECRET_SET_VALUE)) {
2333                 return NT_STATUS_ACCESS_DENIED;
2334         }
2335
2336         status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
2337         if(!NT_STATUS_IS_OK(status)) {
2338                 return status;
2339         }
2340
2341         if (r->in.new_val) {
2342                 blob_new = data_blob_const(r->in.new_val->data,
2343                                            r->in.new_val->length);
2344
2345                 status = sess_decrypt_blob(p->mem_ctx, &blob_new,
2346                                            &session_key,
2347                                            &cleartext_blob_new);
2348                 if (!NT_STATUS_IS_OK(status)) {
2349                         return status;
2350                 }
2351
2352                 cleartext_blob_new_p = &cleartext_blob_new;
2353         }
2354
2355         if (r->in.old_val) {
2356                 blob_old = data_blob_const(r->in.old_val->data,
2357                                            r->in.old_val->length);
2358
2359                 status = sess_decrypt_blob(p->mem_ctx, &blob_old,
2360                                            &session_key,
2361                                            &cleartext_blob_old);
2362                 if (!NT_STATUS_IS_OK(status)) {
2363                         return status;
2364                 }
2365
2366                 cleartext_blob_old_p = &cleartext_blob_old;
2367         }
2368
2369         status = pdb_set_secret(info->name, cleartext_blob_new_p, cleartext_blob_old_p, NULL);
2370         if (!NT_STATUS_IS_OK(status)) {
2371                 return status;
2372         }
2373
2374 #ifdef DEBUG_PASSWORD
2375         DEBUG(10,("_lsa_SetSecret: successfully set new secret\n"));
2376         dump_data(10, cleartext_blob_new.data, cleartext_blob_new.length);
2377         DEBUG(10,("_lsa_SetSecret: successfully set old secret\n"));
2378         dump_data(10, cleartext_blob_old.data, cleartext_blob_old.length);
2379 #endif
2380
2381         return NT_STATUS_OK;
2382 }
2383
2384 /***************************************************************************
2385  _lsa_QuerySecret
2386  ***************************************************************************/
2387
2388 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
2389                           struct lsa_QuerySecret *r)
2390 {
2391         struct lsa_info *info = NULL;
2392         DATA_BLOB blob_new, blob_old;
2393         DATA_BLOB blob_new_crypt, blob_old_crypt;
2394         DATA_BLOB session_key;
2395         NTTIME nttime_new, nttime_old;
2396         NTSTATUS status;
2397
2398         if (!find_policy_by_hnd(p, r->in.sec_handle, (void **)(void *)&info)) {
2399                 return NT_STATUS_INVALID_HANDLE;
2400         }
2401
2402         if (info->type != LSA_HANDLE_SECRET_TYPE) {
2403                 return NT_STATUS_INVALID_HANDLE;
2404         }
2405
2406         if (!(info->access & LSA_SECRET_QUERY_VALUE)) {
2407                 return NT_STATUS_ACCESS_DENIED;
2408         }
2409
2410         status = pdb_get_secret(p->mem_ctx, info->name,
2411                                 &blob_new, &nttime_new,
2412                                 &blob_old, &nttime_old,
2413                                 NULL);
2414         if (!NT_STATUS_IS_OK(status)) {
2415                 return status;
2416         }
2417
2418         status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
2419         if(!NT_STATUS_IS_OK(status)) {
2420                 return status;
2421         }
2422
2423         if (r->in.new_val) {
2424                 if (blob_new.length) {
2425                         if (!r->out.new_val->buf) {
2426                                 r->out.new_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2427                         }
2428                         if (!r->out.new_val->buf) {
2429                                 return NT_STATUS_NO_MEMORY;
2430                         }
2431
2432                         blob_new_crypt = sess_encrypt_blob(p->mem_ctx, &blob_new,
2433                                                            &session_key);
2434                         if (!blob_new_crypt.length) {
2435                                 return NT_STATUS_NO_MEMORY;
2436                         }
2437
2438                         r->out.new_val->buf->data       = blob_new_crypt.data;
2439                         r->out.new_val->buf->length     = blob_new_crypt.length;
2440                         r->out.new_val->buf->size       = blob_new_crypt.length;
2441                 }
2442         }
2443
2444         if (r->in.old_val) {
2445                 if (blob_old.length) {
2446                         if (!r->out.old_val->buf) {
2447                                 r->out.old_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2448                         }
2449                         if (!r->out.old_val->buf) {
2450                                 return NT_STATUS_NO_MEMORY;
2451                         }
2452
2453                         blob_old_crypt = sess_encrypt_blob(p->mem_ctx, &blob_old,
2454                                                            &session_key);
2455                         if (!blob_old_crypt.length) {
2456                                 return NT_STATUS_NO_MEMORY;
2457                         }
2458
2459                         r->out.old_val->buf->data       = blob_old_crypt.data;
2460                         r->out.old_val->buf->length     = blob_old_crypt.length;
2461                         r->out.old_val->buf->size       = blob_old_crypt.length;
2462                 }
2463         }
2464
2465         if (r->out.new_mtime) {
2466                 *r->out.new_mtime = nttime_new;
2467         }
2468
2469         if (r->out.old_mtime) {
2470                 *r->out.old_mtime = nttime_old;
2471         }
2472
2473         return NT_STATUS_OK;
2474 }
2475
2476 /***************************************************************************
2477  _lsa_DeleteObject
2478  ***************************************************************************/
2479
2480 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2481                            struct lsa_DeleteObject *r)
2482 {
2483         NTSTATUS status;
2484         struct lsa_info *info = NULL;
2485
2486         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2487                 return NT_STATUS_INVALID_HANDLE;
2488         }
2489
2490         if (!(info->access & SEC_STD_DELETE)) {
2491                 return NT_STATUS_ACCESS_DENIED;
2492         }
2493
2494         switch (info->type) {
2495         case LSA_HANDLE_ACCOUNT_TYPE:
2496                 status = privilege_delete_account(&info->sid);
2497                 if (!NT_STATUS_IS_OK(status)) {
2498                         DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2499                                 nt_errstr(status)));
2500                         return status;
2501                 }
2502                 break;
2503         case LSA_HANDLE_TRUST_TYPE:
2504                 if (!pdb_del_trusteddom_pw(info->name)) {
2505                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2506                 }
2507                 status = NT_STATUS_OK;
2508                 break;
2509         case LSA_HANDLE_SECRET_TYPE:
2510                 status = pdb_delete_secret(info->name);
2511                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2512                         return NT_STATUS_INVALID_HANDLE;
2513                 }
2514                 break;
2515         default:
2516                 return NT_STATUS_INVALID_HANDLE;
2517         }
2518
2519         close_policy_hnd(p, r->in.handle);
2520         ZERO_STRUCTP(r->out.handle);
2521
2522         return status;
2523 }
2524
2525 /***************************************************************************
2526  _lsa_EnumPrivs
2527  ***************************************************************************/
2528
2529 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2530                         struct lsa_EnumPrivs *r)
2531 {
2532         struct lsa_info *handle;
2533         uint32 i;
2534         uint32 enum_context = *r->in.resume_handle;
2535         int num_privs = num_privileges_in_short_list();
2536         struct lsa_PrivEntry *entries = NULL;
2537
2538         /* remember that the enum_context starts at 0 and not 1 */
2539
2540         if ( enum_context >= num_privs )
2541                 return NT_STATUS_NO_MORE_ENTRIES;
2542
2543         DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2544                 enum_context, num_privs));
2545
2546         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2547                 return NT_STATUS_INVALID_HANDLE;
2548
2549         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2550                 return NT_STATUS_INVALID_HANDLE;
2551         }
2552
2553         /* check if the user has enough rights
2554            I don't know if it's the right one. not documented.  */
2555
2556         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2557                 return NT_STATUS_ACCESS_DENIED;
2558
2559         if (num_privs) {
2560                 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2561                 if (!entries) {
2562                         return NT_STATUS_NO_MEMORY;
2563                 }
2564         } else {
2565                 entries = NULL;
2566         }
2567
2568         for (i = 0; i < num_privs; i++) {
2569                 if( i < enum_context) {
2570
2571                         init_lsa_StringLarge(&entries[i].name, NULL);
2572
2573                         entries[i].luid.low = 0;
2574                         entries[i].luid.high = 0;
2575                 } else {
2576
2577                         init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2578
2579                         entries[i].luid.low = sec_privilege_from_index(i);
2580                         entries[i].luid.high = 0;
2581                 }
2582         }
2583
2584         enum_context = num_privs;
2585
2586         *r->out.resume_handle = enum_context;
2587         r->out.privs->count = num_privs;
2588         r->out.privs->privs = entries;
2589
2590         return NT_STATUS_OK;
2591 }
2592
2593 /***************************************************************************
2594  _lsa_LookupPrivDisplayName
2595  ***************************************************************************/
2596
2597 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2598                                     struct lsa_LookupPrivDisplayName *r)
2599 {
2600         struct lsa_info *handle;
2601         const char *description;
2602         struct lsa_StringLarge *lsa_name;
2603
2604         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2605                 return NT_STATUS_INVALID_HANDLE;
2606
2607         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2608                 return NT_STATUS_INVALID_HANDLE;
2609         }
2610
2611         /* check if the user has enough rights */
2612
2613         /*
2614          * I don't know if it's the right one. not documented.
2615          */
2616         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2617                 return NT_STATUS_ACCESS_DENIED;
2618
2619         DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2620
2621         description = get_privilege_dispname(r->in.name->string);
2622         if (!description) {
2623                 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2624                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2625         }
2626
2627         DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2628
2629         lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2630         if (!lsa_name) {
2631                 return NT_STATUS_NO_MEMORY;
2632         }
2633
2634         init_lsa_StringLarge(lsa_name, description);
2635
2636         *r->out.returned_language_id = r->in.language_id;
2637         *r->out.disp_name = lsa_name;
2638
2639         return NT_STATUS_OK;
2640 }
2641
2642 /***************************************************************************
2643  _lsa_EnumAccounts
2644  ***************************************************************************/
2645
2646 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2647                            struct lsa_EnumAccounts *r)
2648 {
2649         struct lsa_info *handle;
2650         struct dom_sid *sid_list;
2651         int i, j, num_entries;
2652         NTSTATUS status;
2653         struct lsa_SidPtr *sids = NULL;
2654
2655         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2656                 return NT_STATUS_INVALID_HANDLE;
2657
2658         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2659                 return NT_STATUS_INVALID_HANDLE;
2660         }
2661
2662         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2663                 return NT_STATUS_ACCESS_DENIED;
2664
2665         sid_list = NULL;
2666         num_entries = 0;
2667
2668         /* The only way we can currently find out all the SIDs that have been
2669            privileged is to scan all privileges */
2670
2671         status = privilege_enumerate_accounts(&sid_list, &num_entries);
2672         if (!NT_STATUS_IS_OK(status)) {
2673                 return status;
2674         }
2675
2676         if (*r->in.resume_handle >= num_entries) {
2677                 return NT_STATUS_NO_MORE_ENTRIES;
2678         }
2679
2680         if (num_entries - *r->in.resume_handle) {
2681                 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2682                                          num_entries - *r->in.resume_handle);
2683                 if (!sids) {
2684                         talloc_free(sid_list);
2685                         return NT_STATUS_NO_MEMORY;
2686                 }
2687
2688                 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2689                         sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2690                         if (!sids[j].sid) {
2691                                 talloc_free(sid_list);
2692                                 return NT_STATUS_NO_MEMORY;
2693                         }
2694                 }
2695         }
2696
2697         talloc_free(sid_list);
2698
2699         *r->out.resume_handle = num_entries;
2700         r->out.sids->num_sids = num_entries;
2701         r->out.sids->sids = sids;
2702
2703         return NT_STATUS_OK;
2704 }
2705
2706 /***************************************************************************
2707  _lsa_GetUserName
2708  ***************************************************************************/
2709
2710 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2711                           struct lsa_GetUserName *r)
2712 {
2713         const char *username, *domname;
2714         struct lsa_String *account_name = NULL;
2715         struct lsa_String *authority_name = NULL;
2716
2717         if (p->transport != NCACN_NP && p->transport != NCALRPC) {
2718                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
2719                 return NT_STATUS_ACCESS_DENIED;
2720         }
2721
2722         if (r->in.account_name &&
2723            *r->in.account_name) {
2724                 return NT_STATUS_INVALID_PARAMETER;
2725         }
2726
2727         if (r->in.authority_name &&
2728            *r->in.authority_name) {
2729                 return NT_STATUS_INVALID_PARAMETER;
2730         }
2731
2732         if (security_session_user_level(p->session_info, NULL) < SECURITY_USER) {
2733                 /*
2734                  * I'm 99% sure this is not the right place to do this,
2735                  * global_sid_Anonymous should probably be put into the token
2736                  * instead of the guest id -- vl
2737                  */
2738                 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2739                                 &domname, &username, NULL)) {
2740                         return NT_STATUS_NO_MEMORY;
2741                 }
2742         } else {
2743                 username = p->session_info->unix_info->sanitized_username;
2744                 domname = p->session_info->info->domain_name;
2745         }
2746
2747         account_name = talloc(p->mem_ctx, struct lsa_String);
2748         if (!account_name) {
2749                 return NT_STATUS_NO_MEMORY;
2750         }
2751         init_lsa_String(account_name, username);
2752
2753         if (r->out.authority_name) {
2754                 authority_name = talloc(p->mem_ctx, struct lsa_String);
2755                 if (!authority_name) {
2756                         return NT_STATUS_NO_MEMORY;
2757                 }
2758                 init_lsa_String(authority_name, domname);
2759         }
2760
2761         *r->out.account_name = account_name;
2762         if (r->out.authority_name) {
2763                 *r->out.authority_name = authority_name;
2764         }
2765
2766         return NT_STATUS_OK;
2767 }
2768
2769 /***************************************************************************
2770  _lsa_CreateAccount
2771  ***************************************************************************/
2772
2773 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2774                             struct lsa_CreateAccount *r)
2775 {
2776         NTSTATUS status;
2777         struct lsa_info *handle;
2778         uint32_t acc_granted;
2779         struct security_descriptor *psd;
2780         size_t sd_size;
2781         uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
2782                         ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
2783                         LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2784                         SEC_STD_DELETE));
2785
2786         /* find the connection policy handle. */
2787         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2788                 return NT_STATUS_INVALID_HANDLE;
2789
2790         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2791                 return NT_STATUS_INVALID_HANDLE;
2792         }
2793
2794         /* check if the user has enough rights */
2795
2796         if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2797                 return NT_STATUS_ACCESS_DENIED;
2798         }
2799
2800         /* Work out max allowed. */
2801         map_max_allowed_access(p->session_info->security_token,
2802                                p->session_info->unix_token,
2803                                &r->in.access_mask);
2804
2805         /* map the generic bits to the lsa policy ones */
2806         se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2807
2808         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2809                                     &lsa_account_mapping,
2810                                     r->in.sid, owner_access);
2811         if (!NT_STATUS_IS_OK(status)) {
2812                 return status;
2813         }
2814
2815         status = access_check_object(psd, p->session_info->security_token,
2816                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2817                                      &acc_granted, "_lsa_CreateAccount");
2818         if (!NT_STATUS_IS_OK(status)) {
2819                 return status;
2820         }
2821
2822         if ( is_privileged_sid( r->in.sid ) )
2823                 return NT_STATUS_OBJECT_NAME_COLLISION;
2824
2825         status = create_lsa_policy_handle(p->mem_ctx, p,
2826                                           LSA_HANDLE_ACCOUNT_TYPE,
2827                                           acc_granted,
2828                                           r->in.sid,
2829                                           NULL,
2830                                           psd,
2831                                           r->out.acct_handle);
2832         if (!NT_STATUS_IS_OK(status)) {
2833                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2834         }
2835
2836         return privilege_create_account(r->in.sid);
2837 }
2838
2839 /***************************************************************************
2840  _lsa_OpenAccount
2841  ***************************************************************************/
2842
2843 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2844                           struct lsa_OpenAccount *r)
2845 {
2846         struct lsa_info *handle;
2847         struct security_descriptor *psd = NULL;
2848         size_t sd_size;
2849         uint32_t des_access = r->in.access_mask;
2850         uint32_t acc_granted;
2851         uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
2852                         ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
2853                         LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2854                         SEC_STD_DELETE));
2855         NTSTATUS status;
2856
2857         /* find the connection policy handle. */
2858         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2859                 return NT_STATUS_INVALID_HANDLE;
2860
2861         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2862                 return NT_STATUS_INVALID_HANDLE;
2863         }
2864
2865         /* des_access is for the account here, not the policy
2866          * handle - so don't check against policy handle. */
2867
2868         /* Work out max allowed. */
2869         map_max_allowed_access(p->session_info->security_token,
2870                                p->session_info->unix_token,
2871                                &des_access);
2872
2873         /* map the generic bits to the lsa account ones */
2874         se_map_generic(&des_access, &lsa_account_mapping);
2875
2876         /* get the generic lsa account SD until we store it */
2877         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2878                                 &lsa_account_mapping,
2879                                 r->in.sid, owner_access);
2880         if (!NT_STATUS_IS_OK(status)) {
2881                 return status;
2882         }
2883
2884         status = access_check_object(psd, p->session_info->security_token,
2885                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2886                                      &acc_granted, "_lsa_OpenAccount" );
2887         if (!NT_STATUS_IS_OK(status)) {
2888                 return status;
2889         }
2890
2891         /* TODO: Fis the parsing routine before reenabling this check! */
2892         #if 0
2893         if (!lookup_sid(&handle->sid, dom_name, name, &type))
2894                 return NT_STATUS_ACCESS_DENIED;
2895         #endif
2896
2897         status = create_lsa_policy_handle(p->mem_ctx, p,
2898                                           LSA_HANDLE_ACCOUNT_TYPE,
2899                                           acc_granted,
2900                                           r->in.sid,
2901                                           NULL,
2902                                           psd,
2903                                           r->out.acct_handle);
2904         if (!NT_STATUS_IS_OK(status)) {
2905                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2906         }
2907
2908         return NT_STATUS_OK;
2909 }
2910
2911 /***************************************************************************
2912  _lsa_EnumPrivsAccount
2913  For a given SID, enumerate all the privilege this account has.
2914  ***************************************************************************/
2915
2916 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2917                                struct lsa_EnumPrivsAccount *r)
2918 {
2919         NTSTATUS status = NT_STATUS_OK;
2920         struct lsa_info *info=NULL;
2921         PRIVILEGE_SET *privileges;
2922         struct lsa_PrivilegeSet *priv_set = NULL;
2923
2924         /* find the connection policy handle. */
2925         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2926                 return NT_STATUS_INVALID_HANDLE;
2927
2928         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2929                 return NT_STATUS_INVALID_HANDLE;
2930         }
2931
2932         if (!(info->access & LSA_ACCOUNT_VIEW))
2933                 return NT_STATUS_ACCESS_DENIED;
2934
2935         status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2936         if (!NT_STATUS_IS_OK(status)) {
2937                 return status;
2938         }
2939
2940         *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2941         if (!priv_set) {
2942                 return NT_STATUS_NO_MEMORY;
2943         }
2944
2945         DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2946                   sid_string_dbg(&info->sid),
2947                   privileges->count));
2948
2949         priv_set->count = privileges->count;
2950         priv_set->unknown = 0;
2951         priv_set->set = talloc_move(priv_set, &privileges->set);
2952
2953         return status;
2954 }
2955
2956 /***************************************************************************
2957  _lsa_GetSystemAccessAccount
2958  ***************************************************************************/
2959
2960 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2961                                      struct lsa_GetSystemAccessAccount *r)
2962 {
2963         NTSTATUS status;
2964         struct lsa_info *info = NULL;
2965         struct lsa_EnumPrivsAccount e;
2966         struct lsa_PrivilegeSet *privset;
2967
2968         /* find the connection policy handle. */
2969
2970         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2971                 return NT_STATUS_INVALID_HANDLE;
2972
2973         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2974                 return NT_STATUS_INVALID_HANDLE;
2975         }
2976
2977         if (!(info->access & LSA_ACCOUNT_VIEW))
2978                 return NT_STATUS_ACCESS_DENIED;
2979
2980         privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2981         if (!privset) {
2982                 return NT_STATUS_NO_MEMORY;
2983         }
2984
2985         e.in.handle = r->in.handle;
2986         e.out.privs = &privset;
2987
2988         status = _lsa_EnumPrivsAccount(p, &e);
2989         if (!NT_STATUS_IS_OK(status)) {
2990                 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2991                         "failed to call _lsa_EnumPrivsAccount(): %s\n",
2992                         nt_errstr(status)));
2993                 return status;
2994         }
2995
2996         /* Samba4 would iterate over the privset to merge the policy mode bits,
2997          * not sure samba3 can do the same here, so just return what we did in
2998          * the past - gd */
2999
3000         /*
3001           0x01 -> Log on locally
3002           0x02 -> Access this computer from network
3003           0x04 -> Log on as a batch job
3004           0x10 -> Log on as a service
3005
3006           they can be ORed together
3007         */
3008
3009         *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
3010                               LSA_POLICY_MODE_NETWORK;
3011
3012         return NT_STATUS_OK;
3013 }
3014
3015 /***************************************************************************
3016   update the systemaccount information
3017  ***************************************************************************/
3018
3019 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
3020                                      struct lsa_SetSystemAccessAccount *r)
3021 {
3022         struct lsa_info *info=NULL;
3023         NTSTATUS status;
3024         GROUP_MAP *map;
3025
3026         /* find the connection policy handle. */
3027         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3028                 return NT_STATUS_INVALID_HANDLE;
3029
3030         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3031                 return NT_STATUS_INVALID_HANDLE;
3032         }
3033
3034         if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
3035                 return NT_STATUS_ACCESS_DENIED;
3036         }
3037
3038         map = talloc_zero(p->mem_ctx, GROUP_MAP);
3039         if (!map) {
3040                 return NT_STATUS_NO_MEMORY;
3041         }
3042
3043         if (!pdb_getgrsid(map, info->sid)) {
3044                 TALLOC_FREE(map);
3045                 return NT_STATUS_NO_SUCH_GROUP;
3046         }
3047
3048         status = pdb_update_group_mapping_entry(map);
3049         TALLOC_FREE(map);
3050         return status;
3051 }
3052
3053 /***************************************************************************
3054  _lsa_AddPrivilegesToAccount
3055  For a given SID, add some privileges.
3056  ***************************************************************************/
3057
3058 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
3059                                      struct lsa_AddPrivilegesToAccount *r)
3060 {
3061         struct lsa_info *info = NULL;
3062         struct lsa_PrivilegeSet *set = NULL;
3063
3064         /* find the connection policy handle. */
3065         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3066                 return NT_STATUS_INVALID_HANDLE;
3067
3068         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3069                 return NT_STATUS_INVALID_HANDLE;
3070         }
3071
3072         if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3073                 return NT_STATUS_ACCESS_DENIED;
3074         }
3075
3076         set = r->in.privs;
3077
3078         if ( !grant_privilege_set( &info->sid, set ) ) {
3079                 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
3080                          sid_string_dbg(&info->sid) ));
3081                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3082         }
3083
3084         return NT_STATUS_OK;
3085 }
3086
3087 /***************************************************************************
3088  _lsa_RemovePrivilegesFromAccount
3089  For a given SID, remove some privileges.
3090  ***************************************************************************/
3091
3092 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
3093                                           struct lsa_RemovePrivilegesFromAccount *r)
3094 {
3095         struct lsa_info *info = NULL;
3096         struct lsa_PrivilegeSet *set = NULL;
3097
3098         /* find the connection policy handle. */
3099         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3100                 return NT_STATUS_INVALID_HANDLE;
3101
3102         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3103                 return NT_STATUS_INVALID_HANDLE;
3104         }
3105
3106         if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3107                 return NT_STATUS_ACCESS_DENIED;
3108         }
3109
3110         set = r->in.privs;
3111
3112         if ( !revoke_privilege_set( &info->sid, set) ) {
3113                 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
3114                          sid_string_dbg(&info->sid) ));
3115                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3116         }
3117
3118         return NT_STATUS_OK;
3119 }
3120
3121 /***************************************************************************
3122  _lsa_LookupPrivName
3123  ***************************************************************************/
3124
3125 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
3126                              struct lsa_LookupPrivName *r)
3127 {
3128         struct lsa_info *info = NULL;
3129         const char *name;
3130         struct lsa_StringLarge *lsa_name;
3131
3132         /* find the connection policy handle. */
3133         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3134                 return NT_STATUS_INVALID_HANDLE;
3135         }
3136
3137         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3138                 return NT_STATUS_INVALID_HANDLE;
3139         }
3140
3141         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
3142                 return NT_STATUS_ACCESS_DENIED;
3143         }
3144
3145         if (r->in.luid->high != 0) {
3146                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3147         }
3148
3149         name = sec_privilege_name(r->in.luid->low);
3150         if (!name) {
3151                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3152         }
3153
3154         lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
3155         if (!lsa_name) {
3156                 return NT_STATUS_NO_MEMORY;
3157         }
3158
3159         lsa_name->string = talloc_strdup(lsa_name, name);
3160         if (!lsa_name->string) {
3161                 TALLOC_FREE(lsa_name);
3162                 return NT_STATUS_NO_MEMORY;
3163         }
3164
3165         *r->out.name = lsa_name;
3166
3167         return NT_STATUS_OK;
3168 }
3169
3170 /***************************************************************************
3171  _lsa_QuerySecurity
3172  ***************************************************************************/
3173
3174 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
3175                             struct lsa_QuerySecurity *r)
3176 {
3177         struct lsa_info *handle=NULL;
3178         struct security_descriptor *psd = NULL;
3179         size_t sd_size = 0;
3180         NTSTATUS status;
3181
3182         /* find the connection policy handle. */
3183         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
3184                 return NT_STATUS_INVALID_HANDLE;
3185
3186         switch (handle->type) {
3187         case LSA_HANDLE_POLICY_TYPE:
3188         case LSA_HANDLE_ACCOUNT_TYPE:
3189         case LSA_HANDLE_TRUST_TYPE:
3190         case LSA_HANDLE_SECRET_TYPE:
3191                 psd = handle->sd;
3192                 sd_size = ndr_size_security_descriptor(psd, 0);
3193                 status = NT_STATUS_OK;
3194                 break;
3195         default:
3196                 status = NT_STATUS_INVALID_HANDLE;
3197                 break;
3198         }
3199
3200         if (!NT_STATUS_IS_OK(status)) {
3201                 return status;
3202         }
3203
3204         *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
3205         if (!*r->out.sdbuf) {
3206                 return NT_STATUS_NO_MEMORY;
3207         }
3208
3209         return status;
3210 }
3211
3212 /***************************************************************************
3213  _lsa_AddAccountRights
3214  ***************************************************************************/
3215
3216 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
3217                                struct lsa_AddAccountRights *r)
3218 {
3219         struct lsa_info *info = NULL;
3220         int i = 0;
3221         uint32_t acc_granted = 0;
3222         struct security_descriptor *psd = NULL;
3223         size_t sd_size;
3224         struct dom_sid sid;
3225         NTSTATUS status;
3226
3227         /* find the connection policy handle. */
3228         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3229                 return NT_STATUS_INVALID_HANDLE;
3230
3231         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3232                 return NT_STATUS_INVALID_HANDLE;
3233         }
3234
3235         /* get the generic lsa account SD for this SID until we store it */
3236         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3237                                 &lsa_account_mapping,
3238                                 NULL, 0);
3239         if (!NT_STATUS_IS_OK(status)) {
3240                 return status;
3241         }
3242
3243         /*
3244          * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3245          * on the policy handle. If it does, ask for
3246          * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3247          * on the account sid. We don't check here so just use the latter. JRA.
3248          */
3249
3250         status = access_check_object(psd, p->session_info->security_token,
3251                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3252                                      LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3253                                      &acc_granted, "_lsa_AddAccountRights" );
3254         if (!NT_STATUS_IS_OK(status)) {
3255                 return status;
3256         }
3257
3258         /* according to an NT4 PDC, you can add privileges to SIDs even without
3259            call_lsa_create_account() first.  And you can use any arbitrary SID. */
3260
3261         sid_copy( &sid, r->in.sid );
3262
3263         for ( i=0; i < r->in.rights->count; i++ ) {
3264
3265                 const char *privname = r->in.rights->names[i].string;
3266
3267                 /* only try to add non-null strings */
3268
3269                 if ( !privname )
3270                         continue;
3271
3272                 if ( !grant_privilege_by_name( &sid, privname ) ) {
3273                         DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3274                                 privname ));
3275                         return NT_STATUS_NO_SUCH_PRIVILEGE;
3276                 }
3277         }
3278
3279         return NT_STATUS_OK;
3280 }
3281
3282 /***************************************************************************
3283  _lsa_RemoveAccountRights
3284  ***************************************************************************/
3285
3286 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
3287                                   struct lsa_RemoveAccountRights *r)
3288 {
3289         struct lsa_info *info = NULL;
3290         int i = 0;
3291         struct security_descriptor *psd = NULL;
3292         size_t sd_size;
3293         struct dom_sid sid;
3294         const char *privname = NULL;
3295         uint32_t acc_granted = 0;
3296         NTSTATUS status;
3297
3298         /* find the connection policy handle. */
3299         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3300                 return NT_STATUS_INVALID_HANDLE;
3301
3302         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3303                 return NT_STATUS_INVALID_HANDLE;
3304         }
3305
3306         /* get the generic lsa account SD for this SID until we store it */
3307         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3308                                 &lsa_account_mapping,
3309                                 NULL, 0);
3310         if (!NT_STATUS_IS_OK(status)) {
3311                 return status;
3312         }
3313
3314         /*
3315          * From the MS DOCs. We need
3316          * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3317          * and DELETE on the account sid.
3318          */
3319
3320         status = access_check_object(psd, p->session_info->security_token,
3321                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3322                                      LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3323                                      LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
3324                                      &acc_granted, "_lsa_RemoveAccountRights");
3325         if (!NT_STATUS_IS_OK(status)) {
3326                 return status;
3327         }
3328
3329         sid_copy( &sid, r->in.sid );
3330
3331         if ( r->in.remove_all ) {
3332                 if ( !revoke_all_privileges( &sid ) )
3333                         return NT_STATUS_ACCESS_DENIED;
3334
3335                 return NT_STATUS_OK;
3336         }
3337
3338         for ( i=0; i < r->in.rights->count; i++ ) {
3339
3340                 privname = r->in.rights->names[i].string;
3341
3342                 /* only try to add non-null strings */
3343
3344                 if ( !privname )
3345                         continue;
3346
3347                 if ( !revoke_privilege_by_name( &sid, privname ) ) {
3348                         DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3349                                 privname ));
3350                         return NT_STATUS_NO_SUCH_PRIVILEGE;
3351                 }
3352         }
3353
3354         return NT_STATUS_OK;
3355 }
3356
3357 /*******************************************************************
3358 ********************************************************************/
3359
3360 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3361                                    struct lsa_RightSet *r,
3362                                    PRIVILEGE_SET *privileges)
3363 {
3364         uint32 i;
3365         const char *privname;
3366         const char **privname_array = NULL;
3367         int num_priv = 0;
3368
3369         for (i=0; i<privileges->count; i++) {
3370                 if (privileges->set[i].luid.high) {
3371                         continue;
3372                 }
3373                 privname = sec_privilege_name(privileges->set[i].luid.low);
3374                 if (privname) {
3375                         if (!add_string_to_array(mem_ctx, privname,
3376                                                  &privname_array, &num_priv)) {
3377                                 return NT_STATUS_NO_MEMORY;
3378                         }
3379                 }
3380         }
3381
3382         if (num_priv) {
3383
3384                 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3385                                              num_priv);
3386                 if (!r->names) {
3387                         return NT_STATUS_NO_MEMORY;
3388                 }
3389
3390                 for (i=0; i<num_priv; i++) {
3391                         init_lsa_StringLarge(&r->names[i], privname_array[i]);
3392                 }
3393
3394                 r->count = num_priv;
3395         }
3396
3397         return NT_STATUS_OK;
3398 }
3399
3400 /***************************************************************************
3401  _lsa_EnumAccountRights
3402  ***************************************************************************/
3403
3404 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3405                                 struct lsa_EnumAccountRights *r)
3406 {
3407         NTSTATUS status;
3408         struct lsa_info *info = NULL;
3409         PRIVILEGE_SET *privileges;
3410
3411         /* find the connection policy handle. */
3412
3413         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3414                 return NT_STATUS_INVALID_HANDLE;
3415
3416         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3417                 return NT_STATUS_INVALID_HANDLE;
3418         }
3419
3420         if (!(info->access & LSA_ACCOUNT_VIEW)) {
3421                 return NT_STATUS_ACCESS_DENIED;
3422         }
3423
3424         /* according to an NT4 PDC, you can add privileges to SIDs even without
3425            call_lsa_create_account() first.  And you can use any arbitrary SID. */
3426
3427         /* according to MS-LSAD 3.1.4.5.10 it is required to return
3428          * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3429          * the lsa database */
3430
3431         status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3432         if (!NT_STATUS_IS_OK(status)) {
3433                 return status;
3434         }
3435
3436         DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3437                   sid_string_dbg(r->in.sid), privileges->count));
3438
3439         status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3440
3441         return status;
3442 }
3443
3444 /***************************************************************************
3445  _lsa_LookupPrivValue
3446  ***************************************************************************/
3447
3448 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3449                               struct lsa_LookupPrivValue *r)
3450 {
3451         struct lsa_info *info = NULL;
3452         const char *name = NULL;
3453
3454         /* find the connection policy handle. */
3455
3456         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3457                 return NT_STATUS_INVALID_HANDLE;
3458
3459         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3460                 return NT_STATUS_INVALID_HANDLE;
3461         }
3462
3463         if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3464                 return NT_STATUS_ACCESS_DENIED;
3465
3466         name = r->in.name->string;
3467
3468         DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3469
3470         r->out.luid->low = sec_privilege_id(name);
3471         r->out.luid->high = 0;
3472         if (r->out.luid->low == SEC_PRIV_INVALID) {
3473                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3474         }
3475         return NT_STATUS_OK;
3476 }
3477
3478 /***************************************************************************
3479  _lsa_EnumAccountsWithUserRight
3480  ***************************************************************************/
3481
3482 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3483                                         struct lsa_EnumAccountsWithUserRight *r)
3484 {
3485         NTSTATUS status;
3486         struct lsa_info *info = NULL;
3487         struct dom_sid *sids = NULL;
3488         int num_sids = 0;
3489         uint32_t i;
3490         enum sec_privilege privilege;
3491
3492         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3493                 return NT_STATUS_INVALID_HANDLE;
3494         }
3495
3496         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3497                 return NT_STATUS_INVALID_HANDLE;
3498         }
3499
3500         if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3501                 return NT_STATUS_ACCESS_DENIED;
3502         }
3503
3504         if (!r->in.name || !r->in.name->string) {
3505                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3506         }
3507
3508         privilege = sec_privilege_id(r->in.name->string);
3509         if (privilege == SEC_PRIV_INVALID) {
3510                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3511         }
3512
3513         status = privilege_enum_sids(privilege, p->mem_ctx,
3514                                      &sids, &num_sids);
3515         if (!NT_STATUS_IS_OK(status)) {
3516                 return status;
3517         }
3518
3519         r->out.sids->num_sids = num_sids;
3520         r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3521                                          r->out.sids->num_sids);
3522
3523         for (i=0; i < r->out.sids->num_sids; i++) {
3524                 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3525                                                           &sids[i]);
3526                 if (!r->out.sids->sids[i].sid) {
3527                         TALLOC_FREE(r->out.sids->sids);
3528                         r->out.sids->num_sids = 0;
3529                         return NT_STATUS_NO_MEMORY;
3530                 }
3531         }
3532
3533         return NT_STATUS_OK;
3534 }
3535
3536 /***************************************************************************
3537  _lsa_Delete
3538  ***************************************************************************/
3539
3540 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3541                      struct lsa_Delete *r)
3542 {
3543         return NT_STATUS_NOT_SUPPORTED;
3544 }
3545
3546 static NTSTATUS info_ex_2_pdb_trusted_domain(
3547                                       struct lsa_TrustDomainInfoInfoEx *info_ex,
3548                                       struct pdb_trusted_domain *td)
3549 {
3550         if (info_ex->domain_name.string == NULL ||
3551             info_ex->netbios_name.string == NULL ||
3552             info_ex->sid == NULL) {
3553                 return NT_STATUS_INVALID_PARAMETER;
3554         }
3555
3556         td->domain_name = talloc_strdup(td, info_ex->domain_name.string);
3557         td->netbios_name = talloc_strdup(td, info_ex->netbios_name.string);
3558         sid_copy(&td->security_identifier, info_ex->sid);
3559         if (td->domain_name == NULL ||
3560             td->netbios_name == NULL ||
3561             is_null_sid(&td->security_identifier)) {
3562                 return NT_STATUS_NO_MEMORY;
3563         }
3564         td->trust_direction = info_ex->trust_direction;
3565         td->trust_type = info_ex->trust_type;
3566         td->trust_attributes = info_ex->trust_attributes;
3567
3568         return NT_STATUS_OK;
3569 }
3570
3571 static NTSTATUS setInfoTrustedDomain_base(struct pipes_struct *p,
3572                                           TALLOC_CTX *mem_ctx,
3573                                           struct lsa_info *policy,
3574                                           enum lsa_TrustDomInfoEnum level,
3575                                           union lsa_TrustedDomainInfo *info)
3576 {
3577         struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
3578         DATA_BLOB auth_blob;
3579         struct trustDomainPasswords auth_struct;
3580         NTSTATUS nt_status;
3581
3582         struct pdb_trusted_domain *td;
3583         struct pdb_trusted_domain *orig_td;
3584
3585         td = talloc_zero(mem_ctx, struct pdb_trusted_domain);
3586         if (td == NULL) {
3587                 return NT_STATUS_NO_MEMORY;
3588         }
3589
3590         switch (level) {
3591         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
3592                 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3593                         return NT_STATUS_ACCESS_DENIED;
3594                 }
3595                 td->trust_posix_offset = &info->posix_offset.posix_offset;
3596                 break;
3597         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
3598                 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3599                         return NT_STATUS_ACCESS_DENIED;
3600                 }
3601                 nt_status = info_ex_2_pdb_trusted_domain(&info->info_ex, td);
3602                 if (!NT_STATUS_IS_OK(nt_status)) {
3603                         return nt_status;
3604                 }
3605                 break;
3606         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
3607                 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3608                         return NT_STATUS_ACCESS_DENIED;
3609                 }
3610                 nt_status = auth_info_2_auth_blob(td, &info->auth_info,
3611                                                   &td->trust_auth_incoming,
3612                                                   &td->trust_auth_outgoing);
3613                 if (!NT_STATUS_IS_OK(nt_status)) {
3614                         return nt_status;
3615                 }
3616                 break;
3617         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
3618                 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3619                         return NT_STATUS_ACCESS_DENIED;
3620                 }
3621                 td->trust_posix_offset = &info->full_info.posix_offset.posix_offset;
3622                 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info.info_ex,
3623                                                          td);
3624                 if (!NT_STATUS_IS_OK(nt_status)) {
3625                         return nt_status;
3626                 }
3627                 nt_status = auth_info_2_auth_blob(td,
3628                                                   &info->full_info.auth_info,
3629                                                   &td->trust_auth_incoming,
3630                                                   &td->trust_auth_outgoing);
3631                 if (!NT_STATUS_IS_OK(nt_status)) {
3632                         return nt_status;
3633                 }
3634                 break;
3635         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
3636                 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3637                         return NT_STATUS_ACCESS_DENIED;
3638                 }
3639                 auth_info_int = &info->auth_info_internal;
3640                 break;
3641         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
3642                 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3643                         return NT_STATUS_ACCESS_DENIED;
3644                 }
3645                 td->trust_posix_offset = &info->full_info_internal.posix_offset.posix_offset;
3646                 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info_internal.info_ex,
3647                                                          td);
3648                 if (!NT_STATUS_IS_OK(nt_status)) {
3649                         return nt_status;
3650                 }
3651                 auth_info_int = &info->full_info_internal.auth_info;
3652                 break;
3653         case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
3654                 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3655                         return NT_STATUS_ACCESS_DENIED;
3656                 }
3657                 td->supported_enc_type = &info->enc_types.enc_types;
3658                 break;
3659         default:
3660                 return NT_STATUS_INVALID_PARAMETER;
3661         }
3662
3663         /* decode auth_info_int if set */
3664         if (auth_info_int) {
3665
3666                 /* now decrypt blob */
3667                 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
3668                                             auth_info_int->auth_blob.size);
3669
3670                 nt_status = get_trustdom_auth_blob(p, mem_ctx,
3671                                                    &auth_blob, &auth_struct);
3672                 if (!NT_STATUS_IS_OK(nt_status)) {
3673                         return nt_status;
3674                 }
3675         } else {
3676             memset(&auth_struct, 0, sizeof(auth_struct));
3677         }
3678
3679 /* TODO: verify only one object matches the dns/netbios/sid triplet and that
3680  * this is the one we already have */
3681
3682 /* TODO: check if the trust direction is changed and we need to add or remove
3683  * auth data */
3684
3685 /* TODO: check if trust type shall be changed and return an error in this case
3686  * */
3687         nt_status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &policy->sid,
3688                                                &orig_td);
3689         if (!NT_STATUS_IS_OK(nt_status)) {
3690                 return nt_status;
3691         }
3692
3693
3694         /* TODO: should we fetch previous values from the existing entry
3695          * and append them ? */
3696         if (auth_struct.incoming.count) {
3697                 nt_status = get_trustauth_inout_blob(mem_ctx,
3698                                                      &auth_struct.incoming,
3699                                                      &td->trust_auth_incoming);
3700                 if (!NT_STATUS_IS_OK(nt_status)) {
3701                         return nt_status;
3702                 }
3703         } else {
3704                 ZERO_STRUCT(td->trust_auth_incoming);
3705         }
3706
3707         if (auth_struct.outgoing.count) {
3708                 nt_status = get_trustauth_inout_blob(mem_ctx,
3709                                                      &auth_struct.outgoing,
3710                                                      &td->trust_auth_outgoing);
3711                 if (!NT_STATUS_IS_OK(nt_status)) {
3712                         return nt_status;
3713                 }
3714         } else {
3715                 ZERO_STRUCT(td->trust_auth_outgoing);
3716         }
3717
3718         nt_status = pdb_set_trusted_domain(orig_td->domain_name, td);
3719         if (!NT_STATUS_IS_OK(nt_status)) {
3720                 return nt_status;
3721         }
3722
3723         return NT_STATUS_OK;
3724 }
3725
3726 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3727                                    struct lsa_SetTrustedDomainInfo *r)
3728 {
3729         NTSTATUS status;
3730         struct policy_handle trustdom_handle;
3731         struct lsa_OpenTrustedDomain o;
3732         struct lsa_SetInformationTrustedDomain s;
3733         struct lsa_Close c;
3734
3735         o.in.handle             = r->in.handle;
3736         o.in.sid                = r->in.dom_sid;
3737         o.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
3738         o.out.trustdom_handle   = &trustdom_handle;
3739
3740         status = _lsa_OpenTrustedDomain(p, &o);
3741         if (!NT_STATUS_IS_OK(status)) {
3742                 return status;
3743         }
3744
3745         s.in.trustdom_handle    = &trustdom_handle;
3746         s.in.level              = r->in.level;
3747         s.in.info               = r->in.info;
3748
3749         status = _lsa_SetInformationTrustedDomain(p, &s);
3750         if (!NT_STATUS_IS_OK(status)) {
3751                 return status;
3752         }
3753
3754         c.in.handle             = &trustdom_handle;
3755         c.out.handle            = &trustdom_handle;
3756
3757         return _lsa_Close(p, &c);
3758 }
3759
3760 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3761                                          struct lsa_SetTrustedDomainInfoByName *r)
3762 {
3763         NTSTATUS status;
3764         struct policy_handle trustdom_handle;
3765         struct lsa_OpenTrustedDomainByName o;
3766         struct lsa_SetInformationTrustedDomain s;
3767         struct lsa_Close c;
3768
3769         o.in.handle             = r->in.handle;
3770         o.in.name.string        = r->in.trusted_domain->string;
3771         o.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
3772         o.out.trustdom_handle   = &trustdom_handle;
3773
3774         status = _lsa_OpenTrustedDomainByName(p, &o);
3775         if (!NT_STATUS_IS_OK(status)) {
3776                 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
3777                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3778                 }
3779                 return status;
3780         }
3781
3782         s.in.trustdom_handle    = &trustdom_handle;
3783         s.in.level              = r->in.level;
3784         s.in.info               = r->in.info;
3785
3786         status = _lsa_SetInformationTrustedDomain(p, &s);
3787         if (!NT_STATUS_IS_OK(status)) {
3788                 return status;
3789         }
3790
3791         c.in.handle             = &trustdom_handle;
3792         c.out.handle            = &trustdom_handle;
3793
3794         return _lsa_Close(p, &c);
3795 }
3796
3797 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3798                                           struct lsa_SetInformationTrustedDomain *r)
3799 {
3800         struct lsa_info *policy;
3801
3802         if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&policy)) {
3803                 return NT_STATUS_INVALID_HANDLE;
3804         }
3805
3806         if (policy->type != LSA_HANDLE_TRUST_TYPE) {
3807                 return NT_STATUS_INVALID_HANDLE;
3808         }
3809
3810         return setInfoTrustedDomain_base(p, p->mem_ctx, policy,
3811                                          r->in.level, r->in.info);
3812 }
3813
3814
3815 /*
3816  * From here on the server routines are just dummy ones to make smbd link with
3817  * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3818  * pulling the server stubs across one by one.
3819  */
3820
3821 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3822 {
3823         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3824         return NT_STATUS_NOT_IMPLEMENTED;
3825 }
3826
3827 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3828                              struct lsa_ChangePassword *r)
3829 {
3830         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3831         return NT_STATUS_NOT_IMPLEMENTED;
3832 }
3833
3834 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3835 {
3836         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3837         return NT_STATUS_NOT_IMPLEMENTED;
3838 }
3839
3840 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3841 {
3842         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3843         return NT_STATUS_NOT_IMPLEMENTED;
3844 }
3845
3846 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3847                                   struct lsa_GetQuotasForAccount *r)
3848 {
3849         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3850         return NT_STATUS_NOT_IMPLEMENTED;
3851 }
3852
3853 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3854                                   struct lsa_SetQuotasForAccount *r)
3855 {
3856         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3857         return NT_STATUS_NOT_IMPLEMENTED;
3858 }
3859
3860 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3861                                struct lsa_StorePrivateData *r)
3862 {
3863         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3864         return NT_STATUS_NOT_IMPLEMENTED;
3865 }
3866
3867 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3868                                   struct lsa_RetrievePrivateData *r)
3869 {
3870         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3871         return NT_STATUS_NOT_IMPLEMENTED;
3872 }
3873
3874 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3875                              struct lsa_SetInfoPolicy2 *r)
3876 {
3877         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3878         return NT_STATUS_NOT_IMPLEMENTED;
3879 }
3880
3881 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3882                                    struct lsa_EnumTrustedDomainsEx *r)
3883 {
3884         struct lsa_info *info;
3885         uint32_t count;
3886         struct pdb_trusted_domain **domains;
3887         struct lsa_TrustDomainInfoInfoEx *entries;
3888         int i;
3889         NTSTATUS nt_status;
3890
3891         /* bail out early if pdb backend is not capable of ex trusted domains,
3892          * if we dont do that, the client might not call
3893          * _lsa_EnumTrustedDomains() afterwards - gd */
3894
3895         if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3896                 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3897                 return NT_STATUS_NOT_IMPLEMENTED;
3898         }
3899
3900         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3901                 return NT_STATUS_INVALID_HANDLE;
3902
3903         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3904                 return NT_STATUS_INVALID_HANDLE;
3905         }
3906
3907         /* check if the user has enough rights */
3908         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3909                 return NT_STATUS_ACCESS_DENIED;
3910
3911         become_root();
3912         nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3913         unbecome_root();
3914
3915         if (!NT_STATUS_IS_OK(nt_status)) {
3916                 return nt_status;
3917         }
3918
3919         entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3920                                     count);
3921         if (!entries) {
3922                 return NT_STATUS_NO_MEMORY;
3923         }
3924
3925         for (i=0; i<count; i++) {
3926                 init_lsa_StringLarge(&entries[i].netbios_name,
3927                                      domains[i]->netbios_name);
3928                 entries[i].sid = &domains[i]->security_identifier;
3929         }
3930
3931         if (*r->in.resume_handle >= count) {
3932                 *r->out.resume_handle = -1;
3933                 TALLOC_FREE(entries);
3934                 return NT_STATUS_NO_MORE_ENTRIES;
3935         }
3936
3937         /* return the rest, limit by max_size. Note that we
3938            use the w2k3 element size value of 60 */
3939         r->out.domains->count = count - *r->in.resume_handle;
3940         r->out.domains->count = MIN(r->out.domains->count,
3941                                     (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3942
3943         r->out.domains->domains = entries + *r->in.resume_handle;
3944
3945         if (r->out.domains->count < count - *r->in.resume_handle) {
3946                 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3947                 return STATUS_MORE_ENTRIES;
3948         }
3949
3950         /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3951          * always be larger than the previous input resume handle, in
3952          * particular when hitting the last query it is vital to set the
3953          * resume handle correctly to avoid infinite client loops, as
3954          * seen e.g. with Windows XP SP3 when resume handle is 0 and
3955          * status is NT_STATUS_OK - gd */
3956
3957         *r->out.resume_handle = (uint32_t)-1;
3958
3959         return NT_STATUS_OK;
3960 }
3961
3962 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3963                                            struct lsa_QueryDomainInformationPolicy *r)
3964 {
3965         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3966         return NT_STATUS_NOT_IMPLEMENTED;
3967 }
3968
3969 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3970                                          struct lsa_SetDomainInformationPolicy *r)
3971 {
3972         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3973         return NT_STATUS_NOT_IMPLEMENTED;
3974 }
3975
3976 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3977 {
3978         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3979         return NT_STATUS_NOT_IMPLEMENTED;
3980 }
3981
3982 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3983 {
3984         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3985         return NT_STATUS_NOT_IMPLEMENTED;
3986 }
3987
3988 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3989 {
3990         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3991         return NT_STATUS_NOT_IMPLEMENTED;
3992 }
3993
3994 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3995 {
3996         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3997         return NT_STATUS_NOT_IMPLEMENTED;
3998 }
3999
4000 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
4001                                           struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
4002 {
4003         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4004         return NT_STATUS_NOT_IMPLEMENTED;
4005 }
4006
4007 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
4008                                          struct lsa_CREDRREADDOMAINCREDENTIALS *r)
4009 {
4010         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4011         return NT_STATUS_NOT_IMPLEMENTED;
4012 }
4013
4014 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
4015 {
4016         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4017         return NT_STATUS_NOT_IMPLEMENTED;
4018 }
4019
4020 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
4021                                  struct lsa_CREDRGETTARGETINFO *r)
4022 {
4023         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4024         return NT_STATUS_NOT_IMPLEMENTED;
4025 }
4026
4027 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
4028                                  struct lsa_CREDRPROFILELOADED *r)
4029 {
4030         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4031         return NT_STATUS_NOT_IMPLEMENTED;
4032 }
4033
4034 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
4035                                    struct lsa_CREDRGETSESSIONTYPES *r)
4036 {
4037         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4038         return NT_STATUS_NOT_IMPLEMENTED;
4039 }
4040
4041 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
4042                                      struct lsa_LSARREGISTERAUDITEVENT *r)
4043 {
4044         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4045         return NT_STATUS_NOT_IMPLEMENTED;
4046 }
4047
4048 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
4049                                 struct lsa_LSARGENAUDITEVENT *r)
4050 {
4051         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4052         return NT_STATUS_NOT_IMPLEMENTED;
4053 }
4054
4055 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
4056                                        struct lsa_LSARUNREGISTERAUDITEVENT *r)
4057 {
4058         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4059         return NT_STATUS_NOT_IMPLEMENTED;
4060 }
4061
4062 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
4063                                               struct lsa_lsaRQueryForestTrustInformation *r)
4064 {
4065         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4066         return NT_STATUS_NOT_IMPLEMENTED;
4067 }
4068
4069 #define DNS_CMP_MATCH 0
4070 #define DNS_CMP_FIRST_IS_CHILD 1
4071 #define DNS_CMP_SECOND_IS_CHILD 2
4072 #define DNS_CMP_NO_MATCH 3
4073
4074 /* this function assumes names are well formed DNS names.
4075  * it doesn't validate them */
4076 static int dns_cmp(const char *s1, size_t l1,
4077                    const char *s2, size_t l2)
4078 {
4079         const char *p1, *p2;
4080         size_t t1, t2;
4081         int cret;
4082
4083         if (l1 == l2) {
4084                 if (strcasecmp_m(s1, s2) == 0) {
4085                         return DNS_CMP_MATCH;
4086                 }
4087                 return DNS_CMP_NO_MATCH;
4088         }
4089
4090         if (l1 > l2) {
4091                 p1 = s1;
4092                 p2 = s2;
4093                 t1 = l1;
4094                 t2 = l2;
4095                 cret = DNS_CMP_FIRST_IS_CHILD;
4096         } else {
4097                 p1 = s2;
4098                 p2 = s1;
4099                 t1 = l2;
4100                 t2 = l1;
4101                 cret = DNS_CMP_SECOND_IS_CHILD;
4102         }
4103
4104         if (p1[t1 - t2 - 1] != '.') {
4105                 return DNS_CMP_NO_MATCH;
4106         }
4107
4108         if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
4109                 return cret;
4110         }
4111
4112         return DNS_CMP_NO_MATCH;
4113 }
4114
4115 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
4116                              struct lsa_ForestTrustInformation *lfti,
4117                              struct ForestTrustInfo *fti)
4118 {
4119         struct lsa_ForestTrustRecord *lrec;
4120         struct ForestTrustInfoRecord *rec;
4121         struct lsa_StringLarge *tln;
4122         struct lsa_ForestTrustDomainInfo *info;
4123         uint32_t i;
4124
4125         fti->version = 1;
4126         fti->count = lfti->count;
4127         fti->records = talloc_array(mem_ctx,
4128                                     struct ForestTrustInfoRecordArmor,
4129                                     fti->count);
4130         if (!fti->records) {
4131                 return NT_STATUS_NO_MEMORY;
4132         }
4133         for (i = 0; i < fti->count; i++) {
4134                 lrec = lfti->entries[i];
4135                 rec = &fti->records[i].record;
4136
4137                 rec->flags = lrec->flags;
4138                 rec->timestamp = lrec->time;
4139                 rec->type = lrec->type;
4140
4141                 switch (lrec->type) {
4142                 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
4143                 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4144                         tln = &lrec->forest_trust_data.top_level_name;
4145                         rec->data.name.string =
4146                                 talloc_strdup(mem_ctx, tln->string);
4147                         if (!rec->data.name.string) {
4148                                 return NT_STATUS_NO_MEMORY;
4149                         }
4150                         rec->data.name.size = strlen(rec->data.name.string);
4151                         break;
4152                 case LSA_FOREST_TRUST_DOMAIN_INFO:
4153                         info = &lrec->forest_trust_data.domain_info;
4154                         rec->data.info.sid = *info->domain_sid;
4155                         rec->data.info.dns_name.string =
4156                                 talloc_strdup(mem_ctx,
4157                                             info->dns_domain_name.string);
4158                         if (!rec->data.info.dns_name.string) {
4159                                 return NT_STATUS_NO_MEMORY;
4160                         }
4161                         rec->data.info.dns_name.size =
4162                                 strlen(rec->data.info.dns_name.string);
4163                         rec->data.info.netbios_name.string =
4164                                 talloc_strdup(mem_ctx,
4165                                             info->netbios_domain_name.string);
4166                         if (!rec->data.info.netbios_name.string) {
4167                                 return NT_STATUS_NO_MEMORY;
4168                         }
4169                         rec->data.info.netbios_name.size =
4170                                 strlen(rec->data.info.netbios_name.string);
4171                         break;
4172                 default:
4173                         return NT_STATUS_INVALID_DOMAIN_STATE;
4174                 }
4175         }
4176
4177         return NT_STATUS_OK;
4178 }
4179
4180 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4181                               uint32_t index, uint32_t collision_type,
4182                               uint32_t conflict_type, const char *tdo_name);
4183
4184 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
4185                               const char *tdo_name,
4186                               struct ForestTrustInfo *tdo_fti,
4187                               struct ForestTrustInfo *new_fti,
4188                               struct lsa_ForestTrustCollisionInfo *c_info)
4189 {
4190         struct ForestTrustInfoRecord *nrec;
4191         struct ForestTrustInfoRecord *trec;
4192         const char *dns_name;
4193         const char *nb_name = NULL;
4194         struct dom_sid *sid = NULL;
4195         const char *tname = NULL;
4196         size_t dns_len = 0;
4197         size_t tlen = 0;
4198         uint32_t new_fti_idx;
4199         uint32_t i;
4200         /* use always TDO type, until we understand when Xref can be used */
4201         uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
4202         bool tln_conflict;
4203         bool sid_conflict;
4204         bool nb_conflict;
4205         bool exclusion;
4206         bool ex_rule = false;
4207         int ret;
4208
4209         for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
4210
4211                 nrec = &new_fti->records[new_fti_idx].record;
4212                 dns_name = NULL;
4213                 tln_conflict = false;
4214                 sid_conflict = false;
4215                 nb_conflict = false;
4216                 exclusion = false;
4217
4218                 switch (nrec->type) {
4219                 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4220                         /* exclusions do not conflict by definition */
4221                         break;
4222
4223                 case FOREST_TRUST_TOP_LEVEL_NAME:
4224                         dns_name = nrec->data.name.string;
4225                         dns_len = nrec->data.name.size;
4226                         break;
4227
4228                 case LSA_FOREST_TRUST_DOMAIN_INFO:
4229                         dns_name = nrec->data.info.dns_name.string;
4230                         dns_len = nrec->data.info.dns_name.size;
4231                         nb_name = nrec->data.info.netbios_name.string;
4232                         sid = &nrec->data.info.sid;
4233                         break;
4234                 }
4235
4236                 if (!dns_name) continue;
4237
4238                 /* check if this is already taken and not excluded */
4239                 for (i = 0; i < tdo_fti->count; i++) {
4240                         trec = &tdo_fti->records[i].record;
4241
4242                         switch (trec->type) {
4243                         case FOREST_TRUST_TOP_LEVEL_NAME:
4244                                 ex_rule = false;
4245                                 tname = trec->data.name.string;
4246                                 tlen = trec->data.name.size;
4247                                 break;
4248                         case FOREST_TRUST_TOP_LEVEL_NAME_EX:
4249                                 ex_rule = true;
4250                                 tname = trec->data.name.string;
4251                                 tlen = trec->data.name.size;
4252                                 break;
4253                         case FOREST_TRUST_DOMAIN_INFO:
4254                                 ex_rule = false;
4255                                 tname = trec->data.info.dns_name.string;
4256                                 tlen = trec->data.info.dns_name.size;
4257                                 break;
4258                         default:
4259                                 return NT_STATUS_INVALID_PARAMETER;
4260                         }
4261                         ret = dns_cmp(dns_name, dns_len, tname, tlen);
4262                         switch (ret) {
4263                         case DNS_CMP_MATCH:
4264                                 /* if it matches exclusion,
4265                                  * it doesn't conflict */
4266                                 if (ex_rule) {
4267                                         exclusion = true;
4268                                         break;
4269                                 }
4270                                 /* fall through */
4271                         case DNS_CMP_FIRST_IS_CHILD:
4272                         case DNS_CMP_SECOND_IS_CHILD:
4273                                 tln_conflict = true;
4274                                 /* fall through */
4275                         default:
4276                                 break;
4277                         }
4278
4279                         /* explicit exclusion, no dns name conflict here */
4280                         if (exclusion) {
4281                                 tln_conflict = false;
4282                         }
4283
4284                         if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
4285                                 continue;
4286                         }
4287
4288                         /* also test for domain info */
4289                         if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
4290                             dom_sid_compare(&trec->data.info.sid, sid) == 0) {
4291                                 sid_conflict = true;
4292                         }
4293                         if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
4294                             strcasecmp_m(trec->data.info.netbios_name.string,
4295                                        nb_name) == 0) {
4296                                 nb_conflict = true;
4297                         }
4298                 }
4299
4300                 if (tln_conflict) {
4301                         (void)add_collision(c_info, new_fti_idx,
4302                                                   collision_type,
4303                                                   LSA_TLN_DISABLED_CONFLICT,
4304                                                   tdo_name);
4305                 }
4306                 if (sid_conflict) {
4307                         (void)add_collision(c_info, new_fti_idx,
4308                                                   collision_type,
4309                                                   LSA_SID_DISABLED_CONFLICT,
4310                                                   tdo_name);
4311                 }
4312                 if (nb_conflict) {
4313                         (void)add_collision(c_info, new_fti_idx,
4314                                                   collision_type,
4315                                                   LSA_NB_DISABLED_CONFLICT,
4316                                                   tdo_name);
4317                 }
4318         }
4319
4320         return NT_STATUS_OK;
4321 }
4322
4323 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4324                               uint32_t idx, uint32_t collision_type,
4325                               uint32_t conflict_type, const char *tdo_name)
4326 {
4327         struct lsa_ForestTrustCollisionRecord **es;
4328         uint32_t i = c_info->count;
4329
4330         es = talloc_realloc(c_info, c_info->entries,
4331                             struct lsa_ForestTrustCollisionRecord *, i + 1);
4332         if (!es) {
4333                 return NT_STATUS_NO_MEMORY;
4334         }
4335         c_info->entries = es;
4336         c_info->count = i + 1;
4337
4338         es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
4339         if (!es[i]) {
4340                 return NT_STATUS_NO_MEMORY;
4341         }
4342
4343         es[i]->index = idx;
4344         es[i]->type = collision_type;
4345         es[i]->flags.flags = conflict_type;
4346         es[i]->name.string = talloc_strdup(es[i], tdo_name);
4347         if (!es[i]->name.string) {
4348                 return NT_STATUS_NO_MEMORY;
4349         }
4350         es[i]->name.size = strlen(es[i]->name.string);
4351
4352         return NT_STATUS_OK;
4353 }
4354
4355 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
4356                             struct pdb_trusted_domain *td,
4357                             struct ForestTrustInfo *info)
4358 {
4359         enum ndr_err_code ndr_err;
4360
4361         if (td->trust_forest_trust_info.length == 0 ||
4362             td->trust_forest_trust_info.data == NULL) {
4363                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4364         }
4365         ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
4366                                            info,
4367                                            (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
4368         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4369                 return NT_STATUS_INVALID_DOMAIN_STATE;
4370         }
4371
4372         return NT_STATUS_OK;
4373 }
4374
4375 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
4376                             struct ForestTrustInfo *fti)
4377 {
4378         struct ForestTrustDataDomainInfo *info;
4379         struct ForestTrustInfoRecord *rec;
4380
4381         fti->version = 1;
4382         fti->count = 2;
4383         fti->records = talloc_array(fti,
4384                                     struct ForestTrustInfoRecordArmor, 2);
4385         if (!fti->records) {
4386                 return NT_STATUS_NO_MEMORY;
4387         }
4388
4389         /* TLN info */
4390         rec = &fti->records[0].record;
4391
4392         rec->flags = 0;
4393         rec->timestamp = 0;
4394         rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
4395
4396         rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
4397         if (!rec->data.name.string) {
4398                 return NT_STATUS_NO_MEMORY;
4399         }
4400         rec->data.name.size = strlen(rec->data.name.string);
4401
4402         /* DOMAIN info */
4403         rec = &fti->records[1].record;
4404
4405         rec->flags = 0;
4406         rec->timestamp = 0;
4407         rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
4408
4409         info = &rec->data.info;
4410
4411         info->sid = dom_info->sid;
4412         info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
4413         if (!info->dns_name.string) {
4414                 return NT_STATUS_NO_MEMORY;
4415         }
4416         info->dns_name.size = strlen(info->dns_name.string);
4417         info->netbios_name.string = talloc_strdup(fti, dom_info->name);
4418         if (!info->netbios_name.string) {
4419                 return NT_STATUS_NO_MEMORY;
4420         }
4421         info->netbios_name.size = strlen(info->netbios_name.string);
4422
4423         return NT_STATUS_OK;
4424 }
4425
4426 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
4427                                             struct lsa_lsaRSetForestTrustInformation *r)
4428 {
4429         NTSTATUS status;
4430         int i;
4431         int j;
4432         struct lsa_info *handle;
4433         uint32_t num_domains;
4434         struct pdb_trusted_domain **domains;
4435         struct ForestTrustInfo *nfti;
4436         struct ForestTrustInfo *fti;
4437         struct lsa_ForestTrustCollisionInfo *c_info;
4438         struct pdb_domain_info *dom_info;
4439         enum ndr_err_code ndr_err;
4440
4441         if (!IS_DC) {
4442                 return NT_STATUS_NOT_SUPPORTED;
4443         }
4444
4445         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
4446                 return NT_STATUS_INVALID_HANDLE;
4447         }
4448
4449         if (handle->type != LSA_HANDLE_TRUST_TYPE) {
4450                 return NT_STATUS_INVALID_HANDLE;
4451         }
4452
4453         if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
4454                 return NT_STATUS_ACCESS_DENIED;
4455         }
4456
4457         status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
4458         if (!NT_STATUS_IS_OK(status)) {
4459                 return status;
4460         }
4461         if (num_domains == 0) {
4462                 return NT_STATUS_NO_SUCH_DOMAIN;
4463         }
4464
4465         for (i = 0; i < num_domains; i++) {
4466                 if (domains[i]->domain_name == NULL) {
4467                         return NT_STATUS_INVALID_DOMAIN_STATE;
4468                 }
4469                 if (strcasecmp_m(domains[i]->domain_name,
4470                                r->in.trusted_domain_name->string) == 0) {
4471                         break;
4472                 }
4473         }
4474         if (i >= num_domains) {
4475                 return NT_STATUS_NO_SUCH_DOMAIN;
4476         }
4477
4478         if (!(domains[i]->trust_attributes &
4479               LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4480                 return NT_STATUS_INVALID_PARAMETER;
4481         }
4482
4483         if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4484                 return NT_STATUS_INVALID_PARAMETER;
4485         }
4486
4487         /* The following section until COPY_END is a copy from
4488          * source4/rpmc_server/lsa/scesrc_lsa.c */
4489         nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
4490         if (!nfti) {
4491                 return NT_STATUS_NO_MEMORY;
4492         }
4493
4494         status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4495         if (!NT_STATUS_IS_OK(status)) {
4496                 return status;
4497         }
4498
4499         c_info = talloc_zero(r->out.collision_info,
4500                              struct lsa_ForestTrustCollisionInfo);
4501         if (!c_info) {
4502                 return NT_STATUS_NO_MEMORY;
4503         }
4504
4505         /* first check own info, then other domains */
4506         fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4507         if (!fti) {
4508                 return NT_STATUS_NO_MEMORY;
4509         }
4510
4511         dom_info = pdb_get_domain_info(p->mem_ctx);
4512
4513         status = own_ft_info(dom_info, fti);
4514         if (!NT_STATUS_IS_OK(status)) {
4515                 return status;
4516         }
4517
4518         status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
4519         if (!NT_STATUS_IS_OK(status)) {
4520                 return status;
4521         }
4522
4523         for (j = 0; j < num_domains; j++) {
4524                 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4525                 if (!fti) {
4526                         return NT_STATUS_NO_MEMORY;
4527                 }
4528
4529                 status = get_ft_info(p->mem_ctx, domains[j], fti);
4530                 if (!NT_STATUS_IS_OK(status)) {
4531                         if (NT_STATUS_EQUAL(status,
4532                             NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4533                                 continue;
4534                         }
4535                         return status;
4536                 }
4537
4538                 if (domains[j]->domain_name == NULL) {
4539                         return NT_STATUS_INVALID_DOMAIN_STATE;
4540                 }
4541
4542                 status = check_ft_info(c_info, domains[j]->domain_name,
4543                                        fti, nfti, c_info);
4544                 if (!NT_STATUS_IS_OK(status)) {
4545                         return status;
4546                 }
4547         }
4548
4549         *r->out.collision_info = c_info;
4550
4551         if (r->in.check_only != 0) {
4552                 return NT_STATUS_OK;
4553         }
4554
4555         /* COPY_END */
4556
4557         ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
4558                                        p->mem_ctx, nfti,
4559                                        (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4560         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4561                 return NT_STATUS_INVALID_PARAMETER;
4562         }
4563
4564         status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
4565         if (!NT_STATUS_IS_OK(status)) {
4566                 return status;
4567         }
4568
4569         return NT_STATUS_OK;
4570 }
4571
4572 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
4573                           struct lsa_CREDRRENAME *r)
4574 {
4575         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4576         return NT_STATUS_NOT_IMPLEMENTED;
4577 }
4578
4579 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
4580                                 struct lsa_LSAROPENPOLICYSCE *r)
4581 {
4582         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4583         return NT_STATUS_NOT_IMPLEMENTED;
4584 }
4585
4586 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4587                                                  struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4588 {
4589         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4590         return NT_STATUS_NOT_IMPLEMENTED;
4591 }
4592
4593 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4594                                                    struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4595 {
4596         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4597         return NT_STATUS_NOT_IMPLEMENTED;
4598 }
4599
4600 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4601                                          struct lsa_LSARADTREPORTSECURITYEVENT *r)
4602 {
4603         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4604         return NT_STATUS_NOT_IMPLEMENTED;
4605 }