s3-lsa: Fix Bug #6263. Unexpected LookupSids reply crashes XP pre-SP3.
[samba.git] / source3 / rpc_server / srv_lsa_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Jeremy Allison                    2001, 2006.
8  *  Copyright (C) Rafal Szczesniak                  2002,
9  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
10  *  Copyright (C) Simo Sorce                        2003.
11  *  Copyright (C) Gerald (Jerry) Carter             2005.
12  *  Copyright (C) Volker Lendecke                   2005.
13  *  Copyright (C) Guenther Deschner                 2008.
14  *
15  *  This program is free software; you can redistribute it and/or modify
16  *  it under the terms of the GNU General Public License as published by
17  *  the Free Software Foundation; either version 3 of the License, or
18  *  (at your option) any later version.
19  *
20  *  This program is distributed in the hope that it will be useful,
21  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  *  GNU General Public License for more details.
24  *
25  *  You should have received a copy of the GNU General Public License
26  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
27  */
28
29 /* This is the implementation of the lsa server code. */
30
31 #include "includes.h"
32
33 #undef DBGC_CLASS
34 #define DBGC_CLASS DBGC_RPC_SRV
35
36 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
37
38 extern PRIVS privs[];
39
40 struct lsa_info {
41         DOM_SID sid;
42         uint32 access;
43 };
44
45 const struct generic_mapping lsa_generic_mapping = {
46         LSA_POLICY_READ,
47         LSA_POLICY_WRITE,
48         LSA_POLICY_EXECUTE,
49         LSA_POLICY_ALL_ACCESS
50 };
51
52 /***************************************************************************
53  init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
54 ***************************************************************************/
55
56 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
57                                     struct lsa_RefDomainList *ref,
58                                     const char *dom_name,
59                                     DOM_SID *dom_sid)
60 {
61         int num = 0;
62
63         if (dom_name != NULL) {
64                 for (num = 0; num < ref->count; num++) {
65                         if (sid_equal(dom_sid, ref->domains[num].sid)) {
66                                 return num;
67                         }
68                 }
69         } else {
70                 num = ref->count;
71         }
72
73         if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
74                 /* index not found, already at maximum domain limit */
75                 return -1;
76         }
77
78         ref->count = num + 1;
79         ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
80
81         ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains,
82                                             struct lsa_DomainInfo, ref->count);
83         if (!ref->domains) {
84                 return -1;
85         }
86
87         ZERO_STRUCT(ref->domains[num]);
88
89         init_lsa_StringLarge(&ref->domains[num].name, dom_name);
90         ref->domains[num].sid = sid_dup_talloc(mem_ctx, dom_sid);
91         if (!ref->domains[num].sid) {
92                 return -1;
93         }
94
95         return num;
96 }
97
98
99 /***************************************************************************
100  initialize a lsa_DomainInfo structure.
101  ***************************************************************************/
102
103 static void init_dom_query_3(struct lsa_DomainInfo *r,
104                              const char *name,
105                              DOM_SID *sid)
106 {
107         init_lsa_StringLarge(&r->name, name);
108         r->sid = sid;
109 }
110
111 /***************************************************************************
112  initialize a lsa_DomainInfo structure.
113  ***************************************************************************/
114
115 static void init_dom_query_5(struct lsa_DomainInfo *r,
116                              const char *name,
117                              DOM_SID *sid)
118 {
119         init_lsa_StringLarge(&r->name, name);
120         r->sid = sid;
121 }
122
123 /***************************************************************************
124  lookup_lsa_rids. Must be called as root for lookup_name to work.
125  ***************************************************************************/
126
127 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
128                                 struct lsa_RefDomainList *ref,
129                                 struct lsa_TranslatedSid *prid,
130                                 uint32_t num_entries,
131                                 struct lsa_String *name,
132                                 int flags,
133                                 uint32_t *pmapped_count)
134 {
135         uint32 mapped_count, i;
136
137         SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
138
139         mapped_count = 0;
140         *pmapped_count = 0;
141
142         for (i = 0; i < num_entries; i++) {
143                 DOM_SID sid;
144                 uint32 rid;
145                 int dom_idx;
146                 const char *full_name;
147                 const char *domain;
148                 enum lsa_SidType type = SID_NAME_UNKNOWN;
149
150                 /* Split name into domain and user component */
151
152                 full_name = name[i].string;
153                 if (full_name == NULL) {
154                         return NT_STATUS_NO_MEMORY;
155                 }
156
157                 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
158
159                 /* We can ignore the result of lookup_name, it will not touch
160                    "type" if it's not successful */
161
162                 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
163                             &sid, &type);
164
165                 switch (type) {
166                 case SID_NAME_USER:
167                 case SID_NAME_DOM_GRP:
168                 case SID_NAME_DOMAIN:
169                 case SID_NAME_ALIAS:
170                 case SID_NAME_WKN_GRP:
171                         DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
172                         /* Leave these unchanged */
173                         break;
174                 default:
175                         /* Don't hand out anything but the list above */
176                         DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
177                         type = SID_NAME_UNKNOWN;
178                         break;
179                 }
180
181                 rid = 0;
182                 dom_idx = -1;
183
184                 if (type != SID_NAME_UNKNOWN) {
185                         sid_split_rid(&sid, &rid);
186                         dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
187                         mapped_count++;
188                 }
189
190                 prid[i].sid_type        = type;
191                 prid[i].rid             = rid;
192                 prid[i].sid_index       = dom_idx;
193         }
194
195         *pmapped_count = mapped_count;
196         return NT_STATUS_OK;
197 }
198
199 /***************************************************************************
200  lookup_lsa_sids. Must be called as root for lookup_name to work.
201  ***************************************************************************/
202
203 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
204                                 struct lsa_RefDomainList *ref,
205                                 struct lsa_TranslatedSid3 *trans_sids,
206                                 uint32_t num_entries,
207                                 struct lsa_String *name,
208                                 int flags,
209                                 uint32 *pmapped_count)
210 {
211         uint32 mapped_count, i;
212
213         SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
214
215         mapped_count = 0;
216         *pmapped_count = 0;
217
218         for (i = 0; i < num_entries; i++) {
219                 DOM_SID sid;
220                 uint32 rid;
221                 int dom_idx;
222                 const char *full_name;
223                 const char *domain;
224                 enum lsa_SidType type = SID_NAME_UNKNOWN;
225
226                 ZERO_STRUCT(sid);
227
228                 /* Split name into domain and user component */
229
230                 full_name = name[i].string;
231                 if (full_name == NULL) {
232                         return NT_STATUS_NO_MEMORY;
233                 }
234
235                 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
236
237                 /* We can ignore the result of lookup_name, it will not touch
238                    "type" if it's not successful */
239
240                 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
241                             &sid, &type);
242
243                 switch (type) {
244                 case SID_NAME_USER:
245                 case SID_NAME_DOM_GRP:
246                 case SID_NAME_DOMAIN:
247                 case SID_NAME_ALIAS:
248                 case SID_NAME_WKN_GRP:
249                         DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
250                         /* Leave these unchanged */
251                         break;
252                 default:
253                         /* Don't hand out anything but the list above */
254                         DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
255                         type = SID_NAME_UNKNOWN;
256                         break;
257                 }
258
259                 rid = 0;
260                 dom_idx = -1;
261
262                 if (type != SID_NAME_UNKNOWN) {
263                         DOM_SID domain_sid;
264                         sid_copy(&domain_sid, &sid);
265                         sid_split_rid(&domain_sid, &rid);
266                         dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
267                         mapped_count++;
268                 }
269
270                 /* Initialize the lsa_TranslatedSid3 return. */
271                 trans_sids[i].sid_type = type;
272                 trans_sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
273                 trans_sids[i].sid_index = dom_idx;
274         }
275
276         *pmapped_count = mapped_count;
277         return NT_STATUS_OK;
278 }
279
280 static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size)
281 {
282         DOM_SID local_adm_sid;
283         DOM_SID adm_sid;
284
285         SEC_ACE ace[3];
286
287         SEC_ACL *psa = NULL;
288
289         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, 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->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1093         if (!sid_array2->sids) {
1094                 return NT_STATUS_NO_MEMORY;
1095         }
1096
1097         for (i=0; i<sid_array->count; i++) {
1098                 sid_array2->sids[i].sid_type  = sid_array->sids[i].sid_type;
1099                 sid_array2->sids[i].rid       = sid_array->sids[i].rid;
1100                 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1101                 sid_array2->sids[i].unknown   = 0;
1102         }
1103
1104         r->out.sids = sid_array2;
1105
1106         return status;
1107 }
1108
1109 /***************************************************************************
1110  _lsa_LookupNames3
1111  ***************************************************************************/
1112
1113 NTSTATUS _lsa_LookupNames3(pipes_struct *p,
1114                            struct lsa_LookupNames3 *r)
1115 {
1116         NTSTATUS status;
1117         struct lsa_info *handle;
1118         struct lsa_String *names = r->in.names;
1119         uint32 num_entries = r->in.num_names;
1120         struct lsa_RefDomainList *domains = NULL;
1121         struct lsa_TranslatedSid3 *trans_sids = NULL;
1122         uint32 mapped_count = 0;
1123         int flags = 0;
1124         bool check_policy = true;
1125
1126         switch (p->hdr_req.opnum) {
1127                 case NDR_LSA_LOOKUPNAMES4:
1128                         check_policy = false;
1129                         break;
1130                 case NDR_LSA_LOOKUPNAMES3:
1131                 default:
1132                         check_policy = true;
1133         }
1134
1135         if (num_entries >  MAX_LOOKUP_SIDS) {
1136                 num_entries = MAX_LOOKUP_SIDS;
1137                 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1138         }
1139
1140         /* Probably the lookup_level is some sort of bitmask. */
1141         if (r->in.level == 1) {
1142                 flags = LOOKUP_NAME_ALL;
1143         }
1144
1145         domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1146         if (!domains) {
1147                 return NT_STATUS_NO_MEMORY;
1148         }
1149
1150         if (num_entries) {
1151                 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1152                                                num_entries);
1153                 if (!trans_sids) {
1154                         return NT_STATUS_NO_MEMORY;
1155                 }
1156         } else {
1157                 trans_sids = NULL;
1158         }
1159
1160         if (check_policy) {
1161
1162                 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1163                         status = NT_STATUS_INVALID_HANDLE;
1164                         goto done;
1165                 }
1166
1167                 /* check if the user has enough rights */
1168                 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1169                         status = NT_STATUS_ACCESS_DENIED;
1170                         goto done;
1171                 }
1172         }
1173
1174         /* set up the LSA Lookup SIDs response */
1175         become_root(); /* lookup_name can require root privs */
1176         status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1177                                  names, flags, &mapped_count);
1178         unbecome_root();
1179
1180 done:
1181
1182         if (NT_STATUS_IS_OK(status)) {
1183                 if (mapped_count == 0) {
1184                         status = NT_STATUS_NONE_MAPPED;
1185                 } else if (mapped_count != num_entries) {
1186                         status = STATUS_SOME_UNMAPPED;
1187                 }
1188         }
1189
1190         *r->out.count = mapped_count;
1191         *r->out.domains = domains;
1192         r->out.sids->sids = trans_sids;
1193         r->out.sids->count = num_entries;
1194
1195         return status;
1196 }
1197
1198 /***************************************************************************
1199  _lsa_LookupNames4
1200  ***************************************************************************/
1201
1202 NTSTATUS _lsa_LookupNames4(pipes_struct *p,
1203                            struct lsa_LookupNames4 *r)
1204 {
1205         struct lsa_LookupNames3 q;
1206
1207         /* No policy handle on this call. Restrict to crypto connections. */
1208         if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
1209                 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1210                         get_remote_machine_name() ));
1211                 return NT_STATUS_INVALID_PARAMETER;
1212         }
1213
1214         q.in.handle             = NULL;
1215         q.in.num_names          = r->in.num_names;
1216         q.in.names              = r->in.names;
1217         q.in.level              = r->in.level;
1218         q.in.lookup_options     = r->in.lookup_options;
1219         q.in.client_revision    = r->in.client_revision;
1220         q.in.sids               = r->in.sids;
1221         q.in.count              = r->in.count;
1222
1223         q.out.domains           = r->out.domains;
1224         q.out.sids              = r->out.sids;
1225         q.out.count             = r->out.count;
1226
1227         return _lsa_LookupNames3(p, &q);
1228 }
1229
1230 /***************************************************************************
1231  _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1232  ***************************************************************************/
1233
1234 NTSTATUS _lsa_Close(pipes_struct *p, struct lsa_Close *r)
1235 {
1236         if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1237                 return NT_STATUS_INVALID_HANDLE;
1238         }
1239
1240         close_policy_hnd(p, r->in.handle);
1241         ZERO_STRUCTP(r->out.handle);
1242         return NT_STATUS_OK;
1243 }
1244
1245 /***************************************************************************
1246  ***************************************************************************/
1247
1248 NTSTATUS _lsa_OpenSecret(pipes_struct *p, struct lsa_OpenSecret *r)
1249 {
1250         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1251 }
1252
1253 /***************************************************************************
1254  ***************************************************************************/
1255
1256 NTSTATUS _lsa_OpenTrustedDomain(pipes_struct *p, struct lsa_OpenTrustedDomain *r)
1257 {
1258         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1259 }
1260
1261 /***************************************************************************
1262  ***************************************************************************/
1263
1264 NTSTATUS _lsa_CreateTrustedDomain(pipes_struct *p, struct lsa_CreateTrustedDomain *r)
1265 {
1266         return NT_STATUS_ACCESS_DENIED;
1267 }
1268
1269 /***************************************************************************
1270  ***************************************************************************/
1271
1272 NTSTATUS _lsa_CreateSecret(pipes_struct *p, struct lsa_CreateSecret *r)
1273 {
1274         return NT_STATUS_ACCESS_DENIED;
1275 }
1276
1277 /***************************************************************************
1278  ***************************************************************************/
1279
1280 NTSTATUS _lsa_SetSecret(pipes_struct *p, struct lsa_SetSecret *r)
1281 {
1282         return NT_STATUS_ACCESS_DENIED;
1283 }
1284
1285 /***************************************************************************
1286  _lsa_DeleteObject
1287  ***************************************************************************/
1288
1289 NTSTATUS _lsa_DeleteObject(pipes_struct *p,
1290                            struct lsa_DeleteObject *r)
1291 {
1292         return NT_STATUS_ACCESS_DENIED;
1293 }
1294
1295 /***************************************************************************
1296  _lsa_EnumPrivs
1297  ***************************************************************************/
1298
1299 NTSTATUS _lsa_EnumPrivs(pipes_struct *p,
1300                         struct lsa_EnumPrivs *r)
1301 {
1302         struct lsa_info *handle;
1303         uint32 i;
1304         uint32 enum_context = *r->in.resume_handle;
1305         int num_privs = count_all_privileges();
1306         struct lsa_PrivEntry *entries = NULL;
1307         LUID_ATTR luid;
1308
1309         /* remember that the enum_context starts at 0 and not 1 */
1310
1311         if ( enum_context >= num_privs )
1312                 return NT_STATUS_NO_MORE_ENTRIES;
1313
1314         DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
1315                 enum_context, num_privs));
1316
1317         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1318                 return NT_STATUS_INVALID_HANDLE;
1319
1320         /* check if the user has enough rights
1321            I don't know if it's the right one. not documented.  */
1322
1323         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1324                 return NT_STATUS_ACCESS_DENIED;
1325
1326         if (num_privs) {
1327                 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
1328                 if (!entries) {
1329                         return NT_STATUS_NO_MEMORY;
1330                 }
1331         } else {
1332                 entries = NULL;
1333         }
1334
1335         for (i = 0; i < num_privs; i++) {
1336                 if( i < enum_context) {
1337
1338                         init_lsa_StringLarge(&entries[i].name, NULL);
1339
1340                         entries[i].luid.low = 0;
1341                         entries[i].luid.high = 0;
1342                 } else {
1343
1344                         init_lsa_StringLarge(&entries[i].name, privs[i].name);
1345
1346                         luid = get_privilege_luid( &privs[i].se_priv );
1347
1348                         entries[i].luid.low = luid.luid.low;
1349                         entries[i].luid.high = luid.luid.high;
1350                 }
1351         }
1352
1353         enum_context = num_privs;
1354
1355         *r->out.resume_handle = enum_context;
1356         r->out.privs->count = num_privs;
1357         r->out.privs->privs = entries;
1358
1359         return NT_STATUS_OK;
1360 }
1361
1362 /***************************************************************************
1363  _lsa_LookupPrivDisplayName
1364  ***************************************************************************/
1365
1366 NTSTATUS _lsa_LookupPrivDisplayName(pipes_struct *p,
1367                                     struct lsa_LookupPrivDisplayName *r)
1368 {
1369         struct lsa_info *handle;
1370         const char *description;
1371         struct lsa_StringLarge *lsa_name;
1372
1373         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1374                 return NT_STATUS_INVALID_HANDLE;
1375
1376         /* check if the user has enough rights */
1377
1378         /*
1379          * I don't know if it's the right one. not documented.
1380          */
1381         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1382                 return NT_STATUS_ACCESS_DENIED;
1383
1384         DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
1385
1386         description = get_privilege_dispname(r->in.name->string);
1387         if (!description) {
1388                 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
1389                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1390         }
1391
1392         DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
1393
1394         lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
1395         if (!lsa_name) {
1396                 return NT_STATUS_NO_MEMORY;
1397         }
1398
1399         init_lsa_StringLarge(lsa_name, description);
1400
1401         *r->out.returned_language_id = r->in.language_id;
1402         *r->out.disp_name = lsa_name;
1403
1404         return NT_STATUS_OK;
1405 }
1406
1407 /***************************************************************************
1408  _lsa_EnumAccounts
1409  ***************************************************************************/
1410
1411 NTSTATUS _lsa_EnumAccounts(pipes_struct *p,
1412                            struct lsa_EnumAccounts *r)
1413 {
1414         struct lsa_info *handle;
1415         DOM_SID *sid_list;
1416         int i, j, num_entries;
1417         NTSTATUS status;
1418         struct lsa_SidPtr *sids = NULL;
1419
1420         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1421                 return NT_STATUS_INVALID_HANDLE;
1422
1423         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1424                 return NT_STATUS_ACCESS_DENIED;
1425
1426         sid_list = NULL;
1427         num_entries = 0;
1428
1429         /* The only way we can currently find out all the SIDs that have been
1430            privileged is to scan all privileges */
1431
1432         status = privilege_enumerate_accounts(&sid_list, &num_entries);
1433         if (!NT_STATUS_IS_OK(status)) {
1434                 return status;
1435         }
1436
1437         if (*r->in.resume_handle >= num_entries) {
1438                 return NT_STATUS_NO_MORE_ENTRIES;
1439         }
1440
1441         if (num_entries - *r->in.resume_handle) {
1442                 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
1443                                          num_entries - *r->in.resume_handle);
1444                 if (!sids) {
1445                         talloc_free(sid_list);
1446                         return NT_STATUS_NO_MEMORY;
1447                 }
1448
1449                 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
1450                         sids[j].sid = sid_dup_talloc(p->mem_ctx, &sid_list[i]);
1451                         if (!sids[j].sid) {
1452                                 talloc_free(sid_list);
1453                                 return NT_STATUS_NO_MEMORY;
1454                         }
1455                 }
1456         }
1457
1458         talloc_free(sid_list);
1459
1460         *r->out.resume_handle = num_entries;
1461         r->out.sids->num_sids = num_entries;
1462         r->out.sids->sids = sids;
1463
1464         return NT_STATUS_OK;
1465 }
1466
1467 /***************************************************************************
1468  _lsa_GetUserName
1469  ***************************************************************************/
1470
1471 NTSTATUS _lsa_GetUserName(pipes_struct *p,
1472                           struct lsa_GetUserName *r)
1473 {
1474         const char *username, *domname;
1475         struct lsa_String *account_name = NULL;
1476         struct lsa_String *authority_name = NULL;
1477
1478         if (r->in.account_name &&
1479            *r->in.account_name) {
1480                 return NT_STATUS_INVALID_PARAMETER;
1481         }
1482
1483         if (r->in.authority_name &&
1484            *r->in.authority_name) {
1485                 return NT_STATUS_INVALID_PARAMETER;
1486         }
1487
1488         if (p->server_info->guest) {
1489                 /*
1490                  * I'm 99% sure this is not the right place to do this,
1491                  * global_sid_Anonymous should probably be put into the token
1492                  * instead of the guest id -- vl
1493                  */
1494                 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
1495                                 &domname, &username, NULL)) {
1496                         return NT_STATUS_NO_MEMORY;
1497                 }
1498         } else {
1499                 username = p->server_info->sanitized_username;
1500                 domname = pdb_get_domain(p->server_info->sam_account);
1501         }
1502
1503         account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1504         if (!account_name) {
1505                 return NT_STATUS_NO_MEMORY;
1506         }
1507         init_lsa_String(account_name, username);
1508
1509         if (r->out.authority_name) {
1510                 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1511                 if (!authority_name) {
1512                         return NT_STATUS_NO_MEMORY;
1513                 }
1514                 init_lsa_String(authority_name, domname);
1515         }
1516
1517         *r->out.account_name = account_name;
1518         if (r->out.authority_name) {
1519                 *r->out.authority_name = authority_name;
1520         }
1521
1522         return NT_STATUS_OK;
1523 }
1524
1525 /***************************************************************************
1526  _lsa_CreateAccount
1527  ***************************************************************************/
1528
1529 NTSTATUS _lsa_CreateAccount(pipes_struct *p,
1530                             struct lsa_CreateAccount *r)
1531 {
1532         struct lsa_info *handle;
1533         struct lsa_info *info;
1534
1535         /* find the connection policy handle. */
1536         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1537                 return NT_STATUS_INVALID_HANDLE;
1538
1539         /* check if the user has enough rights */
1540
1541         /*
1542          * I don't know if it's the right one. not documented.
1543          * but guessed with rpcclient.
1544          */
1545         if (!(handle->access & LSA_POLICY_GET_PRIVATE_INFORMATION))
1546                 return NT_STATUS_ACCESS_DENIED;
1547
1548         /* check to see if the pipe_user is a Domain Admin since
1549            account_pol.tdb was already opened as root, this is all we have */
1550
1551         if ( p->server_info->utok.uid != sec_initial_uid()
1552                 && !nt_token_check_domain_rid( p->server_info->ptok,
1553                                                DOMAIN_GROUP_RID_ADMINS ) )
1554                 return NT_STATUS_ACCESS_DENIED;
1555
1556         if ( is_privileged_sid( r->in.sid ) )
1557                 return NT_STATUS_OBJECT_NAME_COLLISION;
1558
1559         /* associate the user/group SID with the (unique) handle. */
1560
1561         info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1562         if (info == NULL) {
1563                 return NT_STATUS_NO_MEMORY;
1564         }
1565
1566         info->sid = *r->in.sid;
1567         info->access = r->in.access_mask;
1568
1569         /* get a (unique) handle.  open a policy on it. */
1570         if (!create_policy_hnd(p, r->out.acct_handle, info))
1571                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1572
1573         return privilege_create_account( &info->sid );
1574 }
1575
1576
1577 /***************************************************************************
1578  _lsa_OpenAccount
1579  ***************************************************************************/
1580
1581 NTSTATUS _lsa_OpenAccount(pipes_struct *p,
1582                           struct lsa_OpenAccount *r)
1583 {
1584         struct lsa_info *handle;
1585         struct lsa_info *info;
1586
1587         /* find the connection policy handle. */
1588         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1589                 return NT_STATUS_INVALID_HANDLE;
1590
1591         /* check if the user has enough rights */
1592
1593         /*
1594          * I don't know if it's the right one. not documented.
1595          * but guessed with rpcclient.
1596          */
1597         if (!(handle->access & LSA_POLICY_GET_PRIVATE_INFORMATION))
1598                 return NT_STATUS_ACCESS_DENIED;
1599
1600         /* TODO: Fis the parsing routine before reenabling this check! */
1601         #if 0
1602         if (!lookup_sid(&handle->sid, dom_name, name, &type))
1603                 return NT_STATUS_ACCESS_DENIED;
1604         #endif
1605         /* associate the user/group SID with the (unique) handle. */
1606         info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1607         if (info == NULL) {
1608                 return NT_STATUS_NO_MEMORY;
1609         }
1610
1611         info->sid = *r->in.sid;
1612         info->access = r->in.access_mask;
1613
1614         /* get a (unique) handle.  open a policy on it. */
1615         if (!create_policy_hnd(p, r->out.acct_handle, info))
1616                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1617
1618         return NT_STATUS_OK;
1619 }
1620
1621 /***************************************************************************
1622  _lsa_EnumPrivsAccount
1623  For a given SID, enumerate all the privilege this account has.
1624  ***************************************************************************/
1625
1626 NTSTATUS _lsa_EnumPrivsAccount(pipes_struct *p,
1627                                struct lsa_EnumPrivsAccount *r)
1628 {
1629         NTSTATUS status = NT_STATUS_OK;
1630         struct lsa_info *info=NULL;
1631         SE_PRIV mask;
1632         PRIVILEGE_SET privileges;
1633         struct lsa_PrivilegeSet *priv_set = NULL;
1634         struct lsa_LUIDAttribute *luid_attrs = NULL;
1635         int i;
1636
1637         /* find the connection policy handle. */
1638         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1639                 return NT_STATUS_INVALID_HANDLE;
1640
1641         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1642                 return NT_STATUS_ACCESS_DENIED;
1643
1644         if ( !get_privileges_for_sids( &mask, &info->sid, 1 ) )
1645                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1646
1647         privilege_set_init( &privileges );
1648
1649         if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
1650
1651                 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
1652                           sid_string_dbg(&info->sid),
1653                           privileges.count));
1654
1655                 priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
1656                 if (!priv_set) {
1657                         status = NT_STATUS_NO_MEMORY;
1658                         goto done;
1659                 }
1660
1661                 luid_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx,
1662                                                struct lsa_LUIDAttribute,
1663                                                privileges.count);
1664                 if (!luid_attrs) {
1665                         status = NT_STATUS_NO_MEMORY;
1666                         goto done;
1667                 }
1668
1669                 for (i=0; i<privileges.count; i++) {
1670                         luid_attrs[i].luid.low = privileges.set[i].luid.low;
1671                         luid_attrs[i].luid.high = privileges.set[i].luid.high;
1672                         luid_attrs[i].attribute = privileges.set[i].attr;
1673                 }
1674
1675                 priv_set->count = privileges.count;
1676                 priv_set->unknown = 0;
1677                 priv_set->set = luid_attrs;
1678
1679                 *r->out.privs = priv_set;
1680         } else {
1681                 status = NT_STATUS_NO_SUCH_PRIVILEGE;
1682         }
1683
1684  done:
1685         privilege_set_free( &privileges );
1686
1687         return status;
1688 }
1689
1690 /***************************************************************************
1691  _lsa_GetSystemAccessAccount
1692  ***************************************************************************/
1693
1694 NTSTATUS _lsa_GetSystemAccessAccount(pipes_struct *p,
1695                                      struct lsa_GetSystemAccessAccount *r)
1696 {
1697         struct lsa_info *info=NULL;
1698
1699         /* find the connection policy handle. */
1700
1701         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1702                 return NT_STATUS_INVALID_HANDLE;
1703
1704         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1705                 return NT_STATUS_ACCESS_DENIED;
1706
1707         if (!lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, NULL))
1708                 return NT_STATUS_ACCESS_DENIED;
1709
1710         /*
1711           0x01 -> Log on locally
1712           0x02 -> Access this computer from network
1713           0x04 -> Log on as a batch job
1714           0x10 -> Log on as a service
1715
1716           they can be ORed together
1717         */
1718
1719         *r->out.access_mask = PR_LOG_ON_LOCALLY | PR_ACCESS_FROM_NETWORK;
1720
1721         return NT_STATUS_OK;
1722 }
1723
1724 /***************************************************************************
1725   update the systemaccount information
1726  ***************************************************************************/
1727
1728 NTSTATUS _lsa_SetSystemAccessAccount(pipes_struct *p,
1729                                      struct lsa_SetSystemAccessAccount *r)
1730 {
1731         struct lsa_info *info=NULL;
1732         GROUP_MAP map;
1733
1734         /* find the connection policy handle. */
1735         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1736                 return NT_STATUS_INVALID_HANDLE;
1737
1738         /* check to see if the pipe_user is a Domain Admin since
1739            account_pol.tdb was already opened as root, this is all we have */
1740
1741         if ( p->server_info->utok.uid != sec_initial_uid()
1742                 && !nt_token_check_domain_rid( p->server_info->ptok,
1743                                                DOMAIN_GROUP_RID_ADMINS ) )
1744                 return NT_STATUS_ACCESS_DENIED;
1745
1746         if (!pdb_getgrsid(&map, info->sid))
1747                 return NT_STATUS_NO_SUCH_GROUP;
1748
1749         return pdb_update_group_mapping_entry(&map);
1750 }
1751
1752 /***************************************************************************
1753  _lsa_AddPrivilegesToAccount
1754  For a given SID, add some privileges.
1755  ***************************************************************************/
1756
1757 NTSTATUS _lsa_AddPrivilegesToAccount(pipes_struct *p,
1758                                      struct lsa_AddPrivilegesToAccount *r)
1759 {
1760         struct lsa_info *info = NULL;
1761         SE_PRIV mask;
1762         struct lsa_PrivilegeSet *set = NULL;
1763
1764         /* find the connection policy handle. */
1765         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1766                 return NT_STATUS_INVALID_HANDLE;
1767
1768         /* check to see if the pipe_user is root or a Domain Admin since
1769            account_pol.tdb was already opened as root, this is all we have */
1770
1771         if ( p->server_info->utok.uid != sec_initial_uid()
1772                 && !nt_token_check_domain_rid( p->server_info->ptok,
1773                                                DOMAIN_GROUP_RID_ADMINS ) )
1774         {
1775                 return NT_STATUS_ACCESS_DENIED;
1776         }
1777
1778         set = r->in.privs;
1779         if ( !privilege_set_to_se_priv( &mask, set ) )
1780                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1781
1782         if ( !grant_privilege( &info->sid, &mask ) ) {
1783                 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege(%s) failed!\n",
1784                          sid_string_dbg(&info->sid) ));
1785                 DEBUG(3,("Privilege mask:\n"));
1786                 dump_se_priv( DBGC_ALL, 3, &mask );
1787                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1788         }
1789
1790         return NT_STATUS_OK;
1791 }
1792
1793 /***************************************************************************
1794  _lsa_RemovePrivilegesFromAccount
1795  For a given SID, remove some privileges.
1796  ***************************************************************************/
1797
1798 NTSTATUS _lsa_RemovePrivilegesFromAccount(pipes_struct *p,
1799                                           struct lsa_RemovePrivilegesFromAccount *r)
1800 {
1801         struct lsa_info *info = NULL;
1802         SE_PRIV mask;
1803         struct lsa_PrivilegeSet *set = NULL;
1804
1805         /* find the connection policy handle. */
1806         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1807                 return NT_STATUS_INVALID_HANDLE;
1808
1809         /* check to see if the pipe_user is root or a Domain Admin since
1810            account_pol.tdb was already opened as root, this is all we have */
1811
1812         if ( p->server_info->utok.uid != sec_initial_uid()
1813                 && !nt_token_check_domain_rid( p->server_info->ptok,
1814                                                DOMAIN_GROUP_RID_ADMINS ) )
1815         {
1816                 return NT_STATUS_ACCESS_DENIED;
1817         }
1818
1819         set = r->in.privs;
1820
1821         if ( !privilege_set_to_se_priv( &mask, set ) )
1822                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1823
1824         if ( !revoke_privilege( &info->sid, &mask ) ) {
1825                 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
1826                          sid_string_dbg(&info->sid) ));
1827                 DEBUG(3,("Privilege mask:\n"));
1828                 dump_se_priv( DBGC_ALL, 3, &mask );
1829                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1830         }
1831
1832         return NT_STATUS_OK;
1833 }
1834
1835 /***************************************************************************
1836  _lsa_QuerySecurity
1837  ***************************************************************************/
1838
1839 NTSTATUS _lsa_QuerySecurity(pipes_struct *p,
1840                             struct lsa_QuerySecurity *r)
1841 {
1842         struct lsa_info *handle=NULL;
1843         SEC_DESC *psd = NULL;
1844         size_t sd_size;
1845         NTSTATUS status;
1846
1847         /* find the connection policy handle. */
1848         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1849                 return NT_STATUS_INVALID_HANDLE;
1850
1851         /* check if the user has enough rights */
1852         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1853                 return NT_STATUS_ACCESS_DENIED;
1854
1855         switch (r->in.sec_info) {
1856         case 1:
1857                 /* SD contains only the owner */
1858
1859                 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
1860                 if(!NT_STATUS_IS_OK(status))
1861                         return NT_STATUS_NO_MEMORY;
1862
1863
1864                 if((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1865                         return NT_STATUS_NO_MEMORY;
1866                 break;
1867         case 4:
1868                 /* SD contains only the ACL */
1869
1870                 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
1871                 if(!NT_STATUS_IS_OK(status))
1872                         return NT_STATUS_NO_MEMORY;
1873
1874                 if((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1875                         return NT_STATUS_NO_MEMORY;
1876                 break;
1877         default:
1878                 return NT_STATUS_INVALID_LEVEL;
1879         }
1880
1881         return status;
1882 }
1883
1884 #if 0   /* AD DC work in ongoing in Samba 4 */
1885
1886 /***************************************************************************
1887  ***************************************************************************/
1888
1889  NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_INFO2 *r_u)
1890 {
1891         struct lsa_info *handle;
1892         const char *nb_name;
1893         char *dns_name = NULL;
1894         char *forest_name = NULL;
1895         DOM_SID *sid = NULL;
1896         struct GUID guid;
1897         fstring dnsdomname;
1898
1899         ZERO_STRUCT(guid);
1900         r_u->status = NT_STATUS_OK;
1901
1902         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1903                 return NT_STATUS_INVALID_HANDLE;
1904
1905         switch (q_u->info_class) {
1906         case 0x0c:
1907                 /* check if the user has enough rights */
1908                 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1909                         return NT_STATUS_ACCESS_DENIED;
1910
1911                 /* Request PolicyPrimaryDomainInformation. */
1912                 switch (lp_server_role()) {
1913                         case ROLE_DOMAIN_PDC:
1914                         case ROLE_DOMAIN_BDC:
1915                                 nb_name = get_global_sam_name();
1916                                 /* ugly temp hack for these next two */
1917
1918                                 /* This should be a 'netbios domain -> DNS domain' mapping */
1919                                 dnsdomname = get_mydnsdomname(p->mem_ctx);
1920                                 if (!dnsdomname || !*dnsdomname) {
1921                                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1922                                 }
1923                                 strlower_m(dnsdomname);
1924
1925                                 dns_name = dnsdomname;
1926                                 forest_name = dnsdomname;
1927
1928                                 sid = get_global_sam_sid();
1929                                 secrets_fetch_domain_guid(lp_workgroup(), &guid);
1930                                 break;
1931                         default:
1932                                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1933                 }
1934                 init_dns_dom_info(&r_u->info.dns_dom_info, nb_name, dns_name,
1935                                   forest_name,&guid,sid);
1936                 break;
1937         default:
1938                 DEBUG(0,("_lsa_query_info2: unknown info level in Lsa Query: %d\n", q_u->info_class));
1939                 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
1940                 break;
1941         }
1942
1943         if (NT_STATUS_IS_OK(r_u->status)) {
1944                 r_u->ptr = 0x1;
1945                 r_u->info_class = q_u->info_class;
1946         }
1947
1948         return r_u->status;
1949 }
1950 #endif  /* AD DC work in ongoing in Samba 4 */
1951
1952 /***************************************************************************
1953  _lsa_AddAccountRights
1954  ***************************************************************************/
1955
1956 NTSTATUS _lsa_AddAccountRights(pipes_struct *p,
1957                                struct lsa_AddAccountRights *r)
1958 {
1959         struct lsa_info *info = NULL;
1960         int i = 0;
1961         DOM_SID sid;
1962
1963         /* find the connection policy handle. */
1964         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1965                 return NT_STATUS_INVALID_HANDLE;
1966
1967         /* check to see if the pipe_user is a Domain Admin since
1968            account_pol.tdb was already opened as root, this is all we have */
1969
1970         if ( p->server_info->utok.uid != sec_initial_uid()
1971                 && !nt_token_check_domain_rid( p->server_info->ptok,
1972                                                DOMAIN_GROUP_RID_ADMINS ) )
1973         {
1974                 return NT_STATUS_ACCESS_DENIED;
1975         }
1976
1977         /* according to an NT4 PDC, you can add privileges to SIDs even without
1978            call_lsa_create_account() first.  And you can use any arbitrary SID. */
1979
1980         sid_copy( &sid, r->in.sid );
1981
1982         for ( i=0; i < r->in.rights->count; i++ ) {
1983
1984                 const char *privname = r->in.rights->names[i].string;
1985
1986                 /* only try to add non-null strings */
1987
1988                 if ( !privname )
1989                         continue;
1990
1991                 if ( !grant_privilege_by_name( &sid, privname ) ) {
1992                         DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
1993                                 privname ));
1994                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1995                 }
1996         }
1997
1998         return NT_STATUS_OK;
1999 }
2000
2001 /***************************************************************************
2002  _lsa_RemoveAccountRights
2003  ***************************************************************************/
2004
2005 NTSTATUS _lsa_RemoveAccountRights(pipes_struct *p,
2006                                   struct lsa_RemoveAccountRights *r)
2007 {
2008         struct lsa_info *info = NULL;
2009         int i = 0;
2010         DOM_SID sid;
2011         const char *privname = NULL;
2012
2013         /* find the connection policy handle. */
2014         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2015                 return NT_STATUS_INVALID_HANDLE;
2016
2017         /* check to see if the pipe_user is a Domain Admin since
2018            account_pol.tdb was already opened as root, this is all we have */
2019
2020         if ( p->server_info->utok.uid != sec_initial_uid()
2021                 && !nt_token_check_domain_rid( p->server_info->ptok,
2022                                                DOMAIN_GROUP_RID_ADMINS ) )
2023         {
2024                 return NT_STATUS_ACCESS_DENIED;
2025         }
2026
2027         sid_copy( &sid, r->in.sid );
2028
2029         if ( r->in.remove_all ) {
2030                 if ( !revoke_all_privileges( &sid ) )
2031                         return NT_STATUS_ACCESS_DENIED;
2032
2033                 return NT_STATUS_OK;
2034         }
2035
2036         for ( i=0; i < r->in.rights->count; i++ ) {
2037
2038                 privname = r->in.rights->names[i].string;
2039
2040                 /* only try to add non-null strings */
2041
2042                 if ( !privname )
2043                         continue;
2044
2045                 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2046                         DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2047                                 privname ));
2048                         return NT_STATUS_NO_SUCH_PRIVILEGE;
2049                 }
2050         }
2051
2052         return NT_STATUS_OK;
2053 }
2054
2055 /*******************************************************************
2056 ********************************************************************/
2057
2058 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
2059                                    struct lsa_RightSet *r,
2060                                    PRIVILEGE_SET *privileges)
2061 {
2062         uint32 i;
2063         const char *privname;
2064         const char **privname_array = NULL;
2065         int num_priv = 0;
2066
2067         for (i=0; i<privileges->count; i++) {
2068
2069                 privname = luid_to_privilege_name(&privileges->set[i].luid);
2070                 if (privname) {
2071                         if (!add_string_to_array(mem_ctx, privname,
2072                                                  &privname_array, &num_priv)) {
2073                                 return NT_STATUS_NO_MEMORY;
2074                         }
2075                 }
2076         }
2077
2078         if (num_priv) {
2079
2080                 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
2081                                              num_priv);
2082                 if (!r->names) {
2083                         return NT_STATUS_NO_MEMORY;
2084                 }
2085
2086                 for (i=0; i<num_priv; i++) {
2087                         init_lsa_StringLarge(&r->names[i], privname_array[i]);
2088                 }
2089
2090                 r->count = num_priv;
2091         }
2092
2093         return NT_STATUS_OK;
2094 }
2095
2096 /***************************************************************************
2097  _lsa_EnumAccountRights
2098  ***************************************************************************/
2099
2100 NTSTATUS _lsa_EnumAccountRights(pipes_struct *p,
2101                                 struct lsa_EnumAccountRights *r)
2102 {
2103         NTSTATUS status;
2104         struct lsa_info *info = NULL;
2105         DOM_SID sid;
2106         PRIVILEGE_SET privileges;
2107         SE_PRIV mask;
2108
2109         /* find the connection policy handle. */
2110
2111         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2112                 return NT_STATUS_INVALID_HANDLE;
2113
2114         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2115                 return NT_STATUS_ACCESS_DENIED;
2116
2117         /* according to an NT4 PDC, you can add privileges to SIDs even without
2118            call_lsa_create_account() first.  And you can use any arbitrary SID. */
2119
2120         sid_copy( &sid, r->in.sid );
2121
2122         if ( !get_privileges_for_sids( &mask, &sid, 1 ) )
2123                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2124
2125         privilege_set_init( &privileges );
2126
2127         if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
2128
2129                 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
2130                           sid_string_dbg(&sid), privileges.count));
2131
2132                 status = init_lsa_right_set(p->mem_ctx, r->out.rights, &privileges);
2133         } else {
2134                 status = NT_STATUS_NO_SUCH_PRIVILEGE;
2135         }
2136
2137         privilege_set_free( &privileges );
2138
2139         return status;
2140 }
2141
2142 /***************************************************************************
2143  _lsa_LookupPrivValue
2144  ***************************************************************************/
2145
2146 NTSTATUS _lsa_LookupPrivValue(pipes_struct *p,
2147                               struct lsa_LookupPrivValue *r)
2148 {
2149         struct lsa_info *info = NULL;
2150         const char *name = NULL;
2151         LUID_ATTR priv_luid;
2152         SE_PRIV mask;
2153
2154         /* find the connection policy handle. */
2155
2156         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2157                 return NT_STATUS_INVALID_HANDLE;
2158
2159         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2160                 return NT_STATUS_ACCESS_DENIED;
2161
2162         name = r->in.name->string;
2163
2164         DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
2165
2166         if ( !se_priv_from_name( name, &mask ) )
2167                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2168
2169         priv_luid = get_privilege_luid( &mask );
2170
2171         r->out.luid->low = priv_luid.luid.low;
2172         r->out.luid->high = priv_luid.luid.high;
2173
2174         return NT_STATUS_OK;
2175 }
2176
2177 /*
2178  * From here on the server routines are just dummy ones to make smbd link with
2179  * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
2180  * pulling the server stubs across one by one.
2181  */
2182
2183 NTSTATUS _lsa_Delete(pipes_struct *p, struct lsa_Delete *r)
2184 {
2185         p->rng_fault_state = True;
2186         return NT_STATUS_NOT_IMPLEMENTED;
2187 }
2188
2189 NTSTATUS _lsa_SetSecObj(pipes_struct *p, struct lsa_SetSecObj *r)
2190 {
2191         p->rng_fault_state = True;
2192         return NT_STATUS_NOT_IMPLEMENTED;
2193 }
2194
2195 NTSTATUS _lsa_ChangePassword(pipes_struct *p, struct lsa_ChangePassword *r)
2196 {
2197         p->rng_fault_state = True;
2198         return NT_STATUS_NOT_IMPLEMENTED;
2199 }
2200
2201 NTSTATUS _lsa_SetInfoPolicy(pipes_struct *p, struct lsa_SetInfoPolicy *r)
2202 {
2203         p->rng_fault_state = True;
2204         return NT_STATUS_NOT_IMPLEMENTED;
2205 }
2206
2207 NTSTATUS _lsa_ClearAuditLog(pipes_struct *p, struct lsa_ClearAuditLog *r)
2208 {
2209         p->rng_fault_state = True;
2210         return NT_STATUS_NOT_IMPLEMENTED;
2211 }
2212
2213 NTSTATUS _lsa_GetQuotasForAccount(pipes_struct *p, struct lsa_GetQuotasForAccount *r)
2214 {
2215         p->rng_fault_state = True;
2216         return NT_STATUS_NOT_IMPLEMENTED;
2217 }
2218
2219 NTSTATUS _lsa_SetQuotasForAccount(pipes_struct *p, struct lsa_SetQuotasForAccount *r)
2220 {
2221         p->rng_fault_state = True;
2222         return NT_STATUS_NOT_IMPLEMENTED;
2223 }
2224
2225 NTSTATUS _lsa_QueryTrustedDomainInfo(pipes_struct *p, struct lsa_QueryTrustedDomainInfo *r)
2226 {
2227         p->rng_fault_state = True;
2228         return NT_STATUS_NOT_IMPLEMENTED;
2229 }
2230
2231 NTSTATUS _lsa_SetInformationTrustedDomain(pipes_struct *p, struct lsa_SetInformationTrustedDomain *r)
2232 {
2233         p->rng_fault_state = True;
2234         return NT_STATUS_NOT_IMPLEMENTED;
2235 }
2236
2237 NTSTATUS _lsa_QuerySecret(pipes_struct *p, struct lsa_QuerySecret *r)
2238 {
2239         p->rng_fault_state = True;
2240         return NT_STATUS_NOT_IMPLEMENTED;
2241 }
2242
2243 NTSTATUS _lsa_LookupPrivName(pipes_struct *p, struct lsa_LookupPrivName *r)
2244 {
2245         p->rng_fault_state = True;
2246         return NT_STATUS_NOT_IMPLEMENTED;
2247 }
2248
2249 NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p, struct lsa_EnumAccountsWithUserRight *r)
2250 {
2251         p->rng_fault_state = True;
2252         return NT_STATUS_NOT_IMPLEMENTED;
2253 }
2254
2255 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(pipes_struct *p, struct lsa_QueryTrustedDomainInfoBySid *r)
2256 {
2257         p->rng_fault_state = True;
2258         return NT_STATUS_NOT_IMPLEMENTED;
2259 }
2260
2261 NTSTATUS _lsa_SetTrustedDomainInfo(pipes_struct *p, struct lsa_SetTrustedDomainInfo *r)
2262 {
2263         p->rng_fault_state = True;
2264         return NT_STATUS_NOT_IMPLEMENTED;
2265 }
2266
2267 NTSTATUS _lsa_DeleteTrustedDomain(pipes_struct *p, struct lsa_DeleteTrustedDomain *r)
2268 {
2269         p->rng_fault_state = True;
2270         return NT_STATUS_NOT_IMPLEMENTED;
2271 }
2272
2273 NTSTATUS _lsa_StorePrivateData(pipes_struct *p, struct lsa_StorePrivateData *r)
2274 {
2275         p->rng_fault_state = True;
2276         return NT_STATUS_NOT_IMPLEMENTED;
2277 }
2278
2279 NTSTATUS _lsa_RetrievePrivateData(pipes_struct *p, struct lsa_RetrievePrivateData *r)
2280 {
2281         p->rng_fault_state = True;
2282         return NT_STATUS_NOT_IMPLEMENTED;
2283 }
2284
2285 NTSTATUS _lsa_QueryInfoPolicy2(pipes_struct *p, struct lsa_QueryInfoPolicy2 *r)
2286 {
2287         p->rng_fault_state = True;
2288         return NT_STATUS_NOT_IMPLEMENTED;
2289 }
2290
2291 NTSTATUS _lsa_SetInfoPolicy2(pipes_struct *p, struct lsa_SetInfoPolicy2 *r)
2292 {
2293         p->rng_fault_state = True;
2294         return NT_STATUS_NOT_IMPLEMENTED;
2295 }
2296
2297 NTSTATUS _lsa_QueryTrustedDomainInfoByName(pipes_struct *p, struct lsa_QueryTrustedDomainInfoByName *r)
2298 {
2299         p->rng_fault_state = True;
2300         return NT_STATUS_NOT_IMPLEMENTED;
2301 }
2302
2303 NTSTATUS _lsa_SetTrustedDomainInfoByName(pipes_struct *p, struct lsa_SetTrustedDomainInfoByName *r)
2304 {
2305         p->rng_fault_state = True;
2306         return NT_STATUS_NOT_IMPLEMENTED;
2307 }
2308
2309 NTSTATUS _lsa_EnumTrustedDomainsEx(pipes_struct *p, struct lsa_EnumTrustedDomainsEx *r)
2310 {
2311         p->rng_fault_state = True;
2312         return NT_STATUS_NOT_IMPLEMENTED;
2313 }
2314
2315 NTSTATUS _lsa_CreateTrustedDomainEx(pipes_struct *p, struct lsa_CreateTrustedDomainEx *r)
2316 {
2317         p->rng_fault_state = True;
2318         return NT_STATUS_NOT_IMPLEMENTED;
2319 }
2320
2321 NTSTATUS _lsa_CloseTrustedDomainEx(pipes_struct *p, struct lsa_CloseTrustedDomainEx *r)
2322 {
2323         p->rng_fault_state = True;
2324         return NT_STATUS_NOT_IMPLEMENTED;
2325 }
2326
2327 NTSTATUS _lsa_QueryDomainInformationPolicy(pipes_struct *p, struct lsa_QueryDomainInformationPolicy *r)
2328 {
2329         p->rng_fault_state = True;
2330         return NT_STATUS_NOT_IMPLEMENTED;
2331 }
2332
2333 NTSTATUS _lsa_SetDomainInformationPolicy(pipes_struct *p, struct lsa_SetDomainInformationPolicy *r)
2334 {
2335         p->rng_fault_state = True;
2336         return NT_STATUS_NOT_IMPLEMENTED;
2337 }
2338
2339 NTSTATUS _lsa_OpenTrustedDomainByName(pipes_struct *p, struct lsa_OpenTrustedDomainByName *r)
2340 {
2341         p->rng_fault_state = True;
2342         return NT_STATUS_NOT_IMPLEMENTED;
2343 }
2344
2345 NTSTATUS _lsa_TestCall(pipes_struct *p, struct lsa_TestCall *r)
2346 {
2347         p->rng_fault_state = True;
2348         return NT_STATUS_NOT_IMPLEMENTED;
2349 }
2350
2351 NTSTATUS _lsa_CreateTrustedDomainEx2(pipes_struct *p, struct lsa_CreateTrustedDomainEx2 *r)
2352 {
2353         p->rng_fault_state = True;
2354         return NT_STATUS_NOT_IMPLEMENTED;
2355 }
2356
2357 NTSTATUS _lsa_CREDRWRITE(pipes_struct *p, struct lsa_CREDRWRITE *r)
2358 {
2359         p->rng_fault_state = True;
2360         return NT_STATUS_NOT_IMPLEMENTED;
2361 }
2362
2363 NTSTATUS _lsa_CREDRREAD(pipes_struct *p, struct lsa_CREDRREAD *r)
2364 {
2365         p->rng_fault_state = True;
2366         return NT_STATUS_NOT_IMPLEMENTED;
2367 }
2368
2369 NTSTATUS _lsa_CREDRENUMERATE(pipes_struct *p, struct lsa_CREDRENUMERATE *r)
2370 {
2371         p->rng_fault_state = True;
2372         return NT_STATUS_NOT_IMPLEMENTED;
2373 }
2374
2375 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(pipes_struct *p, struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2376 {
2377         p->rng_fault_state = True;
2378         return NT_STATUS_NOT_IMPLEMENTED;
2379 }
2380
2381 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(pipes_struct *p, struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2382 {
2383         p->rng_fault_state = True;
2384         return NT_STATUS_NOT_IMPLEMENTED;
2385 }
2386
2387 NTSTATUS _lsa_CREDRDELETE(pipes_struct *p, struct lsa_CREDRDELETE *r)
2388 {
2389         p->rng_fault_state = True;
2390         return NT_STATUS_NOT_IMPLEMENTED;
2391 }
2392
2393 NTSTATUS _lsa_CREDRGETTARGETINFO(pipes_struct *p, struct lsa_CREDRGETTARGETINFO *r)
2394 {
2395         p->rng_fault_state = True;
2396         return NT_STATUS_NOT_IMPLEMENTED;
2397 }
2398
2399 NTSTATUS _lsa_CREDRPROFILELOADED(pipes_struct *p, struct lsa_CREDRPROFILELOADED *r)
2400 {
2401         p->rng_fault_state = True;
2402         return NT_STATUS_NOT_IMPLEMENTED;
2403 }
2404
2405 NTSTATUS _lsa_CREDRGETSESSIONTYPES(pipes_struct *p, struct lsa_CREDRGETSESSIONTYPES *r)
2406 {
2407         p->rng_fault_state = True;
2408         return NT_STATUS_NOT_IMPLEMENTED;
2409 }
2410
2411 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARREGISTERAUDITEVENT *r)
2412 {
2413         p->rng_fault_state = True;
2414         return NT_STATUS_NOT_IMPLEMENTED;
2415 }
2416
2417 NTSTATUS _lsa_LSARGENAUDITEVENT(pipes_struct *p, struct lsa_LSARGENAUDITEVENT *r)
2418 {
2419         p->rng_fault_state = True;
2420         return NT_STATUS_NOT_IMPLEMENTED;
2421 }
2422
2423 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARUNREGISTERAUDITEVENT *r)
2424 {
2425         p->rng_fault_state = True;
2426         return NT_STATUS_NOT_IMPLEMENTED;
2427 }
2428
2429 NTSTATUS _lsa_lsaRQueryForestTrustInformation(pipes_struct *p, struct lsa_lsaRQueryForestTrustInformation *r)
2430 {
2431         p->rng_fault_state = True;
2432         return NT_STATUS_NOT_IMPLEMENTED;
2433 }
2434
2435 NTSTATUS _lsa_LSARSETFORESTTRUSTINFORMATION(pipes_struct *p, struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2436 {
2437         p->rng_fault_state = True;
2438         return NT_STATUS_NOT_IMPLEMENTED;
2439 }
2440
2441 NTSTATUS _lsa_CREDRRENAME(pipes_struct *p, struct lsa_CREDRRENAME *r)
2442 {
2443         p->rng_fault_state = True;
2444         return NT_STATUS_NOT_IMPLEMENTED;
2445 }
2446
2447 NTSTATUS _lsa_LSAROPENPOLICYSCE(pipes_struct *p, struct lsa_LSAROPENPOLICYSCE *r)
2448 {
2449         p->rng_fault_state = True;
2450         return NT_STATUS_NOT_IMPLEMENTED;
2451 }
2452
2453 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(pipes_struct *p, struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2454 {
2455         p->rng_fault_state = True;
2456         return NT_STATUS_NOT_IMPLEMENTED;
2457 }
2458
2459 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(pipes_struct *p, struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2460 {
2461         p->rng_fault_state = True;
2462         return NT_STATUS_NOT_IMPLEMENTED;
2463 }
2464
2465 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(pipes_struct *p, struct lsa_LSARADTREPORTSECURITYEVENT *r)
2466 {
2467         p->rng_fault_state = True;
2468         return NT_STATUS_NOT_IMPLEMENTED;
2469 }