s4-lsarpc handle more info levels in SetInfoTrustedDomain calls
[kai/samba.git] / source3 / rpc_server / lsa / srv_lsa_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Jeremy Allison                    2001, 2006.
8  *  Copyright (C) Rafal Szczesniak                  2002,
9  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
10  *  Copyright (C) Simo Sorce                        2003.
11  *  Copyright (C) Gerald (Jerry) Carter             2005.
12  *  Copyright (C) Volker Lendecke                   2005.
13  *  Copyright (C) Guenther Deschner                 2008.
14  *  Copyright (C) Andrew Bartlett                   2010.
15  *
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License as published by
18  *  the Free Software Foundation; either version 3 of the License, or
19  *  (at your option) any later version.
20  *
21  *  This program is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *  GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License
27  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
28  */
29
30 /* This is the implementation of the lsa server code. */
31
32 #include "includes.h"
33 #include "ntdomain.h"
34 #include "../librpc/gen_ndr/srv_lsa.h"
35 #include "secrets.h"
36 #include "../librpc/gen_ndr/netlogon.h"
37 #include "rpc_client/init_lsa.h"
38 #include "../libcli/security/security.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../librpc/gen_ndr/drsblobs.h"
41 #include "../librpc/gen_ndr/ndr_drsblobs.h"
42 #include "../lib/crypto/arcfour.h"
43 #include "../libcli/security/dom_sid.h"
44 #include "../librpc/gen_ndr/ndr_security.h"
45 #include "passdb.h"
46 #include "auth.h"
47 #include "lib/privileges.h"
48 #include "rpc_server/srv_access_check.h"
49 #include "../librpc/gen_ndr/ndr_wkssvc.h"
50 #include "../libcli/auth/libcli_auth.h"
51 #include "../libcli/lsarpc/util_lsarpc.h"
52
53 #undef DBGC_CLASS
54 #define DBGC_CLASS DBGC_RPC_SRV
55
56 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
57
58 enum lsa_handle_type {
59         LSA_HANDLE_POLICY_TYPE = 1,
60         LSA_HANDLE_ACCOUNT_TYPE = 2,
61         LSA_HANDLE_TRUST_TYPE = 3,
62         LSA_HANDLE_SECRET_TYPE = 4};
63
64 struct lsa_info {
65         struct dom_sid sid;
66         const char *name;
67         uint32 access;
68         enum lsa_handle_type type;
69         struct security_descriptor *sd;
70 };
71
72 const struct generic_mapping lsa_account_mapping = {
73         LSA_ACCOUNT_READ,
74         LSA_ACCOUNT_WRITE,
75         LSA_ACCOUNT_EXECUTE,
76         LSA_ACCOUNT_ALL_ACCESS
77 };
78
79 const struct generic_mapping lsa_policy_mapping = {
80         LSA_POLICY_READ,
81         LSA_POLICY_WRITE,
82         LSA_POLICY_EXECUTE,
83         LSA_POLICY_ALL_ACCESS
84 };
85
86 const struct generic_mapping lsa_secret_mapping = {
87         LSA_SECRET_READ,
88         LSA_SECRET_WRITE,
89         LSA_SECRET_EXECUTE,
90         LSA_SECRET_ALL_ACCESS
91 };
92
93 const struct generic_mapping lsa_trusted_domain_mapping = {
94         LSA_TRUSTED_DOMAIN_READ,
95         LSA_TRUSTED_DOMAIN_WRITE,
96         LSA_TRUSTED_DOMAIN_EXECUTE,
97         LSA_TRUSTED_DOMAIN_ALL_ACCESS
98 };
99
100 /***************************************************************************
101  init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
102 ***************************************************************************/
103
104 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
105                                     struct lsa_RefDomainList *ref,
106                                     const char *dom_name,
107                                     struct dom_sid *dom_sid)
108 {
109         int num = 0;
110
111         if (dom_name != NULL) {
112                 for (num = 0; num < ref->count; num++) {
113                         if (dom_sid_equal(dom_sid, ref->domains[num].sid)) {
114                                 return num;
115                         }
116                 }
117         } else {
118                 num = ref->count;
119         }
120
121         if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
122                 /* index not found, already at maximum domain limit */
123                 return -1;
124         }
125
126         ref->count = num + 1;
127         ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
128
129         ref->domains = talloc_realloc(mem_ctx, ref->domains,
130                                             struct lsa_DomainInfo, ref->count);
131         if (!ref->domains) {
132                 return -1;
133         }
134
135         ZERO_STRUCT(ref->domains[num]);
136
137         init_lsa_StringLarge(&ref->domains[num].name, dom_name);
138         ref->domains[num].sid = dom_sid_dup(mem_ctx, dom_sid);
139         if (!ref->domains[num].sid) {
140                 return -1;
141         }
142
143         return num;
144 }
145
146
147 /***************************************************************************
148  initialize a lsa_DomainInfo structure.
149  ***************************************************************************/
150
151 static void init_dom_query_3(struct lsa_DomainInfo *r,
152                              const char *name,
153                              struct dom_sid *sid)
154 {
155         init_lsa_StringLarge(&r->name, name);
156         r->sid = sid;
157 }
158
159 /***************************************************************************
160  initialize a lsa_DomainInfo structure.
161  ***************************************************************************/
162
163 static void init_dom_query_5(struct lsa_DomainInfo *r,
164                              const char *name,
165                              struct dom_sid *sid)
166 {
167         init_lsa_StringLarge(&r->name, name);
168         r->sid = sid;
169 }
170
171 /***************************************************************************
172  lookup_lsa_rids. Must be called as root for lookup_name to work.
173  ***************************************************************************/
174
175 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
176                                 struct lsa_RefDomainList *ref,
177                                 struct lsa_TranslatedSid *prid,
178                                 uint32_t num_entries,
179                                 struct lsa_String *name,
180                                 int flags,
181                                 uint32_t *pmapped_count)
182 {
183         uint32 mapped_count, i;
184
185         SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
186
187         mapped_count = 0;
188         *pmapped_count = 0;
189
190         for (i = 0; i < num_entries; i++) {
191                 struct dom_sid sid;
192                 uint32 rid;
193                 int dom_idx;
194                 const char *full_name;
195                 const char *domain;
196                 enum lsa_SidType type;
197
198                 /* Split name into domain and user component */
199
200                 /* follow w2k8 behavior and return the builtin domain when no
201                  * input has been passed in */
202
203                 if (name[i].string) {
204                         full_name = name[i].string;
205                 } else {
206                         full_name = "BUILTIN";
207                 }
208
209                 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
210
211                 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
212                                  &sid, &type)) {
213                         type = SID_NAME_UNKNOWN;
214                 }
215
216                 switch (type) {
217                 case SID_NAME_USER:
218                 case SID_NAME_DOM_GRP:
219                 case SID_NAME_DOMAIN:
220                 case SID_NAME_ALIAS:
221                 case SID_NAME_WKN_GRP:
222                         DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
223                         /* Leave these unchanged */
224                         break;
225                 default:
226                         /* Don't hand out anything but the list above */
227                         DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
228                         type = SID_NAME_UNKNOWN;
229                         break;
230                 }
231
232                 rid = 0;
233                 dom_idx = -1;
234
235                 if (type != SID_NAME_UNKNOWN) {
236                         if (type == SID_NAME_DOMAIN) {
237                                 rid = (uint32_t)-1;
238                         } else {
239                                 sid_split_rid(&sid, &rid);
240                         }
241                         dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
242                         mapped_count++;
243                 }
244
245                 prid[i].sid_type        = type;
246                 prid[i].rid             = rid;
247                 prid[i].sid_index       = dom_idx;
248         }
249
250         *pmapped_count = mapped_count;
251         return NT_STATUS_OK;
252 }
253
254 /***************************************************************************
255  lookup_lsa_sids. Must be called as root for lookup_name to work.
256  ***************************************************************************/
257
258 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
259                                 struct lsa_RefDomainList *ref,
260                                 struct lsa_TranslatedSid3 *trans_sids,
261                                 uint32_t num_entries,
262                                 struct lsa_String *name,
263                                 int flags,
264                                 uint32 *pmapped_count)
265 {
266         uint32 mapped_count, i;
267
268         SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
269
270         mapped_count = 0;
271         *pmapped_count = 0;
272
273         for (i = 0; i < num_entries; i++) {
274                 struct dom_sid sid;
275                 uint32 rid;
276                 int dom_idx;
277                 const char *full_name;
278                 const char *domain;
279                 enum lsa_SidType type;
280
281                 ZERO_STRUCT(sid);
282
283                 /* Split name into domain and user component */
284
285                 full_name = name[i].string;
286                 if (full_name == NULL) {
287                         return NT_STATUS_NO_MEMORY;
288                 }
289
290                 DEBUG(5, ("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 /***************************************************************************
1664  _lsa_CreateTrustedDomainEx2
1665  ***************************************************************************/
1666
1667 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1668                                      struct lsa_CreateTrustedDomainEx2 *r)
1669 {
1670         struct lsa_info *policy;
1671         NTSTATUS status;
1672         uint32_t acc_granted;
1673         struct security_descriptor *psd;
1674         size_t sd_size;
1675         struct pdb_trusted_domain td;
1676         struct trustDomainPasswords auth_struct;
1677         enum ndr_err_code ndr_err;
1678         DATA_BLOB auth_blob;
1679
1680         if (!IS_DC) {
1681                 return NT_STATUS_NOT_SUPPORTED;
1682         }
1683
1684         if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1685                 return NT_STATUS_INVALID_HANDLE;
1686         }
1687
1688         if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1689                 return NT_STATUS_ACCESS_DENIED;
1690         }
1691
1692         if (p->session_info->unix_token->uid != sec_initial_uid() &&
1693             !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
1694                 return NT_STATUS_ACCESS_DENIED;
1695         }
1696
1697         /* Work out max allowed. */
1698         map_max_allowed_access(p->session_info->security_token,
1699                                p->session_info->unix_token,
1700                                &r->in.access_mask);
1701
1702         /* map the generic bits to the lsa policy ones */
1703         se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1704
1705         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1706                                     &lsa_trusted_domain_mapping,
1707                                     NULL, 0);
1708         if (!NT_STATUS_IS_OK(status)) {
1709                 return status;
1710         }
1711
1712         status = access_check_object(psd, p->session_info->security_token,
1713                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1714                                      r->in.access_mask, &acc_granted,
1715                                      "_lsa_CreateTrustedDomainEx2");
1716         if (!NT_STATUS_IS_OK(status)) {
1717                 return status;
1718         }
1719
1720         ZERO_STRUCT(td);
1721
1722         td.domain_name = talloc_strdup(p->mem_ctx,
1723                                        r->in.info->domain_name.string);
1724         if (td.domain_name == NULL) {
1725                 return NT_STATUS_NO_MEMORY;
1726         }
1727         td.netbios_name = talloc_strdup(p->mem_ctx,
1728                                         r->in.info->netbios_name.string);
1729         if (td.netbios_name == NULL) {
1730                 return NT_STATUS_NO_MEMORY;
1731         }
1732         sid_copy(&td.security_identifier, r->in.info->sid);
1733         td.trust_direction = r->in.info->trust_direction;
1734         td.trust_type = r->in.info->trust_type;
1735         td.trust_attributes = r->in.info->trust_attributes;
1736
1737         if (r->in.auth_info_internal->auth_blob.size != 0) {
1738                 auth_blob.length = r->in.auth_info_internal->auth_blob.size;
1739                 auth_blob.data = r->in.auth_info_internal->auth_blob.data;
1740
1741                 arcfour_crypt_blob(auth_blob.data, auth_blob.length,
1742                                    &p->session_info->session_key);
1743
1744                 ndr_err = ndr_pull_struct_blob(&auth_blob, p->mem_ctx,
1745                                                &auth_struct,
1746                                                (ndr_pull_flags_fn_t) ndr_pull_trustDomainPasswords);
1747                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1748                         return NT_STATUS_UNSUCCESSFUL;
1749                 }
1750
1751                 ndr_err = ndr_push_struct_blob(&td.trust_auth_incoming, p->mem_ctx,
1752                                                &auth_struct.incoming,
1753                                                (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1754                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1755                         return NT_STATUS_UNSUCCESSFUL;
1756                 }
1757
1758                 ndr_err = ndr_push_struct_blob(&td.trust_auth_outgoing, p->mem_ctx,
1759                                                &auth_struct.outgoing,
1760                                                (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1761                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1762                         return NT_STATUS_UNSUCCESSFUL;
1763                 }
1764         } else {
1765                 td.trust_auth_incoming.data = NULL;
1766                 td.trust_auth_incoming.length = 0;
1767                 td.trust_auth_outgoing.data = NULL;
1768                 td.trust_auth_outgoing.length = 0;
1769         }
1770
1771         status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1772         if (!NT_STATUS_IS_OK(status)) {
1773                 return status;
1774         }
1775
1776         status = create_lsa_policy_handle(p->mem_ctx, p,
1777                                           LSA_HANDLE_TRUST_TYPE,
1778                                           acc_granted,
1779                                           r->in.info->sid,
1780                                           r->in.info->netbios_name.string,
1781                                           psd,
1782                                           r->out.trustdom_handle);
1783         if (!NT_STATUS_IS_OK(status)) {
1784                 pdb_del_trusted_domain(r->in.info->netbios_name.string);
1785                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1786         }
1787
1788         return NT_STATUS_OK;
1789 }
1790
1791 /***************************************************************************
1792  _lsa_CreateTrustedDomainEx
1793  ***************************************************************************/
1794
1795 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1796                                     struct lsa_CreateTrustedDomainEx *r)
1797 {
1798         struct lsa_CreateTrustedDomainEx2 q;
1799         struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1800
1801         ZERO_STRUCT(auth_info);
1802
1803         q.in.policy_handle      = r->in.policy_handle;
1804         q.in.info               = r->in.info;
1805         q.in.auth_info_internal = &auth_info;
1806         q.in.access_mask        = r->in.access_mask;
1807         q.out.trustdom_handle   = r->out.trustdom_handle;
1808
1809         return _lsa_CreateTrustedDomainEx2(p, &q);
1810 }
1811
1812 /***************************************************************************
1813  _lsa_CreateTrustedDomain
1814  ***************************************************************************/
1815
1816 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1817                                   struct lsa_CreateTrustedDomain *r)
1818 {
1819         struct lsa_CreateTrustedDomainEx2 c;
1820         struct lsa_TrustDomainInfoInfoEx info;
1821         struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1822
1823         ZERO_STRUCT(auth_info);
1824
1825         info.domain_name        = r->in.info->name;
1826         info.netbios_name       = r->in.info->name;
1827         info.sid                = r->in.info->sid;
1828         info.trust_direction    = LSA_TRUST_DIRECTION_OUTBOUND;
1829         info.trust_type         = LSA_TRUST_TYPE_DOWNLEVEL;
1830         info.trust_attributes   = 0;
1831
1832         c.in.policy_handle      = r->in.policy_handle;
1833         c.in.info               = &info;
1834         c.in.auth_info_internal = &auth_info;
1835         c.in.access_mask        = r->in.access_mask;
1836         c.out.trustdom_handle   = r->out.trustdom_handle;
1837
1838         return _lsa_CreateTrustedDomainEx2(p, &c);
1839 }
1840
1841 /***************************************************************************
1842  _lsa_DeleteTrustedDomain
1843  ***************************************************************************/
1844
1845 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1846                                   struct lsa_DeleteTrustedDomain *r)
1847 {
1848         NTSTATUS status;
1849         struct lsa_info *handle;
1850         struct pdb_trusted_domain *td;
1851
1852         /* find the connection policy handle. */
1853         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1854                 return NT_STATUS_INVALID_HANDLE;
1855         }
1856
1857         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1858                 return NT_STATUS_INVALID_HANDLE;
1859         }
1860
1861         if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1862                 return NT_STATUS_ACCESS_DENIED;
1863         }
1864
1865         status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1866         if (!NT_STATUS_IS_OK(status)) {
1867                 return status;
1868         }
1869
1870         if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1871                 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1872                            sid_string_tos(r->in.dom_sid)));
1873                 return NT_STATUS_UNSUCCESSFUL;
1874         }
1875
1876         status = pdb_del_trusted_domain(td->netbios_name);
1877         if (!NT_STATUS_IS_OK(status)) {
1878                 return status;
1879         }
1880
1881         return NT_STATUS_OK;
1882 }
1883
1884 /***************************************************************************
1885  _lsa_CloseTrustedDomainEx
1886  ***************************************************************************/
1887
1888 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1889                                    struct lsa_CloseTrustedDomainEx *r)
1890 {
1891         return NT_STATUS_NOT_IMPLEMENTED;
1892 }
1893
1894 /***************************************************************************
1895  _lsa_QueryTrustedDomainInfo
1896  ***************************************************************************/
1897
1898 static NTSTATUS pdb_trusted_domain_2_info_ex(TALLOC_CTX *mem_ctx,
1899                                       struct pdb_trusted_domain *td,
1900                                       struct lsa_TrustDomainInfoInfoEx *info_ex)
1901 {
1902         if (td->domain_name == NULL ||
1903             td->netbios_name == NULL ||
1904             is_null_sid(&td->security_identifier)) {
1905                 return NT_STATUS_INVALID_PARAMETER;
1906         }
1907
1908         info_ex->domain_name.string = talloc_strdup(mem_ctx, td->domain_name);
1909         info_ex->netbios_name.string = talloc_strdup(mem_ctx, td->netbios_name);
1910         info_ex->sid = dom_sid_dup(mem_ctx, &td->security_identifier);
1911         if (info_ex->domain_name.string == NULL ||
1912             info_ex->netbios_name.string == NULL ||
1913             info_ex->sid == NULL) {
1914                 return NT_STATUS_NO_MEMORY;
1915         }
1916
1917         info_ex->trust_direction = td->trust_direction;
1918         info_ex->trust_type = td->trust_type;
1919         info_ex->trust_attributes = td->trust_attributes;
1920
1921         return NT_STATUS_OK;
1922 }
1923
1924 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
1925                                      struct lsa_QueryTrustedDomainInfo *r)
1926 {
1927         NTSTATUS status;
1928         struct lsa_info *handle;
1929         union lsa_TrustedDomainInfo *info;
1930         struct pdb_trusted_domain *td;
1931         uint32_t acc_required;
1932
1933         /* find the connection policy handle. */
1934         if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
1935                 return NT_STATUS_INVALID_HANDLE;
1936         }
1937
1938         if (handle->type != LSA_HANDLE_TRUST_TYPE) {
1939                 return NT_STATUS_INVALID_HANDLE;
1940         }
1941
1942         switch (r->in.level) {
1943         case LSA_TRUSTED_DOMAIN_INFO_NAME:
1944                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1945                 break;
1946         case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1947                 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
1948                 break;
1949         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1950                 acc_required = LSA_TRUSTED_QUERY_POSIX;
1951                 break;
1952         case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
1953                 acc_required = LSA_TRUSTED_QUERY_AUTH;
1954                 break;
1955         case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1956                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1957                 break;
1958         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1959                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1960                 break;
1961         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1962                 acc_required = LSA_TRUSTED_QUERY_AUTH;
1963                 break;
1964         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1965                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1966                                LSA_TRUSTED_QUERY_POSIX |
1967                                LSA_TRUSTED_QUERY_AUTH;
1968                 break;
1969         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1970                 acc_required = LSA_TRUSTED_QUERY_AUTH;
1971                 break;
1972         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1973                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1974                                LSA_TRUSTED_QUERY_POSIX |
1975                                LSA_TRUSTED_QUERY_AUTH;
1976                 break;
1977         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1978                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1979                 break;
1980         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1981                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1982                                LSA_TRUSTED_QUERY_POSIX |
1983                                LSA_TRUSTED_QUERY_AUTH;
1984                 break;
1985         case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1986                 acc_required = LSA_TRUSTED_QUERY_POSIX;
1987                 break;
1988         default:
1989                 return NT_STATUS_INVALID_PARAMETER;
1990         }
1991
1992         if (!(handle->access & acc_required)) {
1993                 return NT_STATUS_ACCESS_DENIED;
1994         }
1995
1996         status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
1997         if (!NT_STATUS_IS_OK(status)) {
1998                 return status;
1999         }
2000
2001         info = talloc_zero(p->mem_ctx, union lsa_TrustedDomainInfo);
2002         if (!info) {
2003                 return NT_STATUS_NO_MEMORY;
2004         }
2005
2006         switch (r->in.level) {
2007         case LSA_TRUSTED_DOMAIN_INFO_NAME:
2008                 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2009                 break;
2010         case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2011                 return NT_STATUS_INVALID_PARAMETER;
2012         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2013                 info->posix_offset.posix_offset = *td->trust_posix_offset;
2014                 break;
2015         case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2016                 return NT_STATUS_INVALID_INFO_CLASS;
2017         case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2018                 return NT_STATUS_INVALID_PARAMETER;
2019         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2020                 status = pdb_trusted_domain_2_info_ex(info, td, &info->info_ex);
2021                 if (!NT_STATUS_IS_OK(status)) {
2022                         return status;
2023                 }
2024                 break;
2025         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2026                 return NT_STATUS_INVALID_INFO_CLASS;
2027         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2028                 status = pdb_trusted_domain_2_info_ex(info, td,
2029                                                       &info->full_info.info_ex);
2030                 if (!NT_STATUS_IS_OK(status)) {
2031                         return status;
2032                 }
2033                 info->full_info.posix_offset.posix_offset = *td->trust_posix_offset;
2034                 status = auth_blob_2_auth_info(p->mem_ctx,
2035                                                     td->trust_auth_incoming,
2036                                                     td->trust_auth_outgoing,
2037                                                     &info->full_info.auth_info);
2038                 if (!NT_STATUS_IS_OK(status)) {
2039                         return status;
2040                 }
2041                 break;
2042         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2043                 return NT_STATUS_INVALID_INFO_CLASS;
2044         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2045                 return NT_STATUS_INVALID_INFO_CLASS;
2046         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2047                 return NT_STATUS_INVALID_PARAMETER;
2048         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2049                 info->full_info2_internal.posix_offset.posix_offset = *td->trust_posix_offset;
2050                 status = auth_blob_2_auth_info(p->mem_ctx,
2051                                           td->trust_auth_incoming,
2052                                           td->trust_auth_outgoing,
2053                                           &info->full_info2_internal.auth_info);
2054                 if (!NT_STATUS_IS_OK(status)) {
2055                         return status;
2056                 }
2057                 break;
2058         case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2059                 info->enc_types.enc_types = *td->supported_enc_type;
2060                 break;
2061         default:
2062                 return NT_STATUS_INVALID_PARAMETER;
2063         }
2064
2065         *r->out.info = info;
2066
2067         return NT_STATUS_OK;
2068 }
2069
2070 /***************************************************************************
2071  _lsa_QueryTrustedDomainInfoBySid
2072  ***************************************************************************/
2073
2074 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2075                                           struct lsa_QueryTrustedDomainInfoBySid *r)
2076 {
2077         NTSTATUS status;
2078         struct policy_handle trustdom_handle;
2079         struct lsa_OpenTrustedDomain o;
2080         struct lsa_QueryTrustedDomainInfo q;
2081         struct lsa_Close c;
2082
2083         o.in.handle             = r->in.handle;
2084         o.in.sid                = r->in.dom_sid;
2085         o.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
2086         o.out.trustdom_handle   = &trustdom_handle;
2087
2088         status = _lsa_OpenTrustedDomain(p, &o);
2089         if (!NT_STATUS_IS_OK(status)) {
2090                 return status;
2091         }
2092
2093         q.in.trustdom_handle    = &trustdom_handle;
2094         q.in.level              = r->in.level;
2095         q.out.info              = r->out.info;
2096
2097         status = _lsa_QueryTrustedDomainInfo(p, &q);
2098         if (!NT_STATUS_IS_OK(status)) {
2099                 return status;
2100         }
2101
2102         c.in.handle             = &trustdom_handle;
2103         c.out.handle            = &trustdom_handle;
2104
2105         return _lsa_Close(p, &c);
2106 }
2107
2108 /***************************************************************************
2109  _lsa_QueryTrustedDomainInfoByName
2110  ***************************************************************************/
2111
2112 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2113                                            struct lsa_QueryTrustedDomainInfoByName *r)
2114 {
2115         NTSTATUS status;
2116         struct policy_handle trustdom_handle;
2117         struct lsa_OpenTrustedDomainByName o;
2118         struct lsa_QueryTrustedDomainInfo q;
2119         struct lsa_Close c;
2120
2121         o.in.handle             = r->in.handle;
2122         o.in.name.string        = r->in.trusted_domain->string;
2123         o.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
2124         o.out.trustdom_handle   = &trustdom_handle;
2125
2126         status = _lsa_OpenTrustedDomainByName(p, &o);
2127         if (!NT_STATUS_IS_OK(status)) {
2128                 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2129                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2130                 }
2131                 return status;
2132         }
2133
2134         q.in.trustdom_handle    = &trustdom_handle;
2135         q.in.level              = r->in.level;
2136         q.out.info              = r->out.info;
2137
2138         status = _lsa_QueryTrustedDomainInfo(p, &q);
2139         if (!NT_STATUS_IS_OK(status)) {
2140                 return status;
2141         }
2142
2143         c.in.handle             = &trustdom_handle;
2144         c.out.handle            = &trustdom_handle;
2145
2146         return _lsa_Close(p, &c);
2147 }
2148
2149 /***************************************************************************
2150  _lsa_CreateSecret
2151  ***************************************************************************/
2152
2153 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p,
2154                            struct lsa_CreateSecret *r)
2155 {
2156         NTSTATUS status;
2157         struct lsa_info *handle;
2158         uint32_t acc_granted;
2159         struct security_descriptor *psd;
2160         size_t sd_size;
2161
2162         /* find the connection policy handle. */
2163         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
2164                 return NT_STATUS_INVALID_HANDLE;
2165         }
2166
2167         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2168                 return NT_STATUS_INVALID_HANDLE;
2169         }
2170
2171         /* check if the user has enough rights */
2172
2173         if (!(handle->access & LSA_POLICY_CREATE_SECRET)) {
2174                 return NT_STATUS_ACCESS_DENIED;
2175         }
2176
2177         /* Work out max allowed. */
2178         map_max_allowed_access(p->session_info->security_token,
2179                                p->session_info->unix_token,
2180                                &r->in.access_mask);
2181
2182         /* map the generic bits to the lsa policy ones */
2183         se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
2184
2185         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2186                                     &lsa_secret_mapping,
2187                                     NULL, 0);
2188         if (!NT_STATUS_IS_OK(status)) {
2189                 return status;
2190         }
2191
2192         status = access_check_object(psd, p->session_info->security_token,
2193                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2194                                      r->in.access_mask,
2195                                      &acc_granted, "_lsa_CreateSecret");
2196         if (!NT_STATUS_IS_OK(status)) {
2197                 return status;
2198         }
2199
2200         if (!r->in.name.string) {
2201                 return NT_STATUS_INVALID_PARAMETER;
2202         }
2203
2204         if (strlen(r->in.name.string) > 128) {
2205                 return NT_STATUS_NAME_TOO_LONG;
2206         }
2207
2208         status = pdb_get_secret(p->mem_ctx, r->in.name.string,
2209                                 NULL, NULL, NULL, NULL, NULL);
2210         if (NT_STATUS_IS_OK(status)) {
2211                 return NT_STATUS_OBJECT_NAME_COLLISION;
2212         }
2213
2214         status = pdb_set_secret(r->in.name.string, NULL, NULL, psd);
2215         if (!NT_STATUS_IS_OK(status)) {
2216                 return status;
2217         }
2218
2219         status = create_lsa_policy_handle(p->mem_ctx, p,
2220                                           LSA_HANDLE_SECRET_TYPE,
2221                                           acc_granted,
2222                                           NULL,
2223                                           r->in.name.string,
2224                                           psd,
2225                                           r->out.sec_handle);
2226         if (!NT_STATUS_IS_OK(status)) {
2227                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2228         }
2229
2230         return NT_STATUS_OK;
2231 }
2232
2233 /***************************************************************************
2234  _lsa_SetSecret
2235  ***************************************************************************/
2236
2237 NTSTATUS _lsa_SetSecret(struct pipes_struct *p,
2238                         struct lsa_SetSecret *r)
2239 {
2240         NTSTATUS status;
2241         struct lsa_info *info = NULL;
2242         DATA_BLOB blob_new, blob_old;
2243         DATA_BLOB cleartext_blob_new = data_blob_null;
2244         DATA_BLOB cleartext_blob_old = data_blob_null;
2245         DATA_BLOB *cleartext_blob_new_p = NULL;
2246         DATA_BLOB *cleartext_blob_old_p = NULL;
2247
2248         if (!find_policy_by_hnd(p, r->in.sec_handle, (void **)(void *)&info)) {
2249                 return NT_STATUS_INVALID_HANDLE;
2250         }
2251
2252         if (info->type != LSA_HANDLE_SECRET_TYPE) {
2253                 return NT_STATUS_INVALID_HANDLE;
2254         }
2255
2256         if (!(info->access & LSA_SECRET_SET_VALUE)) {
2257                 return NT_STATUS_ACCESS_DENIED;
2258         }
2259
2260         if (r->in.new_val) {
2261                 blob_new = data_blob_const(r->in.new_val->data,
2262                                            r->in.new_val->length);
2263
2264                 status = sess_decrypt_blob(p->mem_ctx, &blob_new,
2265                                            &p->session_info->session_key,
2266                                            &cleartext_blob_new);
2267                 if (!NT_STATUS_IS_OK(status)) {
2268                         return status;
2269                 }
2270
2271                 cleartext_blob_new_p = &cleartext_blob_new;
2272         }
2273
2274         if (r->in.old_val) {
2275                 blob_old = data_blob_const(r->in.old_val->data,
2276                                            r->in.old_val->length);
2277
2278                 status = sess_decrypt_blob(p->mem_ctx, &blob_old,
2279                                            &p->session_info->session_key,
2280                                            &cleartext_blob_old);
2281                 if (!NT_STATUS_IS_OK(status)) {
2282                         return status;
2283                 }
2284
2285                 cleartext_blob_old_p = &cleartext_blob_old;
2286         }
2287
2288         status = pdb_set_secret(info->name, cleartext_blob_new_p, cleartext_blob_old_p, NULL);
2289         if (!NT_STATUS_IS_OK(status)) {
2290                 return status;
2291         }
2292
2293 #ifdef DEBUG_PASSWORD
2294         DEBUG(10,("_lsa_SetSecret: successfully set new secret\n"));
2295         dump_data(10, cleartext_blob_new.data, cleartext_blob_new.length);
2296         DEBUG(10,("_lsa_SetSecret: successfully set old secret\n"));
2297         dump_data(10, cleartext_blob_old.data, cleartext_blob_old.length);
2298 #endif
2299
2300         return NT_STATUS_OK;
2301 }
2302
2303 /***************************************************************************
2304  _lsa_QuerySecret
2305  ***************************************************************************/
2306
2307 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
2308                           struct lsa_QuerySecret *r)
2309 {
2310         struct lsa_info *info = NULL;
2311         DATA_BLOB blob_new, blob_old;
2312         DATA_BLOB blob_new_crypt, blob_old_crypt;
2313         NTTIME nttime_new, nttime_old;
2314         NTSTATUS status;
2315
2316         if (!find_policy_by_hnd(p, r->in.sec_handle, (void **)(void *)&info)) {
2317                 return NT_STATUS_INVALID_HANDLE;
2318         }
2319
2320         if (info->type != LSA_HANDLE_SECRET_TYPE) {
2321                 return NT_STATUS_INVALID_HANDLE;
2322         }
2323
2324         if (!(info->access & LSA_SECRET_QUERY_VALUE)) {
2325                 return NT_STATUS_ACCESS_DENIED;
2326         }
2327
2328         status = pdb_get_secret(p->mem_ctx, info->name,
2329                                 &blob_new, &nttime_new,
2330                                 &blob_old, &nttime_old,
2331                                 NULL);
2332         if (!NT_STATUS_IS_OK(status)) {
2333                 return status;
2334         }
2335
2336         if (r->in.new_val) {
2337                 if (blob_new.length) {
2338                         if (!r->out.new_val->buf) {
2339                                 r->out.new_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2340                         }
2341                         if (!r->out.new_val->buf) {
2342                                 return NT_STATUS_NO_MEMORY;
2343                         }
2344
2345                         blob_new_crypt = sess_encrypt_blob(p->mem_ctx, &blob_new,
2346                                                            &p->session_info->session_key);
2347                         if (!blob_new_crypt.length) {
2348                                 return NT_STATUS_NO_MEMORY;
2349                         }
2350
2351                         r->out.new_val->buf->data       = blob_new_crypt.data;
2352                         r->out.new_val->buf->length     = blob_new_crypt.length;
2353                         r->out.new_val->buf->size       = blob_new_crypt.length;
2354                 }
2355         }
2356
2357         if (r->in.old_val) {
2358                 if (blob_old.length) {
2359                         if (!r->out.old_val->buf) {
2360                                 r->out.old_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2361                         }
2362                         if (!r->out.old_val->buf) {
2363                                 return NT_STATUS_NO_MEMORY;
2364                         }
2365
2366                         blob_old_crypt = sess_encrypt_blob(p->mem_ctx, &blob_old,
2367                                                            &p->session_info->session_key);
2368                         if (!blob_old_crypt.length) {
2369                                 return NT_STATUS_NO_MEMORY;
2370                         }
2371
2372                         r->out.old_val->buf->data       = blob_old_crypt.data;
2373                         r->out.old_val->buf->length     = blob_old_crypt.length;
2374                         r->out.old_val->buf->size       = blob_old_crypt.length;
2375                 }
2376         }
2377
2378         if (r->out.new_mtime) {
2379                 *r->out.new_mtime = nttime_new;
2380         }
2381
2382         if (r->out.old_mtime) {
2383                 *r->out.old_mtime = nttime_old;
2384         }
2385
2386         return NT_STATUS_OK;
2387 }
2388
2389 /***************************************************************************
2390  _lsa_DeleteObject
2391  ***************************************************************************/
2392
2393 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2394                            struct lsa_DeleteObject *r)
2395 {
2396         NTSTATUS status;
2397         struct lsa_info *info = NULL;
2398
2399         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2400                 return NT_STATUS_INVALID_HANDLE;
2401         }
2402
2403         if (!(info->access & SEC_STD_DELETE)) {
2404                 return NT_STATUS_ACCESS_DENIED;
2405         }
2406
2407         switch (info->type) {
2408         case LSA_HANDLE_ACCOUNT_TYPE:
2409                 status = privilege_delete_account(&info->sid);
2410                 if (!NT_STATUS_IS_OK(status)) {
2411                         DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2412                                 nt_errstr(status)));
2413                         return status;
2414                 }
2415                 break;
2416         case LSA_HANDLE_TRUST_TYPE:
2417                 if (!pdb_del_trusteddom_pw(info->name)) {
2418                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2419                 }
2420                 status = NT_STATUS_OK;
2421                 break;
2422         case LSA_HANDLE_SECRET_TYPE:
2423                 status = pdb_delete_secret(info->name);
2424                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2425                         return NT_STATUS_INVALID_HANDLE;
2426                 }
2427                 break;
2428         default:
2429                 return NT_STATUS_INVALID_HANDLE;
2430         }
2431
2432         close_policy_hnd(p, r->in.handle);
2433         ZERO_STRUCTP(r->out.handle);
2434
2435         return status;
2436 }
2437
2438 /***************************************************************************
2439  _lsa_EnumPrivs
2440  ***************************************************************************/
2441
2442 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2443                         struct lsa_EnumPrivs *r)
2444 {
2445         struct lsa_info *handle;
2446         uint32 i;
2447         uint32 enum_context = *r->in.resume_handle;
2448         int num_privs = num_privileges_in_short_list();
2449         struct lsa_PrivEntry *entries = NULL;
2450
2451         /* remember that the enum_context starts at 0 and not 1 */
2452
2453         if ( enum_context >= num_privs )
2454                 return NT_STATUS_NO_MORE_ENTRIES;
2455
2456         DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2457                 enum_context, num_privs));
2458
2459         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2460                 return NT_STATUS_INVALID_HANDLE;
2461
2462         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2463                 return NT_STATUS_INVALID_HANDLE;
2464         }
2465
2466         /* check if the user has enough rights
2467            I don't know if it's the right one. not documented.  */
2468
2469         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2470                 return NT_STATUS_ACCESS_DENIED;
2471
2472         if (num_privs) {
2473                 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2474                 if (!entries) {
2475                         return NT_STATUS_NO_MEMORY;
2476                 }
2477         } else {
2478                 entries = NULL;
2479         }
2480
2481         for (i = 0; i < num_privs; i++) {
2482                 if( i < enum_context) {
2483
2484                         init_lsa_StringLarge(&entries[i].name, NULL);
2485
2486                         entries[i].luid.low = 0;
2487                         entries[i].luid.high = 0;
2488                 } else {
2489
2490                         init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2491
2492                         entries[i].luid.low = sec_privilege_from_index(i);
2493                         entries[i].luid.high = 0;
2494                 }
2495         }
2496
2497         enum_context = num_privs;
2498
2499         *r->out.resume_handle = enum_context;
2500         r->out.privs->count = num_privs;
2501         r->out.privs->privs = entries;
2502
2503         return NT_STATUS_OK;
2504 }
2505
2506 /***************************************************************************
2507  _lsa_LookupPrivDisplayName
2508  ***************************************************************************/
2509
2510 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2511                                     struct lsa_LookupPrivDisplayName *r)
2512 {
2513         struct lsa_info *handle;
2514         const char *description;
2515         struct lsa_StringLarge *lsa_name;
2516
2517         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2518                 return NT_STATUS_INVALID_HANDLE;
2519
2520         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2521                 return NT_STATUS_INVALID_HANDLE;
2522         }
2523
2524         /* check if the user has enough rights */
2525
2526         /*
2527          * I don't know if it's the right one. not documented.
2528          */
2529         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2530                 return NT_STATUS_ACCESS_DENIED;
2531
2532         DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2533
2534         description = get_privilege_dispname(r->in.name->string);
2535         if (!description) {
2536                 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2537                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2538         }
2539
2540         DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2541
2542         lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2543         if (!lsa_name) {
2544                 return NT_STATUS_NO_MEMORY;
2545         }
2546
2547         init_lsa_StringLarge(lsa_name, description);
2548
2549         *r->out.returned_language_id = r->in.language_id;
2550         *r->out.disp_name = lsa_name;
2551
2552         return NT_STATUS_OK;
2553 }
2554
2555 /***************************************************************************
2556  _lsa_EnumAccounts
2557  ***************************************************************************/
2558
2559 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2560                            struct lsa_EnumAccounts *r)
2561 {
2562         struct lsa_info *handle;
2563         struct dom_sid *sid_list;
2564         int i, j, num_entries;
2565         NTSTATUS status;
2566         struct lsa_SidPtr *sids = NULL;
2567
2568         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2569                 return NT_STATUS_INVALID_HANDLE;
2570
2571         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2572                 return NT_STATUS_INVALID_HANDLE;
2573         }
2574
2575         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2576                 return NT_STATUS_ACCESS_DENIED;
2577
2578         sid_list = NULL;
2579         num_entries = 0;
2580
2581         /* The only way we can currently find out all the SIDs that have been
2582            privileged is to scan all privileges */
2583
2584         status = privilege_enumerate_accounts(&sid_list, &num_entries);
2585         if (!NT_STATUS_IS_OK(status)) {
2586                 return status;
2587         }
2588
2589         if (*r->in.resume_handle >= num_entries) {
2590                 return NT_STATUS_NO_MORE_ENTRIES;
2591         }
2592
2593         if (num_entries - *r->in.resume_handle) {
2594                 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2595                                          num_entries - *r->in.resume_handle);
2596                 if (!sids) {
2597                         talloc_free(sid_list);
2598                         return NT_STATUS_NO_MEMORY;
2599                 }
2600
2601                 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2602                         sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2603                         if (!sids[j].sid) {
2604                                 talloc_free(sid_list);
2605                                 return NT_STATUS_NO_MEMORY;
2606                         }
2607                 }
2608         }
2609
2610         talloc_free(sid_list);
2611
2612         *r->out.resume_handle = num_entries;
2613         r->out.sids->num_sids = num_entries;
2614         r->out.sids->sids = sids;
2615
2616         return NT_STATUS_OK;
2617 }
2618
2619 /***************************************************************************
2620  _lsa_GetUserName
2621  ***************************************************************************/
2622
2623 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2624                           struct lsa_GetUserName *r)
2625 {
2626         const char *username, *domname;
2627         struct lsa_String *account_name = NULL;
2628         struct lsa_String *authority_name = NULL;
2629
2630         if (r->in.account_name &&
2631            *r->in.account_name) {
2632                 return NT_STATUS_INVALID_PARAMETER;
2633         }
2634
2635         if (r->in.authority_name &&
2636            *r->in.authority_name) {
2637                 return NT_STATUS_INVALID_PARAMETER;
2638         }
2639
2640         if (security_session_user_level(p->session_info, NULL) < SECURITY_USER) {
2641                 /*
2642                  * I'm 99% sure this is not the right place to do this,
2643                  * global_sid_Anonymous should probably be put into the token
2644                  * instead of the guest id -- vl
2645                  */
2646                 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2647                                 &domname, &username, NULL)) {
2648                         return NT_STATUS_NO_MEMORY;
2649                 }
2650         } else {
2651                 username = p->session_info->unix_info->sanitized_username;
2652                 domname = p->session_info->info->domain_name;
2653         }
2654
2655         account_name = talloc(p->mem_ctx, struct lsa_String);
2656         if (!account_name) {
2657                 return NT_STATUS_NO_MEMORY;
2658         }
2659         init_lsa_String(account_name, username);
2660
2661         if (r->out.authority_name) {
2662                 authority_name = talloc(p->mem_ctx, struct lsa_String);
2663                 if (!authority_name) {
2664                         return NT_STATUS_NO_MEMORY;
2665                 }
2666                 init_lsa_String(authority_name, domname);
2667         }
2668
2669         *r->out.account_name = account_name;
2670         if (r->out.authority_name) {
2671                 *r->out.authority_name = authority_name;
2672         }
2673
2674         return NT_STATUS_OK;
2675 }
2676
2677 /***************************************************************************
2678  _lsa_CreateAccount
2679  ***************************************************************************/
2680
2681 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2682                             struct lsa_CreateAccount *r)
2683 {
2684         NTSTATUS status;
2685         struct lsa_info *handle;
2686         uint32_t acc_granted;
2687         struct security_descriptor *psd;
2688         size_t sd_size;
2689
2690         /* find the connection policy handle. */
2691         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2692                 return NT_STATUS_INVALID_HANDLE;
2693
2694         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2695                 return NT_STATUS_INVALID_HANDLE;
2696         }
2697
2698         /* check if the user has enough rights */
2699
2700         if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2701                 return NT_STATUS_ACCESS_DENIED;
2702         }
2703
2704         /* Work out max allowed. */
2705         map_max_allowed_access(p->session_info->security_token,
2706                                p->session_info->unix_token,
2707                                &r->in.access_mask);
2708
2709         /* map the generic bits to the lsa policy ones */
2710         se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2711
2712         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2713                                     &lsa_account_mapping,
2714                                     r->in.sid, LSA_POLICY_ALL_ACCESS);
2715         if (!NT_STATUS_IS_OK(status)) {
2716                 return status;
2717         }
2718
2719         status = access_check_object(psd, p->session_info->security_token,
2720                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2721                                      &acc_granted, "_lsa_CreateAccount");
2722         if (!NT_STATUS_IS_OK(status)) {
2723                 return status;
2724         }
2725
2726         if ( is_privileged_sid( r->in.sid ) )
2727                 return NT_STATUS_OBJECT_NAME_COLLISION;
2728
2729         status = create_lsa_policy_handle(p->mem_ctx, p,
2730                                           LSA_HANDLE_ACCOUNT_TYPE,
2731                                           acc_granted,
2732                                           r->in.sid,
2733                                           NULL,
2734                                           psd,
2735                                           r->out.acct_handle);
2736         if (!NT_STATUS_IS_OK(status)) {
2737                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2738         }
2739
2740         return privilege_create_account(r->in.sid);
2741 }
2742
2743 /***************************************************************************
2744  _lsa_OpenAccount
2745  ***************************************************************************/
2746
2747 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2748                           struct lsa_OpenAccount *r)
2749 {
2750         struct lsa_info *handle;
2751         struct security_descriptor *psd = NULL;
2752         size_t sd_size;
2753         uint32_t des_access = r->in.access_mask;
2754         uint32_t acc_granted;
2755         NTSTATUS status;
2756
2757         /* find the connection policy handle. */
2758         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2759                 return NT_STATUS_INVALID_HANDLE;
2760
2761         if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2762                 return NT_STATUS_INVALID_HANDLE;
2763         }
2764
2765         /* des_access is for the account here, not the policy
2766          * handle - so don't check against policy handle. */
2767
2768         /* Work out max allowed. */
2769         map_max_allowed_access(p->session_info->security_token,
2770                                p->session_info->unix_token,
2771                                &des_access);
2772
2773         /* map the generic bits to the lsa account ones */
2774         se_map_generic(&des_access, &lsa_account_mapping);
2775
2776         /* get the generic lsa account SD until we store it */
2777         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2778                                 &lsa_account_mapping,
2779                                 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2780         if (!NT_STATUS_IS_OK(status)) {
2781                 return status;
2782         }
2783
2784         status = access_check_object(psd, p->session_info->security_token,
2785                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2786                                      &acc_granted, "_lsa_OpenAccount" );
2787         if (!NT_STATUS_IS_OK(status)) {
2788                 return status;
2789         }
2790
2791         /* TODO: Fis the parsing routine before reenabling this check! */
2792         #if 0
2793         if (!lookup_sid(&handle->sid, dom_name, name, &type))
2794                 return NT_STATUS_ACCESS_DENIED;
2795         #endif
2796
2797         status = create_lsa_policy_handle(p->mem_ctx, p,
2798                                           LSA_HANDLE_ACCOUNT_TYPE,
2799                                           acc_granted,
2800                                           r->in.sid,
2801                                           NULL,
2802                                           psd,
2803                                           r->out.acct_handle);
2804         if (!NT_STATUS_IS_OK(status)) {
2805                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2806         }
2807
2808         return NT_STATUS_OK;
2809 }
2810
2811 /***************************************************************************
2812  _lsa_EnumPrivsAccount
2813  For a given SID, enumerate all the privilege this account has.
2814  ***************************************************************************/
2815
2816 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2817                                struct lsa_EnumPrivsAccount *r)
2818 {
2819         NTSTATUS status = NT_STATUS_OK;
2820         struct lsa_info *info=NULL;
2821         PRIVILEGE_SET *privileges;
2822         struct lsa_PrivilegeSet *priv_set = NULL;
2823
2824         /* find the connection policy handle. */
2825         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2826                 return NT_STATUS_INVALID_HANDLE;
2827
2828         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2829                 return NT_STATUS_INVALID_HANDLE;
2830         }
2831
2832         if (!(info->access & LSA_ACCOUNT_VIEW))
2833                 return NT_STATUS_ACCESS_DENIED;
2834
2835         status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2836         if (!NT_STATUS_IS_OK(status)) {
2837                 return status;
2838         }
2839
2840         *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2841         if (!priv_set) {
2842                 return NT_STATUS_NO_MEMORY;
2843         }
2844
2845         DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2846                   sid_string_dbg(&info->sid),
2847                   privileges->count));
2848
2849         priv_set->count = privileges->count;
2850         priv_set->unknown = 0;
2851         priv_set->set = talloc_move(priv_set, &privileges->set);
2852
2853         return status;
2854 }
2855
2856 /***************************************************************************
2857  _lsa_GetSystemAccessAccount
2858  ***************************************************************************/
2859
2860 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2861                                      struct lsa_GetSystemAccessAccount *r)
2862 {
2863         NTSTATUS status;
2864         struct lsa_info *info = NULL;
2865         struct lsa_EnumPrivsAccount e;
2866         struct lsa_PrivilegeSet *privset;
2867
2868         /* find the connection policy handle. */
2869
2870         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2871                 return NT_STATUS_INVALID_HANDLE;
2872
2873         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2874                 return NT_STATUS_INVALID_HANDLE;
2875         }
2876
2877         if (!(info->access & LSA_ACCOUNT_VIEW))
2878                 return NT_STATUS_ACCESS_DENIED;
2879
2880         privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2881         if (!privset) {
2882                 return NT_STATUS_NO_MEMORY;
2883         }
2884
2885         e.in.handle = r->in.handle;
2886         e.out.privs = &privset;
2887
2888         status = _lsa_EnumPrivsAccount(p, &e);
2889         if (!NT_STATUS_IS_OK(status)) {
2890                 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2891                         "failed to call _lsa_EnumPrivsAccount(): %s\n",
2892                         nt_errstr(status)));
2893                 return status;
2894         }
2895
2896         /* Samba4 would iterate over the privset to merge the policy mode bits,
2897          * not sure samba3 can do the same here, so just return what we did in
2898          * the past - gd */
2899
2900         /*
2901           0x01 -> Log on locally
2902           0x02 -> Access this computer from network
2903           0x04 -> Log on as a batch job
2904           0x10 -> Log on as a service
2905
2906           they can be ORed together
2907         */
2908
2909         *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2910                               LSA_POLICY_MODE_NETWORK;
2911
2912         return NT_STATUS_OK;
2913 }
2914
2915 /***************************************************************************
2916   update the systemaccount information
2917  ***************************************************************************/
2918
2919 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2920                                      struct lsa_SetSystemAccessAccount *r)
2921 {
2922         struct lsa_info *info=NULL;
2923         NTSTATUS status;
2924         GROUP_MAP *map;
2925
2926         /* find the connection policy handle. */
2927         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2928                 return NT_STATUS_INVALID_HANDLE;
2929
2930         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2931                 return NT_STATUS_INVALID_HANDLE;
2932         }
2933
2934         if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2935                 return NT_STATUS_ACCESS_DENIED;
2936         }
2937
2938         map = talloc_zero(p->mem_ctx, GROUP_MAP);
2939         if (!map) {
2940                 return NT_STATUS_NO_MEMORY;
2941         }
2942
2943         if (!pdb_getgrsid(map, info->sid)) {
2944                 TALLOC_FREE(map);
2945                 return NT_STATUS_NO_SUCH_GROUP;
2946         }
2947
2948         status = pdb_update_group_mapping_entry(map);
2949         TALLOC_FREE(map);
2950         return status;
2951 }
2952
2953 /***************************************************************************
2954  _lsa_AddPrivilegesToAccount
2955  For a given SID, add some privileges.
2956  ***************************************************************************/
2957
2958 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
2959                                      struct lsa_AddPrivilegesToAccount *r)
2960 {
2961         struct lsa_info *info = NULL;
2962         struct lsa_PrivilegeSet *set = NULL;
2963
2964         /* find the connection policy handle. */
2965         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2966                 return NT_STATUS_INVALID_HANDLE;
2967
2968         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2969                 return NT_STATUS_INVALID_HANDLE;
2970         }
2971
2972         if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2973                 return NT_STATUS_ACCESS_DENIED;
2974         }
2975
2976         set = r->in.privs;
2977
2978         if ( !grant_privilege_set( &info->sid, set ) ) {
2979                 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
2980                          sid_string_dbg(&info->sid) ));
2981                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2982         }
2983
2984         return NT_STATUS_OK;
2985 }
2986
2987 /***************************************************************************
2988  _lsa_RemovePrivilegesFromAccount
2989  For a given SID, remove some privileges.
2990  ***************************************************************************/
2991
2992 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2993                                           struct lsa_RemovePrivilegesFromAccount *r)
2994 {
2995         struct lsa_info *info = NULL;
2996         struct lsa_PrivilegeSet *set = NULL;
2997
2998         /* find the connection policy handle. */
2999         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3000                 return NT_STATUS_INVALID_HANDLE;
3001
3002         if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3003                 return NT_STATUS_INVALID_HANDLE;
3004         }
3005
3006         if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3007                 return NT_STATUS_ACCESS_DENIED;
3008         }
3009
3010         set = r->in.privs;
3011
3012         if ( !revoke_privilege_set( &info->sid, set) ) {
3013                 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
3014                          sid_string_dbg(&info->sid) ));
3015                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3016         }
3017
3018         return NT_STATUS_OK;
3019 }
3020
3021 /***************************************************************************
3022  _lsa_LookupPrivName
3023  ***************************************************************************/
3024
3025 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
3026                              struct lsa_LookupPrivName *r)
3027 {
3028         struct lsa_info *info = NULL;
3029         const char *name;
3030         struct lsa_StringLarge *lsa_name;
3031
3032         /* find the connection policy handle. */
3033         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3034                 return NT_STATUS_INVALID_HANDLE;
3035         }
3036
3037         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3038                 return NT_STATUS_INVALID_HANDLE;
3039         }
3040
3041         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
3042                 return NT_STATUS_ACCESS_DENIED;
3043         }
3044
3045         if (r->in.luid->high != 0) {
3046                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3047         }
3048
3049         name = sec_privilege_name(r->in.luid->low);
3050         if (!name) {
3051                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3052         }
3053
3054         lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
3055         if (!lsa_name) {
3056                 return NT_STATUS_NO_MEMORY;
3057         }
3058
3059         lsa_name->string = talloc_strdup(lsa_name, name);
3060         if (!lsa_name->string) {
3061                 TALLOC_FREE(lsa_name);
3062                 return NT_STATUS_NO_MEMORY;
3063         }
3064
3065         *r->out.name = lsa_name;
3066
3067         return NT_STATUS_OK;
3068 }
3069
3070 /***************************************************************************
3071  _lsa_QuerySecurity
3072  ***************************************************************************/
3073
3074 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
3075                             struct lsa_QuerySecurity *r)
3076 {
3077         struct lsa_info *handle=NULL;
3078         struct security_descriptor *psd = NULL;
3079         size_t sd_size = 0;
3080         NTSTATUS status;
3081
3082         /* find the connection policy handle. */
3083         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
3084                 return NT_STATUS_INVALID_HANDLE;
3085
3086         switch (handle->type) {
3087         case LSA_HANDLE_POLICY_TYPE:
3088         case LSA_HANDLE_ACCOUNT_TYPE:
3089         case LSA_HANDLE_TRUST_TYPE:
3090         case LSA_HANDLE_SECRET_TYPE:
3091                 psd = handle->sd;
3092                 sd_size = ndr_size_security_descriptor(psd, 0);
3093                 status = NT_STATUS_OK;
3094                 break;
3095         default:
3096                 status = NT_STATUS_INVALID_HANDLE;
3097                 break;
3098         }
3099
3100         if (!NT_STATUS_IS_OK(status)) {
3101                 return status;
3102         }
3103
3104         *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
3105         if (!*r->out.sdbuf) {
3106                 return NT_STATUS_NO_MEMORY;
3107         }
3108
3109         return status;
3110 }
3111
3112 /***************************************************************************
3113  _lsa_AddAccountRights
3114  ***************************************************************************/
3115
3116 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
3117                                struct lsa_AddAccountRights *r)
3118 {
3119         struct lsa_info *info = NULL;
3120         int i = 0;
3121         uint32_t acc_granted = 0;
3122         struct security_descriptor *psd = NULL;
3123         size_t sd_size;
3124         struct dom_sid sid;
3125         NTSTATUS status;
3126
3127         /* find the connection policy handle. */
3128         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3129                 return NT_STATUS_INVALID_HANDLE;
3130
3131         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3132                 return NT_STATUS_INVALID_HANDLE;
3133         }
3134
3135         /* get the generic lsa account SD for this SID until we store it */
3136         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3137                                 &lsa_account_mapping,
3138                                 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
3139         if (!NT_STATUS_IS_OK(status)) {
3140                 return status;
3141         }
3142
3143         /*
3144          * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3145          * on the policy handle. If it does, ask for
3146          * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3147          * on the account sid. We don't check here so just use the latter. JRA.
3148          */
3149
3150         status = access_check_object(psd, p->session_info->security_token,
3151                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3152                                      LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3153                                      &acc_granted, "_lsa_AddAccountRights" );
3154         if (!NT_STATUS_IS_OK(status)) {
3155                 return status;
3156         }
3157
3158         /* according to an NT4 PDC, you can add privileges to SIDs even without
3159            call_lsa_create_account() first.  And you can use any arbitrary SID. */
3160
3161         sid_copy( &sid, r->in.sid );
3162
3163         for ( i=0; i < r->in.rights->count; i++ ) {
3164
3165                 const char *privname = r->in.rights->names[i].string;
3166
3167                 /* only try to add non-null strings */
3168
3169                 if ( !privname )
3170                         continue;
3171
3172                 if ( !grant_privilege_by_name( &sid, privname ) ) {
3173                         DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3174                                 privname ));
3175                         return NT_STATUS_NO_SUCH_PRIVILEGE;
3176                 }
3177         }
3178
3179         return NT_STATUS_OK;
3180 }
3181
3182 /***************************************************************************
3183  _lsa_RemoveAccountRights
3184  ***************************************************************************/
3185
3186 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
3187                                   struct lsa_RemoveAccountRights *r)
3188 {
3189         struct lsa_info *info = NULL;
3190         int i = 0;
3191         struct security_descriptor *psd = NULL;
3192         size_t sd_size;
3193         struct dom_sid sid;
3194         const char *privname = NULL;
3195         uint32_t acc_granted = 0;
3196         NTSTATUS status;
3197
3198         /* find the connection policy handle. */
3199         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3200                 return NT_STATUS_INVALID_HANDLE;
3201
3202         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3203                 return NT_STATUS_INVALID_HANDLE;
3204         }
3205
3206         /* get the generic lsa account SD for this SID until we store it */
3207         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3208                                 &lsa_account_mapping,
3209                                 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
3210         if (!NT_STATUS_IS_OK(status)) {
3211                 return status;
3212         }
3213
3214         /*
3215          * From the MS DOCs. We need
3216          * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3217          * and DELETE on the account sid.
3218          */
3219
3220         status = access_check_object(psd, p->session_info->security_token,
3221                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3222                                      LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3223                                      LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
3224                                      &acc_granted, "_lsa_RemoveAccountRights");
3225         if (!NT_STATUS_IS_OK(status)) {
3226                 return status;
3227         }
3228
3229         sid_copy( &sid, r->in.sid );
3230
3231         if ( r->in.remove_all ) {
3232                 if ( !revoke_all_privileges( &sid ) )
3233                         return NT_STATUS_ACCESS_DENIED;
3234
3235                 return NT_STATUS_OK;
3236         }
3237
3238         for ( i=0; i < r->in.rights->count; i++ ) {
3239
3240                 privname = r->in.rights->names[i].string;
3241
3242                 /* only try to add non-null strings */
3243
3244                 if ( !privname )
3245                         continue;
3246
3247                 if ( !revoke_privilege_by_name( &sid, privname ) ) {
3248                         DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3249                                 privname ));
3250                         return NT_STATUS_NO_SUCH_PRIVILEGE;
3251                 }
3252         }
3253
3254         return NT_STATUS_OK;
3255 }
3256
3257 /*******************************************************************
3258 ********************************************************************/
3259
3260 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3261                                    struct lsa_RightSet *r,
3262                                    PRIVILEGE_SET *privileges)
3263 {
3264         uint32 i;
3265         const char *privname;
3266         const char **privname_array = NULL;
3267         int num_priv = 0;
3268
3269         for (i=0; i<privileges->count; i++) {
3270                 if (privileges->set[i].luid.high) {
3271                         continue;
3272                 }
3273                 privname = sec_privilege_name(privileges->set[i].luid.low);
3274                 if (privname) {
3275                         if (!add_string_to_array(mem_ctx, privname,
3276                                                  &privname_array, &num_priv)) {
3277                                 return NT_STATUS_NO_MEMORY;
3278                         }
3279                 }
3280         }
3281
3282         if (num_priv) {
3283
3284                 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3285                                              num_priv);
3286                 if (!r->names) {
3287                         return NT_STATUS_NO_MEMORY;
3288                 }
3289
3290                 for (i=0; i<num_priv; i++) {
3291                         init_lsa_StringLarge(&r->names[i], privname_array[i]);
3292                 }
3293
3294                 r->count = num_priv;
3295         }
3296
3297         return NT_STATUS_OK;
3298 }
3299
3300 /***************************************************************************
3301  _lsa_EnumAccountRights
3302  ***************************************************************************/
3303
3304 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3305                                 struct lsa_EnumAccountRights *r)
3306 {
3307         NTSTATUS status;
3308         struct lsa_info *info = NULL;
3309         PRIVILEGE_SET *privileges;
3310
3311         /* find the connection policy handle. */
3312
3313         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3314                 return NT_STATUS_INVALID_HANDLE;
3315
3316         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3317                 return NT_STATUS_INVALID_HANDLE;
3318         }
3319
3320         if (!(info->access & LSA_ACCOUNT_VIEW)) {
3321                 return NT_STATUS_ACCESS_DENIED;
3322         }
3323
3324         /* according to an NT4 PDC, you can add privileges to SIDs even without
3325            call_lsa_create_account() first.  And you can use any arbitrary SID. */
3326
3327         /* according to MS-LSAD 3.1.4.5.10 it is required to return
3328          * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3329          * the lsa database */
3330
3331         status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3332         if (!NT_STATUS_IS_OK(status)) {
3333                 return status;
3334         }
3335
3336         DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3337                   sid_string_dbg(r->in.sid), privileges->count));
3338
3339         status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3340
3341         return status;
3342 }
3343
3344 /***************************************************************************
3345  _lsa_LookupPrivValue
3346  ***************************************************************************/
3347
3348 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3349                               struct lsa_LookupPrivValue *r)
3350 {
3351         struct lsa_info *info = NULL;
3352         const char *name = NULL;
3353
3354         /* find the connection policy handle. */
3355
3356         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3357                 return NT_STATUS_INVALID_HANDLE;
3358
3359         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3360                 return NT_STATUS_INVALID_HANDLE;
3361         }
3362
3363         if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3364                 return NT_STATUS_ACCESS_DENIED;
3365
3366         name = r->in.name->string;
3367
3368         DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3369
3370         r->out.luid->low = sec_privilege_id(name);
3371         r->out.luid->high = 0;
3372         if (r->out.luid->low == SEC_PRIV_INVALID) {
3373                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3374         }
3375         return NT_STATUS_OK;
3376 }
3377
3378 /***************************************************************************
3379  _lsa_EnumAccountsWithUserRight
3380  ***************************************************************************/
3381
3382 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3383                                         struct lsa_EnumAccountsWithUserRight *r)
3384 {
3385         NTSTATUS status;
3386         struct lsa_info *info = NULL;
3387         struct dom_sid *sids = NULL;
3388         int num_sids = 0;
3389         uint32_t i;
3390         enum sec_privilege privilege;
3391
3392         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3393                 return NT_STATUS_INVALID_HANDLE;
3394         }
3395
3396         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3397                 return NT_STATUS_INVALID_HANDLE;
3398         }
3399
3400         if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3401                 return NT_STATUS_ACCESS_DENIED;
3402         }
3403
3404         if (!r->in.name || !r->in.name->string) {
3405                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3406         }
3407
3408         privilege = sec_privilege_id(r->in.name->string);
3409         if (privilege == SEC_PRIV_INVALID) {
3410                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3411         }
3412
3413         status = privilege_enum_sids(privilege, p->mem_ctx,
3414                                      &sids, &num_sids);
3415         if (!NT_STATUS_IS_OK(status)) {
3416                 return status;
3417         }
3418
3419         r->out.sids->num_sids = num_sids;
3420         r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3421                                          r->out.sids->num_sids);
3422
3423         for (i=0; i < r->out.sids->num_sids; i++) {
3424                 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3425                                                           &sids[i]);
3426                 if (!r->out.sids->sids[i].sid) {
3427                         TALLOC_FREE(r->out.sids->sids);
3428                         r->out.sids->num_sids = 0;
3429                         return NT_STATUS_NO_MEMORY;
3430                 }
3431         }
3432
3433         return NT_STATUS_OK;
3434 }
3435
3436 /***************************************************************************
3437  _lsa_Delete
3438  ***************************************************************************/
3439
3440 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3441                      struct lsa_Delete *r)
3442 {
3443         return NT_STATUS_NOT_SUPPORTED;
3444 }
3445
3446 static NTSTATUS info_ex_2_pdb_trusted_domain(
3447                                       struct lsa_TrustDomainInfoInfoEx *info_ex,
3448                                       struct pdb_trusted_domain *td)
3449 {
3450         if (info_ex->domain_name.string == NULL ||
3451             info_ex->netbios_name.string == NULL ||
3452             info_ex->sid == NULL) {
3453                 return NT_STATUS_INVALID_PARAMETER;
3454         }
3455
3456         td->domain_name = talloc_strdup(td, info_ex->domain_name.string);
3457         td->netbios_name = talloc_strdup(td, info_ex->netbios_name.string);
3458         sid_copy(&td->security_identifier, info_ex->sid);
3459         if (td->domain_name == NULL ||
3460             td->netbios_name == NULL ||
3461             is_null_sid(&td->security_identifier)) {
3462                 return NT_STATUS_NO_MEMORY;
3463         }
3464         td->trust_direction = info_ex->trust_direction;
3465         td->trust_type = info_ex->trust_type;
3466         td->trust_attributes = info_ex->trust_attributes;
3467
3468         return NT_STATUS_OK;
3469 }
3470
3471 static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p,
3472                                        TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
3473                                        struct trustDomainPasswords *auth_struct)
3474 {
3475         enum ndr_err_code ndr_err;
3476
3477         arcfour_crypt_blob(auth_blob->data, auth_blob->length,
3478                            &p->session_info->session_key);
3479         ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
3480                                        auth_struct,
3481                                        (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
3482         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3483                 return NT_STATUS_INVALID_PARAMETER;
3484         }
3485
3486         return NT_STATUS_OK;
3487 }
3488
3489 static NTSTATUS get_trustauth_inout_blob(TALLOC_CTX *mem_ctx,
3490                                          struct trustAuthInOutBlob *iopw,
3491                                          DATA_BLOB *trustauth_blob)
3492 {
3493         enum ndr_err_code ndr_err;
3494
3495         ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
3496                                        iopw,
3497                                        (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
3498         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3499                 return NT_STATUS_INVALID_PARAMETER;
3500         }
3501
3502         return NT_STATUS_OK;
3503 }
3504
3505 static NTSTATUS setInfoTrustedDomain_base(struct pipes_struct *p,
3506                                           TALLOC_CTX *mem_ctx,
3507                                           struct lsa_info *policy,
3508                                           enum lsa_TrustDomInfoEnum level,
3509                                           union lsa_TrustedDomainInfo *info)
3510 {
3511         struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
3512         DATA_BLOB auth_blob;
3513         struct trustDomainPasswords auth_struct;
3514         NTSTATUS nt_status;
3515
3516         struct pdb_trusted_domain *td;
3517         struct pdb_trusted_domain *orig_td;
3518
3519         td = talloc_zero(mem_ctx, struct pdb_trusted_domain);
3520         if (td == NULL) {
3521                 return NT_STATUS_NO_MEMORY;
3522         }
3523
3524         switch (level) {
3525         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
3526                 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3527                         return NT_STATUS_ACCESS_DENIED;
3528                 }
3529                 td->trust_posix_offset = &info->posix_offset.posix_offset;
3530                 break;
3531         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
3532                 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3533                         return NT_STATUS_ACCESS_DENIED;
3534                 }
3535                 nt_status = info_ex_2_pdb_trusted_domain(&info->info_ex, td);
3536                 if (!NT_STATUS_IS_OK(nt_status)) {
3537                         return nt_status;
3538                 }
3539                 break;
3540         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
3541                 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3542                         return NT_STATUS_ACCESS_DENIED;
3543                 }
3544                 nt_status = auth_info_2_auth_blob(td, &info->auth_info,
3545                                                   &td->trust_auth_incoming,
3546                                                   &td->trust_auth_outgoing);
3547                 if (!NT_STATUS_IS_OK(nt_status)) {
3548                         return nt_status;
3549                 }
3550                 break;
3551         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
3552                 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3553                         return NT_STATUS_ACCESS_DENIED;
3554                 }
3555                 td->trust_posix_offset = &info->full_info.posix_offset.posix_offset;
3556                 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info.info_ex,
3557                                                          td);
3558                 if (!NT_STATUS_IS_OK(nt_status)) {
3559                         return nt_status;
3560                 }
3561                 nt_status = auth_info_2_auth_blob(td,
3562                                                   &info->full_info.auth_info,
3563                                                   &td->trust_auth_incoming,
3564                                                   &td->trust_auth_outgoing);
3565                 if (!NT_STATUS_IS_OK(nt_status)) {
3566                         return nt_status;
3567                 }
3568                 break;
3569         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
3570                 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3571                         return NT_STATUS_ACCESS_DENIED;
3572                 }
3573                 auth_info_int = &info->auth_info_internal;
3574                 break;
3575         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
3576                 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3577                         return NT_STATUS_ACCESS_DENIED;
3578                 }
3579                 td->trust_posix_offset = &info->full_info_internal.posix_offset.posix_offset;
3580                 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info_internal.info_ex,
3581                                                          td);
3582                 if (!NT_STATUS_IS_OK(nt_status)) {
3583                         return nt_status;
3584                 }
3585                 auth_info_int = &info->full_info_internal.auth_info;
3586                 break;
3587         case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
3588                 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3589                         return NT_STATUS_ACCESS_DENIED;
3590                 }
3591                 td->supported_enc_type = &info->enc_types.enc_types;
3592                 break;
3593         default:
3594                 return NT_STATUS_INVALID_PARAMETER;
3595         }
3596
3597         /* decode auth_info_int if set */
3598         if (auth_info_int) {
3599
3600                 /* now decrypt blob */
3601                 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
3602                                             auth_info_int->auth_blob.size);
3603
3604                 nt_status = get_trustdom_auth_blob(p, mem_ctx,
3605                                                    &auth_blob, &auth_struct);
3606                 if (!NT_STATUS_IS_OK(nt_status)) {
3607                         return nt_status;
3608                 }
3609         } else {
3610             memset(&auth_struct, 0, sizeof(auth_struct));
3611         }
3612
3613 /* TODO: verify only one object matches the dns/netbios/sid triplet and that
3614  * this is the one we already have */
3615
3616 /* TODO: check if the trust direction is changed and we need to add or remove
3617  * auth data */
3618
3619 /* TODO: check if trust type shall be changed and return an error in this case
3620  * */
3621         nt_status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &policy->sid,
3622                                                &orig_td);
3623         if (!NT_STATUS_IS_OK(nt_status)) {
3624                 return nt_status;
3625         }
3626
3627
3628         /* TODO: should we fetch previous values from the existing entry
3629          * and append them ? */
3630         if (auth_struct.incoming.count) {
3631                 nt_status = get_trustauth_inout_blob(mem_ctx,
3632                                                      &auth_struct.incoming,
3633                                                      &td->trust_auth_incoming);
3634                 if (!NT_STATUS_IS_OK(nt_status)) {
3635                         return nt_status;
3636                 }
3637         } else {
3638                 ZERO_STRUCT(td->trust_auth_incoming);
3639         }
3640
3641         if (auth_struct.outgoing.count) {
3642                 nt_status = get_trustauth_inout_blob(mem_ctx,
3643                                                      &auth_struct.outgoing,
3644                                                      &td->trust_auth_outgoing);
3645                 if (!NT_STATUS_IS_OK(nt_status)) {
3646                         return nt_status;
3647                 }
3648         } else {
3649                 ZERO_STRUCT(td->trust_auth_outgoing);
3650         }
3651
3652         nt_status = pdb_set_trusted_domain(orig_td->domain_name, td);
3653         if (!NT_STATUS_IS_OK(nt_status)) {
3654                 return nt_status;
3655         }
3656
3657         return NT_STATUS_OK;
3658 }
3659
3660 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3661                                    struct lsa_SetTrustedDomainInfo *r)
3662 {
3663         NTSTATUS status;
3664         struct policy_handle trustdom_handle;
3665         struct lsa_OpenTrustedDomain o;
3666         struct lsa_SetInformationTrustedDomain s;
3667         struct lsa_Close c;
3668
3669         o.in.handle             = r->in.handle;
3670         o.in.sid                = r->in.dom_sid;
3671         o.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
3672         o.out.trustdom_handle   = &trustdom_handle;
3673
3674         status = _lsa_OpenTrustedDomain(p, &o);
3675         if (!NT_STATUS_IS_OK(status)) {
3676                 return status;
3677         }
3678
3679         s.in.trustdom_handle    = &trustdom_handle;
3680         s.in.level              = r->in.level;
3681         s.in.info               = r->in.info;
3682
3683         status = _lsa_SetInformationTrustedDomain(p, &s);
3684         if (!NT_STATUS_IS_OK(status)) {
3685                 return status;
3686         }
3687
3688         c.in.handle             = &trustdom_handle;
3689         c.out.handle            = &trustdom_handle;
3690
3691         return _lsa_Close(p, &c);
3692 }
3693
3694 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3695                                          struct lsa_SetTrustedDomainInfoByName *r)
3696 {
3697         NTSTATUS status;
3698         struct policy_handle trustdom_handle;
3699         struct lsa_OpenTrustedDomainByName o;
3700         struct lsa_SetInformationTrustedDomain s;
3701         struct lsa_Close c;
3702
3703         o.in.handle             = r->in.handle;
3704         o.in.name.string        = r->in.trusted_domain->string;
3705         o.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
3706         o.out.trustdom_handle   = &trustdom_handle;
3707
3708         status = _lsa_OpenTrustedDomainByName(p, &o);
3709         if (!NT_STATUS_IS_OK(status)) {
3710                 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
3711                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3712                 }
3713                 return status;
3714         }
3715
3716         s.in.trustdom_handle    = &trustdom_handle;
3717         s.in.level              = r->in.level;
3718         s.in.info               = r->in.info;
3719
3720         status = _lsa_SetInformationTrustedDomain(p, &s);
3721         if (!NT_STATUS_IS_OK(status)) {
3722                 return status;
3723         }
3724
3725         c.in.handle             = &trustdom_handle;
3726         c.out.handle            = &trustdom_handle;
3727
3728         return _lsa_Close(p, &c);
3729 }
3730
3731 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3732                                           struct lsa_SetInformationTrustedDomain *r)
3733 {
3734         struct lsa_info *policy;
3735
3736         if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&policy)) {
3737                 return NT_STATUS_INVALID_HANDLE;
3738         }
3739
3740         if (policy->type != LSA_HANDLE_TRUST_TYPE) {
3741                 return NT_STATUS_INVALID_HANDLE;
3742         }
3743
3744         return setInfoTrustedDomain_base(p, p->mem_ctx, policy,
3745                                          r->in.level, r->in.info);
3746 }
3747
3748
3749 /*
3750  * From here on the server routines are just dummy ones to make smbd link with
3751  * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3752  * pulling the server stubs across one by one.
3753  */
3754
3755 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3756 {
3757         p->rng_fault_state = True;
3758         return NT_STATUS_NOT_IMPLEMENTED;
3759 }
3760
3761 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3762                              struct lsa_ChangePassword *r)
3763 {
3764         p->rng_fault_state = True;
3765         return NT_STATUS_NOT_IMPLEMENTED;
3766 }
3767
3768 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3769 {
3770         p->rng_fault_state = True;
3771         return NT_STATUS_NOT_IMPLEMENTED;
3772 }
3773
3774 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3775 {
3776         p->rng_fault_state = True;
3777         return NT_STATUS_NOT_IMPLEMENTED;
3778 }
3779
3780 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3781                                   struct lsa_GetQuotasForAccount *r)
3782 {
3783         p->rng_fault_state = True;
3784         return NT_STATUS_NOT_IMPLEMENTED;
3785 }
3786
3787 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3788                                   struct lsa_SetQuotasForAccount *r)
3789 {
3790         p->rng_fault_state = True;
3791         return NT_STATUS_NOT_IMPLEMENTED;
3792 }
3793
3794 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3795                                struct lsa_StorePrivateData *r)
3796 {
3797         p->rng_fault_state = True;
3798         return NT_STATUS_NOT_IMPLEMENTED;
3799 }
3800
3801 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3802                                   struct lsa_RetrievePrivateData *r)
3803 {
3804         p->rng_fault_state = True;
3805         return NT_STATUS_NOT_IMPLEMENTED;
3806 }
3807
3808 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3809                              struct lsa_SetInfoPolicy2 *r)
3810 {
3811         p->rng_fault_state = True;
3812         return NT_STATUS_NOT_IMPLEMENTED;
3813 }
3814
3815 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3816                                    struct lsa_EnumTrustedDomainsEx *r)
3817 {
3818         struct lsa_info *info;
3819         uint32_t count;
3820         struct pdb_trusted_domain **domains;
3821         struct lsa_TrustDomainInfoInfoEx *entries;
3822         int i;
3823         NTSTATUS nt_status;
3824
3825         /* bail out early if pdb backend is not capable of ex trusted domains,
3826          * if we dont do that, the client might not call
3827          * _lsa_EnumTrustedDomains() afterwards - gd */
3828
3829         if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3830                 p->rng_fault_state = True;
3831                 return NT_STATUS_NOT_IMPLEMENTED;
3832         }
3833
3834         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3835                 return NT_STATUS_INVALID_HANDLE;
3836
3837         if (info->type != LSA_HANDLE_POLICY_TYPE) {
3838                 return NT_STATUS_INVALID_HANDLE;
3839         }
3840
3841         /* check if the user has enough rights */
3842         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3843                 return NT_STATUS_ACCESS_DENIED;
3844
3845         become_root();
3846         nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3847         unbecome_root();
3848
3849         if (!NT_STATUS_IS_OK(nt_status)) {
3850                 return nt_status;
3851         }
3852
3853         entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3854                                     count);
3855         if (!entries) {
3856                 return NT_STATUS_NO_MEMORY;
3857         }
3858
3859         for (i=0; i<count; i++) {
3860                 init_lsa_StringLarge(&entries[i].netbios_name,
3861                                      domains[i]->netbios_name);
3862                 entries[i].sid = &domains[i]->security_identifier;
3863         }
3864
3865         if (*r->in.resume_handle >= count) {
3866                 *r->out.resume_handle = -1;
3867                 TALLOC_FREE(entries);
3868                 return NT_STATUS_NO_MORE_ENTRIES;
3869         }
3870
3871         /* return the rest, limit by max_size. Note that we
3872            use the w2k3 element size value of 60 */
3873         r->out.domains->count = count - *r->in.resume_handle;
3874         r->out.domains->count = MIN(r->out.domains->count,
3875                                     (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3876
3877         r->out.domains->domains = entries + *r->in.resume_handle;
3878
3879         if (r->out.domains->count < count - *r->in.resume_handle) {
3880                 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3881                 return STATUS_MORE_ENTRIES;
3882         }
3883
3884         /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3885          * always be larger than the previous input resume handle, in
3886          * particular when hitting the last query it is vital to set the
3887          * resume handle correctly to avoid infinite client loops, as
3888          * seen e.g. with Windows XP SP3 when resume handle is 0 and
3889          * status is NT_STATUS_OK - gd */
3890
3891         *r->out.resume_handle = (uint32_t)-1;
3892
3893         return NT_STATUS_OK;
3894 }
3895
3896 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3897                                            struct lsa_QueryDomainInformationPolicy *r)
3898 {
3899         p->rng_fault_state = True;
3900         return NT_STATUS_NOT_IMPLEMENTED;
3901 }
3902
3903 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3904                                          struct lsa_SetDomainInformationPolicy *r)
3905 {
3906         p->rng_fault_state = True;
3907         return NT_STATUS_NOT_IMPLEMENTED;
3908 }
3909
3910 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3911 {
3912         p->rng_fault_state = True;
3913         return NT_STATUS_NOT_IMPLEMENTED;
3914 }
3915
3916 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3917 {
3918         p->rng_fault_state = True;
3919         return NT_STATUS_NOT_IMPLEMENTED;
3920 }
3921
3922 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3923 {
3924         p->rng_fault_state = True;
3925         return NT_STATUS_NOT_IMPLEMENTED;
3926 }
3927
3928 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3929 {
3930         p->rng_fault_state = True;
3931         return NT_STATUS_NOT_IMPLEMENTED;
3932 }
3933
3934 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3935                                           struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3936 {
3937         p->rng_fault_state = True;
3938         return NT_STATUS_NOT_IMPLEMENTED;
3939 }
3940
3941 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3942                                          struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3943 {
3944         p->rng_fault_state = True;
3945         return NT_STATUS_NOT_IMPLEMENTED;
3946 }
3947
3948 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3949 {
3950         p->rng_fault_state = True;
3951         return NT_STATUS_NOT_IMPLEMENTED;
3952 }
3953
3954 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3955                                  struct lsa_CREDRGETTARGETINFO *r)
3956 {
3957         p->rng_fault_state = True;
3958         return NT_STATUS_NOT_IMPLEMENTED;
3959 }
3960
3961 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3962                                  struct lsa_CREDRPROFILELOADED *r)
3963 {
3964         p->rng_fault_state = True;
3965         return NT_STATUS_NOT_IMPLEMENTED;
3966 }
3967
3968 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3969                                    struct lsa_CREDRGETSESSIONTYPES *r)
3970 {
3971         p->rng_fault_state = True;
3972         return NT_STATUS_NOT_IMPLEMENTED;
3973 }
3974
3975 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3976                                      struct lsa_LSARREGISTERAUDITEVENT *r)
3977 {
3978         p->rng_fault_state = True;
3979         return NT_STATUS_NOT_IMPLEMENTED;
3980 }
3981
3982 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3983                                 struct lsa_LSARGENAUDITEVENT *r)
3984 {
3985         p->rng_fault_state = True;
3986         return NT_STATUS_NOT_IMPLEMENTED;
3987 }
3988
3989 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3990                                        struct lsa_LSARUNREGISTERAUDITEVENT *r)
3991 {
3992         p->rng_fault_state = True;
3993         return NT_STATUS_NOT_IMPLEMENTED;
3994 }
3995
3996 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3997                                               struct lsa_lsaRQueryForestTrustInformation *r)
3998 {
3999         p->rng_fault_state = True;
4000         return NT_STATUS_NOT_IMPLEMENTED;
4001 }
4002
4003 #define DNS_CMP_MATCH 0
4004 #define DNS_CMP_FIRST_IS_CHILD 1
4005 #define DNS_CMP_SECOND_IS_CHILD 2
4006 #define DNS_CMP_NO_MATCH 3
4007
4008 /* this function assumes names are well formed DNS names.
4009  * it doesn't validate them */
4010 static int dns_cmp(const char *s1, size_t l1,
4011                    const char *s2, size_t l2)
4012 {
4013         const char *p1, *p2;
4014         size_t t1, t2;
4015         int cret;
4016
4017         if (l1 == l2) {
4018                 if (strcasecmp_m(s1, s2) == 0) {
4019                         return DNS_CMP_MATCH;
4020                 }
4021                 return DNS_CMP_NO_MATCH;
4022         }
4023
4024         if (l1 > l2) {
4025                 p1 = s1;
4026                 p2 = s2;
4027                 t1 = l1;
4028                 t2 = l2;
4029                 cret = DNS_CMP_FIRST_IS_CHILD;
4030         } else {
4031                 p1 = s2;
4032                 p2 = s1;
4033                 t1 = l2;
4034                 t2 = l1;
4035                 cret = DNS_CMP_SECOND_IS_CHILD;
4036         }
4037
4038         if (p1[t1 - t2 - 1] != '.') {
4039                 return DNS_CMP_NO_MATCH;
4040         }
4041
4042         if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
4043                 return cret;
4044         }
4045
4046         return DNS_CMP_NO_MATCH;
4047 }
4048
4049 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
4050                              struct lsa_ForestTrustInformation *lfti,
4051                              struct ForestTrustInfo *fti)
4052 {
4053         struct lsa_ForestTrustRecord *lrec;
4054         struct ForestTrustInfoRecord *rec;
4055         struct lsa_StringLarge *tln;
4056         struct lsa_ForestTrustDomainInfo *info;
4057         uint32_t i;
4058
4059         fti->version = 1;
4060         fti->count = lfti->count;
4061         fti->records = talloc_array(mem_ctx,
4062                                     struct ForestTrustInfoRecordArmor,
4063                                     fti->count);
4064         if (!fti->records) {
4065                 return NT_STATUS_NO_MEMORY;
4066         }
4067         for (i = 0; i < fti->count; i++) {
4068                 lrec = lfti->entries[i];
4069                 rec = &fti->records[i].record;
4070
4071                 rec->flags = lrec->flags;
4072                 rec->timestamp = lrec->time;
4073                 rec->type = lrec->type;
4074
4075                 switch (lrec->type) {
4076                 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
4077                 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4078                         tln = &lrec->forest_trust_data.top_level_name;
4079                         rec->data.name.string =
4080                                 talloc_strdup(mem_ctx, tln->string);
4081                         if (!rec->data.name.string) {
4082                                 return NT_STATUS_NO_MEMORY;
4083                         }
4084                         rec->data.name.size = strlen(rec->data.name.string);
4085                         break;
4086                 case LSA_FOREST_TRUST_DOMAIN_INFO:
4087                         info = &lrec->forest_trust_data.domain_info;
4088                         rec->data.info.sid = *info->domain_sid;
4089                         rec->data.info.dns_name.string =
4090                                 talloc_strdup(mem_ctx,
4091                                             info->dns_domain_name.string);
4092                         if (!rec->data.info.dns_name.string) {
4093                                 return NT_STATUS_NO_MEMORY;
4094                         }
4095                         rec->data.info.dns_name.size =
4096                                 strlen(rec->data.info.dns_name.string);
4097                         rec->data.info.netbios_name.string =
4098                                 talloc_strdup(mem_ctx,
4099                                             info->netbios_domain_name.string);
4100                         if (!rec->data.info.netbios_name.string) {
4101                                 return NT_STATUS_NO_MEMORY;
4102                         }
4103                         rec->data.info.netbios_name.size =
4104                                 strlen(rec->data.info.netbios_name.string);
4105                         break;
4106                 default:
4107                         return NT_STATUS_INVALID_DOMAIN_STATE;
4108                 }
4109         }
4110
4111         return NT_STATUS_OK;
4112 }
4113
4114 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4115                               uint32_t index, uint32_t collision_type,
4116                               uint32_t conflict_type, const char *tdo_name);
4117
4118 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
4119                               const char *tdo_name,
4120                               struct ForestTrustInfo *tdo_fti,
4121                               struct ForestTrustInfo *new_fti,
4122                               struct lsa_ForestTrustCollisionInfo *c_info)
4123 {
4124         struct ForestTrustInfoRecord *nrec;
4125         struct ForestTrustInfoRecord *trec;
4126         const char *dns_name;
4127         const char *nb_name = NULL;
4128         struct dom_sid *sid = NULL;
4129         const char *tname = NULL;
4130         size_t dns_len = 0;
4131         size_t nb_len;
4132         size_t tlen = 0;
4133         NTSTATUS nt_status;
4134         uint32_t new_fti_idx;
4135         uint32_t i;
4136         /* use always TDO type, until we understand when Xref can be used */
4137         uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
4138         bool tln_conflict;
4139         bool sid_conflict;
4140         bool nb_conflict;
4141         bool exclusion;
4142         bool ex_rule = false;
4143         int ret;
4144
4145         for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
4146
4147                 nrec = &new_fti->records[new_fti_idx].record;
4148                 dns_name = NULL;
4149                 tln_conflict = false;
4150                 sid_conflict = false;
4151                 nb_conflict = false;
4152                 exclusion = false;
4153
4154                 switch (nrec->type) {
4155                 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4156                         /* exclusions do not conflict by definition */
4157                         break;
4158
4159                 case FOREST_TRUST_TOP_LEVEL_NAME:
4160                         dns_name = nrec->data.name.string;
4161                         dns_len = nrec->data.name.size;
4162                         break;
4163
4164                 case LSA_FOREST_TRUST_DOMAIN_INFO:
4165                         dns_name = nrec->data.info.dns_name.string;
4166                         dns_len = nrec->data.info.dns_name.size;
4167                         nb_name = nrec->data.info.netbios_name.string;
4168                         nb_len = nrec->data.info.netbios_name.size;
4169                         sid = &nrec->data.info.sid;
4170                         break;
4171                 }
4172
4173                 if (!dns_name) continue;
4174
4175                 /* check if this is already taken and not excluded */
4176                 for (i = 0; i < tdo_fti->count; i++) {
4177                         trec = &tdo_fti->records[i].record;
4178
4179                         switch (trec->type) {
4180                         case FOREST_TRUST_TOP_LEVEL_NAME:
4181                                 ex_rule = false;
4182                                 tname = trec->data.name.string;
4183                                 tlen = trec->data.name.size;
4184                                 break;
4185                         case FOREST_TRUST_TOP_LEVEL_NAME_EX:
4186                                 ex_rule = true;
4187                                 tname = trec->data.name.string;
4188                                 tlen = trec->data.name.size;
4189                                 break;
4190                         case FOREST_TRUST_DOMAIN_INFO:
4191                                 ex_rule = false;
4192                                 tname = trec->data.info.dns_name.string;
4193                                 tlen = trec->data.info.dns_name.size;
4194                                 break;
4195                         default:
4196                                 return NT_STATUS_INVALID_PARAMETER;
4197                         }
4198                         ret = dns_cmp(dns_name, dns_len, tname, tlen);
4199                         switch (ret) {
4200                         case DNS_CMP_MATCH:
4201                                 /* if it matches exclusion,
4202                                  * it doesn't conflict */
4203                                 if (ex_rule) {
4204                                         exclusion = true;
4205                                         break;
4206                                 }
4207                                 /* fall through */
4208                         case DNS_CMP_FIRST_IS_CHILD:
4209                         case DNS_CMP_SECOND_IS_CHILD:
4210                                 tln_conflict = true;
4211                                 /* fall through */
4212                         default:
4213                                 break;
4214                         }
4215
4216                         /* explicit exclusion, no dns name conflict here */
4217                         if (exclusion) {
4218                                 tln_conflict = false;
4219                         }
4220
4221                         if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
4222                                 continue;
4223                         }
4224
4225                         /* also test for domain info */
4226                         if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
4227                             dom_sid_compare(&trec->data.info.sid, sid) == 0) {
4228                                 sid_conflict = true;
4229                         }
4230                         if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
4231                             strcasecmp_m(trec->data.info.netbios_name.string,
4232                                        nb_name) == 0) {
4233                                 nb_conflict = true;
4234                         }
4235                 }
4236
4237                 if (tln_conflict) {
4238                         nt_status = add_collision(c_info, new_fti_idx,
4239                                                   collision_type,
4240                                                   LSA_TLN_DISABLED_CONFLICT,
4241                                                   tdo_name);
4242                 }
4243                 if (sid_conflict) {
4244                         nt_status = add_collision(c_info, new_fti_idx,
4245                                                   collision_type,
4246                                                   LSA_SID_DISABLED_CONFLICT,
4247                                                   tdo_name);
4248                 }
4249                 if (nb_conflict) {
4250                         nt_status = add_collision(c_info, new_fti_idx,
4251                                                   collision_type,
4252                                                   LSA_NB_DISABLED_CONFLICT,
4253                                                   tdo_name);
4254                 }
4255         }
4256
4257         return NT_STATUS_OK;
4258 }
4259
4260 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4261                               uint32_t idx, uint32_t collision_type,
4262                               uint32_t conflict_type, const char *tdo_name)
4263 {
4264         struct lsa_ForestTrustCollisionRecord **es;
4265         uint32_t i = c_info->count;
4266
4267         es = talloc_realloc(c_info, c_info->entries,
4268                             struct lsa_ForestTrustCollisionRecord *, i + 1);
4269         if (!es) {
4270                 return NT_STATUS_NO_MEMORY;
4271         }
4272         c_info->entries = es;
4273         c_info->count = i + 1;
4274
4275         es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
4276         if (!es[i]) {
4277                 return NT_STATUS_NO_MEMORY;
4278         }
4279
4280         es[i]->index = idx;
4281         es[i]->type = collision_type;
4282         es[i]->flags.flags = conflict_type;
4283         es[i]->name.string = talloc_strdup(es[i], tdo_name);
4284         if (!es[i]->name.string) {
4285                 return NT_STATUS_NO_MEMORY;
4286         }
4287         es[i]->name.size = strlen(es[i]->name.string);
4288
4289         return NT_STATUS_OK;
4290 }
4291
4292 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
4293                             struct pdb_trusted_domain *td,
4294                             struct ForestTrustInfo *info)
4295 {
4296         enum ndr_err_code ndr_err;
4297
4298         if (td->trust_forest_trust_info.length == 0 ||
4299             td->trust_forest_trust_info.data == NULL) {
4300                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4301         }
4302         ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
4303                                            info,
4304                                            (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
4305         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4306                 return NT_STATUS_INVALID_DOMAIN_STATE;
4307         }
4308
4309         return NT_STATUS_OK;
4310 }
4311
4312 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
4313                             struct ForestTrustInfo *fti)
4314 {
4315         struct ForestTrustDataDomainInfo *info;
4316         struct ForestTrustInfoRecord *rec;
4317
4318         fti->version = 1;
4319         fti->count = 2;
4320         fti->records = talloc_array(fti,
4321                                     struct ForestTrustInfoRecordArmor, 2);
4322         if (!fti->records) {
4323                 return NT_STATUS_NO_MEMORY;
4324         }
4325
4326         /* TLN info */
4327         rec = &fti->records[0].record;
4328
4329         rec->flags = 0;
4330         rec->timestamp = 0;
4331         rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
4332
4333         rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
4334         if (!rec->data.name.string) {
4335                 return NT_STATUS_NO_MEMORY;
4336         }
4337         rec->data.name.size = strlen(rec->data.name.string);
4338
4339         /* DOMAIN info */
4340         rec = &fti->records[1].record;
4341
4342         rec->flags = 0;
4343         rec->timestamp = 0;
4344         rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
4345
4346         info = &rec->data.info;
4347
4348         info->sid = dom_info->sid;
4349         info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
4350         if (!info->dns_name.string) {
4351                 return NT_STATUS_NO_MEMORY;
4352         }
4353         info->dns_name.size = strlen(info->dns_name.string);
4354         info->netbios_name.string = talloc_strdup(fti, dom_info->name);
4355         if (!info->netbios_name.string) {
4356                 return NT_STATUS_NO_MEMORY;
4357         }
4358         info->netbios_name.size = strlen(info->netbios_name.string);
4359
4360         return NT_STATUS_OK;
4361 }
4362
4363 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
4364                                             struct lsa_lsaRSetForestTrustInformation *r)
4365 {
4366         NTSTATUS status;
4367         int i;
4368         int j;
4369         struct lsa_info *handle;
4370         uint32_t num_domains;
4371         struct pdb_trusted_domain **domains;
4372         struct ForestTrustInfo *nfti;
4373         struct ForestTrustInfo *fti;
4374         struct lsa_ForestTrustCollisionInfo *c_info;
4375         struct pdb_domain_info *dom_info;
4376         enum ndr_err_code ndr_err;
4377
4378         if (!IS_DC) {
4379                 return NT_STATUS_NOT_SUPPORTED;
4380         }
4381
4382         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
4383                 return NT_STATUS_INVALID_HANDLE;
4384         }
4385
4386         if (handle->type != LSA_HANDLE_TRUST_TYPE) {
4387                 return NT_STATUS_INVALID_HANDLE;
4388         }
4389
4390         if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
4391                 return NT_STATUS_ACCESS_DENIED;
4392         }
4393
4394         status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
4395         if (!NT_STATUS_IS_OK(status)) {
4396                 return status;
4397         }
4398         if (num_domains == 0) {
4399                 return NT_STATUS_NO_SUCH_DOMAIN;
4400         }
4401
4402         for (i = 0; i < num_domains; i++) {
4403                 if (domains[i]->domain_name == NULL) {
4404                         return NT_STATUS_INVALID_DOMAIN_STATE;
4405                 }
4406                 if (strcasecmp_m(domains[i]->domain_name,
4407                                r->in.trusted_domain_name->string) == 0) {
4408                         break;
4409                 }
4410         }
4411         if (i >= num_domains) {
4412                 return NT_STATUS_NO_SUCH_DOMAIN;
4413         }
4414
4415         if (!(domains[i]->trust_attributes &
4416               LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4417                 return NT_STATUS_INVALID_PARAMETER;
4418         }
4419
4420         if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4421                 return NT_STATUS_INVALID_PARAMETER;
4422         }
4423
4424         /* The following section until COPY_END is a copy from
4425          * source4/rpmc_server/lsa/scesrc_lsa.c */
4426         nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
4427         if (!nfti) {
4428                 return NT_STATUS_NO_MEMORY;
4429         }
4430
4431         status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4432         if (!NT_STATUS_IS_OK(status)) {
4433                 return status;
4434         }
4435
4436         c_info = talloc_zero(r->out.collision_info,
4437                              struct lsa_ForestTrustCollisionInfo);
4438         if (!c_info) {
4439                 return NT_STATUS_NO_MEMORY;
4440         }
4441
4442         /* first check own info, then other domains */
4443         fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4444         if (!fti) {
4445                 return NT_STATUS_NO_MEMORY;
4446         }
4447
4448         dom_info = pdb_get_domain_info(p->mem_ctx);
4449
4450         status = own_ft_info(dom_info, fti);
4451         if (!NT_STATUS_IS_OK(status)) {
4452                 return status;
4453         }
4454
4455         status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
4456         if (!NT_STATUS_IS_OK(status)) {
4457                 return status;
4458         }
4459
4460         for (j = 0; j < num_domains; j++) {
4461                 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4462                 if (!fti) {
4463                         return NT_STATUS_NO_MEMORY;
4464                 }
4465
4466                 status = get_ft_info(p->mem_ctx, domains[j], fti);
4467                 if (!NT_STATUS_IS_OK(status)) {
4468                         if (NT_STATUS_EQUAL(status,
4469                             NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4470                                 continue;
4471                         }
4472                         return status;
4473                 }
4474
4475                 if (domains[j]->domain_name == NULL) {
4476                         return NT_STATUS_INVALID_DOMAIN_STATE;
4477                 }
4478
4479                 status = check_ft_info(c_info, domains[j]->domain_name,
4480                                        fti, nfti, c_info);
4481                 if (!NT_STATUS_IS_OK(status)) {
4482                         return status;
4483                 }
4484         }
4485
4486         *r->out.collision_info = c_info;
4487
4488         if (r->in.check_only != 0) {
4489                 return NT_STATUS_OK;
4490         }
4491
4492         /* COPY_END */
4493
4494         ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
4495                                        p->mem_ctx, nfti,
4496                                        (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4497         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4498                 return NT_STATUS_INVALID_PARAMETER;
4499         }
4500
4501         status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
4502         if (!NT_STATUS_IS_OK(status)) {
4503                 return status;
4504         }
4505
4506         return NT_STATUS_OK;
4507 }
4508
4509 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
4510                           struct lsa_CREDRRENAME *r)
4511 {
4512         p->rng_fault_state = True;
4513         return NT_STATUS_NOT_IMPLEMENTED;
4514 }
4515
4516 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
4517                                 struct lsa_LSAROPENPOLICYSCE *r)
4518 {
4519         p->rng_fault_state = True;
4520         return NT_STATUS_NOT_IMPLEMENTED;
4521 }
4522
4523 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4524                                                  struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4525 {
4526         p->rng_fault_state = True;
4527         return NT_STATUS_NOT_IMPLEMENTED;
4528 }
4529
4530 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4531                                                    struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4532 {
4533         p->rng_fault_state = True;
4534         return NT_STATUS_NOT_IMPLEMENTED;
4535 }
4536
4537 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4538                                          struct lsa_LSARADTREPORTSECURITYEVENT *r)
4539 {
4540         p->rng_fault_state = True;
4541         return NT_STATUS_NOT_IMPLEMENTED;
4542 }