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