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