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