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