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