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