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