d9d74ed7257a8a03990cffbcc553252db5e592cf
[ira/wip.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 = LSA_POLICY_MODE_INTERACTIVE |
1720                               LSA_POLICY_MODE_NETWORK;
1721
1722         return NT_STATUS_OK;
1723 }
1724
1725 /***************************************************************************
1726   update the systemaccount information
1727  ***************************************************************************/
1728
1729 NTSTATUS _lsa_SetSystemAccessAccount(pipes_struct *p,
1730                                      struct lsa_SetSystemAccessAccount *r)
1731 {
1732         struct lsa_info *info=NULL;
1733         GROUP_MAP map;
1734
1735         /* find the connection policy handle. */
1736         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1737                 return NT_STATUS_INVALID_HANDLE;
1738
1739         /* check to see if the pipe_user is a Domain Admin since
1740            account_pol.tdb was already opened as root, this is all we have */
1741
1742         if ( p->server_info->utok.uid != sec_initial_uid()
1743                 && !nt_token_check_domain_rid( p->server_info->ptok,
1744                                                DOMAIN_GROUP_RID_ADMINS ) )
1745                 return NT_STATUS_ACCESS_DENIED;
1746
1747         if (!pdb_getgrsid(&map, info->sid))
1748                 return NT_STATUS_NO_SUCH_GROUP;
1749
1750         return pdb_update_group_mapping_entry(&map);
1751 }
1752
1753 /***************************************************************************
1754  _lsa_AddPrivilegesToAccount
1755  For a given SID, add some privileges.
1756  ***************************************************************************/
1757
1758 NTSTATUS _lsa_AddPrivilegesToAccount(pipes_struct *p,
1759                                      struct lsa_AddPrivilegesToAccount *r)
1760 {
1761         struct lsa_info *info = NULL;
1762         SE_PRIV mask;
1763         struct lsa_PrivilegeSet *set = NULL;
1764
1765         /* find the connection policy handle. */
1766         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1767                 return NT_STATUS_INVALID_HANDLE;
1768
1769         /* check to see if the pipe_user is root or a Domain Admin since
1770            account_pol.tdb was already opened as root, this is all we have */
1771
1772         if ( p->server_info->utok.uid != sec_initial_uid()
1773                 && !nt_token_check_domain_rid( p->server_info->ptok,
1774                                                DOMAIN_GROUP_RID_ADMINS ) )
1775         {
1776                 return NT_STATUS_ACCESS_DENIED;
1777         }
1778
1779         set = r->in.privs;
1780         if ( !privilege_set_to_se_priv( &mask, set ) )
1781                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1782
1783         if ( !grant_privilege( &info->sid, &mask ) ) {
1784                 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege(%s) failed!\n",
1785                          sid_string_dbg(&info->sid) ));
1786                 DEBUG(3,("Privilege mask:\n"));
1787                 dump_se_priv( DBGC_ALL, 3, &mask );
1788                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1789         }
1790
1791         return NT_STATUS_OK;
1792 }
1793
1794 /***************************************************************************
1795  _lsa_RemovePrivilegesFromAccount
1796  For a given SID, remove some privileges.
1797  ***************************************************************************/
1798
1799 NTSTATUS _lsa_RemovePrivilegesFromAccount(pipes_struct *p,
1800                                           struct lsa_RemovePrivilegesFromAccount *r)
1801 {
1802         struct lsa_info *info = NULL;
1803         SE_PRIV mask;
1804         struct lsa_PrivilegeSet *set = NULL;
1805
1806         /* find the connection policy handle. */
1807         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1808                 return NT_STATUS_INVALID_HANDLE;
1809
1810         /* check to see if the pipe_user is root or a Domain Admin since
1811            account_pol.tdb was already opened as root, this is all we have */
1812
1813         if ( p->server_info->utok.uid != sec_initial_uid()
1814                 && !nt_token_check_domain_rid( p->server_info->ptok,
1815                                                DOMAIN_GROUP_RID_ADMINS ) )
1816         {
1817                 return NT_STATUS_ACCESS_DENIED;
1818         }
1819
1820         set = r->in.privs;
1821
1822         if ( !privilege_set_to_se_priv( &mask, set ) )
1823                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1824
1825         if ( !revoke_privilege( &info->sid, &mask ) ) {
1826                 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
1827                          sid_string_dbg(&info->sid) ));
1828                 DEBUG(3,("Privilege mask:\n"));
1829                 dump_se_priv( DBGC_ALL, 3, &mask );
1830                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1831         }
1832
1833         return NT_STATUS_OK;
1834 }
1835
1836 /***************************************************************************
1837  _lsa_QuerySecurity
1838  ***************************************************************************/
1839
1840 NTSTATUS _lsa_QuerySecurity(pipes_struct *p,
1841                             struct lsa_QuerySecurity *r)
1842 {
1843         struct lsa_info *handle=NULL;
1844         SEC_DESC *psd = NULL;
1845         size_t sd_size;
1846         NTSTATUS status;
1847
1848         /* find the connection policy handle. */
1849         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1850                 return NT_STATUS_INVALID_HANDLE;
1851
1852         /* check if the user has enough rights */
1853         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1854                 return NT_STATUS_ACCESS_DENIED;
1855
1856         switch (r->in.sec_info) {
1857         case 1:
1858                 /* SD contains only the owner */
1859
1860                 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
1861                 if(!NT_STATUS_IS_OK(status))
1862                         return NT_STATUS_NO_MEMORY;
1863
1864
1865                 if((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1866                         return NT_STATUS_NO_MEMORY;
1867                 break;
1868         case 4:
1869                 /* SD contains only the ACL */
1870
1871                 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
1872                 if(!NT_STATUS_IS_OK(status))
1873                         return NT_STATUS_NO_MEMORY;
1874
1875                 if((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1876                         return NT_STATUS_NO_MEMORY;
1877                 break;
1878         default:
1879                 return NT_STATUS_INVALID_LEVEL;
1880         }
1881
1882         return status;
1883 }
1884
1885 #if 0   /* AD DC work in ongoing in Samba 4 */
1886
1887 /***************************************************************************
1888  ***************************************************************************/
1889
1890  NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_INFO2 *r_u)
1891 {
1892         struct lsa_info *handle;
1893         const char *nb_name;
1894         char *dns_name = NULL;
1895         char *forest_name = NULL;
1896         DOM_SID *sid = NULL;
1897         struct GUID guid;
1898         fstring dnsdomname;
1899
1900         ZERO_STRUCT(guid);
1901         r_u->status = NT_STATUS_OK;
1902
1903         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1904                 return NT_STATUS_INVALID_HANDLE;
1905
1906         switch (q_u->info_class) {
1907         case 0x0c:
1908                 /* check if the user has enough rights */
1909                 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1910                         return NT_STATUS_ACCESS_DENIED;
1911
1912                 /* Request PolicyPrimaryDomainInformation. */
1913                 switch (lp_server_role()) {
1914                         case ROLE_DOMAIN_PDC:
1915                         case ROLE_DOMAIN_BDC:
1916                                 nb_name = get_global_sam_name();
1917                                 /* ugly temp hack for these next two */
1918
1919                                 /* This should be a 'netbios domain -> DNS domain' mapping */
1920                                 dnsdomname = get_mydnsdomname(p->mem_ctx);
1921                                 if (!dnsdomname || !*dnsdomname) {
1922                                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1923                                 }
1924                                 strlower_m(dnsdomname);
1925
1926                                 dns_name = dnsdomname;
1927                                 forest_name = dnsdomname;
1928
1929                                 sid = get_global_sam_sid();
1930                                 secrets_fetch_domain_guid(lp_workgroup(), &guid);
1931                                 break;
1932                         default:
1933                                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1934                 }
1935                 init_dns_dom_info(&r_u->info.dns_dom_info, nb_name, dns_name,
1936                                   forest_name,&guid,sid);
1937                 break;
1938         default:
1939                 DEBUG(0,("_lsa_query_info2: unknown info level in Lsa Query: %d\n", q_u->info_class));
1940                 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
1941                 break;
1942         }
1943
1944         if (NT_STATUS_IS_OK(r_u->status)) {
1945                 r_u->ptr = 0x1;
1946                 r_u->info_class = q_u->info_class;
1947         }
1948
1949         return r_u->status;
1950 }
1951 #endif  /* AD DC work in ongoing in Samba 4 */
1952
1953 /***************************************************************************
1954  _lsa_AddAccountRights
1955  ***************************************************************************/
1956
1957 NTSTATUS _lsa_AddAccountRights(pipes_struct *p,
1958                                struct lsa_AddAccountRights *r)
1959 {
1960         struct lsa_info *info = NULL;
1961         int i = 0;
1962         DOM_SID sid;
1963
1964         /* find the connection policy handle. */
1965         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1966                 return NT_STATUS_INVALID_HANDLE;
1967
1968         /* check to see if the pipe_user is a Domain Admin since
1969            account_pol.tdb was already opened as root, this is all we have */
1970
1971         if ( p->server_info->utok.uid != sec_initial_uid()
1972                 && !nt_token_check_domain_rid( p->server_info->ptok,
1973                                                DOMAIN_GROUP_RID_ADMINS ) )
1974         {
1975                 return NT_STATUS_ACCESS_DENIED;
1976         }
1977
1978         /* according to an NT4 PDC, you can add privileges to SIDs even without
1979            call_lsa_create_account() first.  And you can use any arbitrary SID. */
1980
1981         sid_copy( &sid, r->in.sid );
1982
1983         for ( i=0; i < r->in.rights->count; i++ ) {
1984
1985                 const char *privname = r->in.rights->names[i].string;
1986
1987                 /* only try to add non-null strings */
1988
1989                 if ( !privname )
1990                         continue;
1991
1992                 if ( !grant_privilege_by_name( &sid, privname ) ) {
1993                         DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
1994                                 privname ));
1995                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1996                 }
1997         }
1998
1999         return NT_STATUS_OK;
2000 }
2001
2002 /***************************************************************************
2003  _lsa_RemoveAccountRights
2004  ***************************************************************************/
2005
2006 NTSTATUS _lsa_RemoveAccountRights(pipes_struct *p,
2007                                   struct lsa_RemoveAccountRights *r)
2008 {
2009         struct lsa_info *info = NULL;
2010         int i = 0;
2011         DOM_SID sid;
2012         const char *privname = NULL;
2013
2014         /* find the connection policy handle. */
2015         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2016                 return NT_STATUS_INVALID_HANDLE;
2017
2018         /* check to see if the pipe_user is a Domain Admin since
2019            account_pol.tdb was already opened as root, this is all we have */
2020
2021         if ( p->server_info->utok.uid != sec_initial_uid()
2022                 && !nt_token_check_domain_rid( p->server_info->ptok,
2023                                                DOMAIN_GROUP_RID_ADMINS ) )
2024         {
2025                 return NT_STATUS_ACCESS_DENIED;
2026         }
2027
2028         sid_copy( &sid, r->in.sid );
2029
2030         if ( r->in.remove_all ) {
2031                 if ( !revoke_all_privileges( &sid ) )
2032                         return NT_STATUS_ACCESS_DENIED;
2033
2034                 return NT_STATUS_OK;
2035         }
2036
2037         for ( i=0; i < r->in.rights->count; i++ ) {
2038
2039                 privname = r->in.rights->names[i].string;
2040
2041                 /* only try to add non-null strings */
2042
2043                 if ( !privname )
2044                         continue;
2045
2046                 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2047                         DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2048                                 privname ));
2049                         return NT_STATUS_NO_SUCH_PRIVILEGE;
2050                 }
2051         }
2052
2053         return NT_STATUS_OK;
2054 }
2055
2056 /*******************************************************************
2057 ********************************************************************/
2058
2059 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
2060                                    struct lsa_RightSet *r,
2061                                    PRIVILEGE_SET *privileges)
2062 {
2063         uint32 i;
2064         const char *privname;
2065         const char **privname_array = NULL;
2066         int num_priv = 0;
2067
2068         for (i=0; i<privileges->count; i++) {
2069
2070                 privname = luid_to_privilege_name(&privileges->set[i].luid);
2071                 if (privname) {
2072                         if (!add_string_to_array(mem_ctx, privname,
2073                                                  &privname_array, &num_priv)) {
2074                                 return NT_STATUS_NO_MEMORY;
2075                         }
2076                 }
2077         }
2078
2079         if (num_priv) {
2080
2081                 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
2082                                              num_priv);
2083                 if (!r->names) {
2084                         return NT_STATUS_NO_MEMORY;
2085                 }
2086
2087                 for (i=0; i<num_priv; i++) {
2088                         init_lsa_StringLarge(&r->names[i], privname_array[i]);
2089                 }
2090
2091                 r->count = num_priv;
2092         }
2093
2094         return NT_STATUS_OK;
2095 }
2096
2097 /***************************************************************************
2098  _lsa_EnumAccountRights
2099  ***************************************************************************/
2100
2101 NTSTATUS _lsa_EnumAccountRights(pipes_struct *p,
2102                                 struct lsa_EnumAccountRights *r)
2103 {
2104         NTSTATUS status;
2105         struct lsa_info *info = NULL;
2106         DOM_SID sid;
2107         PRIVILEGE_SET privileges;
2108         SE_PRIV mask;
2109
2110         /* find the connection policy handle. */
2111
2112         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2113                 return NT_STATUS_INVALID_HANDLE;
2114
2115         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2116                 return NT_STATUS_ACCESS_DENIED;
2117
2118         /* according to an NT4 PDC, you can add privileges to SIDs even without
2119            call_lsa_create_account() first.  And you can use any arbitrary SID. */
2120
2121         sid_copy( &sid, r->in.sid );
2122
2123         if ( !get_privileges_for_sids( &mask, &sid, 1 ) )
2124                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2125
2126         privilege_set_init( &privileges );
2127
2128         if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
2129
2130                 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
2131                           sid_string_dbg(&sid), privileges.count));
2132
2133                 status = init_lsa_right_set(p->mem_ctx, r->out.rights, &privileges);
2134         } else {
2135                 status = NT_STATUS_NO_SUCH_PRIVILEGE;
2136         }
2137
2138         privilege_set_free( &privileges );
2139
2140         return status;
2141 }
2142
2143 /***************************************************************************
2144  _lsa_LookupPrivValue
2145  ***************************************************************************/
2146
2147 NTSTATUS _lsa_LookupPrivValue(pipes_struct *p,
2148                               struct lsa_LookupPrivValue *r)
2149 {
2150         struct lsa_info *info = NULL;
2151         const char *name = NULL;
2152         LUID_ATTR priv_luid;
2153         SE_PRIV mask;
2154
2155         /* find the connection policy handle. */
2156
2157         if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2158                 return NT_STATUS_INVALID_HANDLE;
2159
2160         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2161                 return NT_STATUS_ACCESS_DENIED;
2162
2163         name = r->in.name->string;
2164
2165         DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
2166
2167         if ( !se_priv_from_name( name, &mask ) )
2168                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2169
2170         priv_luid = get_privilege_luid( &mask );
2171
2172         r->out.luid->low = priv_luid.luid.low;
2173         r->out.luid->high = priv_luid.luid.high;
2174
2175         return NT_STATUS_OK;
2176 }
2177
2178 /*
2179  * From here on the server routines are just dummy ones to make smbd link with
2180  * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
2181  * pulling the server stubs across one by one.
2182  */
2183
2184 NTSTATUS _lsa_Delete(pipes_struct *p, struct lsa_Delete *r)
2185 {
2186         p->rng_fault_state = True;
2187         return NT_STATUS_NOT_IMPLEMENTED;
2188 }
2189
2190 NTSTATUS _lsa_SetSecObj(pipes_struct *p, struct lsa_SetSecObj *r)
2191 {
2192         p->rng_fault_state = True;
2193         return NT_STATUS_NOT_IMPLEMENTED;
2194 }
2195
2196 NTSTATUS _lsa_ChangePassword(pipes_struct *p, struct lsa_ChangePassword *r)
2197 {
2198         p->rng_fault_state = True;
2199         return NT_STATUS_NOT_IMPLEMENTED;
2200 }
2201
2202 NTSTATUS _lsa_SetInfoPolicy(pipes_struct *p, struct lsa_SetInfoPolicy *r)
2203 {
2204         p->rng_fault_state = True;
2205         return NT_STATUS_NOT_IMPLEMENTED;
2206 }
2207
2208 NTSTATUS _lsa_ClearAuditLog(pipes_struct *p, struct lsa_ClearAuditLog *r)
2209 {
2210         p->rng_fault_state = True;
2211         return NT_STATUS_NOT_IMPLEMENTED;
2212 }
2213
2214 NTSTATUS _lsa_GetQuotasForAccount(pipes_struct *p, struct lsa_GetQuotasForAccount *r)
2215 {
2216         p->rng_fault_state = True;
2217         return NT_STATUS_NOT_IMPLEMENTED;
2218 }
2219
2220 NTSTATUS _lsa_SetQuotasForAccount(pipes_struct *p, struct lsa_SetQuotasForAccount *r)
2221 {
2222         p->rng_fault_state = True;
2223         return NT_STATUS_NOT_IMPLEMENTED;
2224 }
2225
2226 NTSTATUS _lsa_QueryTrustedDomainInfo(pipes_struct *p, struct lsa_QueryTrustedDomainInfo *r)
2227 {
2228         p->rng_fault_state = True;
2229         return NT_STATUS_NOT_IMPLEMENTED;
2230 }
2231
2232 NTSTATUS _lsa_SetInformationTrustedDomain(pipes_struct *p, struct lsa_SetInformationTrustedDomain *r)
2233 {
2234         p->rng_fault_state = True;
2235         return NT_STATUS_NOT_IMPLEMENTED;
2236 }
2237
2238 NTSTATUS _lsa_QuerySecret(pipes_struct *p, struct lsa_QuerySecret *r)
2239 {
2240         p->rng_fault_state = True;
2241         return NT_STATUS_NOT_IMPLEMENTED;
2242 }
2243
2244 NTSTATUS _lsa_LookupPrivName(pipes_struct *p, struct lsa_LookupPrivName *r)
2245 {
2246         p->rng_fault_state = True;
2247         return NT_STATUS_NOT_IMPLEMENTED;
2248 }
2249
2250 NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p, struct lsa_EnumAccountsWithUserRight *r)
2251 {
2252         p->rng_fault_state = True;
2253         return NT_STATUS_NOT_IMPLEMENTED;
2254 }
2255
2256 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(pipes_struct *p, struct lsa_QueryTrustedDomainInfoBySid *r)
2257 {
2258         p->rng_fault_state = True;
2259         return NT_STATUS_NOT_IMPLEMENTED;
2260 }
2261
2262 NTSTATUS _lsa_SetTrustedDomainInfo(pipes_struct *p, struct lsa_SetTrustedDomainInfo *r)
2263 {
2264         p->rng_fault_state = True;
2265         return NT_STATUS_NOT_IMPLEMENTED;
2266 }
2267
2268 NTSTATUS _lsa_DeleteTrustedDomain(pipes_struct *p, struct lsa_DeleteTrustedDomain *r)
2269 {
2270         p->rng_fault_state = True;
2271         return NT_STATUS_NOT_IMPLEMENTED;
2272 }
2273
2274 NTSTATUS _lsa_StorePrivateData(pipes_struct *p, struct lsa_StorePrivateData *r)
2275 {
2276         p->rng_fault_state = True;
2277         return NT_STATUS_NOT_IMPLEMENTED;
2278 }
2279
2280 NTSTATUS _lsa_RetrievePrivateData(pipes_struct *p, struct lsa_RetrievePrivateData *r)
2281 {
2282         p->rng_fault_state = True;
2283         return NT_STATUS_NOT_IMPLEMENTED;
2284 }
2285
2286 NTSTATUS _lsa_QueryInfoPolicy2(pipes_struct *p, struct lsa_QueryInfoPolicy2 *r)
2287 {
2288         p->rng_fault_state = True;
2289         return NT_STATUS_NOT_IMPLEMENTED;
2290 }
2291
2292 NTSTATUS _lsa_SetInfoPolicy2(pipes_struct *p, struct lsa_SetInfoPolicy2 *r)
2293 {
2294         p->rng_fault_state = True;
2295         return NT_STATUS_NOT_IMPLEMENTED;
2296 }
2297
2298 NTSTATUS _lsa_QueryTrustedDomainInfoByName(pipes_struct *p, struct lsa_QueryTrustedDomainInfoByName *r)
2299 {
2300         p->rng_fault_state = True;
2301         return NT_STATUS_NOT_IMPLEMENTED;
2302 }
2303
2304 NTSTATUS _lsa_SetTrustedDomainInfoByName(pipes_struct *p, struct lsa_SetTrustedDomainInfoByName *r)
2305 {
2306         p->rng_fault_state = True;
2307         return NT_STATUS_NOT_IMPLEMENTED;
2308 }
2309
2310 NTSTATUS _lsa_EnumTrustedDomainsEx(pipes_struct *p, struct lsa_EnumTrustedDomainsEx *r)
2311 {
2312         p->rng_fault_state = True;
2313         return NT_STATUS_NOT_IMPLEMENTED;
2314 }
2315
2316 NTSTATUS _lsa_CreateTrustedDomainEx(pipes_struct *p, struct lsa_CreateTrustedDomainEx *r)
2317 {
2318         p->rng_fault_state = True;
2319         return NT_STATUS_NOT_IMPLEMENTED;
2320 }
2321
2322 NTSTATUS _lsa_CloseTrustedDomainEx(pipes_struct *p, struct lsa_CloseTrustedDomainEx *r)
2323 {
2324         p->rng_fault_state = True;
2325         return NT_STATUS_NOT_IMPLEMENTED;
2326 }
2327
2328 NTSTATUS _lsa_QueryDomainInformationPolicy(pipes_struct *p, struct lsa_QueryDomainInformationPolicy *r)
2329 {
2330         p->rng_fault_state = True;
2331         return NT_STATUS_NOT_IMPLEMENTED;
2332 }
2333
2334 NTSTATUS _lsa_SetDomainInformationPolicy(pipes_struct *p, struct lsa_SetDomainInformationPolicy *r)
2335 {
2336         p->rng_fault_state = True;
2337         return NT_STATUS_NOT_IMPLEMENTED;
2338 }
2339
2340 NTSTATUS _lsa_OpenTrustedDomainByName(pipes_struct *p, struct lsa_OpenTrustedDomainByName *r)
2341 {
2342         p->rng_fault_state = True;
2343         return NT_STATUS_NOT_IMPLEMENTED;
2344 }
2345
2346 NTSTATUS _lsa_TestCall(pipes_struct *p, struct lsa_TestCall *r)
2347 {
2348         p->rng_fault_state = True;
2349         return NT_STATUS_NOT_IMPLEMENTED;
2350 }
2351
2352 NTSTATUS _lsa_CreateTrustedDomainEx2(pipes_struct *p, struct lsa_CreateTrustedDomainEx2 *r)
2353 {
2354         p->rng_fault_state = True;
2355         return NT_STATUS_NOT_IMPLEMENTED;
2356 }
2357
2358 NTSTATUS _lsa_CREDRWRITE(pipes_struct *p, struct lsa_CREDRWRITE *r)
2359 {
2360         p->rng_fault_state = True;
2361         return NT_STATUS_NOT_IMPLEMENTED;
2362 }
2363
2364 NTSTATUS _lsa_CREDRREAD(pipes_struct *p, struct lsa_CREDRREAD *r)
2365 {
2366         p->rng_fault_state = True;
2367         return NT_STATUS_NOT_IMPLEMENTED;
2368 }
2369
2370 NTSTATUS _lsa_CREDRENUMERATE(pipes_struct *p, struct lsa_CREDRENUMERATE *r)
2371 {
2372         p->rng_fault_state = True;
2373         return NT_STATUS_NOT_IMPLEMENTED;
2374 }
2375
2376 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(pipes_struct *p, struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2377 {
2378         p->rng_fault_state = True;
2379         return NT_STATUS_NOT_IMPLEMENTED;
2380 }
2381
2382 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(pipes_struct *p, struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2383 {
2384         p->rng_fault_state = True;
2385         return NT_STATUS_NOT_IMPLEMENTED;
2386 }
2387
2388 NTSTATUS _lsa_CREDRDELETE(pipes_struct *p, struct lsa_CREDRDELETE *r)
2389 {
2390         p->rng_fault_state = True;
2391         return NT_STATUS_NOT_IMPLEMENTED;
2392 }
2393
2394 NTSTATUS _lsa_CREDRGETTARGETINFO(pipes_struct *p, struct lsa_CREDRGETTARGETINFO *r)
2395 {
2396         p->rng_fault_state = True;
2397         return NT_STATUS_NOT_IMPLEMENTED;
2398 }
2399
2400 NTSTATUS _lsa_CREDRPROFILELOADED(pipes_struct *p, struct lsa_CREDRPROFILELOADED *r)
2401 {
2402         p->rng_fault_state = True;
2403         return NT_STATUS_NOT_IMPLEMENTED;
2404 }
2405
2406 NTSTATUS _lsa_CREDRGETSESSIONTYPES(pipes_struct *p, struct lsa_CREDRGETSESSIONTYPES *r)
2407 {
2408         p->rng_fault_state = True;
2409         return NT_STATUS_NOT_IMPLEMENTED;
2410 }
2411
2412 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARREGISTERAUDITEVENT *r)
2413 {
2414         p->rng_fault_state = True;
2415         return NT_STATUS_NOT_IMPLEMENTED;
2416 }
2417
2418 NTSTATUS _lsa_LSARGENAUDITEVENT(pipes_struct *p, struct lsa_LSARGENAUDITEVENT *r)
2419 {
2420         p->rng_fault_state = True;
2421         return NT_STATUS_NOT_IMPLEMENTED;
2422 }
2423
2424 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARUNREGISTERAUDITEVENT *r)
2425 {
2426         p->rng_fault_state = True;
2427         return NT_STATUS_NOT_IMPLEMENTED;
2428 }
2429
2430 NTSTATUS _lsa_lsaRQueryForestTrustInformation(pipes_struct *p, struct lsa_lsaRQueryForestTrustInformation *r)
2431 {
2432         p->rng_fault_state = True;
2433         return NT_STATUS_NOT_IMPLEMENTED;
2434 }
2435
2436 NTSTATUS _lsa_LSARSETFORESTTRUSTINFORMATION(pipes_struct *p, struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2437 {
2438         p->rng_fault_state = True;
2439         return NT_STATUS_NOT_IMPLEMENTED;
2440 }
2441
2442 NTSTATUS _lsa_CREDRRENAME(pipes_struct *p, struct lsa_CREDRRENAME *r)
2443 {
2444         p->rng_fault_state = True;
2445         return NT_STATUS_NOT_IMPLEMENTED;
2446 }
2447
2448 NTSTATUS _lsa_LSAROPENPOLICYSCE(pipes_struct *p, struct lsa_LSAROPENPOLICYSCE *r)
2449 {
2450         p->rng_fault_state = True;
2451         return NT_STATUS_NOT_IMPLEMENTED;
2452 }
2453
2454 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(pipes_struct *p, struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2455 {
2456         p->rng_fault_state = True;
2457         return NT_STATUS_NOT_IMPLEMENTED;
2458 }
2459
2460 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(pipes_struct *p, struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2461 {
2462         p->rng_fault_state = True;
2463         return NT_STATUS_NOT_IMPLEMENTED;
2464 }
2465
2466 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(pipes_struct *p, struct lsa_LSARADTREPORTSECURITYEVENT *r)
2467 {
2468         p->rng_fault_state = True;
2469         return NT_STATUS_NOT_IMPLEMENTED;
2470 }