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