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