r13316: Let the carnage begin....
[samba.git] / source / rpc_server / srv_lsa_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Jeremy Allison                    2001,
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  *
14  *  This program is free software; you can redistribute it and/or modify
15  *  it under the terms of the GNU General Public License as published by
16  *  the Free Software Foundation; either version 2 of the License, or
17  *  (at your option) any later version.
18  *  
19  *  This program is distributed in the hope that it will be useful,
20  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  *  GNU General Public License for more details.
23  *  
24  *  You should have received a copy of the GNU General Public License
25  *  along with this program; if not, write to the Free Software
26  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27  */
28
29 /* This is the implementation of the lsa server code. */
30
31 #include "includes.h"
32
33 #undef DBGC_CLASS
34 #define DBGC_CLASS DBGC_RPC_SRV
35
36 extern PRIVS privs[];
37
38 struct lsa_info {
39         DOM_SID sid;
40         uint32 access;
41 };
42
43 struct generic_mapping lsa_generic_mapping = {
44         POLICY_READ,
45         POLICY_WRITE,
46         POLICY_EXECUTE,
47         POLICY_ALL_ACCESS
48 };
49
50 /*******************************************************************
51  Function to free the per handle data.
52  ********************************************************************/
53
54 static void free_lsa_info(void *ptr)
55 {
56         struct lsa_info *lsa = (struct lsa_info *)ptr;
57
58         SAFE_FREE(lsa);
59 }
60
61 /***************************************************************************
62 Init dom_query
63  ***************************************************************************/
64
65 static void init_dom_query(DOM_QUERY *d_q, const char *dom_name, DOM_SID *dom_sid)
66 {
67         d_q->buffer_dom_name = (dom_name != NULL) ? 1 : 0; /* domain buffer pointer */
68         d_q->buffer_dom_sid = (dom_sid != NULL) ? 1 : 0;  /* domain sid pointer */
69
70         /* this string is supposed to be non-null terminated. */
71         /* But the maxlen in this UNISTR2 must include the terminating null. */
72         init_unistr2(&d_q->uni_domain_name, dom_name, UNI_BROKEN_NON_NULL);
73
74         /*
75          * I'm not sure why this really odd combination of length
76          * values works, but it does appear to. I need to look at
77          * this *much* more closely - but at the moment leave alone
78          * until it's understood. This allows a W2k client to join
79          * a domain with both odd and even length names... JRA.
80          */
81
82         /*
83          * IMPORTANT NOTE !!!!
84          * The two fields below probably are reversed in meaning, ie.
85          * the first field is probably the str_len, the second the max
86          * len. Both are measured in bytes anyway.
87          */
88
89         d_q->uni_dom_str_len = d_q->uni_domain_name.uni_max_len * 2;
90         d_q->uni_dom_max_len = d_q->uni_domain_name.uni_str_len * 2;
91
92         if (dom_sid != NULL)
93                 init_dom_sid2(&d_q->dom_sid, dom_sid);
94 }
95
96 /***************************************************************************
97  init_dom_ref - adds a domain if it's not already in, returns the index.
98 ***************************************************************************/
99
100 static int init_dom_ref(DOM_R_REF *ref, const char *dom_name, DOM_SID *dom_sid)
101 {
102         int num = 0;
103
104         if (dom_name != NULL) {
105                 for (num = 0; num < ref->num_ref_doms_1; num++) {
106                         if (sid_equal(dom_sid, &ref->ref_dom[num].ref_dom.sid))
107                                 return num;
108                 }
109         } else {
110                 num = ref->num_ref_doms_1;
111         }
112
113         if (num >= MAX_REF_DOMAINS) {
114                 /* index not found, already at maximum domain limit */
115                 return -1;
116         }
117
118         ref->num_ref_doms_1 = num+1;
119         ref->ptr_ref_dom  = 1;
120         ref->max_entries = MAX_REF_DOMAINS;
121         ref->num_ref_doms_2 = num+1;
122
123         ref->hdr_ref_dom[num].ptr_dom_sid = dom_sid != NULL ? 1 : 0;
124
125         init_unistr2(&ref->ref_dom[num].uni_dom_name, dom_name, UNI_FLAGS_NONE);
126         init_uni_hdr(&ref->hdr_ref_dom[num].hdr_dom_name, &ref->ref_dom[num].uni_dom_name);
127
128         init_dom_sid2(&ref->ref_dom[num].ref_dom, dom_sid );
129
130         return num;
131 }
132
133 /***************************************************************************
134  init_lsa_rid2s
135  ***************************************************************************/
136
137 static int init_lsa_rid2s(TALLOC_CTX *mem_ctx,
138                           DOM_R_REF *ref, DOM_RID2 *rid2,
139                           int num_entries, UNISTR2 *name,
140                           int flags)
141 {
142         int mapped_count, i;
143
144         SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
145
146         mapped_count = 0;
147
148         become_root(); /* lookup_name can require root privs */
149
150         for (i = 0; i < num_entries; i++) {
151                 BOOL status = False;
152                 DOM_SID sid;
153                 uint32 rid;
154                 int dom_idx;
155                 char *full_name;
156                 const char *domain;
157                 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
158
159                 /* Split name into domain and user component */
160
161                 full_name = rpcstr_pull_unistr2_talloc(mem_ctx, &name[i]);
162                 if (full_name == NULL) {
163                         DEBUG(0, ("pull_ucs2_talloc failed\n"));
164                         return 0;
165                 }
166
167                 DEBUG(5, ("init_lsa_rid2s: 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                 DEBUG(5, ("init_lsa_rid2s: %s\n", status ? "found" : 
176                           "not found"));
177
178                 switch (type) {
179                 case SID_NAME_USER:
180                 case SID_NAME_DOM_GRP:
181                 case SID_NAME_DOMAIN:
182                 case SID_NAME_ALIAS:
183                 case SID_NAME_WKN_GRP:
184                         /* Leave these unchanged */
185                         break;
186                 default:
187                         /* Don't hand out anything but the list above */
188                         type = SID_NAME_UNKNOWN;
189                         break;
190                 }
191
192                 rid = 0;
193                 dom_idx = -1;
194
195                 if (type != SID_NAME_UNKNOWN) {
196                         sid_split_rid(&sid, &rid);
197                         dom_idx = init_dom_ref(ref, domain, &sid);
198                         mapped_count++;
199                 }
200
201                 init_dom_rid2(&rid2[i], rid, type, dom_idx);
202         }
203
204         unbecome_root();
205
206         return mapped_count;
207 }
208
209 /***************************************************************************
210  init_reply_lookup_names
211  ***************************************************************************/
212
213 static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
214                 DOM_R_REF *ref, uint32 num_entries,
215                 DOM_RID2 *rid2, uint32 mapped_count)
216 {
217         r_l->ptr_dom_ref  = 1;
218         r_l->dom_ref      = ref;
219
220         r_l->num_entries  = num_entries;
221         r_l->ptr_entries  = 1;
222         r_l->num_entries2 = num_entries;
223         r_l->dom_rid      = rid2;
224
225         r_l->mapped_count = mapped_count;
226 }
227
228 /***************************************************************************
229  Init_reply_lookup_sids.
230  ***************************************************************************/
231
232 static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
233                 DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *names,
234                 uint32 mapped_count)
235 {
236         r_l->ptr_dom_ref  = ref ? 1 : 0;
237         r_l->dom_ref      = ref;
238         r_l->names        = names;
239         r_l->mapped_count = mapped_count;
240 }
241
242 static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size)
243 {
244         DOM_SID local_adm_sid;
245         DOM_SID adm_sid;
246
247         SEC_ACE ace[3];
248         SEC_ACCESS mask;
249
250         SEC_ACL *psa = NULL;
251
252         init_sec_access(&mask, POLICY_EXECUTE);
253         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
254
255         sid_copy(&adm_sid, get_global_sam_sid());
256         sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS);
257         init_sec_access(&mask, POLICY_ALL_ACCESS);
258         init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
259
260         sid_copy(&local_adm_sid, &global_sid_Builtin);
261         sid_append_rid(&local_adm_sid, BUILTIN_ALIAS_RID_ADMINS);
262         init_sec_access(&mask, POLICY_ALL_ACCESS);
263         init_sec_ace(&ace[2], &local_adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
264
265         if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
266                 return NT_STATUS_NO_MEMORY;
267
268         if((*sd = make_sec_desc(mem_ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL, psa, sd_size)) == NULL)
269                 return NT_STATUS_NO_MEMORY;
270
271         return NT_STATUS_OK;
272 }
273
274 #if 0   /* AD DC work in ongoing in Samba 4 */
275
276 /***************************************************************************
277  Init_dns_dom_info.
278 ***************************************************************************/
279
280 static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name,
281                               const char *dns_name, const char *forest_name,
282                               struct uuid *dom_guid, DOM_SID *dom_sid)
283 {
284         if (nb_name && *nb_name) {
285                 init_unistr2(&r_l->uni_nb_dom_name, nb_name, UNI_FLAGS_NONE);
286                 init_uni_hdr(&r_l->hdr_nb_dom_name, &r_l->uni_nb_dom_name);
287                 r_l->hdr_nb_dom_name.uni_max_len += 2;
288                 r_l->uni_nb_dom_name.uni_max_len += 1;
289         }
290         
291         if (dns_name && *dns_name) {
292                 init_unistr2(&r_l->uni_dns_dom_name, dns_name, UNI_FLAGS_NONE);
293                 init_uni_hdr(&r_l->hdr_dns_dom_name, &r_l->uni_dns_dom_name);
294                 r_l->hdr_dns_dom_name.uni_max_len += 2;
295                 r_l->uni_dns_dom_name.uni_max_len += 1;
296         }
297
298         if (forest_name && *forest_name) {
299                 init_unistr2(&r_l->uni_forest_name, forest_name, UNI_FLAGS_NONE);
300                 init_uni_hdr(&r_l->hdr_forest_name, &r_l->uni_forest_name);
301                 r_l->hdr_forest_name.uni_max_len += 2;
302                 r_l->uni_forest_name.uni_max_len += 1;
303         }
304
305         /* how do we init the guid ? probably should write an init fn */
306         if (dom_guid) {
307                 memcpy(&r_l->dom_guid, dom_guid, sizeof(struct uuid));
308         }
309         
310         if (dom_sid) {
311                 r_l->ptr_dom_sid = 1;
312                 init_dom_sid2(&r_l->dom_sid, dom_sid);
313         }
314 }
315 #endif  /* AD DC work in ongoing in Samba 4 */
316
317
318 /***************************************************************************
319  _lsa_open_policy2.
320  ***************************************************************************/
321
322 NTSTATUS _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL2 *r_u)
323 {
324         struct lsa_info *info;
325         SEC_DESC *psd = NULL;
326         size_t sd_size;
327         uint32 des_access=q_u->des_access;
328         uint32 acc_granted;
329         NTSTATUS status;
330
331
332         /* map the generic bits to the lsa policy ones */
333         se_map_generic(&des_access, &lsa_generic_mapping);
334
335         /* get the generic lsa policy SD until we store it */
336         lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
337
338         if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
339                 if (geteuid() != 0) {
340                         return status;
341                 }
342                 DEBUG(4,("ACCESS should be DENIED (granted: %#010x;  required: %#010x)\n",
343                          acc_granted, des_access));
344                 DEBUGADD(4,("but overwritten by euid == 0\n"));
345         }
346
347         /* This is needed for lsa_open_account and rpcclient .... :-) */
348
349         if (geteuid() == 0)
350                 acc_granted = POLICY_ALL_ACCESS;
351
352         /* associate the domain SID with the (unique) handle. */
353         if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
354                 return NT_STATUS_NO_MEMORY;
355
356         ZERO_STRUCTP(info);
357         sid_copy(&info->sid,get_global_sam_sid());
358         info->access = acc_granted;
359
360         /* set up the LSA QUERY INFO response */
361         if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
362                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
363
364         return NT_STATUS_OK;
365 }
366
367 /***************************************************************************
368  _lsa_open_policy
369  ***************************************************************************/
370
371 NTSTATUS _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL *r_u)
372 {
373         struct lsa_info *info;
374         SEC_DESC *psd = NULL;
375         size_t sd_size;
376         uint32 des_access=q_u->des_access;
377         uint32 acc_granted;
378         NTSTATUS status;
379
380
381         /* map the generic bits to the lsa policy ones */
382         se_map_generic(&des_access, &lsa_generic_mapping);
383
384         /* get the generic lsa policy SD until we store it */
385         lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
386
387         if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
388                 if (geteuid() != 0) {
389                         return status;
390                 }
391                 DEBUG(4,("ACCESS should be DENIED (granted: %#010x;  required: %#010x)\n",
392                          acc_granted, des_access));
393                 DEBUGADD(4,("but overwritten by euid == 0\n"));
394                 acc_granted = des_access;
395         }
396
397         /* associate the domain SID with the (unique) handle. */
398         if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
399                 return NT_STATUS_NO_MEMORY;
400
401         ZERO_STRUCTP(info);
402         sid_copy(&info->sid,get_global_sam_sid());
403         info->access = acc_granted;
404
405         /* set up the LSA QUERY INFO response */
406         if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
407                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
408
409         return NT_STATUS_OK;
410 }
411
412 /***************************************************************************
413  _lsa_enum_trust_dom - this needs fixing to do more than return NULL ! JRA.
414  ufff, done :)  mimir
415  ***************************************************************************/
416
417 NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u,
418                              LSA_R_ENUM_TRUST_DOM *r_u)
419 {
420         struct lsa_info *info;
421         uint32 next_idx;
422         struct trustdom_info **domains;
423
424         /*
425          * preferred length is set to 5 as a "our" preferred length
426          * nt sets this parameter to 2
427          * update (20.08.2002): it's not preferred length, but preferred size!
428          * it needs further investigation how to optimally choose this value
429          */
430         uint32 max_num_domains =
431                 q_u->preferred_len < 5 ? q_u->preferred_len : 10;
432         uint32 num_domains;
433         NTSTATUS nt_status;
434         uint32 num_thistime;
435
436         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
437                 return NT_STATUS_INVALID_HANDLE;
438
439         /* check if the user have enough rights */
440         if (!(info->access & POLICY_VIEW_LOCAL_INFORMATION))
441                 return NT_STATUS_ACCESS_DENIED;
442
443         nt_status = secrets_trusted_domains(p->mem_ctx, &num_domains,
444                                             &domains);
445
446         if (!NT_STATUS_IS_OK(nt_status)) {
447                 return nt_status;
448         }
449
450         if (q_u->enum_context < num_domains) {
451                 num_thistime = MIN(num_domains, max_num_domains);
452
453                 r_u->status = STATUS_MORE_ENTRIES;
454
455                 if (q_u->enum_context + num_thistime > num_domains) {
456                         num_thistime = num_domains - q_u->enum_context;
457                         r_u->status = NT_STATUS_OK;
458                 }
459
460                 next_idx = q_u->enum_context + num_thistime;
461         } else {
462                 num_thistime = 0;
463                 next_idx = 0xffffffff;
464                 r_u->status = NT_STATUS_NO_MORE_ENTRIES;
465         }
466                 
467         /* set up the lsa_enum_trust_dom response */
468
469         init_r_enum_trust_dom(p->mem_ctx, r_u, next_idx,
470                               num_thistime, domains+q_u->enum_context);
471
472         return r_u->status;
473 }
474
475 /***************************************************************************
476  _lsa_query_info. See the POLICY_INFOMATION_CLASS docs at msdn.
477  ***************************************************************************/
478
479 NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO *r_u)
480 {
481         struct lsa_info *handle;
482         LSA_INFO_UNION *info = &r_u->dom;
483         DOM_SID domain_sid;
484         const char *name;
485         DOM_SID *sid = NULL;
486
487         r_u->status = NT_STATUS_OK;
488
489         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
490                 return NT_STATUS_INVALID_HANDLE;
491
492         switch (q_u->info_class) {
493         case 0x02:
494                 {
495                 unsigned int i;
496                 /* check if the user have enough rights */
497                 if (!(handle->access & POLICY_VIEW_AUDIT_INFORMATION))
498                         return NT_STATUS_ACCESS_DENIED;
499
500                 /* fake info: We audit everything. ;) */
501                 info->id2.auditing_enabled = 1;
502                 info->id2.count1 = 7;
503                 info->id2.count2 = 7;
504                 if ((info->id2.auditsettings = TALLOC_ARRAY(p->mem_ctx,uint32, 7)) == NULL)
505                         return NT_STATUS_NO_MEMORY;
506                 for (i = 0; i < 7; i++)
507                         info->id2.auditsettings[i] = 3;
508                 break;
509                 }
510         case 0x03:
511                 /* check if the user have enough rights */
512                 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
513                         return NT_STATUS_ACCESS_DENIED;
514
515                 /* Request PolicyPrimaryDomainInformation. */
516                 switch (lp_server_role()) {
517                         case ROLE_DOMAIN_PDC:
518                         case ROLE_DOMAIN_BDC:
519                                 name = get_global_sam_name();
520                                 sid = get_global_sam_sid();
521                                 break;
522                         case ROLE_DOMAIN_MEMBER:
523                                 name = lp_workgroup();
524                                 /* We need to return the Domain SID here. */
525                                 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid))
526                                         sid = &domain_sid;
527                                 else
528                                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
529                                 break;
530                         case ROLE_STANDALONE:
531                                 name = lp_workgroup();
532                                 sid = NULL;
533                                 break;
534                         default:
535                                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
536                 }
537                 init_dom_query(&r_u->dom.id3, name, sid);
538                 break;
539         case 0x05:
540                 /* check if the user have enough rights */
541                 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
542                         return NT_STATUS_ACCESS_DENIED;
543
544                 /* Request PolicyAccountDomainInformation. */
545                 name = get_global_sam_name();
546                 sid = get_global_sam_sid();
547                 init_dom_query(&r_u->dom.id5, name, sid);
548                 break;
549         case 0x06:
550                 /* check if the user have enough rights */
551                 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
552                         return NT_STATUS_ACCESS_DENIED;
553
554                 switch (lp_server_role()) {
555                         case ROLE_DOMAIN_BDC:
556                                 /*
557                                  * only a BDC is a backup controller
558                                  * of the domain, it controls.
559                                  */
560                                 info->id6.server_role = 2;
561                                 break;
562                         default:
563                                 /*
564                                  * any other role is a primary
565                                  * of the domain, it controls.
566                                  */
567                                 info->id6.server_role = 3;
568                                 break; 
569                 }
570                 break;
571         default:
572                 DEBUG(0,("_lsa_query_info: unknown info level in Lsa Query: %d\n", q_u->info_class));
573                 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
574                 break;
575         }
576
577         if (NT_STATUS_IS_OK(r_u->status)) {
578                 r_u->undoc_buffer = 0x22000000; /* bizarre */
579                 r_u->info_class = q_u->info_class;
580         }
581
582         return r_u->status;
583 }
584
585 /***************************************************************************
586  _lsa_lookup_sids
587  ***************************************************************************/
588
589 NTSTATUS _lsa_lookup_sids(pipes_struct *p,
590                           LSA_Q_LOOKUP_SIDS *q_u,
591                           LSA_R_LOOKUP_SIDS *r_u)
592 {
593         struct lsa_info *handle;
594
595         int i, num_sids;
596         const DOM_SID **sids;
597         uint32 mapped_count = 0;
598
599         struct lsa_dom_info *dom_infos;
600         struct lsa_name_info *name_infos;
601
602         DOM_R_REF *ref = NULL;
603         LSA_TRANS_NAME_ENUM *names = NULL;
604
605         names = TALLOC_ZERO_P(p->mem_ctx, LSA_TRANS_NAME_ENUM);
606
607         if ((q_u->level < 1) || (q_u->level > 6)) {
608                 r_u->status = NT_STATUS_INVALID_PARAMETER;
609                 goto done;
610         }
611
612         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
613                 r_u->status = NT_STATUS_INVALID_HANDLE;
614                 goto done;
615         }
616
617         /* check if the user have enough rights */
618         if (!(handle->access & POLICY_LOOKUP_NAMES)) {
619                 r_u->status = NT_STATUS_ACCESS_DENIED;
620                 goto done;
621         }
622
623         num_sids = q_u->sids.num_entries;
624         if (num_sids >  MAX_LOOKUP_SIDS) {
625                 DEBUG(5,("_lsa_lookup_sids: limit of %d exceeded, truncating "
626                          "SID lookup list to %d\n",
627                          MAX_LOOKUP_SIDS, num_sids));
628                 r_u->status = NT_STATUS_NONE_MAPPED;
629                 goto done;
630         }
631
632         ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
633
634         sids = TALLOC_ARRAY(p->mem_ctx, const DOM_SID *, num_sids);
635         if ((ref == NULL) || (names == NULL) || (sids == NULL)) {
636                 r_u->status = NT_STATUS_NO_MEMORY;
637                 goto done;
638         }
639
640         for (i=0; i<num_sids; i++) {
641                 sids[i] = &q_u->sids.sid[i].sid;
642         }
643
644         r_u->status = lookup_sids(p->mem_ctx, num_sids, sids, q_u->level,
645                                   &dom_infos, &name_infos);
646
647         if (!NT_STATUS_IS_OK(r_u->status)) {
648                 goto done;
649         }
650
651         if (num_sids > 0) {
652                 names->name = TALLOC_ARRAY(names, LSA_TRANS_NAME, num_sids);
653                 names->uni_name = TALLOC_ARRAY(names, UNISTR2, num_sids);
654                 if ((names->name == NULL) || (names->uni_name == NULL)) {
655                         r_u->status = NT_STATUS_NO_MEMORY;
656                         goto done;
657                 }
658         }
659
660         for (i=0; i<MAX_REF_DOMAINS; i++) {
661
662                 if (!dom_infos[i].valid) {
663                         break;
664                 }
665
666                 if (init_dom_ref(ref, dom_infos[i].name,
667                                  &dom_infos[i].sid) != i) {
668                         DEBUG(0, ("Domain %s mentioned twice??\n",
669                                   dom_infos[i].name));
670                         r_u->status = NT_STATUS_INTERNAL_ERROR;
671                         goto done;
672                 }
673         }
674
675         for (i=0; i<num_sids; i++) {
676                 struct lsa_name_info *name = &name_infos[i];
677
678                 if (name->type == SID_NAME_UNKNOWN) {
679                         name->dom_idx = -1;
680                         name->name = talloc_asprintf(p->mem_ctx, "%8.8x",
681                                                      name->rid);
682                         if (name->name == NULL) {
683                                 r_u->status = NT_STATUS_NO_MEMORY;
684                                 goto done;
685                         }
686                 } else {
687                         mapped_count += 1;
688                 }
689                 init_lsa_trans_name(&names->name[i], &names->uni_name[i],
690                                     name->type, name->name, name->dom_idx);
691         }
692
693         names->num_entries = num_sids;
694         names->ptr_trans_names = 1;
695         names->num_entries2 = num_sids;
696
697         r_u->status = NT_STATUS_NONE_MAPPED;
698         if (mapped_count > 0) {
699                 r_u->status = (mapped_count < num_sids) ?
700                         STATUS_SOME_UNMAPPED : NT_STATUS_OK;
701         }
702
703         DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
704                    num_sids, mapped_count, nt_errstr(r_u->status)));
705
706  done:
707         init_reply_lookup_sids(r_u, ref, names, mapped_count);
708
709         return r_u->status;
710 }
711
712 /***************************************************************************
713 lsa_reply_lookup_names
714  ***************************************************************************/
715
716 NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_NAMES *r_u)
717 {
718         struct lsa_info *handle;
719         UNISTR2 *names = q_u->uni_name;
720         int num_entries = q_u->num_entries;
721         DOM_R_REF *ref;
722         DOM_RID2 *rids;
723         uint32 mapped_count = 0;
724         int flags = 0;
725
726         if (num_entries >  MAX_LOOKUP_SIDS) {
727                 num_entries = MAX_LOOKUP_SIDS;
728                 DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries));
729         }
730                 
731         /* Probably the lookup_level is some sort of bitmask. */
732         if (q_u->lookup_level == 1) {
733                 flags = LOOKUP_NAME_ALL;
734         }
735
736         ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
737         rids = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID2, num_entries);
738
739         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
740                 r_u->status = NT_STATUS_INVALID_HANDLE;
741                 goto done;
742         }
743
744         /* check if the user have enough rights */
745         if (!(handle->access & POLICY_LOOKUP_NAMES)) {
746                 r_u->status = NT_STATUS_ACCESS_DENIED;
747                 goto done;
748         }
749
750         if (!ref || !rids)
751                 return NT_STATUS_NO_MEMORY;
752
753         /* set up the LSA Lookup RIDs response */
754         mapped_count = init_lsa_rid2s(p->mem_ctx, ref, rids, num_entries,
755                                       names, flags);
756 done:
757
758         if (NT_STATUS_IS_OK(r_u->status)) {
759                 if (mapped_count == 0)
760                         r_u->status = NT_STATUS_NONE_MAPPED;
761                 else if (mapped_count != num_entries)
762                         r_u->status = STATUS_SOME_UNMAPPED;
763         }
764         init_reply_lookup_names(r_u, ref, num_entries, rids, mapped_count);
765
766         return r_u->status;
767 }
768
769 /***************************************************************************
770  _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
771  ***************************************************************************/
772
773 NTSTATUS _lsa_close(pipes_struct *p, LSA_Q_CLOSE *q_u, LSA_R_CLOSE *r_u)
774 {
775         if (!find_policy_by_hnd(p, &q_u->pol, NULL))
776                 return NT_STATUS_INVALID_HANDLE;
777
778         close_policy_hnd(p, &q_u->pol);
779         return NT_STATUS_OK;
780 }
781
782 /***************************************************************************
783  ***************************************************************************/
784
785 NTSTATUS _lsa_open_secret(pipes_struct *p, LSA_Q_OPEN_SECRET *q_u, LSA_R_OPEN_SECRET *r_u)
786 {
787         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
788 }
789
790 /***************************************************************************
791  ***************************************************************************/
792
793 NTSTATUS _lsa_open_trusted_domain(pipes_struct *p, LSA_Q_OPEN_TRUSTED_DOMAIN *q_u, LSA_R_OPEN_TRUSTED_DOMAIN *r_u)
794 {
795         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
796 }
797
798 /***************************************************************************
799  ***************************************************************************/
800
801 NTSTATUS _lsa_create_trusted_domain(pipes_struct *p, LSA_Q_CREATE_TRUSTED_DOMAIN *q_u, LSA_R_CREATE_TRUSTED_DOMAIN *r_u)
802 {
803         return NT_STATUS_ACCESS_DENIED;
804 }
805
806 /***************************************************************************
807  ***************************************************************************/
808
809 NTSTATUS _lsa_create_secret(pipes_struct *p, LSA_Q_CREATE_SECRET *q_u, LSA_R_CREATE_SECRET *r_u)
810 {
811         return NT_STATUS_ACCESS_DENIED;
812 }
813
814 /***************************************************************************
815  ***************************************************************************/
816
817 NTSTATUS _lsa_set_secret(pipes_struct *p, LSA_Q_SET_SECRET *q_u, LSA_R_SET_SECRET *r_u)
818 {
819         return NT_STATUS_ACCESS_DENIED;
820 }
821
822 /***************************************************************************
823  ***************************************************************************/
824
825 NTSTATUS _lsa_delete_object(pipes_struct *p, LSA_Q_DELETE_OBJECT *q_u, LSA_R_DELETE_OBJECT *r_u)
826 {
827         return NT_STATUS_ACCESS_DENIED;
828 }
829
830 /***************************************************************************
831 _lsa_enum_privs.
832  ***************************************************************************/
833
834 NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIVS *r_u)
835 {
836         struct lsa_info *handle;
837         uint32 i;
838         uint32 enum_context = q_u->enum_context;
839         int num_privs = count_all_privileges();
840         LSA_PRIV_ENTRY *entries = NULL;
841         LUID_ATTR luid;
842
843         /* remember that the enum_context starts at 0 and not 1 */
844
845         if ( enum_context >= num_privs )
846                 return NT_STATUS_NO_MORE_ENTRIES;
847                 
848         DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n", 
849                 enum_context, num_privs));
850         
851         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
852                 return NT_STATUS_INVALID_HANDLE;
853
854         /* check if the user have enough rights
855            I don't know if it's the right one. not documented.  */
856
857         if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
858                 return NT_STATUS_ACCESS_DENIED;
859
860         if ( !(entries = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_PRIV_ENTRY, num_privs )) )
861                 return NT_STATUS_NO_MEMORY;
862
863         for (i = 0; i < num_privs; i++) {
864                 if( i < enum_context) {
865                         init_unistr2(&entries[i].name, NULL, UNI_FLAGS_NONE);
866                         init_uni_hdr(&entries[i].hdr_name, &entries[i].name);
867                         
868                         entries[i].luid_low = 0;
869                         entries[i].luid_high = 0;
870                 } else {
871                         init_unistr2(&entries[i].name, privs[i].name, UNI_FLAGS_NONE);
872                         init_uni_hdr(&entries[i].hdr_name, &entries[i].name);
873                         
874                         luid = get_privilege_luid( &privs[i].se_priv );
875                         
876                         entries[i].luid_low = luid.luid.low;
877                         entries[i].luid_high = luid.luid.high;
878                 }
879         }
880
881         enum_context = num_privs;
882         
883         init_lsa_r_enum_privs(r_u, enum_context, num_privs, entries);
884
885         return NT_STATUS_OK;
886 }
887
888 /***************************************************************************
889 _lsa_priv_get_dispname.
890  ***************************************************************************/
891
892 NTSTATUS _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, LSA_R_PRIV_GET_DISPNAME *r_u)
893 {
894         struct lsa_info *handle;
895         fstring name_asc;
896         const char *description;
897
898         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
899                 return NT_STATUS_INVALID_HANDLE;
900
901         /* check if the user have enough rights */
902
903         /*
904          * I don't know if it's the right one. not documented.
905          */
906         if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
907                 return NT_STATUS_ACCESS_DENIED;
908
909         unistr2_to_ascii(name_asc, &q_u->name, sizeof(name_asc));
910
911         DEBUG(10,("_lsa_priv_get_dispname: name = %s\n", name_asc));
912
913         description = get_privilege_dispname( name_asc );
914         
915         if ( description ) {
916                 DEBUG(10,("_lsa_priv_get_dispname: display name = %s\n", description));
917                 
918                 init_unistr2(&r_u->desc, description, UNI_FLAGS_NONE);
919                 init_uni_hdr(&r_u->hdr_desc, &r_u->desc);
920
921                 r_u->ptr_info = 0xdeadbeef;
922                 r_u->lang_id = q_u->lang_id;
923                 
924                 return NT_STATUS_OK;
925         } else {
926                 DEBUG(10,("_lsa_priv_get_dispname: doesn't exist\n"));
927                 
928                 r_u->ptr_info = 0;
929                 
930                 return NT_STATUS_NO_SUCH_PRIVILEGE;
931         }
932 }
933
934 /***************************************************************************
935 _lsa_enum_accounts.
936  ***************************************************************************/
937
938 NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENUM_ACCOUNTS *r_u)
939 {
940         struct lsa_info *handle;
941         DOM_SID *sid_list;
942         int i, j, num_entries;
943         LSA_SID_ENUM *sids=&r_u->sids;
944         NTSTATUS ret;
945
946         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
947                 return NT_STATUS_INVALID_HANDLE;
948
949         if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
950                 return NT_STATUS_ACCESS_DENIED;
951
952         sid_list = NULL;
953         num_entries = 0;
954
955         /* The only way we can currently find out all the SIDs that have been
956            privileged is to scan all privileges */
957
958         if (!NT_STATUS_IS_OK(ret = privilege_enumerate_accounts(&sid_list, &num_entries))) {
959                 return ret;
960         }
961
962         if (q_u->enum_context >= num_entries)
963                 return NT_STATUS_NO_MORE_ENTRIES;
964
965         sids->ptr_sid = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_entries-q_u->enum_context);
966         sids->sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_entries-q_u->enum_context);
967
968         if (sids->ptr_sid==NULL || sids->sid==NULL) {
969                 SAFE_FREE(sid_list);
970                 return NT_STATUS_NO_MEMORY;
971         }
972
973         for (i = q_u->enum_context, j = 0; i < num_entries; i++, j++) {
974                 init_dom_sid2(&(*sids).sid[j], &sid_list[i]);
975                 (*sids).ptr_sid[j] = 1;
976         }
977
978         SAFE_FREE(sid_list);
979
980         init_lsa_r_enum_accounts(r_u, num_entries);
981
982         return NT_STATUS_OK;
983 }
984
985
986 NTSTATUS _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u)
987 {
988         fstring username, domname;
989         user_struct *vuser = get_valid_user_struct(p->vuid);
990   
991         if (vuser == NULL)
992                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
993   
994         fstrcpy(username, vuser->user.smb_name);
995         fstrcpy(domname, vuser->user.domain);
996   
997         r_u->ptr_user_name = 1;
998         init_unistr2(&r_u->uni2_user_name, username, UNI_STR_TERMINATE);
999         init_uni_hdr(&r_u->hdr_user_name, &r_u->uni2_user_name);
1000
1001         r_u->unk1 = 1;
1002   
1003         r_u->ptr_dom_name = 1;
1004         init_unistr2(&r_u->uni2_dom_name, domname,  UNI_STR_TERMINATE);
1005         init_uni_hdr(&r_u->hdr_dom_name, &r_u->uni2_dom_name);
1006
1007         r_u->status = NT_STATUS_OK;
1008   
1009         return r_u->status;
1010 }
1011
1012 /***************************************************************************
1013  Lsa Create Account 
1014  ***************************************************************************/
1015
1016 NTSTATUS _lsa_create_account(pipes_struct *p, LSA_Q_CREATEACCOUNT *q_u, LSA_R_CREATEACCOUNT *r_u)
1017 {
1018         struct lsa_info *handle;
1019         struct lsa_info *info;
1020
1021         /* find the connection policy handle. */
1022         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1023                 return NT_STATUS_INVALID_HANDLE;
1024
1025         /* check if the user have enough rights */
1026
1027         /*
1028          * I don't know if it's the right one. not documented.
1029          * but guessed with rpcclient.
1030          */
1031         if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION))
1032                 return NT_STATUS_ACCESS_DENIED;
1033
1034         /* check to see if the pipe_user is a Domain Admin since 
1035            account_pol.tdb was already opened as root, this is all we have */
1036            
1037         if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1038                 return NT_STATUS_ACCESS_DENIED;
1039                 
1040         if ( is_privileged_sid( &q_u->sid.sid ) )
1041                 return NT_STATUS_OBJECT_NAME_COLLISION;
1042
1043         /* associate the user/group SID with the (unique) handle. */
1044         
1045         if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
1046                 return NT_STATUS_NO_MEMORY;
1047
1048         ZERO_STRUCTP(info);
1049         info->sid = q_u->sid.sid;
1050         info->access = q_u->access;
1051
1052         /* get a (unique) handle.  open a policy on it. */
1053         if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
1054                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1055
1056         return privilege_create_account( &info->sid );
1057 }
1058
1059
1060 /***************************************************************************
1061  Lsa Open Account
1062  ***************************************************************************/
1063
1064 NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENACCOUNT *r_u)
1065 {
1066         struct lsa_info *handle;
1067         struct lsa_info *info;
1068
1069         /* find the connection policy handle. */
1070         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1071                 return NT_STATUS_INVALID_HANDLE;
1072
1073         /* check if the user have enough rights */
1074
1075         /*
1076          * I don't know if it's the right one. not documented.
1077          * but guessed with rpcclient.
1078          */
1079         if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION))
1080                 return NT_STATUS_ACCESS_DENIED;
1081
1082         /* TODO: Fis the parsing routine before reenabling this check! */
1083         #if 0
1084         if (!lookup_sid(&handle->sid, dom_name, name, &type))
1085                 return NT_STATUS_ACCESS_DENIED;
1086         #endif
1087         /* associate the user/group SID with the (unique) handle. */
1088         if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
1089                 return NT_STATUS_NO_MEMORY;
1090
1091         ZERO_STRUCTP(info);
1092         info->sid = q_u->sid.sid;
1093         info->access = q_u->access;
1094
1095         /* get a (unique) handle.  open a policy on it. */
1096         if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
1097                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1098
1099         return NT_STATUS_OK;
1100 }
1101
1102 /***************************************************************************
1103  For a given SID, enumerate all the privilege this account has.
1104  ***************************************************************************/
1105
1106 NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVSACCOUNT *q_u, LSA_R_ENUMPRIVSACCOUNT *r_u)
1107 {
1108         struct lsa_info *info=NULL;
1109         SE_PRIV mask;
1110         PRIVILEGE_SET privileges;
1111
1112         /* find the connection policy handle. */
1113         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1114                 return NT_STATUS_INVALID_HANDLE;
1115
1116         if ( !get_privileges_for_sids( &mask, &info->sid, 1 ) ) 
1117                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1118
1119         privilege_set_init( &privileges );
1120
1121         if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
1122
1123                 DEBUG(10,("_lsa_enum_privsaccount: %s has %d privileges\n", 
1124                         sid_string_static(&info->sid), privileges.count));
1125
1126                 r_u->status = init_lsa_r_enum_privsaccount(ps->mem_ctx, r_u, privileges.set, privileges.count, 0);
1127         }
1128         else
1129                 r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE;
1130
1131         privilege_set_free( &privileges );
1132
1133         return r_u->status;
1134 }
1135
1136 /***************************************************************************
1137  
1138  ***************************************************************************/
1139
1140 NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA_R_GETSYSTEMACCOUNT *r_u)
1141 {
1142         struct lsa_info *info=NULL;
1143
1144         /* find the connection policy handle. */
1145
1146         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1147                 return NT_STATUS_INVALID_HANDLE;
1148
1149         if (!lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, NULL))
1150                 return NT_STATUS_ACCESS_DENIED;
1151
1152         /*
1153           0x01 -> Log on locally
1154           0x02 -> Access this computer from network
1155           0x04 -> Log on as a batch job
1156           0x10 -> Log on as a service
1157           
1158           they can be ORed together
1159         */
1160
1161         r_u->access = PR_LOG_ON_LOCALLY | PR_ACCESS_FROM_NETWORK;
1162
1163         return NT_STATUS_OK;
1164 }
1165
1166 /***************************************************************************
1167   update the systemaccount information
1168  ***************************************************************************/
1169
1170 NTSTATUS _lsa_setsystemaccount(pipes_struct *p, LSA_Q_SETSYSTEMACCOUNT *q_u, LSA_R_SETSYSTEMACCOUNT *r_u)
1171 {
1172         struct lsa_info *info=NULL;
1173         GROUP_MAP map;
1174         r_u->status = NT_STATUS_OK;
1175
1176         /* find the connection policy handle. */
1177         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1178                 return NT_STATUS_INVALID_HANDLE;
1179
1180         /* check to see if the pipe_user is a Domain Admin since 
1181            account_pol.tdb was already opened as root, this is all we have */
1182            
1183         if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1184                 return NT_STATUS_ACCESS_DENIED;
1185
1186         if (!pdb_getgrsid(&map, info->sid))
1187                 return NT_STATUS_NO_SUCH_GROUP;
1188
1189         return pdb_update_group_mapping_entry(&map);
1190 }
1191
1192 /***************************************************************************
1193  For a given SID, add some privileges.
1194  ***************************************************************************/
1195
1196 NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u)
1197 {
1198         struct lsa_info *info = NULL;
1199         SE_PRIV mask;
1200         PRIVILEGE_SET *set = NULL;
1201         struct current_user user;
1202
1203         /* find the connection policy handle. */
1204         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1205                 return NT_STATUS_INVALID_HANDLE;
1206                 
1207         /* check to see if the pipe_user is root or a Domain Admin since 
1208            account_pol.tdb was already opened as root, this is all we have */
1209            
1210         get_current_user( &user, p );
1211         if ( user.ut.uid != sec_initial_uid() 
1212                 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1213         {
1214                 return NT_STATUS_ACCESS_DENIED;
1215         }
1216
1217         set = &q_u->set;
1218
1219         if ( !privilege_set_to_se_priv( &mask, set ) )
1220                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1221
1222         if ( !grant_privilege( &info->sid, &mask ) ) {
1223                 DEBUG(3,("_lsa_addprivs: grant_privilege(%s) failed!\n",
1224                         sid_string_static(&info->sid) ));
1225                 DEBUG(3,("Privilege mask:\n"));
1226                 dump_se_priv( DBGC_ALL, 3, &mask );
1227                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1228         }
1229
1230         return NT_STATUS_OK;
1231 }
1232
1233 /***************************************************************************
1234  For a given SID, remove some privileges.
1235  ***************************************************************************/
1236
1237 NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEPRIVS *r_u)
1238 {
1239         struct lsa_info *info = NULL;
1240         SE_PRIV mask;
1241         PRIVILEGE_SET *set = NULL;
1242         struct current_user user;
1243
1244         /* find the connection policy handle. */
1245         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1246                 return NT_STATUS_INVALID_HANDLE;
1247
1248         /* check to see if the pipe_user is root or a Domain Admin since 
1249            account_pol.tdb was already opened as root, this is all we have */
1250            
1251         get_current_user( &user, p );
1252         if ( user.ut.uid != sec_initial_uid()
1253                 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) 
1254         {
1255                 return NT_STATUS_ACCESS_DENIED;
1256         }
1257
1258         set = &q_u->set;
1259
1260         if ( !privilege_set_to_se_priv( &mask, set ) )
1261                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1262
1263         if ( !revoke_privilege( &info->sid, &mask ) ) {
1264                 DEBUG(3,("_lsa_removeprivs: revoke_privilege(%s) failed!\n",
1265                         sid_string_static(&info->sid) ));
1266                 DEBUG(3,("Privilege mask:\n"));
1267                 dump_se_priv( DBGC_ALL, 3, &mask );
1268                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1269         }
1270
1271         return NT_STATUS_OK;
1272 }
1273
1274 /***************************************************************************
1275  For a given SID, remove some privileges.
1276  ***************************************************************************/
1277
1278 NTSTATUS _lsa_query_secobj(pipes_struct *p, LSA_Q_QUERY_SEC_OBJ *q_u, LSA_R_QUERY_SEC_OBJ *r_u)
1279 {
1280         struct lsa_info *handle=NULL;
1281         SEC_DESC *psd = NULL;
1282         size_t sd_size;
1283         NTSTATUS status;
1284
1285         r_u->status = NT_STATUS_OK;
1286
1287         /* find the connection policy handle. */
1288         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1289                 return NT_STATUS_INVALID_HANDLE;
1290
1291         /* check if the user have enough rights */
1292         if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
1293                 return NT_STATUS_ACCESS_DENIED;
1294
1295
1296         switch (q_u->sec_info) {
1297         case 1:
1298                 /* SD contains only the owner */
1299
1300                 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
1301                 if(!NT_STATUS_IS_OK(status))
1302                         return NT_STATUS_NO_MEMORY;
1303
1304
1305                 if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1306                         return NT_STATUS_NO_MEMORY;
1307                 break;
1308         case 4:
1309                 /* SD contains only the ACL */
1310
1311                 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
1312                 if(!NT_STATUS_IS_OK(status))
1313                         return NT_STATUS_NO_MEMORY;
1314
1315                 if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1316                         return NT_STATUS_NO_MEMORY;
1317                 break;
1318         default:
1319                 return NT_STATUS_INVALID_LEVEL;
1320         }
1321
1322         r_u->ptr=1;
1323
1324         return r_u->status;
1325 }
1326
1327 #if 0   /* AD DC work in ongoing in Samba 4 */
1328
1329 /***************************************************************************
1330  ***************************************************************************/
1331
1332 NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_INFO2 *r_u)
1333 {
1334         struct lsa_info *handle;
1335         const char *nb_name;
1336         char *dns_name = NULL;
1337         char *forest_name = NULL;
1338         DOM_SID *sid = NULL;
1339         struct uuid guid;
1340         fstring dnsdomname;
1341
1342         ZERO_STRUCT(guid);
1343         r_u->status = NT_STATUS_OK;
1344
1345         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1346                 return NT_STATUS_INVALID_HANDLE;
1347
1348         switch (q_u->info_class) {
1349         case 0x0c:
1350                 /* check if the user have enough rights */
1351                 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
1352                         return NT_STATUS_ACCESS_DENIED;
1353
1354                 /* Request PolicyPrimaryDomainInformation. */
1355                 switch (lp_server_role()) {
1356                         case ROLE_DOMAIN_PDC:
1357                         case ROLE_DOMAIN_BDC:
1358                                 nb_name = get_global_sam_name();
1359                                 /* ugly temp hack for these next two */
1360
1361                                 /* This should be a 'netbios domain -> DNS domain' mapping */
1362                                 dnsdomname[0] = '\0';
1363                                 get_mydnsdomname(dnsdomname);
1364                                 strlower_m(dnsdomname);
1365                                 
1366                                 dns_name = dnsdomname;
1367                                 forest_name = dnsdomname;
1368
1369                                 sid = get_global_sam_sid();
1370                                 secrets_fetch_domain_guid(lp_workgroup(), &guid);
1371                                 break;
1372                         default:
1373                                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1374                 }
1375                 init_dns_dom_info(&r_u->info.dns_dom_info, nb_name, dns_name, 
1376                                   forest_name,&guid,sid);
1377                 break;
1378         default:
1379                 DEBUG(0,("_lsa_query_info2: unknown info level in Lsa Query: %d\n", q_u->info_class));
1380                 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
1381                 break;
1382         }
1383
1384         if (NT_STATUS_IS_OK(r_u->status)) {
1385                 r_u->ptr = 0x1;
1386                 r_u->info_class = q_u->info_class;
1387         }
1388
1389         return r_u->status;
1390 }
1391 #endif  /* AD DC work in ongoing in Samba 4 */
1392
1393 /***************************************************************************
1394  ***************************************************************************/
1395
1396 NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R_ADD_ACCT_RIGHTS *r_u)
1397 {
1398         struct lsa_info *info = NULL;
1399         int i = 0;
1400         DOM_SID sid;
1401         fstring privname;
1402         UNISTR4_ARRAY *uni_privnames = q_u->rights;
1403         struct current_user user;
1404         
1405
1406         /* find the connection policy handle. */
1407         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1408                 return NT_STATUS_INVALID_HANDLE;
1409                 
1410         /* check to see if the pipe_user is a Domain Admin since 
1411            account_pol.tdb was already opened as root, this is all we have */
1412            
1413         get_current_user( &user, p );
1414         if ( user.ut.uid != sec_initial_uid()
1415                 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) 
1416         {
1417                 return NT_STATUS_ACCESS_DENIED;
1418         }
1419
1420         /* according to an NT4 PDC, you can add privileges to SIDs even without
1421            call_lsa_create_account() first.  And you can use any arbitrary SID. */
1422            
1423         sid_copy( &sid, &q_u->sid.sid );
1424         
1425         /* just a little sanity check */
1426         
1427         if ( q_u->count != uni_privnames->count ) {
1428                 DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n"));
1429                 return NT_STATUS_INVALID_HANDLE;        
1430         }
1431                 
1432         for ( i=0; i<q_u->count; i++ ) {
1433                 UNISTR4 *uni4_str = &uni_privnames->strings[i];
1434
1435                 /* only try to add non-null strings */
1436
1437                 if ( !uni4_str->string )
1438                         continue;
1439
1440                 rpcstr_pull( privname, uni4_str->string->buffer, sizeof(privname), -1, STR_TERMINATE );
1441                 
1442                 if ( !grant_privilege_by_name( &sid, privname ) ) {
1443                         DEBUG(2,("_lsa_add_acct_rights: Failed to add privilege [%s]\n", privname ));
1444                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1445                 }
1446         }
1447
1448         return NT_STATUS_OK;
1449 }
1450
1451 /***************************************************************************
1452  ***************************************************************************/
1453
1454 NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u, LSA_R_REMOVE_ACCT_RIGHTS *r_u)
1455 {
1456         struct lsa_info *info = NULL;
1457         int i = 0;
1458         DOM_SID sid;
1459         fstring privname;
1460         UNISTR4_ARRAY *uni_privnames = q_u->rights;
1461         struct current_user user;
1462         
1463
1464         /* find the connection policy handle. */
1465         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1466                 return NT_STATUS_INVALID_HANDLE;
1467                 
1468         /* check to see if the pipe_user is a Domain Admin since 
1469            account_pol.tdb was already opened as root, this is all we have */
1470            
1471         get_current_user( &user, p );
1472         if ( user.ut.uid != sec_initial_uid()
1473                 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1474         {
1475                 return NT_STATUS_ACCESS_DENIED;
1476         }
1477
1478         sid_copy( &sid, &q_u->sid.sid );
1479
1480         if ( q_u->removeall ) {
1481                 if ( !revoke_all_privileges( &sid ) ) 
1482                         return NT_STATUS_ACCESS_DENIED;
1483         
1484                 return NT_STATUS_OK;
1485         }
1486         
1487         /* just a little sanity check */
1488         
1489         if ( q_u->count != uni_privnames->count ) {
1490                 DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n"));
1491                 return NT_STATUS_INVALID_HANDLE;        
1492         }
1493                 
1494         for ( i=0; i<q_u->count; i++ ) {
1495                 UNISTR4 *uni4_str = &uni_privnames->strings[i];
1496
1497                 /* only try to add non-null strings */
1498
1499                 if ( !uni4_str->string )
1500                         continue;
1501
1502                 rpcstr_pull( privname, uni4_str->string->buffer, sizeof(privname), -1, STR_TERMINATE );
1503                 
1504                 if ( !revoke_privilege_by_name( &sid, privname ) ) {
1505                         DEBUG(2,("_lsa_remove_acct_rights: Failed to revoke privilege [%s]\n", privname ));
1506                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1507                 }
1508         }
1509
1510         return NT_STATUS_OK;
1511 }
1512
1513
1514 /***************************************************************************
1515  ***************************************************************************/
1516
1517 NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA_R_ENUM_ACCT_RIGHTS *r_u)
1518 {
1519         struct lsa_info *info = NULL;
1520         DOM_SID sid;
1521         PRIVILEGE_SET privileges;
1522         SE_PRIV mask;
1523         
1524
1525         /* find the connection policy handle. */
1526         
1527         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1528                 return NT_STATUS_INVALID_HANDLE;
1529                 
1530         /* according to an NT4 PDC, you can add privileges to SIDs even without
1531            call_lsa_create_account() first.  And you can use any arbitrary SID. */
1532            
1533         sid_copy( &sid, &q_u->sid.sid );
1534         
1535         if ( !get_privileges_for_sids( &mask, &sid, 1 ) )
1536                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1537
1538         privilege_set_init( &privileges );
1539
1540         if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
1541
1542                 DEBUG(10,("_lsa_enum_acct_rights: %s has %d privileges\n", 
1543                         sid_string_static(&sid), privileges.count));
1544
1545                 r_u->status = init_r_enum_acct_rights( r_u, &privileges );
1546         }
1547         else 
1548                 r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE;
1549
1550         privilege_set_free( &privileges );
1551
1552         return r_u->status;
1553 }
1554
1555
1556 /***************************************************************************
1557  ***************************************************************************/
1558
1559 NTSTATUS _lsa_lookup_priv_value(pipes_struct *p, LSA_Q_LOOKUP_PRIV_VALUE *q_u, LSA_R_LOOKUP_PRIV_VALUE *r_u)
1560 {
1561         struct lsa_info *info = NULL;
1562         fstring name;
1563         LUID_ATTR priv_luid;
1564         SE_PRIV mask;
1565         
1566         /* find the connection policy handle. */
1567         
1568         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1569                 return NT_STATUS_INVALID_HANDLE;
1570                 
1571         unistr2_to_ascii(name, &q_u->privname.unistring, sizeof(name));
1572         
1573         DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
1574
1575         if ( !se_priv_from_name( name, &mask ) )
1576                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1577
1578         priv_luid = get_privilege_luid( &mask );
1579
1580         r_u->luid.low  = priv_luid.luid.low;
1581         r_u->luid.high = priv_luid.luid.high;
1582                 
1583
1584         return NT_STATUS_OK;
1585 }