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