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