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