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