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