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