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