s3-lsa: let _lsa_OpenPolicy() just call _lsa_OpenPolicy2().
[ira/wip.git] / source3 / rpc_server / 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  *
15  *  This program is free software; you can redistribute it and/or modify
16  *  it under the terms of the GNU General Public License as published by
17  *  the Free Software Foundation; either version 3 of the License, or
18  *  (at your option) any later version.
19  *
20  *  This program is distributed in the hope that it will be useful,
21  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  *  GNU General Public License for more details.
24  *
25  *  You should have received a copy of the GNU General Public License
26  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
27  */
28
29 /* This is the implementation of the lsa server code. */
30
31 #include "includes.h"
32
33 #undef DBGC_CLASS
34 #define DBGC_CLASS DBGC_RPC_SRV
35
36 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
37
38 extern PRIVS privs[];
39
40 struct lsa_info {
41         DOM_SID sid;
42         uint32 access;
43 };
44
45 const struct generic_mapping lsa_generic_mapping = {
46         LSA_POLICY_READ,
47         LSA_POLICY_WRITE,
48         LSA_POLICY_EXECUTE,
49         LSA_POLICY_ALL_ACCESS
50 };
51
52 /***************************************************************************
53  init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
54 ***************************************************************************/
55
56 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
57                                     struct lsa_RefDomainList *ref,
58                                     const char *dom_name,
59                                     DOM_SID *dom_sid)
60 {
61         int num = 0;
62
63         if (dom_name != NULL) {
64                 for (num = 0; num < ref->count; num++) {
65                         if (sid_equal(dom_sid, ref->domains[num].sid)) {
66                                 return num;
67                         }
68                 }
69         } else {
70                 num = ref->count;
71         }
72
73         if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
74                 /* index not found, already at maximum domain limit */
75                 return -1;
76         }
77
78         ref->count = num + 1;
79         ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
80
81         ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains,
82                                             struct lsa_DomainInfo, ref->count);
83         if (!ref->domains) {
84                 return -1;
85         }
86
87         ZERO_STRUCT(ref->domains[num]);
88
89         init_lsa_StringLarge(&ref->domains[num].name, dom_name);
90         ref->domains[num].sid = sid_dup_talloc(mem_ctx, dom_sid);
91         if (!ref->domains[num].sid) {
92                 return -1;
93         }
94
95         return num;
96 }
97
98
99 /***************************************************************************
100  initialize a lsa_DomainInfo structure.
101  ***************************************************************************/
102
103 static void init_dom_query_3(struct lsa_DomainInfo *r,
104                              const char *name,
105                              DOM_SID *sid)
106 {
107         init_lsa_StringLarge(&r->name, name);
108         r->sid = sid;
109 }
110
111 /***************************************************************************
112  initialize a lsa_DomainInfo structure.
113  ***************************************************************************/
114
115 static void init_dom_query_5(struct lsa_DomainInfo *r,
116                              const char *name,
117                              DOM_SID *sid)
118 {
119         init_lsa_StringLarge(&r->name, name);
120         r->sid = sid;
121 }
122
123 /***************************************************************************
124  lookup_lsa_rids. Must be called as root for lookup_name to work.
125  ***************************************************************************/
126
127 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
128                                 struct lsa_RefDomainList *ref,
129                                 struct lsa_TranslatedSid *prid,
130                                 uint32_t num_entries,
131                                 struct lsa_String *name,
132                                 int flags,
133                                 uint32_t *pmapped_count)
134 {
135         uint32 mapped_count, i;
136
137         SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
138
139         mapped_count = 0;
140         *pmapped_count = 0;
141
142         for (i = 0; i < num_entries; i++) {
143                 DOM_SID sid;
144                 uint32 rid;
145                 int dom_idx;
146                 const char *full_name;
147                 const char *domain;
148                 enum lsa_SidType type = SID_NAME_UNKNOWN;
149
150                 /* Split name into domain and user component */
151
152                 full_name = name[i].string;
153                 if (full_name == NULL) {
154                         return NT_STATUS_NO_MEMORY;
155                 }
156
157                 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
158
159                 /* We can ignore the result of lookup_name, it will not touch
160                    "type" if it's not successful */
161
162                 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
163                             &sid, &type);
164
165                 switch (type) {
166                 case SID_NAME_USER:
167                 case SID_NAME_DOM_GRP:
168                 case SID_NAME_DOMAIN:
169                 case SID_NAME_ALIAS:
170                 case SID_NAME_WKN_GRP:
171                         DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
172                         /* Leave these unchanged */
173                         break;
174                 default:
175                         /* Don't hand out anything but the list above */
176                         DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
177                         type = SID_NAME_UNKNOWN;
178                         break;
179                 }
180
181                 rid = 0;
182                 dom_idx = -1;
183
184                 if (type != SID_NAME_UNKNOWN) {
185                         sid_split_rid(&sid, &rid);
186                         dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
187                         mapped_count++;
188                 }
189
190                 prid[i].sid_type        = type;
191                 prid[i].rid             = rid;
192                 prid[i].sid_index       = dom_idx;
193         }
194
195         *pmapped_count = mapped_count;
196         return NT_STATUS_OK;
197 }
198
199 /***************************************************************************
200  lookup_lsa_sids. Must be called as root for lookup_name to work.
201  ***************************************************************************/
202
203 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
204                                 struct lsa_RefDomainList *ref,
205                                 struct lsa_TranslatedSid3 *trans_sids,
206                                 uint32_t num_entries,
207                                 struct lsa_String *name,
208                                 int flags,
209                                 uint32 *pmapped_count)
210 {
211         uint32 mapped_count, i;
212
213         SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
214
215         mapped_count = 0;
216         *pmapped_count = 0;
217
218         for (i = 0; i < num_entries; i++) {
219                 DOM_SID sid;
220                 uint32 rid;
221                 int dom_idx;
222                 const char *full_name;
223                 const char *domain;
224                 enum lsa_SidType type = SID_NAME_UNKNOWN;
225
226                 ZERO_STRUCT(sid);
227
228                 /* Split name into domain and user component */
229
230                 full_name = name[i].string;
231                 if (full_name == NULL) {
232                         return NT_STATUS_NO_MEMORY;
233                 }
234
235                 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
236
237                 /* We can ignore the result of lookup_name, it will not touch
238                    "type" if it's not successful */
239
240                 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
241                             &sid, &type);
242
243                 switch (type) {
244                 case SID_NAME_USER:
245                 case SID_NAME_DOM_GRP:
246                 case SID_NAME_DOMAIN:
247                 case SID_NAME_ALIAS:
248                 case SID_NAME_WKN_GRP:
249                         DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
250                         /* Leave these unchanged */
251                         break;
252                 default:
253                         /* Don't hand out anything but the list above */
254                         DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
255                         type = SID_NAME_UNKNOWN;
256                         break;
257                 }
258
259                 rid = 0;
260                 dom_idx = -1;
261
262                 if (type != SID_NAME_UNKNOWN) {
263                         DOM_SID domain_sid;
264                         sid_copy(&domain_sid, &sid);
265                         sid_split_rid(&domain_sid, &rid);
266                         dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
267                         mapped_count++;
268                 }
269
270                 /* Initialize the lsa_TranslatedSid3 return. */
271                 trans_sids[i].sid_type = type;
272                 trans_sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
273                 trans_sids[i].sid_index = dom_idx;
274         }
275
276         *pmapped_count = mapped_count;
277         return NT_STATUS_OK;
278 }
279
280 static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size)
281 {
282         DOM_SID local_adm_sid;
283         DOM_SID adm_sid;
284
285         SEC_ACE ace[3];
286
287         SEC_ACL *psa = NULL;
288
289         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, LSA_POLICY_EXECUTE, 0);
290
291         sid_copy(&adm_sid, get_global_sam_sid());
292         sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS);
293         init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, LSA_POLICY_ALL_ACCESS, 0);
294
295         sid_copy(&local_adm_sid, &global_sid_Builtin);
296         sid_append_rid(&local_adm_sid, BUILTIN_ALIAS_RID_ADMINS);
297         init_sec_ace(&ace[2], &local_adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, LSA_POLICY_ALL_ACCESS, 0);
298
299         if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
300                 return NT_STATUS_NO_MEMORY;
301
302         if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
303                                 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
304                                 psa, sd_size)) == NULL)
305                 return NT_STATUS_NO_MEMORY;
306
307         return NT_STATUS_OK;
308 }
309
310 #if 0   /* AD DC work in ongoing in Samba 4 */
311
312 /***************************************************************************
313  Init_dns_dom_info.
314 ***************************************************************************/
315
316 static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name,
317                               const char *dns_name, const char *forest_name,
318                               struct GUID *dom_guid, DOM_SID *dom_sid)
319 {
320         if (nb_name && *nb_name) {
321                 init_unistr2(&r_l->uni_nb_dom_name, nb_name, UNI_FLAGS_NONE);
322                 init_uni_hdr(&r_l->hdr_nb_dom_name, &r_l->uni_nb_dom_name);
323                 r_l->hdr_nb_dom_name.uni_max_len += 2;
324                 r_l->uni_nb_dom_name.uni_max_len += 1;
325         }
326
327         if (dns_name && *dns_name) {
328                 init_unistr2(&r_l->uni_dns_dom_name, dns_name, UNI_FLAGS_NONE);
329                 init_uni_hdr(&r_l->hdr_dns_dom_name, &r_l->uni_dns_dom_name);
330                 r_l->hdr_dns_dom_name.uni_max_len += 2;
331                 r_l->uni_dns_dom_name.uni_max_len += 1;
332         }
333
334         if (forest_name && *forest_name) {
335                 init_unistr2(&r_l->uni_forest_name, forest_name, UNI_FLAGS_NONE);
336                 init_uni_hdr(&r_l->hdr_forest_name, &r_l->uni_forest_name);
337                 r_l->hdr_forest_name.uni_max_len += 2;
338                 r_l->uni_forest_name.uni_max_len += 1;
339         }
340
341         /* how do we init the guid ? probably should write an init fn */
342         if (dom_guid) {
343                 memcpy(&r_l->dom_guid, dom_guid, sizeof(struct GUID));
344         }
345
346         if (dom_sid) {
347                 r_l->ptr_dom_sid = 1;
348                 init_dom_sid2(&r_l->dom_sid, dom_sid);
349         }
350 }
351 #endif  /* AD DC work in ongoing in Samba 4 */
352
353
354 /***************************************************************************
355  _lsa_OpenPolicy2
356  ***************************************************************************/
357
358 NTSTATUS _lsa_OpenPolicy2(pipes_struct *p,
359                           struct lsa_OpenPolicy2 *r)
360 {
361         struct lsa_info *info;
362         SEC_DESC *psd = NULL;
363         size_t sd_size;
364         uint32 des_access = r->in.access_mask;
365         uint32 acc_granted;
366         NTSTATUS status;
367
368
369         /* map the generic bits to the lsa policy ones */
370         se_map_generic(&des_access, &lsa_generic_mapping);
371
372         /* get the generic lsa policy SD until we store it */
373         lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
374
375         status = se_access_check(psd, p->server_info->ptok, des_access,
376                                  &acc_granted);
377         if (!NT_STATUS_IS_OK(status)) {
378                 if (p->server_info->utok.uid != sec_initial_uid()) {
379                         return status;
380                 }
381                 DEBUG(4,("ACCESS should be DENIED (granted: %#010x;  required: %#010x)\n",
382                          acc_granted, des_access));
383                 DEBUGADD(4,("but overwritten by euid == 0\n"));
384         }
385
386         /* This is needed for lsa_open_account and rpcclient .... :-) */
387
388         if (p->server_info->utok.uid == sec_initial_uid())
389                 acc_granted = LSA_POLICY_ALL_ACCESS;
390
391         /* associate the domain SID with the (unique) handle. */
392         info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
393         if (info == NULL) {
394                 return NT_STATUS_NO_MEMORY;
395         }
396
397         sid_copy(&info->sid,get_global_sam_sid());
398         info->access = acc_granted;
399
400         /* set up the LSA QUERY INFO response */
401         if (!create_policy_hnd(p, r->out.handle, info))
402                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
403
404         return NT_STATUS_OK;
405 }
406
407 /***************************************************************************
408  _lsa_OpenPolicy
409  ***************************************************************************/
410
411 NTSTATUS _lsa_OpenPolicy(pipes_struct *p,
412                          struct lsa_OpenPolicy *r)
413 {
414         struct lsa_OpenPolicy2 o;
415
416         o.in.system_name        = NULL; /* should be ignored */
417         o.in.attr               = r->in.attr;
418         o.in.access_mask        = r->in.access_mask;
419
420         o.out.handle            = r->out.handle;
421
422         return _lsa_OpenPolicy2(p, &o);
423 }
424
425 /***************************************************************************
426  _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
427  ufff, done :)  mimir
428  ***************************************************************************/
429
430 NTSTATUS _lsa_EnumTrustDom(pipes_struct *p,
431                            struct lsa_EnumTrustDom *r)
432 {
433         struct lsa_info *info;
434         uint32 next_idx;
435         struct trustdom_info **domains;
436         struct lsa_DomainInfo *lsa_domains = NULL;
437         int i;
438
439         /*
440          * preferred length is set to 5 as a "our" preferred length
441          * nt sets this parameter to 2
442          * update (20.08.2002): it's not preferred length, but preferred size!
443          * it needs further investigation how to optimally choose this value
444          */
445         uint32 max_num_domains =
446                 r->in.max_size < 5 ? r->in.max_size : 10;
447         uint32 num_domains;
448         NTSTATUS nt_status;
449         uint32 num_thistime;
450
451         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
452                 return NT_STATUS_INVALID_HANDLE;
453
454         /* check if the user has enough rights */
455         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
456                 return NT_STATUS_ACCESS_DENIED;
457
458         become_root();
459         nt_status = pdb_enum_trusteddoms(p->mem_ctx, &num_domains, &domains);
460         unbecome_root();
461
462         if (!NT_STATUS_IS_OK(nt_status)) {
463                 return nt_status;
464         }
465
466         if (*r->in.resume_handle < num_domains) {
467                 num_thistime = MIN(num_domains, max_num_domains);
468
469                 nt_status = STATUS_MORE_ENTRIES;
470
471                 if (*r->in.resume_handle + num_thistime > num_domains) {
472                         num_thistime = num_domains - *r->in.resume_handle;
473                         nt_status = NT_STATUS_OK;
474                 }
475
476                 next_idx = *r->in.resume_handle + num_thistime;
477         } else {
478                 num_thistime = 0;
479                 next_idx = 0xffffffff;
480                 nt_status = NT_STATUS_NO_MORE_ENTRIES;
481         }
482
483         /* set up the lsa_enum_trust_dom response */
484
485         lsa_domains = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo,
486                                         num_thistime);
487         if (!lsa_domains) {
488                 return NT_STATUS_NO_MEMORY;
489         }
490
491         for (i=0; i<num_thistime; i++) {
492                 init_lsa_StringLarge(&lsa_domains[i].name, domains[i]->name);
493                 lsa_domains[i].sid = &domains[i]->sid;
494         }
495
496         *r->out.resume_handle = next_idx;
497         r->out.domains->count = num_thistime;
498         r->out.domains->domains = lsa_domains;
499
500         return nt_status;
501 }
502
503 #define LSA_AUDIT_NUM_CATEGORIES_NT4    7
504 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K  9
505 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
506
507 /***************************************************************************
508  _lsa_QueryInfoPolicy
509  ***************************************************************************/
510
511 NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p,
512                               struct lsa_QueryInfoPolicy *r)
513 {
514         NTSTATUS status = NT_STATUS_OK;
515         struct lsa_info *handle;
516         DOM_SID domain_sid;
517         const char *name;
518         DOM_SID *sid = NULL;
519         union lsa_PolicyInformation *info = NULL;
520
521         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
522                 return NT_STATUS_INVALID_HANDLE;
523
524         info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
525         if (!info) {
526                 return NT_STATUS_NO_MEMORY;
527         }
528
529         switch (r->in.level) {
530         case 0x02:
531                 {
532
533                 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
534
535                 /* check if the user has enough rights */
536                 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
537                         DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
538                         return NT_STATUS_ACCESS_DENIED;
539                 }
540
541                 /* fake info: We audit everything. ;) */
542
543                 info->audit_events.auditing_mode = true;
544                 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
545                 info->audit_events.settings = TALLOC_ZERO_ARRAY(p->mem_ctx,
546                                                                 enum lsa_PolicyAuditPolicy,
547                                                                 info->audit_events.count);
548                 if (!info->audit_events.settings) {
549                         return NT_STATUS_NO_MEMORY;
550                 }
551
552                 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
553                 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
554                 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
555                 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
556                 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
557                 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
558                 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
559
560                 break;
561                 }
562         case 0x03:
563                 /* check if the user has enough rights */
564                 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
565                         return NT_STATUS_ACCESS_DENIED;
566
567                 /* Request PolicyPrimaryDomainInformation. */
568                 switch (lp_server_role()) {
569                         case ROLE_DOMAIN_PDC:
570                         case ROLE_DOMAIN_BDC:
571                                 name = get_global_sam_name();
572                                 sid = sid_dup_talloc(p->mem_ctx, get_global_sam_sid());
573                                 if (!sid) {
574                                         return NT_STATUS_NO_MEMORY;
575                                 }
576                                 break;
577                         case ROLE_DOMAIN_MEMBER:
578                                 name = lp_workgroup();
579                                 /* We need to return the Domain SID here. */
580                                 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
581                                         sid = sid_dup_talloc(p->mem_ctx, &domain_sid);
582                                         if (!sid) {
583                                                 return NT_STATUS_NO_MEMORY;
584                                         }
585                                 } else {
586                                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
587                                 }
588                                 break;
589                         case ROLE_STANDALONE:
590                                 name = lp_workgroup();
591                                 sid = NULL;
592                                 break;
593                         default:
594                                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
595                 }
596                 init_dom_query_3(&info->domain, name, sid);
597                 break;
598         case 0x05:
599                 /* check if the user has enough rights */
600                 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
601                         return NT_STATUS_ACCESS_DENIED;
602
603                 /* Request PolicyAccountDomainInformation. */
604                 name = get_global_sam_name();
605                 sid = get_global_sam_sid();
606
607                 init_dom_query_5(&info->account_domain, name, sid);
608                 break;
609         case 0x06:
610                 /* check if the user has enough rights */
611                 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
612                         return NT_STATUS_ACCESS_DENIED;
613
614                 switch (lp_server_role()) {
615                         case ROLE_DOMAIN_BDC:
616                                 /*
617                                  * only a BDC is a backup controller
618                                  * of the domain, it controls.
619                                  */
620                                 info->role.role = LSA_ROLE_BACKUP;
621                                 break;
622                         default:
623                                 /*
624                                  * any other role is a primary
625                                  * of the domain, it controls.
626                                  */
627                                 info->role.role = LSA_ROLE_PRIMARY;
628                                 break;
629                 }
630                 break;
631         default:
632                 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
633                         r->in.level));
634                 status = NT_STATUS_INVALID_INFO_CLASS;
635                 break;
636         }
637
638         *r->out.info = info;
639
640         return status;
641 }
642
643 /***************************************************************************
644  _lsa_lookup_sids_internal
645  ***************************************************************************/
646
647 static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p,
648                                           TALLOC_CTX *mem_ctx,
649                                           uint16_t level,                       /* input */
650                                           int num_sids,                         /* input */
651                                           struct lsa_SidPtr *sid,               /* input */
652                                           struct lsa_RefDomainList **pp_ref,    /* input/output */
653                                           struct lsa_TranslatedName2 **pp_names,/* input/output */
654                                           uint32_t *pp_mapped_count)            /* input/output */
655 {
656         NTSTATUS status;
657         int i;
658         const DOM_SID **sids = NULL;
659         struct lsa_RefDomainList *ref = NULL;
660         uint32 mapped_count = 0;
661         struct lsa_dom_info *dom_infos = NULL;
662         struct lsa_name_info *name_infos = NULL;
663         struct lsa_TranslatedName2 *names = NULL;
664
665         *pp_mapped_count = 0;
666         *pp_names = NULL;
667         *pp_ref = NULL;
668
669         if (num_sids == 0) {
670                 return NT_STATUS_OK;
671         }
672
673         sids = TALLOC_ARRAY(p->mem_ctx, const DOM_SID *, num_sids);
674         ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
675
676         if (sids == NULL || ref == NULL) {
677                 return NT_STATUS_NO_MEMORY;
678         }
679
680         for (i=0; i<num_sids; i++) {
681                 sids[i] = sid[i].sid;
682         }
683
684         status = lookup_sids(p->mem_ctx, num_sids, sids, level,
685                                   &dom_infos, &name_infos);
686
687         if (!NT_STATUS_IS_OK(status)) {
688                 return status;
689         }
690
691         names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
692         if (names == NULL) {
693                 return NT_STATUS_NO_MEMORY;
694         }
695
696         for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
697
698                 if (!dom_infos[i].valid) {
699                         break;
700                 }
701
702                 if (init_lsa_ref_domain_list(mem_ctx, ref,
703                                              dom_infos[i].name,
704                                              &dom_infos[i].sid) != i) {
705                         DEBUG(0, ("Domain %s mentioned twice??\n",
706                                   dom_infos[i].name));
707                         return NT_STATUS_INTERNAL_ERROR;
708                 }
709         }
710
711         for (i=0; i<num_sids; i++) {
712                 struct lsa_name_info *name = &name_infos[i];
713
714                 if (name->type == SID_NAME_UNKNOWN) {
715                         fstring tmp;
716                         name->dom_idx = -1;
717                         /* Unknown sids should return the string
718                          * representation of the SID. Windows 2003 behaves
719                          * rather erratic here, in many cases it returns the
720                          * RID as 8 bytes hex, in others it returns the full
721                          * SID. We (Jerry/VL) could not figure out which the
722                          * hard cases are, so leave it with the SID.  */
723                         name->name = talloc_asprintf(p->mem_ctx, "%s",
724                                                      sid_to_fstring(tmp,
725                                                                     sids[i]));
726                         if (name->name == NULL) {
727                                 return NT_STATUS_NO_MEMORY;
728                         }
729                 } else {
730                         mapped_count += 1;
731                 }
732
733                 names[i].sid_type       = name->type;
734                 names[i].name.string    = name->name;
735                 names[i].sid_index      = name->dom_idx;
736                 names[i].unknown        = 0;
737         }
738
739         status = NT_STATUS_NONE_MAPPED;
740         if (mapped_count > 0) {
741                 status = (mapped_count < num_sids) ?
742                         STATUS_SOME_UNMAPPED : NT_STATUS_OK;
743         }
744
745         DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
746                    num_sids, mapped_count, nt_errstr(status)));
747
748         *pp_mapped_count = mapped_count;
749         *pp_names = names;
750         *pp_ref = ref;
751
752         return status;
753 }
754
755 /***************************************************************************
756  _lsa_LookupSids
757  ***************************************************************************/
758
759 NTSTATUS _lsa_LookupSids(pipes_struct *p,
760                          struct lsa_LookupSids *r)
761 {
762         NTSTATUS status;
763         struct lsa_info *handle;
764         int num_sids = r->in.sids->num_sids;
765         uint32 mapped_count = 0;
766         struct lsa_RefDomainList *domains = NULL;
767         struct lsa_TranslatedName *names_out = NULL;
768         struct lsa_TranslatedName2 *names = NULL;
769         int i;
770
771         if ((r->in.level < 1) || (r->in.level > 6)) {
772                 return NT_STATUS_INVALID_PARAMETER;
773         }
774
775         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
776                 return NT_STATUS_INVALID_HANDLE;
777         }
778
779         /* check if the user has enough rights */
780         if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
781                 return NT_STATUS_ACCESS_DENIED;
782         }
783
784         if (num_sids >  MAX_LOOKUP_SIDS) {
785                 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
786                          MAX_LOOKUP_SIDS, num_sids));
787                 return NT_STATUS_NONE_MAPPED;
788         }
789
790         status = _lsa_lookup_sids_internal(p,
791                                            p->mem_ctx,
792                                            r->in.level,
793                                            num_sids,
794                                            r->in.sids->sids,
795                                            &domains,
796                                            &names,
797                                            &mapped_count);
798
799         /* Only return here when there is a real error.
800            NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
801            the requested sids could be resolved. Older versions of XP (pre SP3)
802            rely that we return with the string representations of those SIDs in
803            that case. If we don't, XP crashes - Guenther
804            */
805
806         if (NT_STATUS_IS_ERR(status) &&
807             !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
808                 return status;
809         }
810
811         /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
812         names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
813                                  num_sids);
814         if (!names_out) {
815                 return NT_STATUS_NO_MEMORY;
816         }
817
818         for (i=0; i<num_sids; i++) {
819                 names_out[i].sid_type = names[i].sid_type;
820                 names_out[i].name = names[i].name;
821                 names_out[i].sid_index = names[i].sid_index;
822         }
823
824         *r->out.domains = domains;
825         r->out.names->count = num_sids;
826         r->out.names->names = names_out;
827         *r->out.count = mapped_count;
828
829         return status;
830 }
831
832 /***************************************************************************
833  _lsa_LookupSids2
834  ***************************************************************************/
835
836 NTSTATUS _lsa_LookupSids2(pipes_struct *p,
837                           struct lsa_LookupSids2 *r)
838 {
839         NTSTATUS status;
840         struct lsa_info *handle;
841         int num_sids = r->in.sids->num_sids;
842         uint32 mapped_count = 0;
843         struct lsa_RefDomainList *domains = NULL;
844         struct lsa_TranslatedName2 *names = NULL;
845         bool check_policy = true;
846
847         switch (p->hdr_req.opnum) {
848                 case NDR_LSA_LOOKUPSIDS3:
849                         check_policy = false;
850                         break;
851                 case NDR_LSA_LOOKUPSIDS2:
852                 default:
853                         check_policy = true;
854         }
855
856         if ((r->in.level < 1) || (r->in.level > 6)) {
857                 return NT_STATUS_INVALID_PARAMETER;
858         }
859
860         if (check_policy) {
861                 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
862                         return NT_STATUS_INVALID_HANDLE;
863                 }
864
865                 /* check if the user has enough rights */
866                 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
867                         return NT_STATUS_ACCESS_DENIED;
868                 }
869         }
870
871         if (num_sids >  MAX_LOOKUP_SIDS) {
872                 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
873                          MAX_LOOKUP_SIDS, num_sids));
874                 return NT_STATUS_NONE_MAPPED;
875         }
876
877         status = _lsa_lookup_sids_internal(p,
878                                            p->mem_ctx,
879                                            r->in.level,
880                                            num_sids,
881                                            r->in.sids->sids,
882                                            &domains,
883                                            &names,
884                                            &mapped_count);
885
886         *r->out.domains = domains;
887         r->out.names->count = num_sids;
888         r->out.names->names = names;
889         *r->out.count = mapped_count;
890
891         return status;
892 }
893
894 /***************************************************************************
895  _lsa_LookupSids3
896  ***************************************************************************/
897
898 NTSTATUS _lsa_LookupSids3(pipes_struct *p,
899                           struct lsa_LookupSids3 *r)
900 {
901         struct lsa_LookupSids2 q;
902
903         /* No policy handle on this call. Restrict to crypto connections. */
904         if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
905                 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
906                         get_remote_machine_name() ));
907                 return NT_STATUS_INVALID_PARAMETER;
908         }
909
910         q.in.handle             = NULL;
911         q.in.sids               = r->in.sids;
912         q.in.level              = r->in.level;
913         q.in.unknown1           = r->in.unknown1;
914         q.in.unknown2           = r->in.unknown2;
915         q.in.names              = r->in.names;
916         q.in.count              = r->in.count;
917
918         q.out.domains           = r->out.domains;
919         q.out.names             = r->out.names;
920         q.out.count             = r->out.count;
921
922         return _lsa_LookupSids2(p, &q);
923 }
924
925 /***************************************************************************
926  ***************************************************************************/
927
928 static int lsa_lookup_level_to_flags(uint16 level)
929 {
930         int flags;
931
932         switch (level) {
933                 case 1:
934                         flags = LOOKUP_NAME_ALL;
935                         break;
936                 case 2:
937                         flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
938                         break;
939                 case 3:
940                         flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
941                         break;
942                 case 4:
943                 case 5:
944                 case 6:
945                 default:
946                         flags = LOOKUP_NAME_NONE;
947                         break;
948         }
949
950         return flags;
951 }
952
953 /***************************************************************************
954  _lsa_LookupNames
955  ***************************************************************************/
956
957 NTSTATUS _lsa_LookupNames(pipes_struct *p,
958                           struct lsa_LookupNames *r)
959 {
960         NTSTATUS status = NT_STATUS_NONE_MAPPED;
961         struct lsa_info *handle;
962         struct lsa_String *names = r->in.names;
963         uint32 num_entries = r->in.num_names;
964         struct lsa_RefDomainList *domains = NULL;
965         struct lsa_TranslatedSid *rids = NULL;
966         uint32 mapped_count = 0;
967         int flags = 0;
968
969         if (num_entries >  MAX_LOOKUP_SIDS) {
970                 num_entries = MAX_LOOKUP_SIDS;
971                 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
972                         num_entries));
973         }
974
975         flags = lsa_lookup_level_to_flags(r->in.level);
976
977         domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
978         if (!domains) {
979                 return NT_STATUS_NO_MEMORY;
980         }
981
982         if (num_entries) {
983                 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
984                                          num_entries);
985                 if (!rids) {
986                         return NT_STATUS_NO_MEMORY;
987                 }
988         } else {
989                 rids = NULL;
990         }
991
992         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
993                 status = NT_STATUS_INVALID_HANDLE;
994                 goto done;
995         }
996
997         /* check if the user has enough rights */
998         if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
999                 status = NT_STATUS_ACCESS_DENIED;
1000                 goto done;
1001         }
1002
1003         /* set up the LSA Lookup RIDs response */
1004         become_root(); /* lookup_name can require root privs */
1005         status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1006                                  names, flags, &mapped_count);
1007         unbecome_root();
1008
1009 done:
1010
1011         if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1012                 if (mapped_count == 0) {
1013                         status = NT_STATUS_NONE_MAPPED;
1014                 } else if (mapped_count != num_entries) {
1015                         status = STATUS_SOME_UNMAPPED;
1016                 }
1017         }
1018
1019         *r->out.count = mapped_count;
1020         *r->out.domains = domains;
1021         r->out.sids->sids = rids;
1022         r->out.sids->count = num_entries;
1023
1024         return status;
1025 }
1026
1027 /***************************************************************************
1028  _lsa_LookupNames2
1029  ***************************************************************************/
1030
1031 NTSTATUS _lsa_LookupNames2(pipes_struct *p,
1032                            struct lsa_LookupNames2 *r)
1033 {
1034         NTSTATUS status;
1035         struct lsa_LookupNames q;
1036         struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1037         struct lsa_TransSidArray *sid_array = NULL;
1038         uint32_t i;
1039
1040         sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1041         if (!sid_array) {
1042                 return NT_STATUS_NO_MEMORY;
1043         }
1044
1045         q.in.handle             = r->in.handle;
1046         q.in.num_names          = r->in.num_names;
1047         q.in.names              = r->in.names;
1048         q.in.level              = r->in.level;
1049         q.in.sids               = sid_array;
1050         q.in.count              = r->in.count;
1051         /* we do not know what this is for */
1052         /*                      = r->in.unknown1; */
1053         /*                      = r->in.unknown2; */
1054
1055         q.out.domains           = r->out.domains;
1056         q.out.sids              = sid_array;
1057         q.out.count             = r->out.count;
1058
1059         status = _lsa_LookupNames(p, &q);
1060
1061         sid_array2->count = sid_array->count;
1062         sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1063         if (!sid_array2->sids) {
1064                 return NT_STATUS_NO_MEMORY;
1065         }
1066
1067         for (i=0; i<sid_array->count; i++) {
1068                 sid_array2->sids[i].sid_type  = sid_array->sids[i].sid_type;
1069                 sid_array2->sids[i].rid       = sid_array->sids[i].rid;
1070                 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1071                 sid_array2->sids[i].unknown   = 0;
1072         }
1073
1074         r->out.sids = sid_array2;
1075
1076         return status;
1077 }
1078
1079 /***************************************************************************
1080  _lsa_LookupNames3
1081  ***************************************************************************/
1082
1083 NTSTATUS _lsa_LookupNames3(pipes_struct *p,
1084                            struct lsa_LookupNames3 *r)
1085 {
1086         NTSTATUS status;
1087         struct lsa_info *handle;
1088         struct lsa_String *names = r->in.names;
1089         uint32 num_entries = r->in.num_names;
1090         struct lsa_RefDomainList *domains = NULL;
1091         struct lsa_TranslatedSid3 *trans_sids = NULL;
1092         uint32 mapped_count = 0;
1093         int flags = 0;
1094         bool check_policy = true;
1095
1096         switch (p->hdr_req.opnum) {
1097                 case NDR_LSA_LOOKUPNAMES4:
1098                         check_policy = false;
1099                         break;
1100                 case NDR_LSA_LOOKUPNAMES3:
1101                 default:
1102                         check_policy = true;
1103         }
1104
1105         if (num_entries >  MAX_LOOKUP_SIDS) {
1106                 num_entries = MAX_LOOKUP_SIDS;
1107                 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1108         }
1109
1110         /* Probably the lookup_level is some sort of bitmask. */
1111         if (r->in.level == 1) {
1112                 flags = LOOKUP_NAME_ALL;
1113         }
1114
1115         domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1116         if (!domains) {
1117                 return NT_STATUS_NO_MEMORY;
1118         }
1119
1120         if (num_entries) {
1121                 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1122                                                num_entries);
1123                 if (!trans_sids) {
1124                         return NT_STATUS_NO_MEMORY;
1125                 }
1126         } else {
1127                 trans_sids = NULL;
1128         }
1129
1130         if (check_policy) {
1131
1132                 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1133                         status = NT_STATUS_INVALID_HANDLE;
1134                         goto done;
1135                 }
1136
1137                 /* check if the user has enough rights */
1138                 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1139                         status = NT_STATUS_ACCESS_DENIED;
1140                         goto done;
1141                 }
1142         }
1143
1144         /* set up the LSA Lookup SIDs response */
1145         become_root(); /* lookup_name can require root privs */
1146         status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1147                                  names, flags, &mapped_count);
1148         unbecome_root();
1149
1150 done:
1151
1152         if (NT_STATUS_IS_OK(status)) {
1153                 if (mapped_count == 0) {
1154                         status = NT_STATUS_NONE_MAPPED;
1155                 } else if (mapped_count != num_entries) {
1156                         status = STATUS_SOME_UNMAPPED;
1157                 }
1158         }
1159
1160         *r->out.count = mapped_count;
1161         *r->out.domains = domains;
1162         r->out.sids->sids = trans_sids;
1163         r->out.sids->count = num_entries;
1164
1165         return status;
1166 }
1167
1168 /***************************************************************************
1169  _lsa_LookupNames4
1170  ***************************************************************************/
1171
1172 NTSTATUS _lsa_LookupNames4(pipes_struct *p,
1173                            struct lsa_LookupNames4 *r)
1174 {
1175         struct lsa_LookupNames3 q;
1176
1177         /* No policy handle on this call. Restrict to crypto connections. */
1178         if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
1179                 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1180                         get_remote_machine_name() ));
1181                 return NT_STATUS_INVALID_PARAMETER;
1182         }
1183
1184         q.in.handle             = NULL;
1185         q.in.num_names          = r->in.num_names;
1186         q.in.names              = r->in.names;
1187         q.in.level              = r->in.level;
1188         q.in.lookup_options     = r->in.lookup_options;
1189         q.in.client_revision    = r->in.client_revision;
1190         q.in.sids               = r->in.sids;
1191         q.in.count              = r->in.count;
1192
1193         q.out.domains           = r->out.domains;
1194         q.out.sids              = r->out.sids;
1195         q.out.count             = r->out.count;
1196
1197         return _lsa_LookupNames3(p, &q);
1198 }
1199
1200 /***************************************************************************
1201  _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1202  ***************************************************************************/
1203
1204 NTSTATUS _lsa_Close(pipes_struct *p, struct lsa_Close *r)
1205 {
1206         if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1207                 return NT_STATUS_INVALID_HANDLE;
1208         }
1209
1210         close_policy_hnd(p, r->in.handle);
1211         ZERO_STRUCTP(r->out.handle);
1212         return NT_STATUS_OK;
1213 }
1214
1215 /***************************************************************************
1216  ***************************************************************************/
1217
1218 NTSTATUS _lsa_OpenSecret(pipes_struct *p, struct lsa_OpenSecret *r)
1219 {
1220         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1221 }
1222
1223 /***************************************************************************
1224  ***************************************************************************/
1225
1226 NTSTATUS _lsa_OpenTrustedDomain(pipes_struct *p, struct lsa_OpenTrustedDomain *r)
1227 {
1228         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1229 }
1230
1231 /***************************************************************************
1232  ***************************************************************************/
1233
1234 NTSTATUS _lsa_CreateTrustedDomain(pipes_struct *p, struct lsa_CreateTrustedDomain *r)
1235 {
1236         return NT_STATUS_ACCESS_DENIED;
1237 }
1238
1239 /***************************************************************************
1240  ***************************************************************************/
1241
1242 NTSTATUS _lsa_CreateSecret(pipes_struct *p, struct lsa_CreateSecret *r)
1243 {
1244         return NT_STATUS_ACCESS_DENIED;
1245 }
1246
1247 /***************************************************************************
1248  ***************************************************************************/
1249
1250 NTSTATUS _lsa_SetSecret(pipes_struct *p, struct lsa_SetSecret *r)
1251 {
1252         return NT_STATUS_ACCESS_DENIED;
1253 }
1254
1255 /***************************************************************************
1256  _lsa_DeleteObject
1257  ***************************************************************************/
1258
1259 NTSTATUS _lsa_DeleteObject(pipes_struct *p,
1260                            struct lsa_DeleteObject *r)
1261 {
1262         NTSTATUS status;
1263         struct lsa_info *info = NULL;
1264
1265         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
1266                 return NT_STATUS_INVALID_HANDLE;
1267         }
1268
1269         /* check to see if the pipe_user is root or a Domain Admin since
1270            account_pol.tdb was already opened as root, this is all we have */
1271
1272         if (p->server_info->utok.uid != sec_initial_uid() &&
1273             !nt_token_check_domain_rid(p->server_info->ptok,
1274                                        DOMAIN_GROUP_RID_ADMINS)) {
1275                 return NT_STATUS_ACCESS_DENIED;
1276         }
1277
1278         status = privilege_delete_account(&info->sid);
1279         if (!NT_STATUS_IS_OK(status)) {
1280                 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
1281                         nt_errstr(status)));
1282         }
1283
1284         return status;
1285 }
1286
1287 /***************************************************************************
1288  _lsa_EnumPrivs
1289  ***************************************************************************/
1290
1291 NTSTATUS _lsa_EnumPrivs(pipes_struct *p,
1292                         struct lsa_EnumPrivs *r)
1293 {
1294         struct lsa_info *handle;
1295         uint32 i;
1296         uint32 enum_context = *r->in.resume_handle;
1297         int num_privs = count_all_privileges();
1298         struct lsa_PrivEntry *entries = NULL;
1299         LUID_ATTR luid;
1300
1301         /* remember that the enum_context starts at 0 and not 1 */
1302
1303         if ( enum_context >= num_privs )
1304                 return NT_STATUS_NO_MORE_ENTRIES;
1305
1306         DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
1307                 enum_context, num_privs));
1308
1309         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1310                 return NT_STATUS_INVALID_HANDLE;
1311
1312         /* check if the user has enough rights
1313            I don't know if it's the right one. not documented.  */
1314
1315         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1316                 return NT_STATUS_ACCESS_DENIED;
1317
1318         if (num_privs) {
1319                 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
1320                 if (!entries) {
1321                         return NT_STATUS_NO_MEMORY;
1322                 }
1323         } else {
1324                 entries = NULL;
1325         }
1326
1327         for (i = 0; i < num_privs; i++) {
1328                 if( i < enum_context) {
1329
1330                         init_lsa_StringLarge(&entries[i].name, NULL);
1331
1332                         entries[i].luid.low = 0;
1333                         entries[i].luid.high = 0;
1334                 } else {
1335
1336                         init_lsa_StringLarge(&entries[i].name, privs[i].name);
1337
1338                         luid = get_privilege_luid( &privs[i].se_priv );
1339
1340                         entries[i].luid.low = luid.luid.low;
1341                         entries[i].luid.high = luid.luid.high;
1342                 }
1343         }
1344
1345         enum_context = num_privs;
1346
1347         *r->out.resume_handle = enum_context;
1348         r->out.privs->count = num_privs;
1349         r->out.privs->privs = entries;
1350
1351         return NT_STATUS_OK;
1352 }
1353
1354 /***************************************************************************
1355  _lsa_LookupPrivDisplayName
1356  ***************************************************************************/
1357
1358 NTSTATUS _lsa_LookupPrivDisplayName(pipes_struct *p,
1359                                     struct lsa_LookupPrivDisplayName *r)
1360 {
1361         struct lsa_info *handle;
1362         const char *description;
1363         struct lsa_StringLarge *lsa_name;
1364
1365         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1366                 return NT_STATUS_INVALID_HANDLE;
1367
1368         /* check if the user has enough rights */
1369
1370         /*
1371          * I don't know if it's the right one. not documented.
1372          */
1373         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1374                 return NT_STATUS_ACCESS_DENIED;
1375
1376         DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
1377
1378         description = get_privilege_dispname(r->in.name->string);
1379         if (!description) {
1380                 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
1381                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1382         }
1383
1384         DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
1385
1386         lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
1387         if (!lsa_name) {
1388                 return NT_STATUS_NO_MEMORY;
1389         }
1390
1391         init_lsa_StringLarge(lsa_name, description);
1392
1393         *r->out.returned_language_id = r->in.language_id;
1394         *r->out.disp_name = lsa_name;
1395
1396         return NT_STATUS_OK;
1397 }
1398
1399 /***************************************************************************
1400  _lsa_EnumAccounts
1401  ***************************************************************************/
1402
1403 NTSTATUS _lsa_EnumAccounts(pipes_struct *p,
1404                            struct lsa_EnumAccounts *r)
1405 {
1406         struct lsa_info *handle;
1407         DOM_SID *sid_list;
1408         int i, j, num_entries;
1409         NTSTATUS status;
1410         struct lsa_SidPtr *sids = NULL;
1411
1412         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1413                 return NT_STATUS_INVALID_HANDLE;
1414
1415         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1416                 return NT_STATUS_ACCESS_DENIED;
1417
1418         sid_list = NULL;
1419         num_entries = 0;
1420
1421         /* The only way we can currently find out all the SIDs that have been
1422            privileged is to scan all privileges */
1423
1424         status = privilege_enumerate_accounts(&sid_list, &num_entries);
1425         if (!NT_STATUS_IS_OK(status)) {
1426                 return status;
1427         }
1428
1429         if (*r->in.resume_handle >= num_entries) {
1430                 return NT_STATUS_NO_MORE_ENTRIES;
1431         }
1432
1433         if (num_entries - *r->in.resume_handle) {
1434                 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
1435                                          num_entries - *r->in.resume_handle);
1436                 if (!sids) {
1437                         talloc_free(sid_list);
1438                         return NT_STATUS_NO_MEMORY;
1439                 }
1440
1441                 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
1442                         sids[j].sid = sid_dup_talloc(p->mem_ctx, &sid_list[i]);
1443                         if (!sids[j].sid) {
1444                                 talloc_free(sid_list);
1445                                 return NT_STATUS_NO_MEMORY;
1446                         }
1447                 }
1448         }
1449
1450         talloc_free(sid_list);
1451
1452         *r->out.resume_handle = num_entries;
1453         r->out.sids->num_sids = num_entries;
1454         r->out.sids->sids = sids;
1455
1456         return NT_STATUS_OK;
1457 }
1458
1459 /***************************************************************************
1460  _lsa_GetUserName
1461  ***************************************************************************/
1462
1463 NTSTATUS _lsa_GetUserName(pipes_struct *p,
1464                           struct lsa_GetUserName *r)
1465 {
1466         const char *username, *domname;
1467         struct lsa_String *account_name = NULL;
1468         struct lsa_String *authority_name = NULL;
1469
1470         if (r->in.account_name &&
1471            *r->in.account_name) {
1472                 return NT_STATUS_INVALID_PARAMETER;
1473         }
1474
1475         if (r->in.authority_name &&
1476            *r->in.authority_name) {
1477                 return NT_STATUS_INVALID_PARAMETER;
1478         }
1479
1480         if (p->server_info->guest) {
1481                 /*
1482                  * I'm 99% sure this is not the right place to do this,
1483                  * global_sid_Anonymous should probably be put into the token
1484                  * instead of the guest id -- vl
1485                  */
1486                 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
1487                                 &domname, &username, NULL)) {
1488                         return NT_STATUS_NO_MEMORY;
1489                 }
1490         } else {
1491                 username = p->server_info->sanitized_username;
1492                 domname = pdb_get_domain(p->server_info->sam_account);
1493         }
1494
1495         account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1496         if (!account_name) {
1497                 return NT_STATUS_NO_MEMORY;
1498         }
1499         init_lsa_String(account_name, username);
1500
1501         if (r->out.authority_name) {
1502                 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1503                 if (!authority_name) {
1504                         return NT_STATUS_NO_MEMORY;
1505                 }
1506                 init_lsa_String(authority_name, domname);
1507         }
1508
1509         *r->out.account_name = account_name;
1510         if (r->out.authority_name) {
1511                 *r->out.authority_name = authority_name;
1512         }
1513
1514         return NT_STATUS_OK;
1515 }
1516
1517 /***************************************************************************
1518  _lsa_CreateAccount
1519  ***************************************************************************/
1520
1521 NTSTATUS _lsa_CreateAccount(pipes_struct *p,
1522                             struct lsa_CreateAccount *r)
1523 {
1524         struct lsa_info *handle;
1525         struct lsa_info *info;
1526
1527         /* find the connection policy handle. */
1528         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1529                 return NT_STATUS_INVALID_HANDLE;
1530
1531         /* check if the user has enough rights */
1532
1533         /*
1534          * I don't know if it's the right one. not documented.
1535          * but guessed with rpcclient.
1536          */
1537         if (!(handle->access & LSA_POLICY_GET_PRIVATE_INFORMATION))
1538                 return NT_STATUS_ACCESS_DENIED;
1539
1540         /* check to see if the pipe_user is a Domain Admin since
1541            account_pol.tdb was already opened as root, this is all we have */
1542
1543         if ( p->server_info->utok.uid != sec_initial_uid()
1544                 && !nt_token_check_domain_rid( p->server_info->ptok,
1545                                                DOMAIN_GROUP_RID_ADMINS ) )
1546                 return NT_STATUS_ACCESS_DENIED;
1547
1548         if ( is_privileged_sid( r->in.sid ) )
1549                 return NT_STATUS_OBJECT_NAME_COLLISION;
1550
1551         /* associate the user/group SID with the (unique) handle. */
1552
1553         info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1554         if (info == NULL) {
1555                 return NT_STATUS_NO_MEMORY;
1556         }
1557
1558         info->sid = *r->in.sid;
1559         info->access = r->in.access_mask;
1560
1561         /* get a (unique) handle.  open a policy on it. */
1562         if (!create_policy_hnd(p, r->out.acct_handle, info))
1563                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1564
1565         return privilege_create_account( &info->sid );
1566 }
1567
1568
1569 /***************************************************************************
1570  _lsa_OpenAccount
1571  ***************************************************************************/
1572
1573 NTSTATUS _lsa_OpenAccount(pipes_struct *p,
1574                           struct lsa_OpenAccount *r)
1575 {
1576         struct lsa_info *handle;
1577         struct lsa_info *info;
1578
1579         /* find the connection policy handle. */
1580         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1581                 return NT_STATUS_INVALID_HANDLE;
1582
1583         /* check if the user has enough rights */
1584
1585         /*
1586          * I don't know if it's the right one. not documented.
1587          * but guessed with rpcclient.
1588          */
1589         if (!(handle->access & LSA_POLICY_GET_PRIVATE_INFORMATION))
1590                 return NT_STATUS_ACCESS_DENIED;
1591
1592         /* TODO: Fis the parsing routine before reenabling this check! */
1593         #if 0
1594         if (!lookup_sid(&handle->sid, dom_name, name, &type))
1595                 return NT_STATUS_ACCESS_DENIED;
1596         #endif
1597         /* associate the user/group SID with the (unique) handle. */
1598         info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1599         if (info == NULL) {
1600                 return NT_STATUS_NO_MEMORY;
1601         }
1602
1603         info->sid = *r->in.sid;
1604         info->access = r->in.access_mask;
1605
1606         /* get a (unique) handle.  open a policy on it. */
1607         if (!create_policy_hnd(p, r->out.acct_handle, info))
1608                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1609
1610         return NT_STATUS_OK;
1611 }
1612
1613 /***************************************************************************
1614  _lsa_EnumPrivsAccount
1615  For a given SID, enumerate all the privilege this account has.
1616  ***************************************************************************/
1617
1618 NTSTATUS _lsa_EnumPrivsAccount(pipes_struct *p,
1619                                struct lsa_EnumPrivsAccount *r)
1620 {
1621         NTSTATUS status = NT_STATUS_OK;
1622         struct lsa_info *info=NULL;
1623         SE_PRIV mask;
1624         PRIVILEGE_SET privileges;
1625         struct lsa_PrivilegeSet *priv_set = NULL;
1626         struct lsa_LUIDAttribute *luid_attrs = NULL;
1627         int i;
1628
1629         /* find the connection policy handle. */
1630         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1631                 return NT_STATUS_INVALID_HANDLE;
1632
1633         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1634                 return NT_STATUS_ACCESS_DENIED;
1635
1636         if ( !get_privileges_for_sids( &mask, &info->sid, 1 ) )
1637                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1638
1639         privilege_set_init( &privileges );
1640
1641         if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
1642
1643                 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
1644                           sid_string_dbg(&info->sid),
1645                           privileges.count));
1646
1647                 priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
1648                 if (!priv_set) {
1649                         status = NT_STATUS_NO_MEMORY;
1650                         goto done;
1651                 }
1652
1653                 luid_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx,
1654                                                struct lsa_LUIDAttribute,
1655                                                privileges.count);
1656                 if (!luid_attrs) {
1657                         status = NT_STATUS_NO_MEMORY;
1658                         goto done;
1659                 }
1660
1661                 for (i=0; i<privileges.count; i++) {
1662                         luid_attrs[i].luid.low = privileges.set[i].luid.low;
1663                         luid_attrs[i].luid.high = privileges.set[i].luid.high;
1664                         luid_attrs[i].attribute = privileges.set[i].attr;
1665                 }
1666
1667                 priv_set->count = privileges.count;
1668                 priv_set->unknown = 0;
1669                 priv_set->set = luid_attrs;
1670
1671                 *r->out.privs = priv_set;
1672         } else {
1673                 status = NT_STATUS_NO_SUCH_PRIVILEGE;
1674         }
1675
1676  done:
1677         privilege_set_free( &privileges );
1678
1679         return status;
1680 }
1681
1682 /***************************************************************************
1683  _lsa_GetSystemAccessAccount
1684  ***************************************************************************/
1685
1686 NTSTATUS _lsa_GetSystemAccessAccount(pipes_struct *p,
1687                                      struct lsa_GetSystemAccessAccount *r)
1688 {
1689         NTSTATUS status;
1690         struct lsa_info *info = NULL;
1691         struct lsa_EnumPrivsAccount e;
1692         struct lsa_PrivilegeSet *privset;
1693
1694         /* find the connection policy handle. */
1695
1696         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1697                 return NT_STATUS_INVALID_HANDLE;
1698
1699         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1700                 return NT_STATUS_ACCESS_DENIED;
1701
1702         privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
1703         if (!privset) {
1704                 return NT_STATUS_NO_MEMORY;
1705         }
1706
1707         e.in.handle = r->in.handle;
1708         e.out.privs = &privset;
1709
1710         status = _lsa_EnumPrivsAccount(p, &e);
1711         if (!NT_STATUS_IS_OK(status)) {
1712                 DEBUG(10,("_lsa_GetSystemAccessAccount: "
1713                         "failed to call _lsa_EnumPrivsAccount(): %s\n",
1714                         nt_errstr(status)));
1715                 return status;
1716         }
1717
1718         /* Samba4 would iterate over the privset to merge the policy mode bits,
1719          * not sure samba3 can do the same here, so just return what we did in
1720          * the past - gd */
1721
1722         /*
1723           0x01 -> Log on locally
1724           0x02 -> Access this computer from network
1725           0x04 -> Log on as a batch job
1726           0x10 -> Log on as a service
1727
1728           they can be ORed together
1729         */
1730
1731         *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
1732                               LSA_POLICY_MODE_NETWORK;
1733
1734         return NT_STATUS_OK;
1735 }
1736
1737 /***************************************************************************
1738   update the systemaccount information
1739  ***************************************************************************/
1740
1741 NTSTATUS _lsa_SetSystemAccessAccount(pipes_struct *p,
1742                                      struct lsa_SetSystemAccessAccount *r)
1743 {
1744         struct lsa_info *info=NULL;
1745         GROUP_MAP map;
1746
1747         /* find the connection policy handle. */
1748         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1749                 return NT_STATUS_INVALID_HANDLE;
1750
1751         /* check to see if the pipe_user is a Domain Admin since
1752            account_pol.tdb was already opened as root, this is all we have */
1753
1754         if ( p->server_info->utok.uid != sec_initial_uid()
1755                 && !nt_token_check_domain_rid( p->server_info->ptok,
1756                                                DOMAIN_GROUP_RID_ADMINS ) )
1757                 return NT_STATUS_ACCESS_DENIED;
1758
1759         if (!pdb_getgrsid(&map, info->sid))
1760                 return NT_STATUS_NO_SUCH_GROUP;
1761
1762         return pdb_update_group_mapping_entry(&map);
1763 }
1764
1765 /***************************************************************************
1766  _lsa_AddPrivilegesToAccount
1767  For a given SID, add some privileges.
1768  ***************************************************************************/
1769
1770 NTSTATUS _lsa_AddPrivilegesToAccount(pipes_struct *p,
1771                                      struct lsa_AddPrivilegesToAccount *r)
1772 {
1773         struct lsa_info *info = NULL;
1774         SE_PRIV mask;
1775         struct lsa_PrivilegeSet *set = NULL;
1776
1777         /* find the connection policy handle. */
1778         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1779                 return NT_STATUS_INVALID_HANDLE;
1780
1781         /* check to see if the pipe_user is root or a Domain Admin since
1782            account_pol.tdb was already opened as root, this is all we have */
1783
1784         if ( p->server_info->utok.uid != sec_initial_uid()
1785                 && !nt_token_check_domain_rid( p->server_info->ptok,
1786                                                DOMAIN_GROUP_RID_ADMINS ) )
1787         {
1788                 return NT_STATUS_ACCESS_DENIED;
1789         }
1790
1791         set = r->in.privs;
1792         if ( !privilege_set_to_se_priv( &mask, set ) )
1793                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1794
1795         if ( !grant_privilege( &info->sid, &mask ) ) {
1796                 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege(%s) failed!\n",
1797                          sid_string_dbg(&info->sid) ));
1798                 DEBUG(3,("Privilege mask:\n"));
1799                 dump_se_priv( DBGC_ALL, 3, &mask );
1800                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1801         }
1802
1803         return NT_STATUS_OK;
1804 }
1805
1806 /***************************************************************************
1807  _lsa_RemovePrivilegesFromAccount
1808  For a given SID, remove some privileges.
1809  ***************************************************************************/
1810
1811 NTSTATUS _lsa_RemovePrivilegesFromAccount(pipes_struct *p,
1812                                           struct lsa_RemovePrivilegesFromAccount *r)
1813 {
1814         struct lsa_info *info = NULL;
1815         SE_PRIV mask;
1816         struct lsa_PrivilegeSet *set = NULL;
1817
1818         /* find the connection policy handle. */
1819         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1820                 return NT_STATUS_INVALID_HANDLE;
1821
1822         /* check to see if the pipe_user is root or a Domain Admin since
1823            account_pol.tdb was already opened as root, this is all we have */
1824
1825         if ( p->server_info->utok.uid != sec_initial_uid()
1826                 && !nt_token_check_domain_rid( p->server_info->ptok,
1827                                                DOMAIN_GROUP_RID_ADMINS ) )
1828         {
1829                 return NT_STATUS_ACCESS_DENIED;
1830         }
1831
1832         set = r->in.privs;
1833
1834         if ( !privilege_set_to_se_priv( &mask, set ) )
1835                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1836
1837         if ( !revoke_privilege( &info->sid, &mask ) ) {
1838                 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
1839                          sid_string_dbg(&info->sid) ));
1840                 DEBUG(3,("Privilege mask:\n"));
1841                 dump_se_priv( DBGC_ALL, 3, &mask );
1842                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1843         }
1844
1845         return NT_STATUS_OK;
1846 }
1847
1848 /***************************************************************************
1849  _lsa_QuerySecurity
1850  ***************************************************************************/
1851
1852 NTSTATUS _lsa_QuerySecurity(pipes_struct *p,
1853                             struct lsa_QuerySecurity *r)
1854 {
1855         struct lsa_info *handle=NULL;
1856         SEC_DESC *psd = NULL;
1857         size_t sd_size;
1858         NTSTATUS status;
1859
1860         /* find the connection policy handle. */
1861         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1862                 return NT_STATUS_INVALID_HANDLE;
1863
1864         /* check if the user has enough rights */
1865         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1866                 return NT_STATUS_ACCESS_DENIED;
1867
1868         switch (r->in.sec_info) {
1869         case 1:
1870                 /* SD contains only the owner */
1871
1872                 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
1873                 if(!NT_STATUS_IS_OK(status))
1874                         return NT_STATUS_NO_MEMORY;
1875
1876
1877                 if((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1878                         return NT_STATUS_NO_MEMORY;
1879                 break;
1880         case 4:
1881                 /* SD contains only the ACL */
1882
1883                 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
1884                 if(!NT_STATUS_IS_OK(status))
1885                         return NT_STATUS_NO_MEMORY;
1886
1887                 if((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1888                         return NT_STATUS_NO_MEMORY;
1889                 break;
1890         default:
1891                 return NT_STATUS_INVALID_LEVEL;
1892         }
1893
1894         return status;
1895 }
1896
1897 #if 0   /* AD DC work in ongoing in Samba 4 */
1898
1899 /***************************************************************************
1900  ***************************************************************************/
1901
1902  NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_INFO2 *r_u)
1903 {
1904         struct lsa_info *handle;
1905         const char *nb_name;
1906         char *dns_name = NULL;
1907         char *forest_name = NULL;
1908         DOM_SID *sid = NULL;
1909         struct GUID guid;
1910         fstring dnsdomname;
1911
1912         ZERO_STRUCT(guid);
1913         r_u->status = NT_STATUS_OK;
1914
1915         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1916                 return NT_STATUS_INVALID_HANDLE;
1917
1918         switch (q_u->info_class) {
1919         case 0x0c:
1920                 /* check if the user has enough rights */
1921                 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1922                         return NT_STATUS_ACCESS_DENIED;
1923
1924                 /* Request PolicyPrimaryDomainInformation. */
1925                 switch (lp_server_role()) {
1926                         case ROLE_DOMAIN_PDC:
1927                         case ROLE_DOMAIN_BDC:
1928                                 nb_name = get_global_sam_name();
1929                                 /* ugly temp hack for these next two */
1930
1931                                 /* This should be a 'netbios domain -> DNS domain' mapping */
1932                                 dnsdomname = get_mydnsdomname(p->mem_ctx);
1933                                 if (!dnsdomname || !*dnsdomname) {
1934                                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1935                                 }
1936                                 strlower_m(dnsdomname);
1937
1938                                 dns_name = dnsdomname;
1939                                 forest_name = dnsdomname;
1940
1941                                 sid = get_global_sam_sid();
1942                                 secrets_fetch_domain_guid(lp_workgroup(), &guid);
1943                                 break;
1944                         default:
1945                                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1946                 }
1947                 init_dns_dom_info(&r_u->info.dns_dom_info, nb_name, dns_name,
1948                                   forest_name,&guid,sid);
1949                 break;
1950         default:
1951                 DEBUG(0,("_lsa_query_info2: unknown info level in Lsa Query: %d\n", q_u->info_class));
1952                 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
1953                 break;
1954         }
1955
1956         if (NT_STATUS_IS_OK(r_u->status)) {
1957                 r_u->ptr = 0x1;
1958                 r_u->info_class = q_u->info_class;
1959         }
1960
1961         return r_u->status;
1962 }
1963 #endif  /* AD DC work in ongoing in Samba 4 */
1964
1965 /***************************************************************************
1966  _lsa_AddAccountRights
1967  ***************************************************************************/
1968
1969 NTSTATUS _lsa_AddAccountRights(pipes_struct *p,
1970                                struct lsa_AddAccountRights *r)
1971 {
1972         struct lsa_info *info = NULL;
1973         int i = 0;
1974         DOM_SID sid;
1975
1976         /* find the connection policy handle. */
1977         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1978                 return NT_STATUS_INVALID_HANDLE;
1979
1980         /* check to see if the pipe_user is a Domain Admin since
1981            account_pol.tdb was already opened as root, this is all we have */
1982
1983         if ( p->server_info->utok.uid != sec_initial_uid()
1984                 && !nt_token_check_domain_rid( p->server_info->ptok,
1985                                                DOMAIN_GROUP_RID_ADMINS ) )
1986         {
1987                 return NT_STATUS_ACCESS_DENIED;
1988         }
1989
1990         /* according to an NT4 PDC, you can add privileges to SIDs even without
1991            call_lsa_create_account() first.  And you can use any arbitrary SID. */
1992
1993         sid_copy( &sid, r->in.sid );
1994
1995         for ( i=0; i < r->in.rights->count; i++ ) {
1996
1997                 const char *privname = r->in.rights->names[i].string;
1998
1999                 /* only try to add non-null strings */
2000
2001                 if ( !privname )
2002                         continue;
2003
2004                 if ( !grant_privilege_by_name( &sid, privname ) ) {
2005                         DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2006                                 privname ));
2007                         return NT_STATUS_NO_SUCH_PRIVILEGE;
2008                 }
2009         }
2010
2011         return NT_STATUS_OK;
2012 }
2013
2014 /***************************************************************************
2015  _lsa_RemoveAccountRights
2016  ***************************************************************************/
2017
2018 NTSTATUS _lsa_RemoveAccountRights(pipes_struct *p,
2019                                   struct lsa_RemoveAccountRights *r)
2020 {
2021         struct lsa_info *info = NULL;
2022         int i = 0;
2023         DOM_SID sid;
2024         const char *privname = NULL;
2025
2026         /* find the connection policy handle. */
2027         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2028                 return NT_STATUS_INVALID_HANDLE;
2029
2030         /* check to see if the pipe_user is a Domain Admin since
2031            account_pol.tdb was already opened as root, this is all we have */
2032
2033         if ( p->server_info->utok.uid != sec_initial_uid()
2034                 && !nt_token_check_domain_rid( p->server_info->ptok,
2035                                                DOMAIN_GROUP_RID_ADMINS ) )
2036         {
2037                 return NT_STATUS_ACCESS_DENIED;
2038         }
2039
2040         sid_copy( &sid, r->in.sid );
2041
2042         if ( r->in.remove_all ) {
2043                 if ( !revoke_all_privileges( &sid ) )
2044                         return NT_STATUS_ACCESS_DENIED;
2045
2046                 return NT_STATUS_OK;
2047         }
2048
2049         for ( i=0; i < r->in.rights->count; i++ ) {
2050
2051                 privname = r->in.rights->names[i].string;
2052
2053                 /* only try to add non-null strings */
2054
2055                 if ( !privname )
2056                         continue;
2057
2058                 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2059                         DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2060                                 privname ));
2061                         return NT_STATUS_NO_SUCH_PRIVILEGE;
2062                 }
2063         }
2064
2065         return NT_STATUS_OK;
2066 }
2067
2068 /*******************************************************************
2069 ********************************************************************/
2070
2071 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
2072                                    struct lsa_RightSet *r,
2073                                    PRIVILEGE_SET *privileges)
2074 {
2075         uint32 i;
2076         const char *privname;
2077         const char **privname_array = NULL;
2078         int num_priv = 0;
2079
2080         for (i=0; i<privileges->count; i++) {
2081
2082                 privname = luid_to_privilege_name(&privileges->set[i].luid);
2083                 if (privname) {
2084                         if (!add_string_to_array(mem_ctx, privname,
2085                                                  &privname_array, &num_priv)) {
2086                                 return NT_STATUS_NO_MEMORY;
2087                         }
2088                 }
2089         }
2090
2091         if (num_priv) {
2092
2093                 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
2094                                              num_priv);
2095                 if (!r->names) {
2096                         return NT_STATUS_NO_MEMORY;
2097                 }
2098
2099                 for (i=0; i<num_priv; i++) {
2100                         init_lsa_StringLarge(&r->names[i], privname_array[i]);
2101                 }
2102
2103                 r->count = num_priv;
2104         }
2105
2106         return NT_STATUS_OK;
2107 }
2108
2109 /***************************************************************************
2110  _lsa_EnumAccountRights
2111  ***************************************************************************/
2112
2113 NTSTATUS _lsa_EnumAccountRights(pipes_struct *p,
2114                                 struct lsa_EnumAccountRights *r)
2115 {
2116         NTSTATUS status;
2117         struct lsa_info *info = NULL;
2118         DOM_SID sid;
2119         PRIVILEGE_SET privileges;
2120         SE_PRIV mask;
2121
2122         /* find the connection policy handle. */
2123
2124         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2125                 return NT_STATUS_INVALID_HANDLE;
2126
2127         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2128                 return NT_STATUS_ACCESS_DENIED;
2129
2130         /* according to an NT4 PDC, you can add privileges to SIDs even without
2131            call_lsa_create_account() first.  And you can use any arbitrary SID. */
2132
2133         sid_copy( &sid, r->in.sid );
2134
2135         if ( !get_privileges_for_sids( &mask, &sid, 1 ) )
2136                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2137
2138         privilege_set_init( &privileges );
2139
2140         if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
2141
2142                 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
2143                           sid_string_dbg(&sid), privileges.count));
2144
2145                 status = init_lsa_right_set(p->mem_ctx, r->out.rights, &privileges);
2146         } else {
2147                 status = NT_STATUS_NO_SUCH_PRIVILEGE;
2148         }
2149
2150         privilege_set_free( &privileges );
2151
2152         return status;
2153 }
2154
2155 /***************************************************************************
2156  _lsa_LookupPrivValue
2157  ***************************************************************************/
2158
2159 NTSTATUS _lsa_LookupPrivValue(pipes_struct *p,
2160                               struct lsa_LookupPrivValue *r)
2161 {
2162         struct lsa_info *info = NULL;
2163         const char *name = NULL;
2164         LUID_ATTR priv_luid;
2165         SE_PRIV mask;
2166
2167         /* find the connection policy handle. */
2168
2169         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2170                 return NT_STATUS_INVALID_HANDLE;
2171
2172         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2173                 return NT_STATUS_ACCESS_DENIED;
2174
2175         name = r->in.name->string;
2176
2177         DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
2178
2179         if ( !se_priv_from_name( name, &mask ) )
2180                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2181
2182         priv_luid = get_privilege_luid( &mask );
2183
2184         r->out.luid->low = priv_luid.luid.low;
2185         r->out.luid->high = priv_luid.luid.high;
2186
2187         return NT_STATUS_OK;
2188 }
2189
2190 /*
2191  * From here on the server routines are just dummy ones to make smbd link with
2192  * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
2193  * pulling the server stubs across one by one.
2194  */
2195
2196 NTSTATUS _lsa_Delete(pipes_struct *p, struct lsa_Delete *r)
2197 {
2198         p->rng_fault_state = True;
2199         return NT_STATUS_NOT_IMPLEMENTED;
2200 }
2201
2202 NTSTATUS _lsa_SetSecObj(pipes_struct *p, struct lsa_SetSecObj *r)
2203 {
2204         p->rng_fault_state = True;
2205         return NT_STATUS_NOT_IMPLEMENTED;
2206 }
2207
2208 NTSTATUS _lsa_ChangePassword(pipes_struct *p, struct lsa_ChangePassword *r)
2209 {
2210         p->rng_fault_state = True;
2211         return NT_STATUS_NOT_IMPLEMENTED;
2212 }
2213
2214 NTSTATUS _lsa_SetInfoPolicy(pipes_struct *p, struct lsa_SetInfoPolicy *r)
2215 {
2216         p->rng_fault_state = True;
2217         return NT_STATUS_NOT_IMPLEMENTED;
2218 }
2219
2220 NTSTATUS _lsa_ClearAuditLog(pipes_struct *p, struct lsa_ClearAuditLog *r)
2221 {
2222         p->rng_fault_state = True;
2223         return NT_STATUS_NOT_IMPLEMENTED;
2224 }
2225
2226 NTSTATUS _lsa_GetQuotasForAccount(pipes_struct *p, struct lsa_GetQuotasForAccount *r)
2227 {
2228         p->rng_fault_state = True;
2229         return NT_STATUS_NOT_IMPLEMENTED;
2230 }
2231
2232 NTSTATUS _lsa_SetQuotasForAccount(pipes_struct *p, struct lsa_SetQuotasForAccount *r)
2233 {
2234         p->rng_fault_state = True;
2235         return NT_STATUS_NOT_IMPLEMENTED;
2236 }
2237
2238 NTSTATUS _lsa_QueryTrustedDomainInfo(pipes_struct *p, struct lsa_QueryTrustedDomainInfo *r)
2239 {
2240         p->rng_fault_state = True;
2241         return NT_STATUS_NOT_IMPLEMENTED;
2242 }
2243
2244 NTSTATUS _lsa_SetInformationTrustedDomain(pipes_struct *p, struct lsa_SetInformationTrustedDomain *r)
2245 {
2246         p->rng_fault_state = True;
2247         return NT_STATUS_NOT_IMPLEMENTED;
2248 }
2249
2250 NTSTATUS _lsa_QuerySecret(pipes_struct *p, struct lsa_QuerySecret *r)
2251 {
2252         p->rng_fault_state = True;
2253         return NT_STATUS_NOT_IMPLEMENTED;
2254 }
2255
2256 NTSTATUS _lsa_LookupPrivName(pipes_struct *p, struct lsa_LookupPrivName *r)
2257 {
2258         p->rng_fault_state = True;
2259         return NT_STATUS_NOT_IMPLEMENTED;
2260 }
2261
2262 NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p, struct lsa_EnumAccountsWithUserRight *r)
2263 {
2264         p->rng_fault_state = True;
2265         return NT_STATUS_NOT_IMPLEMENTED;
2266 }
2267
2268 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(pipes_struct *p, struct lsa_QueryTrustedDomainInfoBySid *r)
2269 {
2270         p->rng_fault_state = True;
2271         return NT_STATUS_NOT_IMPLEMENTED;
2272 }
2273
2274 NTSTATUS _lsa_SetTrustedDomainInfo(pipes_struct *p, struct lsa_SetTrustedDomainInfo *r)
2275 {
2276         p->rng_fault_state = True;
2277         return NT_STATUS_NOT_IMPLEMENTED;
2278 }
2279
2280 NTSTATUS _lsa_DeleteTrustedDomain(pipes_struct *p, struct lsa_DeleteTrustedDomain *r)
2281 {
2282         p->rng_fault_state = True;
2283         return NT_STATUS_NOT_IMPLEMENTED;
2284 }
2285
2286 NTSTATUS _lsa_StorePrivateData(pipes_struct *p, struct lsa_StorePrivateData *r)
2287 {
2288         p->rng_fault_state = True;
2289         return NT_STATUS_NOT_IMPLEMENTED;
2290 }
2291
2292 NTSTATUS _lsa_RetrievePrivateData(pipes_struct *p, struct lsa_RetrievePrivateData *r)
2293 {
2294         p->rng_fault_state = True;
2295         return NT_STATUS_NOT_IMPLEMENTED;
2296 }
2297
2298 NTSTATUS _lsa_QueryInfoPolicy2(pipes_struct *p, struct lsa_QueryInfoPolicy2 *r)
2299 {
2300         p->rng_fault_state = True;
2301         return NT_STATUS_NOT_IMPLEMENTED;
2302 }
2303
2304 NTSTATUS _lsa_SetInfoPolicy2(pipes_struct *p, struct lsa_SetInfoPolicy2 *r)
2305 {
2306         p->rng_fault_state = True;
2307         return NT_STATUS_NOT_IMPLEMENTED;
2308 }
2309
2310 NTSTATUS _lsa_QueryTrustedDomainInfoByName(pipes_struct *p, struct lsa_QueryTrustedDomainInfoByName *r)
2311 {
2312         p->rng_fault_state = True;
2313         return NT_STATUS_NOT_IMPLEMENTED;
2314 }
2315
2316 NTSTATUS _lsa_SetTrustedDomainInfoByName(pipes_struct *p, struct lsa_SetTrustedDomainInfoByName *r)
2317 {
2318         p->rng_fault_state = True;
2319         return NT_STATUS_NOT_IMPLEMENTED;
2320 }
2321
2322 NTSTATUS _lsa_EnumTrustedDomainsEx(pipes_struct *p, struct lsa_EnumTrustedDomainsEx *r)
2323 {
2324         p->rng_fault_state = True;
2325         return NT_STATUS_NOT_IMPLEMENTED;
2326 }
2327
2328 NTSTATUS _lsa_CreateTrustedDomainEx(pipes_struct *p, struct lsa_CreateTrustedDomainEx *r)
2329 {
2330         p->rng_fault_state = True;
2331         return NT_STATUS_NOT_IMPLEMENTED;
2332 }
2333
2334 NTSTATUS _lsa_CloseTrustedDomainEx(pipes_struct *p, struct lsa_CloseTrustedDomainEx *r)
2335 {
2336         p->rng_fault_state = True;
2337         return NT_STATUS_NOT_IMPLEMENTED;
2338 }
2339
2340 NTSTATUS _lsa_QueryDomainInformationPolicy(pipes_struct *p, struct lsa_QueryDomainInformationPolicy *r)
2341 {
2342         p->rng_fault_state = True;
2343         return NT_STATUS_NOT_IMPLEMENTED;
2344 }
2345
2346 NTSTATUS _lsa_SetDomainInformationPolicy(pipes_struct *p, struct lsa_SetDomainInformationPolicy *r)
2347 {
2348         p->rng_fault_state = True;
2349         return NT_STATUS_NOT_IMPLEMENTED;
2350 }
2351
2352 NTSTATUS _lsa_OpenTrustedDomainByName(pipes_struct *p, struct lsa_OpenTrustedDomainByName *r)
2353 {
2354         p->rng_fault_state = True;
2355         return NT_STATUS_NOT_IMPLEMENTED;
2356 }
2357
2358 NTSTATUS _lsa_TestCall(pipes_struct *p, struct lsa_TestCall *r)
2359 {
2360         p->rng_fault_state = True;
2361         return NT_STATUS_NOT_IMPLEMENTED;
2362 }
2363
2364 NTSTATUS _lsa_CreateTrustedDomainEx2(pipes_struct *p, struct lsa_CreateTrustedDomainEx2 *r)
2365 {
2366         p->rng_fault_state = True;
2367         return NT_STATUS_NOT_IMPLEMENTED;
2368 }
2369
2370 NTSTATUS _lsa_CREDRWRITE(pipes_struct *p, struct lsa_CREDRWRITE *r)
2371 {
2372         p->rng_fault_state = True;
2373         return NT_STATUS_NOT_IMPLEMENTED;
2374 }
2375
2376 NTSTATUS _lsa_CREDRREAD(pipes_struct *p, struct lsa_CREDRREAD *r)
2377 {
2378         p->rng_fault_state = True;
2379         return NT_STATUS_NOT_IMPLEMENTED;
2380 }
2381
2382 NTSTATUS _lsa_CREDRENUMERATE(pipes_struct *p, struct lsa_CREDRENUMERATE *r)
2383 {
2384         p->rng_fault_state = True;
2385         return NT_STATUS_NOT_IMPLEMENTED;
2386 }
2387
2388 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(pipes_struct *p, struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2389 {
2390         p->rng_fault_state = True;
2391         return NT_STATUS_NOT_IMPLEMENTED;
2392 }
2393
2394 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(pipes_struct *p, struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2395 {
2396         p->rng_fault_state = True;
2397         return NT_STATUS_NOT_IMPLEMENTED;
2398 }
2399
2400 NTSTATUS _lsa_CREDRDELETE(pipes_struct *p, struct lsa_CREDRDELETE *r)
2401 {
2402         p->rng_fault_state = True;
2403         return NT_STATUS_NOT_IMPLEMENTED;
2404 }
2405
2406 NTSTATUS _lsa_CREDRGETTARGETINFO(pipes_struct *p, struct lsa_CREDRGETTARGETINFO *r)
2407 {
2408         p->rng_fault_state = True;
2409         return NT_STATUS_NOT_IMPLEMENTED;
2410 }
2411
2412 NTSTATUS _lsa_CREDRPROFILELOADED(pipes_struct *p, struct lsa_CREDRPROFILELOADED *r)
2413 {
2414         p->rng_fault_state = True;
2415         return NT_STATUS_NOT_IMPLEMENTED;
2416 }
2417
2418 NTSTATUS _lsa_CREDRGETSESSIONTYPES(pipes_struct *p, struct lsa_CREDRGETSESSIONTYPES *r)
2419 {
2420         p->rng_fault_state = True;
2421         return NT_STATUS_NOT_IMPLEMENTED;
2422 }
2423
2424 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARREGISTERAUDITEVENT *r)
2425 {
2426         p->rng_fault_state = True;
2427         return NT_STATUS_NOT_IMPLEMENTED;
2428 }
2429
2430 NTSTATUS _lsa_LSARGENAUDITEVENT(pipes_struct *p, struct lsa_LSARGENAUDITEVENT *r)
2431 {
2432         p->rng_fault_state = True;
2433         return NT_STATUS_NOT_IMPLEMENTED;
2434 }
2435
2436 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARUNREGISTERAUDITEVENT *r)
2437 {
2438         p->rng_fault_state = True;
2439         return NT_STATUS_NOT_IMPLEMENTED;
2440 }
2441
2442 NTSTATUS _lsa_lsaRQueryForestTrustInformation(pipes_struct *p, struct lsa_lsaRQueryForestTrustInformation *r)
2443 {
2444         p->rng_fault_state = True;
2445         return NT_STATUS_NOT_IMPLEMENTED;
2446 }
2447
2448 NTSTATUS _lsa_LSARSETFORESTTRUSTINFORMATION(pipes_struct *p, struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2449 {
2450         p->rng_fault_state = True;
2451         return NT_STATUS_NOT_IMPLEMENTED;
2452 }
2453
2454 NTSTATUS _lsa_CREDRRENAME(pipes_struct *p, struct lsa_CREDRRENAME *r)
2455 {
2456         p->rng_fault_state = True;
2457         return NT_STATUS_NOT_IMPLEMENTED;
2458 }
2459
2460 NTSTATUS _lsa_LSAROPENPOLICYSCE(pipes_struct *p, struct lsa_LSAROPENPOLICYSCE *r)
2461 {
2462         p->rng_fault_state = True;
2463         return NT_STATUS_NOT_IMPLEMENTED;
2464 }
2465
2466 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(pipes_struct *p, struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2467 {
2468         p->rng_fault_state = True;
2469         return NT_STATUS_NOT_IMPLEMENTED;
2470 }
2471
2472 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(pipes_struct *p, struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2473 {
2474         p->rng_fault_state = True;
2475         return NT_STATUS_NOT_IMPLEMENTED;
2476 }
2477
2478 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(pipes_struct *p, struct lsa_LSARADTREPORTSECURITYEVENT *r)
2479 {
2480         p->rng_fault_state = True;
2481         return NT_STATUS_NOT_IMPLEMENTED;
2482 }