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