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