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