r17463: A bit of cleanup work:
[jra/samba/.git] / source3 / rpc_server / srv_lsa_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Jeremy Allison                    2001, 2006.
8  *  Copyright (C) Rafal Szczesniak                  2002,
9  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
10  *  Copyright (C) Simo Sorce                        2003.
11  *  Copyright (C) Gerald (Jerry) Carter             2005.
12  *  Copyright (C) Volker Lendecke                   2005.
13  *
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_3(DOM_QUERY_3 *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_query
98  ***************************************************************************/
99
100 static void init_dom_query_5(DOM_QUERY_5 *d_q, const char *dom_name, DOM_SID *dom_sid)
101 {
102         init_dom_query_3(d_q, dom_name, dom_sid);
103 }
104
105 /***************************************************************************
106  init_dom_ref - adds a domain if it's not already in, returns the index.
107 ***************************************************************************/
108
109 static int init_dom_ref(DOM_R_REF *ref, const char *dom_name, DOM_SID *dom_sid)
110 {
111         int num = 0;
112
113         if (dom_name != NULL) {
114                 for (num = 0; num < ref->num_ref_doms_1; num++) {
115                         if (sid_equal(dom_sid, &ref->ref_dom[num].ref_dom.sid))
116                                 return num;
117                 }
118         } else {
119                 num = ref->num_ref_doms_1;
120         }
121
122         if (num >= MAX_REF_DOMAINS) {
123                 /* index not found, already at maximum domain limit */
124                 return -1;
125         }
126
127         ref->num_ref_doms_1 = num+1;
128         ref->ptr_ref_dom  = 1;
129         ref->max_entries = MAX_REF_DOMAINS;
130         ref->num_ref_doms_2 = num+1;
131
132         ref->hdr_ref_dom[num].ptr_dom_sid = 1; /* dom sid cannot be NULL. */
133
134         init_unistr2(&ref->ref_dom[num].uni_dom_name, dom_name, UNI_FLAGS_NONE);
135         init_uni_hdr(&ref->hdr_ref_dom[num].hdr_dom_name, &ref->ref_dom[num].uni_dom_name);
136
137         init_dom_sid2(&ref->ref_dom[num].ref_dom, dom_sid );
138
139         return num;
140 }
141
142 /***************************************************************************
143  lookup_lsa_rids. Must be called as root for lookup_name to work.
144  ***************************************************************************/
145
146 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
147                         DOM_R_REF *ref,
148                         DOM_RID *prid,
149                         uint32 num_entries,
150                         const UNISTR2 *name,
151                         int flags,
152                         uint32 *pmapped_count)
153 {
154         uint32 mapped_count, i;
155
156         SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
157
158         mapped_count = 0;
159         *pmapped_count = 0;
160
161         for (i = 0; i < num_entries; i++) {
162                 DOM_SID sid;
163                 uint32 rid;
164                 int dom_idx;
165                 char *full_name;
166                 const char *domain;
167                 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
168
169                 /* Split name into domain and user component */
170
171                 full_name = rpcstr_pull_unistr2_talloc(mem_ctx, &name[i]);
172                 if (full_name == NULL) {
173                         DEBUG(0, ("pull_ucs2_talloc failed\n"));
174                         return NT_STATUS_NO_MEMORY;
175                 }
176
177                 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
178
179                 /* We can ignore the result of lookup_name, it will not touch
180                    "type" if it's not successful */
181
182                 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
183                             &sid, &type);
184
185                 switch (type) {
186                 case SID_NAME_USER:
187                 case SID_NAME_DOM_GRP:
188                 case SID_NAME_DOMAIN:
189                 case SID_NAME_ALIAS:
190                 case SID_NAME_WKN_GRP:
191                         DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
192                         /* Leave these unchanged */
193                         break;
194                 default:
195                         /* Don't hand out anything but the list above */
196                         DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
197                         type = SID_NAME_UNKNOWN;
198                         break;
199                 }
200
201                 rid = 0;
202                 dom_idx = -1;
203
204                 if (type != SID_NAME_UNKNOWN) {
205                         sid_split_rid(&sid, &rid);
206                         dom_idx = init_dom_ref(ref, domain, &sid);
207                         mapped_count++;
208                 }
209
210                 init_dom_rid(&prid[i], rid, type, dom_idx);
211         }
212
213         *pmapped_count = mapped_count;
214         return NT_STATUS_OK;
215 }
216
217 /***************************************************************************
218  lookup_lsa_sids. Must be called as root for lookup_name to work.
219  ***************************************************************************/
220
221 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
222                         DOM_R_REF *ref,
223                         LSA_TRANSLATED_SID3 *trans_sids,
224                         uint32 num_entries,
225                         const UNISTR2 *name,
226                         int flags,
227                         uint32 *pmapped_count)
228 {
229         uint32 mapped_count, i;
230
231         SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
232
233         mapped_count = 0;
234         *pmapped_count = 0;
235
236         for (i = 0; i < num_entries; i++) {
237                 DOM_SID sid;
238                 uint32 rid;
239                 int dom_idx;
240                 char *full_name;
241                 const char *domain;
242                 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
243
244                 /* Split name into domain and user component */
245
246                 full_name = rpcstr_pull_unistr2_talloc(mem_ctx, &name[i]);
247                 if (full_name == NULL) {
248                         DEBUG(0, ("pull_ucs2_talloc failed\n"));
249                         return NT_STATUS_NO_MEMORY;
250                 }
251
252                 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
253
254                 /* We can ignore the result of lookup_name, it will not touch
255                    "type" if it's not successful */
256
257                 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
258                             &sid, &type);
259
260                 switch (type) {
261                 case SID_NAME_USER:
262                 case SID_NAME_DOM_GRP:
263                 case SID_NAME_DOMAIN:
264                 case SID_NAME_ALIAS:
265                 case SID_NAME_WKN_GRP:
266                         DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
267                         /* Leave these unchanged */
268                         break;
269                 default:
270                         /* Don't hand out anything but the list above */
271                         DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
272                         type = SID_NAME_UNKNOWN;
273                         break;
274                 }
275
276                 rid = 0;
277                 dom_idx = -1;
278
279                 if (type != SID_NAME_UNKNOWN) {
280                         DOM_SID domain_sid;
281                         sid_copy(&domain_sid, &sid);
282                         sid_split_rid(&domain_sid, &rid);
283                         dom_idx = init_dom_ref(ref, domain, &domain_sid);
284                         mapped_count++;
285                 }
286
287                 /* Initialize the LSA_TRANSLATED_SID3 return. */
288                 trans_sids[i].sid_type = type;
289                 trans_sids[i].sid2 = TALLOC_P(mem_ctx, DOM_SID2);
290                 if (trans_sids[i].sid2 == NULL) {
291                         return NT_STATUS_NO_MEMORY;
292                 }
293                 init_dom_sid2(trans_sids[i].sid2, &sid);
294                 trans_sids[i].sid_idx = dom_idx;
295         }
296
297         *pmapped_count = mapped_count;
298         return NT_STATUS_OK;
299 }
300
301 /***************************************************************************
302  init_reply_lookup_names
303  ***************************************************************************/
304
305 static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
306                 DOM_R_REF *ref, uint32 num_entries,
307                 DOM_RID *rid, uint32 mapped_count)
308 {
309         r_l->ptr_dom_ref  = 1;
310         r_l->dom_ref      = ref;
311
312         r_l->num_entries  = num_entries;
313         r_l->ptr_entries  = 1;
314         r_l->num_entries2 = num_entries;
315         r_l->dom_rid      = rid;
316
317         r_l->mapped_count = mapped_count;
318 }
319
320 /***************************************************************************
321  init_reply_lookup_names2
322  ***************************************************************************/
323
324 static void init_reply_lookup_names2(LSA_R_LOOKUP_NAMES2 *r_l,
325                 DOM_R_REF *ref, uint32 num_entries,
326                 DOM_RID2 *rid, uint32 mapped_count)
327 {
328         r_l->ptr_dom_ref  = 1;
329         r_l->dom_ref      = ref;
330
331         r_l->num_entries  = num_entries;
332         r_l->ptr_entries  = 1;
333         r_l->num_entries2 = num_entries;
334         r_l->dom_rid      = rid;
335
336         r_l->mapped_count = mapped_count;
337 }
338
339 /***************************************************************************
340  init_reply_lookup_names3
341  ***************************************************************************/
342
343 static void init_reply_lookup_names3(LSA_R_LOOKUP_NAMES3 *r_l,
344                 DOM_R_REF *ref, uint32 num_entries,
345                 LSA_TRANSLATED_SID3 *trans_sids, uint32 mapped_count)
346 {
347         r_l->ptr_dom_ref  = 1;
348         r_l->dom_ref      = ref;
349
350         r_l->num_entries  = num_entries;
351         r_l->ptr_entries  = 1;
352         r_l->num_entries2 = num_entries;
353         r_l->trans_sids   = trans_sids;
354
355         r_l->mapped_count = mapped_count;
356 }
357
358 /***************************************************************************
359  init_reply_lookup_names4
360  ***************************************************************************/
361
362 static void init_reply_lookup_names4(LSA_R_LOOKUP_NAMES4 *r_l,
363                 DOM_R_REF *ref, uint32 num_entries,
364                 LSA_TRANSLATED_SID3 *trans_sids, uint32 mapped_count)
365 {
366         r_l->ptr_dom_ref  = 1;
367         r_l->dom_ref      = ref;
368
369         r_l->num_entries  = num_entries;
370         r_l->ptr_entries  = 1;
371         r_l->num_entries2 = num_entries;
372         r_l->trans_sids   = trans_sids;
373
374         r_l->mapped_count = mapped_count;
375 }
376
377 /***************************************************************************
378  Init_reply_lookup_sids.
379  ***************************************************************************/
380
381 static void init_reply_lookup_sids2(LSA_R_LOOKUP_SIDS2 *r_l,
382                                 DOM_R_REF *ref,
383                                 LSA_TRANS_NAME_ENUM2 *names,
384                                 uint32 mapped_count)
385 {
386         r_l->ptr_dom_ref  = ref ? 1 : 0;
387         r_l->dom_ref      = ref;
388         r_l->names        = names;
389         r_l->mapped_count = mapped_count;
390 }
391
392 /***************************************************************************
393  Init_reply_lookup_sids.
394  ***************************************************************************/
395
396 static void init_reply_lookup_sids3(LSA_R_LOOKUP_SIDS3 *r_l,
397                                 DOM_R_REF *ref,
398                                 LSA_TRANS_NAME_ENUM2 *names,
399                                 uint32 mapped_count)
400 {
401         r_l->ptr_dom_ref  = ref ? 1 : 0;
402         r_l->dom_ref      = ref;
403         r_l->names        = names;
404         r_l->mapped_count = mapped_count;
405 }
406
407 /***************************************************************************
408  Init_reply_lookup_sids.
409  ***************************************************************************/
410
411 static NTSTATUS init_reply_lookup_sids(TALLOC_CTX *mem_ctx,
412                                 LSA_R_LOOKUP_SIDS *r_l,
413                                 DOM_R_REF *ref,
414                                 LSA_TRANS_NAME_ENUM2 *names,
415                                 uint32 mapped_count)
416 {
417         LSA_TRANS_NAME_ENUM *oldnames = TALLOC_ZERO_P(mem_ctx, LSA_TRANS_NAME_ENUM);
418
419         if (!oldnames) {
420                 return NT_STATUS_NO_MEMORY;
421         }
422
423         oldnames->num_entries = names->num_entries;
424         oldnames->ptr_trans_names = names->ptr_trans_names;
425         oldnames->num_entries2 = names->num_entries2;
426         oldnames->uni_name = names->uni_name;
427
428         if (names->num_entries) {
429                 int i;
430
431                 oldnames->name = TALLOC_ARRAY(oldnames, LSA_TRANS_NAME, names->num_entries);
432
433                 if (!oldnames->name) {
434                         return NT_STATUS_NO_MEMORY;
435                 }
436                 for (i = 0; i < names->num_entries; i++) {
437                         oldnames->name[i].sid_name_use = names->name[i].sid_name_use;
438                         oldnames->name[i].hdr_name = names->name[i].hdr_name;
439                         oldnames->name[i].domain_idx = names->name[i].domain_idx;
440                 }
441         }
442
443         r_l->ptr_dom_ref  = ref ? 1 : 0;
444         r_l->dom_ref      = ref;
445         r_l->names        = oldnames;
446         r_l->mapped_count = mapped_count;
447         return NT_STATUS_OK;
448 }
449
450 static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size)
451 {
452         DOM_SID local_adm_sid;
453         DOM_SID adm_sid;
454
455         SEC_ACE ace[3];
456         SEC_ACCESS mask;
457
458         SEC_ACL *psa = NULL;
459
460         init_sec_access(&mask, POLICY_EXECUTE);
461         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
462
463         sid_copy(&adm_sid, get_global_sam_sid());
464         sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS);
465         init_sec_access(&mask, POLICY_ALL_ACCESS);
466         init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
467
468         sid_copy(&local_adm_sid, &global_sid_Builtin);
469         sid_append_rid(&local_adm_sid, BUILTIN_ALIAS_RID_ADMINS);
470         init_sec_access(&mask, POLICY_ALL_ACCESS);
471         init_sec_ace(&ace[2], &local_adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
472
473         if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
474                 return NT_STATUS_NO_MEMORY;
475
476         if((*sd = make_sec_desc(mem_ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL, psa, sd_size)) == NULL)
477                 return NT_STATUS_NO_MEMORY;
478
479         return NT_STATUS_OK;
480 }
481
482 #if 0   /* AD DC work in ongoing in Samba 4 */
483
484 /***************************************************************************
485  Init_dns_dom_info.
486 ***************************************************************************/
487
488 static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name,
489                               const char *dns_name, const char *forest_name,
490                               struct uuid *dom_guid, DOM_SID *dom_sid)
491 {
492         if (nb_name && *nb_name) {
493                 init_unistr2(&r_l->uni_nb_dom_name, nb_name, UNI_FLAGS_NONE);
494                 init_uni_hdr(&r_l->hdr_nb_dom_name, &r_l->uni_nb_dom_name);
495                 r_l->hdr_nb_dom_name.uni_max_len += 2;
496                 r_l->uni_nb_dom_name.uni_max_len += 1;
497         }
498         
499         if (dns_name && *dns_name) {
500                 init_unistr2(&r_l->uni_dns_dom_name, dns_name, UNI_FLAGS_NONE);
501                 init_uni_hdr(&r_l->hdr_dns_dom_name, &r_l->uni_dns_dom_name);
502                 r_l->hdr_dns_dom_name.uni_max_len += 2;
503                 r_l->uni_dns_dom_name.uni_max_len += 1;
504         }
505
506         if (forest_name && *forest_name) {
507                 init_unistr2(&r_l->uni_forest_name, forest_name, UNI_FLAGS_NONE);
508                 init_uni_hdr(&r_l->hdr_forest_name, &r_l->uni_forest_name);
509                 r_l->hdr_forest_name.uni_max_len += 2;
510                 r_l->uni_forest_name.uni_max_len += 1;
511         }
512
513         /* how do we init the guid ? probably should write an init fn */
514         if (dom_guid) {
515                 memcpy(&r_l->dom_guid, dom_guid, sizeof(struct uuid));
516         }
517         
518         if (dom_sid) {
519                 r_l->ptr_dom_sid = 1;
520                 init_dom_sid2(&r_l->dom_sid, dom_sid);
521         }
522 }
523 #endif  /* AD DC work in ongoing in Samba 4 */
524
525
526 /***************************************************************************
527  _lsa_open_policy2.
528  ***************************************************************************/
529
530 NTSTATUS _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL2 *r_u)
531 {
532         struct lsa_info *info;
533         SEC_DESC *psd = NULL;
534         size_t sd_size;
535         uint32 des_access=q_u->des_access;
536         uint32 acc_granted;
537         NTSTATUS status;
538
539
540         /* map the generic bits to the lsa policy ones */
541         se_map_generic(&des_access, &lsa_generic_mapping);
542
543         /* get the generic lsa policy SD until we store it */
544         lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
545
546         if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
547                 if (p->pipe_user.ut.uid != sec_initial_uid()) {
548                         return status;
549                 }
550                 DEBUG(4,("ACCESS should be DENIED (granted: %#010x;  required: %#010x)\n",
551                          acc_granted, des_access));
552                 DEBUGADD(4,("but overwritten by euid == 0\n"));
553         }
554
555         /* This is needed for lsa_open_account and rpcclient .... :-) */
556
557         if (p->pipe_user.ut.uid == sec_initial_uid())
558                 acc_granted = POLICY_ALL_ACCESS;
559
560         /* associate the domain SID with the (unique) handle. */
561         if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
562                 return NT_STATUS_NO_MEMORY;
563
564         ZERO_STRUCTP(info);
565         sid_copy(&info->sid,get_global_sam_sid());
566         info->access = acc_granted;
567
568         /* set up the LSA QUERY INFO response */
569         if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
570                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
571
572         return NT_STATUS_OK;
573 }
574
575 /***************************************************************************
576  _lsa_open_policy
577  ***************************************************************************/
578
579 NTSTATUS _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL *r_u)
580 {
581         struct lsa_info *info;
582         SEC_DESC *psd = NULL;
583         size_t sd_size;
584         uint32 des_access=q_u->des_access;
585         uint32 acc_granted;
586         NTSTATUS status;
587
588
589         /* map the generic bits to the lsa policy ones */
590         se_map_generic(&des_access, &lsa_generic_mapping);
591
592         /* get the generic lsa policy SD until we store it */
593         lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
594
595         if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
596                 if (geteuid() != 0) {
597                         return status;
598                 }
599                 DEBUG(4,("ACCESS should be DENIED (granted: %#010x;  required: %#010x)\n",
600                          acc_granted, des_access));
601                 DEBUGADD(4,("but overwritten by euid == 0\n"));
602                 acc_granted = des_access;
603         }
604
605         /* associate the domain SID with the (unique) handle. */
606         if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
607                 return NT_STATUS_NO_MEMORY;
608
609         ZERO_STRUCTP(info);
610         sid_copy(&info->sid,get_global_sam_sid());
611         info->access = acc_granted;
612
613         /* set up the LSA QUERY INFO response */
614         if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
615                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
616
617         return NT_STATUS_OK;
618 }
619
620 /***************************************************************************
621  _lsa_enum_trust_dom - this needs fixing to do more than return NULL ! JRA.
622  ufff, done :)  mimir
623  ***************************************************************************/
624
625 NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u,
626                              LSA_R_ENUM_TRUST_DOM *r_u)
627 {
628         struct lsa_info *info;
629         uint32 next_idx;
630         struct trustdom_info **domains;
631
632         /*
633          * preferred length is set to 5 as a "our" preferred length
634          * nt sets this parameter to 2
635          * update (20.08.2002): it's not preferred length, but preferred size!
636          * it needs further investigation how to optimally choose this value
637          */
638         uint32 max_num_domains =
639                 q_u->preferred_len < 5 ? q_u->preferred_len : 10;
640         uint32 num_domains;
641         NTSTATUS nt_status;
642         uint32 num_thistime;
643
644         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
645                 return NT_STATUS_INVALID_HANDLE;
646
647         /* check if the user have enough rights */
648         if (!(info->access & POLICY_VIEW_LOCAL_INFORMATION))
649                 return NT_STATUS_ACCESS_DENIED;
650
651         nt_status = secrets_trusted_domains(p->mem_ctx, &num_domains,
652                                             &domains);
653
654         if (!NT_STATUS_IS_OK(nt_status)) {
655                 return nt_status;
656         }
657
658         if (q_u->enum_context < num_domains) {
659                 num_thistime = MIN(num_domains, max_num_domains);
660
661                 r_u->status = STATUS_MORE_ENTRIES;
662
663                 if (q_u->enum_context + num_thistime > num_domains) {
664                         num_thistime = num_domains - q_u->enum_context;
665                         r_u->status = NT_STATUS_OK;
666                 }
667
668                 next_idx = q_u->enum_context + num_thistime;
669         } else {
670                 num_thistime = 0;
671                 next_idx = 0xffffffff;
672                 r_u->status = NT_STATUS_NO_MORE_ENTRIES;
673         }
674                 
675         /* set up the lsa_enum_trust_dom response */
676
677         init_r_enum_trust_dom(p->mem_ctx, r_u, next_idx,
678                               num_thistime, domains+q_u->enum_context);
679
680         return r_u->status;
681 }
682
683 /***************************************************************************
684  _lsa_query_info. See the POLICY_INFOMATION_CLASS docs at msdn.
685  ***************************************************************************/
686
687 NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO *r_u)
688 {
689         struct lsa_info *handle;
690         LSA_INFO_CTR *ctr = &r_u->ctr;
691         DOM_SID domain_sid;
692         const char *name;
693         DOM_SID *sid = NULL;
694
695         r_u->status = NT_STATUS_OK;
696
697         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
698                 return NT_STATUS_INVALID_HANDLE;
699
700         switch (q_u->info_class) {
701         case 0x02:
702                 {
703
704                 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
705                 
706                 /* check if the user have enough rights */
707                 if (!(handle->access & POLICY_VIEW_AUDIT_INFORMATION)) {
708                         DEBUG(10,("_lsa_query_info: insufficient access rights\n"));
709                         return NT_STATUS_ACCESS_DENIED;
710                 }
711
712                 /* fake info: We audit everything. ;) */
713                 ctr->info.id2.ptr = 1;
714                 ctr->info.id2.auditing_enabled = True;
715                 ctr->info.id2.count1 = ctr->info.id2.count2 = LSA_AUDIT_NUM_CATEGORIES;
716
717                 if ((ctr->info.id2.auditsettings = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, LSA_AUDIT_NUM_CATEGORIES)) == NULL)
718                         return NT_STATUS_NO_MEMORY;
719
720                 ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
721                 ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def; 
722                 ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_LOGON] = policy_def; 
723                 ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def; 
724                 ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
725                 ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
726                 ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def; 
727
728                 break;
729                 }
730         case 0x03:
731                 /* check if the user have enough rights */
732                 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
733                         return NT_STATUS_ACCESS_DENIED;
734
735                 /* Request PolicyPrimaryDomainInformation. */
736                 switch (lp_server_role()) {
737                         case ROLE_DOMAIN_PDC:
738                         case ROLE_DOMAIN_BDC:
739                                 name = get_global_sam_name();
740                                 sid = get_global_sam_sid();
741                                 break;
742                         case ROLE_DOMAIN_MEMBER:
743                                 name = lp_workgroup();
744                                 /* We need to return the Domain SID here. */
745                                 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid))
746                                         sid = &domain_sid;
747                                 else
748                                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
749                                 break;
750                         case ROLE_STANDALONE:
751                                 name = lp_workgroup();
752                                 sid = NULL;
753                                 break;
754                         default:
755                                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
756                 }
757                 init_dom_query_3(&r_u->ctr.info.id3, name, sid);
758                 break;
759         case 0x05:
760                 /* check if the user have enough rights */
761                 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
762                         return NT_STATUS_ACCESS_DENIED;
763
764                 /* Request PolicyAccountDomainInformation. */
765                 name = get_global_sam_name();
766                 sid = get_global_sam_sid();
767                 init_dom_query_5(&r_u->ctr.info.id5, name, sid);
768                 break;
769         case 0x06:
770                 /* check if the user have enough rights */
771                 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
772                         return NT_STATUS_ACCESS_DENIED;
773
774                 switch (lp_server_role()) {
775                         case ROLE_DOMAIN_BDC:
776                                 /*
777                                  * only a BDC is a backup controller
778                                  * of the domain, it controls.
779                                  */
780                                 ctr->info.id6.server_role = 2;
781                                 break;
782                         default:
783                                 /*
784                                  * any other role is a primary
785                                  * of the domain, it controls.
786                                  */
787                                 ctr->info.id6.server_role = 3;
788                                 break; 
789                 }
790                 break;
791         default:
792                 DEBUG(0,("_lsa_query_info: unknown info level in Lsa Query: %d\n", q_u->info_class));
793                 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
794                 break;
795         }
796
797         if (NT_STATUS_IS_OK(r_u->status)) {
798                 r_u->dom_ptr = 0x22000000; /* bizarre */
799                 ctr->info_class = q_u->info_class;
800         }
801
802         return r_u->status;
803 }
804
805 /***************************************************************************
806  _lsa_lookup_sids_internal
807  ***************************************************************************/
808
809 static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p,
810                                 uint16 level,                           /* input */
811                                 int num_sids,                           /* input */
812                                 const DOM_SID2 *sid,                    /* input */
813                                 DOM_R_REF **pp_ref,                     /* output */
814                                 LSA_TRANS_NAME_ENUM2 **pp_names,        /* output */
815                                 uint32 *pp_mapped_count)
816 {
817         NTSTATUS status;
818         int i;
819         const DOM_SID **sids = NULL;
820         LSA_TRANS_NAME_ENUM2 *names = NULL;
821         DOM_R_REF *ref = NULL;
822         uint32 mapped_count = 0;
823         struct lsa_dom_info *dom_infos = NULL;
824         struct lsa_name_info *name_infos = NULL;
825
826         *pp_mapped_count = 0;
827         *pp_ref = NULL;
828         *pp_names = NULL;
829         
830         names = TALLOC_ZERO_P(p->mem_ctx, LSA_TRANS_NAME_ENUM2);
831         sids = TALLOC_ARRAY(p->mem_ctx, const DOM_SID *, num_sids);
832         ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
833
834         if (sids == NULL || names == NULL || ref == NULL) {
835                 return NT_STATUS_NO_MEMORY;
836         }
837
838         for (i=0; i<num_sids; i++) {
839                 sids[i] = &sid[i].sid;
840         }
841
842         status = lookup_sids(p->mem_ctx, num_sids, sids, level,
843                                   &dom_infos, &name_infos);
844
845         if (!NT_STATUS_IS_OK(status)) {
846                 return status;
847         }
848
849         if (num_sids > 0) {
850                 names->name = TALLOC_ARRAY(names, LSA_TRANS_NAME2, num_sids);
851                 names->uni_name = TALLOC_ARRAY(names, UNISTR2, num_sids);
852                 if ((names->name == NULL) || (names->uni_name == NULL)) {
853                         return NT_STATUS_NO_MEMORY;
854                 }
855         }
856
857         for (i=0; i<MAX_REF_DOMAINS; i++) {
858
859                 if (!dom_infos[i].valid) {
860                         break;
861                 }
862
863                 if (init_dom_ref(ref, dom_infos[i].name,
864                                  &dom_infos[i].sid) != i) {
865                         DEBUG(0, ("Domain %s mentioned twice??\n",
866                                   dom_infos[i].name));
867                         return NT_STATUS_INTERNAL_ERROR;
868                 }
869         }
870
871         for (i=0; i<num_sids; i++) {
872                 struct lsa_name_info *name = &name_infos[i];
873
874                 if (name->type == SID_NAME_UNKNOWN) {
875                         name->dom_idx = -1;
876                         /* Unknown sids should return the string
877                          * representation of the SID. Windows 2003 behaves
878                          * rather erratic here, in many cases it returns the
879                          * RID as 8 bytes hex, in others it returns the full
880                          * SID. We (Jerry/VL) could not figure out which the
881                          * hard cases are, so leave it with the SID.  */
882                         name->name = talloc_asprintf(p->mem_ctx, "%s", 
883                                                      sid_string_static(sids[i]));
884                         if (name->name == NULL) {
885                                 return NT_STATUS_NO_MEMORY;
886                         }
887                 } else {
888                         mapped_count += 1;
889                 }
890                 init_lsa_trans_name2(&names->name[i], &names->uni_name[i],
891                                     name->type, name->name, name->dom_idx);
892         }
893
894         names->num_entries = num_sids;
895         names->ptr_trans_names = 1;
896         names->num_entries2 = num_sids;
897
898         status = NT_STATUS_NONE_MAPPED;
899         if (mapped_count > 0) {
900                 status = (mapped_count < num_sids) ?
901                         STATUS_SOME_UNMAPPED : NT_STATUS_OK;
902         }
903
904         DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
905                    num_sids, mapped_count, nt_errstr(status)));
906
907         *pp_mapped_count = mapped_count;
908         *pp_ref = ref;
909         *pp_names = names;
910
911         return status;
912 }
913
914 /***************************************************************************
915  _lsa_lookup_sids
916  ***************************************************************************/
917
918 NTSTATUS _lsa_lookup_sids(pipes_struct *p,
919                           LSA_Q_LOOKUP_SIDS *q_u,
920                           LSA_R_LOOKUP_SIDS *r_u)
921 {
922         struct lsa_info *handle;
923         int num_sids = q_u->sids.num_entries;
924         uint32 mapped_count = 0;
925         DOM_R_REF *ref = NULL;
926         LSA_TRANS_NAME_ENUM2 *names = NULL;
927         NTSTATUS status;
928
929         if ((q_u->level < 1) || (q_u->level > 6)) {
930                 return NT_STATUS_INVALID_PARAMETER;
931         }
932
933         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
934                 return NT_STATUS_INVALID_HANDLE;
935         }
936
937         /* check if the user has enough rights */
938         if (!(handle->access & POLICY_LOOKUP_NAMES)) {
939                 return NT_STATUS_ACCESS_DENIED;
940         }
941
942         if (num_sids >  MAX_LOOKUP_SIDS) {
943                 DEBUG(5,("_lsa_lookup_sids: limit of %d exceeded, requested %d\n",
944                          MAX_LOOKUP_SIDS, num_sids));
945                 return NT_STATUS_NONE_MAPPED;
946         }
947
948         r_u->status = _lsa_lookup_sids_internal(p,
949                                                 q_u->level,
950                                                 num_sids, 
951                                                 q_u->sids.sid,
952                                                 &ref,
953                                                 &names,
954                                                 &mapped_count);
955
956         /* Convert from LSA_TRANS_NAME_ENUM2 to LSA_TRANS_NAME_ENUM */
957
958         status = init_reply_lookup_sids(p->mem_ctx, r_u, ref, names, mapped_count);
959         if (!NT_STATUS_IS_OK(status)) {
960                 return status;
961         }
962         return r_u->status;
963 }
964
965 /***************************************************************************
966  _lsa_lookup_sids2
967  ***************************************************************************/
968
969 NTSTATUS _lsa_lookup_sids2(pipes_struct *p,
970                           LSA_Q_LOOKUP_SIDS2 *q_u,
971                           LSA_R_LOOKUP_SIDS2 *r_u)
972 {
973         struct lsa_info *handle;
974         int num_sids = q_u->sids.num_entries;
975         uint32 mapped_count = 0;
976         DOM_R_REF *ref = NULL;
977         LSA_TRANS_NAME_ENUM2 *names = NULL;
978
979         if ((q_u->level < 1) || (q_u->level > 6)) {
980                 return NT_STATUS_INVALID_PARAMETER;
981         }
982
983         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
984                 return NT_STATUS_INVALID_HANDLE;
985         }
986
987         /* check if the user have enough rights */
988         if (!(handle->access & POLICY_LOOKUP_NAMES)) {
989                 return NT_STATUS_ACCESS_DENIED;
990         }
991
992         if (num_sids >  MAX_LOOKUP_SIDS) {
993                 DEBUG(5,("_lsa_lookup_sids2: limit of %d exceeded, requested %d\n",
994                          MAX_LOOKUP_SIDS, num_sids));
995                 return NT_STATUS_NONE_MAPPED;
996         }
997
998         r_u->status = _lsa_lookup_sids_internal(p,
999                                                 q_u->level,
1000                                                 num_sids, 
1001                                                 q_u->sids.sid,
1002                                                 &ref,
1003                                                 &names,
1004                                                 &mapped_count);
1005
1006         init_reply_lookup_sids2(r_u, ref, names, mapped_count);
1007         return r_u->status;
1008 }
1009
1010 /***************************************************************************
1011  _lsa_lookup_sida3
1012
1013  Before someone actually re-activates this, please present a sniff showing
1014  this call against some Windows server. I (vl) could not make it work against
1015  w2k3 at all.
1016  ***************************************************************************/
1017
1018 NTSTATUS _lsa_lookup_sids3(pipes_struct *p,
1019                           LSA_Q_LOOKUP_SIDS3 *q_u,
1020                           LSA_R_LOOKUP_SIDS3 *r_u)
1021 {
1022         uint32 mapped_count = 0;
1023         DOM_R_REF *ref;
1024         LSA_TRANS_NAME_ENUM2 *names;
1025
1026         if ((q_u->level < 1) || (q_u->level > 6)) {
1027                 return NT_STATUS_INVALID_PARAMETER;
1028         }
1029
1030         r_u->status = NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED;
1031
1032         ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
1033         names = TALLOC_ZERO_P(p->mem_ctx, LSA_TRANS_NAME_ENUM2);
1034
1035         if ((ref == NULL) || (names == NULL)) {
1036                 /* We would segfault later on in lsa_io_r_lookup_sids3 anyway,
1037                  * so do a planned exit here. We NEEEED pidl! */
1038                 smb_panic("talloc failed");
1039         }
1040
1041         init_reply_lookup_sids3(r_u, ref, names, mapped_count);
1042         return r_u->status;
1043 }
1044
1045 /***************************************************************************
1046 lsa_reply_lookup_names
1047  ***************************************************************************/
1048
1049 NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_NAMES *r_u)
1050 {
1051         struct lsa_info *handle;
1052         UNISTR2 *names = q_u->uni_name;
1053         uint32 num_entries = q_u->num_entries;
1054         DOM_R_REF *ref;
1055         DOM_RID *rids;
1056         uint32 mapped_count = 0;
1057         int flags = 0;
1058
1059         if (num_entries >  MAX_LOOKUP_SIDS) {
1060                 num_entries = MAX_LOOKUP_SIDS;
1061                 DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries));
1062         }
1063                 
1064         /* Probably the lookup_level is some sort of bitmask. */
1065         if (q_u->lookup_level == 1) {
1066                 flags = LOOKUP_NAME_ALL;
1067         }
1068
1069         ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
1070         rids = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID, num_entries);
1071
1072         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
1073                 r_u->status = NT_STATUS_INVALID_HANDLE;
1074                 goto done;
1075         }
1076
1077         /* check if the user have enough rights */
1078         if (!(handle->access & POLICY_LOOKUP_NAMES)) {
1079                 r_u->status = NT_STATUS_ACCESS_DENIED;
1080                 goto done;
1081         }
1082
1083         if (!ref || !rids)
1084                 return NT_STATUS_NO_MEMORY;
1085
1086         /* set up the LSA Lookup RIDs response */
1087         become_root(); /* lookup_name can require root privs */
1088         r_u->status = lookup_lsa_rids(p->mem_ctx, ref, rids, num_entries,
1089                                       names, flags, &mapped_count);
1090         unbecome_root();
1091
1092 done:
1093
1094         if (NT_STATUS_IS_OK(r_u->status) && (num_entries != 0) ) {
1095                 if (mapped_count == 0)
1096                         r_u->status = NT_STATUS_NONE_MAPPED;
1097                 else if (mapped_count != num_entries)
1098                         r_u->status = STATUS_SOME_UNMAPPED;
1099         }
1100
1101         init_reply_lookup_names(r_u, ref, num_entries, rids, mapped_count);
1102         return r_u->status;
1103 }
1104
1105 /***************************************************************************
1106 lsa_reply_lookup_names2
1107  ***************************************************************************/
1108
1109 NTSTATUS _lsa_lookup_names2(pipes_struct *p, LSA_Q_LOOKUP_NAMES2 *q_u, LSA_R_LOOKUP_NAMES2 *r_u)
1110 {
1111         struct lsa_info *handle;
1112         UNISTR2 *names = q_u->uni_name;
1113         uint32 num_entries = q_u->num_entries;
1114         DOM_R_REF *ref;
1115         DOM_RID *rids;
1116         DOM_RID2 *rids2;
1117         int i;
1118         uint32 mapped_count = 0;
1119         int flags = 0;
1120
1121         if (num_entries >  MAX_LOOKUP_SIDS) {
1122                 num_entries = MAX_LOOKUP_SIDS;
1123                 DEBUG(5,("_lsa_lookup_names2: truncating name lookup list to %d\n", num_entries));
1124         }
1125                 
1126         /* Probably the lookup_level is some sort of bitmask. */
1127         if (q_u->lookup_level == 1) {
1128                 flags = LOOKUP_NAME_ALL;
1129         }
1130
1131         ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
1132         rids = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID, num_entries);
1133         rids2 = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID2, num_entries);
1134
1135         if ((ref == NULL) || (rids == NULL) || (rids2 == NULL)) {
1136                 r_u->status = NT_STATUS_NO_MEMORY;
1137                 return NT_STATUS_NO_MEMORY;
1138         }
1139
1140         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
1141                 r_u->status = NT_STATUS_INVALID_HANDLE;
1142                 goto done;
1143         }
1144
1145         /* check if the user have enough rights */
1146         if (!(handle->access & POLICY_LOOKUP_NAMES)) {
1147                 r_u->status = NT_STATUS_ACCESS_DENIED;
1148                 goto done;
1149         }
1150
1151         /* set up the LSA Lookup RIDs response */
1152         become_root(); /* lookup_name can require root privs */
1153         r_u->status = lookup_lsa_rids(p->mem_ctx, ref, rids, num_entries,
1154                                       names, flags, &mapped_count);
1155         unbecome_root();
1156
1157 done:
1158
1159         if (NT_STATUS_IS_OK(r_u->status)) {
1160                 if (mapped_count == 0) {
1161                         r_u->status = NT_STATUS_NONE_MAPPED;
1162                 } else if (mapped_count != num_entries) {
1163                         r_u->status = STATUS_SOME_UNMAPPED;
1164                 }
1165         }
1166
1167         /* Convert the rids array to rids2. */
1168         for (i = 0; i < num_entries; i++) {
1169                 rids2[i].type = rids[i].type;
1170                 rids2[i].rid = rids[i].rid;
1171                 rids2[i].rid_idx = rids[i].rid_idx;
1172                 rids2[i].unknown = 0;
1173         }
1174
1175         init_reply_lookup_names2(r_u, ref, num_entries, rids2, mapped_count);
1176         return r_u->status;
1177 }
1178
1179 /***************************************************************************
1180 lsa_reply_lookup_names3.
1181  ***************************************************************************/
1182
1183 NTSTATUS _lsa_lookup_names3(pipes_struct *p, LSA_Q_LOOKUP_NAMES3 *q_u, LSA_R_LOOKUP_NAMES3 *r_u)
1184 {
1185         struct lsa_info *handle;
1186         UNISTR2 *names = q_u->uni_name;
1187         uint32 num_entries = q_u->num_entries;
1188         DOM_R_REF *ref = NULL;
1189         LSA_TRANSLATED_SID3 *trans_sids = NULL;
1190         uint32 mapped_count = 0;
1191         int flags = 0;
1192
1193         if (num_entries >  MAX_LOOKUP_SIDS) {
1194                 num_entries = MAX_LOOKUP_SIDS;
1195                 DEBUG(5,("_lsa_lookup_names3: truncating name lookup list to %d\n", num_entries));
1196         }
1197                 
1198         /* Probably the lookup_level is some sort of bitmask. */
1199         if (q_u->lookup_level == 1) {
1200                 flags = LOOKUP_NAME_ALL;
1201         }
1202
1203         ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
1204         trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_TRANSLATED_SID3, num_entries);
1205
1206         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
1207                 r_u->status = NT_STATUS_INVALID_HANDLE;
1208                 goto done;
1209         }
1210
1211         /* check if the user have enough rights */
1212         if (!(handle->access & POLICY_LOOKUP_NAMES)) {
1213                 r_u->status = NT_STATUS_ACCESS_DENIED;
1214                 goto done;
1215         }
1216
1217         if (!ref || !trans_sids) {
1218                 return NT_STATUS_NO_MEMORY;
1219         }
1220
1221         /* set up the LSA Lookup SIDs response */
1222         become_root(); /* lookup_name can require root privs */
1223         r_u->status = lookup_lsa_sids(p->mem_ctx, ref, trans_sids, num_entries,
1224                                       names, flags, &mapped_count);
1225         unbecome_root();
1226
1227 done:
1228
1229         if (NT_STATUS_IS_OK(r_u->status)) {
1230                 if (mapped_count == 0) {
1231                         r_u->status = NT_STATUS_NONE_MAPPED;
1232                 } else if (mapped_count != num_entries) {
1233                         r_u->status = STATUS_SOME_UNMAPPED;
1234                 }
1235         }
1236
1237         init_reply_lookup_names3(r_u, ref, num_entries, trans_sids, mapped_count);
1238         return r_u->status;
1239 }
1240
1241 /***************************************************************************
1242 lsa_reply_lookup_names4.
1243  ***************************************************************************/
1244
1245 NTSTATUS _lsa_lookup_names4(pipes_struct *p, LSA_Q_LOOKUP_NAMES4 *q_u, LSA_R_LOOKUP_NAMES4 *r_u)
1246 {
1247         UNISTR2 *names = q_u->uni_name;
1248         uint32 num_entries = q_u->num_entries;
1249         DOM_R_REF *ref = NULL;
1250         LSA_TRANSLATED_SID3 *trans_sids = NULL;
1251         uint32 mapped_count = 0;
1252         int flags = 0;
1253
1254         if (num_entries >  MAX_LOOKUP_SIDS) {
1255                 num_entries = MAX_LOOKUP_SIDS;
1256                 DEBUG(5,("_lsa_lookup_names4: truncating name lookup list to %d\n", num_entries));
1257         }
1258                 
1259         /* Probably the lookup_level is some sort of bitmask. */
1260         if (q_u->lookup_level == 1) {
1261                 flags = LOOKUP_NAME_ALL;
1262         }
1263
1264         /* No policy handle on this call. Restrict to crypto connections. */
1265         if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
1266                 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1267                         get_remote_machine_name() ));
1268                 return NT_STATUS_INVALID_PARAMETER;
1269         }
1270
1271         ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
1272         trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_TRANSLATED_SID3, num_entries);
1273
1274         if (!ref || !trans_sids) {
1275                 return NT_STATUS_NO_MEMORY;
1276         }
1277
1278         /* set up the LSA Lookup SIDs response */
1279         become_root(); /* lookup_name can require root privs */
1280         r_u->status = lookup_lsa_sids(p->mem_ctx, ref, trans_sids, num_entries,
1281                                       names, flags, &mapped_count);
1282         unbecome_root();
1283
1284         if (NT_STATUS_IS_OK(r_u->status)) {
1285                 if (mapped_count == 0) {
1286                         r_u->status = NT_STATUS_NONE_MAPPED;
1287                 } else if (mapped_count != num_entries) {
1288                         r_u->status = STATUS_SOME_UNMAPPED;
1289                 }
1290         }
1291
1292         init_reply_lookup_names4(r_u, ref, num_entries, trans_sids, mapped_count);
1293         return r_u->status;
1294 }
1295
1296 /***************************************************************************
1297  _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1298  ***************************************************************************/
1299
1300 NTSTATUS _lsa_close(pipes_struct *p, LSA_Q_CLOSE *q_u, LSA_R_CLOSE *r_u)
1301 {
1302         if (!find_policy_by_hnd(p, &q_u->pol, NULL)) {
1303                 return NT_STATUS_INVALID_HANDLE;
1304         }
1305
1306         close_policy_hnd(p, &q_u->pol);
1307         return NT_STATUS_OK;
1308 }
1309
1310 /***************************************************************************
1311  ***************************************************************************/
1312
1313 NTSTATUS _lsa_open_secret(pipes_struct *p, LSA_Q_OPEN_SECRET *q_u, LSA_R_OPEN_SECRET *r_u)
1314 {
1315         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1316 }
1317
1318 /***************************************************************************
1319  ***************************************************************************/
1320
1321 NTSTATUS _lsa_open_trusted_domain(pipes_struct *p, LSA_Q_OPEN_TRUSTED_DOMAIN *q_u, LSA_R_OPEN_TRUSTED_DOMAIN *r_u)
1322 {
1323         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1324 }
1325
1326 /***************************************************************************
1327  ***************************************************************************/
1328
1329 NTSTATUS _lsa_create_trusted_domain(pipes_struct *p, LSA_Q_CREATE_TRUSTED_DOMAIN *q_u, LSA_R_CREATE_TRUSTED_DOMAIN *r_u)
1330 {
1331         return NT_STATUS_ACCESS_DENIED;
1332 }
1333
1334 /***************************************************************************
1335  ***************************************************************************/
1336
1337 NTSTATUS _lsa_create_secret(pipes_struct *p, LSA_Q_CREATE_SECRET *q_u, LSA_R_CREATE_SECRET *r_u)
1338 {
1339         return NT_STATUS_ACCESS_DENIED;
1340 }
1341
1342 /***************************************************************************
1343  ***************************************************************************/
1344
1345 NTSTATUS _lsa_set_secret(pipes_struct *p, LSA_Q_SET_SECRET *q_u, LSA_R_SET_SECRET *r_u)
1346 {
1347         return NT_STATUS_ACCESS_DENIED;
1348 }
1349
1350 /***************************************************************************
1351  ***************************************************************************/
1352
1353 NTSTATUS _lsa_delete_object(pipes_struct *p, LSA_Q_DELETE_OBJECT *q_u, LSA_R_DELETE_OBJECT *r_u)
1354 {
1355         return NT_STATUS_ACCESS_DENIED;
1356 }
1357
1358 /***************************************************************************
1359 _lsa_enum_privs.
1360  ***************************************************************************/
1361
1362 NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIVS *r_u)
1363 {
1364         struct lsa_info *handle;
1365         uint32 i;
1366         uint32 enum_context = q_u->enum_context;
1367         int num_privs = count_all_privileges();
1368         LSA_PRIV_ENTRY *entries = NULL;
1369         LUID_ATTR luid;
1370
1371         /* remember that the enum_context starts at 0 and not 1 */
1372
1373         if ( enum_context >= num_privs )
1374                 return NT_STATUS_NO_MORE_ENTRIES;
1375                 
1376         DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n", 
1377                 enum_context, num_privs));
1378         
1379         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1380                 return NT_STATUS_INVALID_HANDLE;
1381
1382         /* check if the user have enough rights
1383            I don't know if it's the right one. not documented.  */
1384
1385         if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
1386                 return NT_STATUS_ACCESS_DENIED;
1387
1388         if ( !(entries = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_PRIV_ENTRY, num_privs )) )
1389                 return NT_STATUS_NO_MEMORY;
1390
1391         for (i = 0; i < num_privs; i++) {
1392                 if( i < enum_context) {
1393                         init_unistr2(&entries[i].name, NULL, UNI_FLAGS_NONE);
1394                         init_uni_hdr(&entries[i].hdr_name, &entries[i].name);
1395                         
1396                         entries[i].luid_low = 0;
1397                         entries[i].luid_high = 0;
1398                 } else {
1399                         init_unistr2(&entries[i].name, privs[i].name, UNI_FLAGS_NONE);
1400                         init_uni_hdr(&entries[i].hdr_name, &entries[i].name);
1401                         
1402                         luid = get_privilege_luid( &privs[i].se_priv );
1403                         
1404                         entries[i].luid_low = luid.luid.low;
1405                         entries[i].luid_high = luid.luid.high;
1406                 }
1407         }
1408
1409         enum_context = num_privs;
1410         
1411         init_lsa_r_enum_privs(r_u, enum_context, num_privs, entries);
1412
1413         return NT_STATUS_OK;
1414 }
1415
1416 /***************************************************************************
1417 _lsa_priv_get_dispname.
1418  ***************************************************************************/
1419
1420 NTSTATUS _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, LSA_R_PRIV_GET_DISPNAME *r_u)
1421 {
1422         struct lsa_info *handle;
1423         fstring name_asc;
1424         const char *description;
1425
1426         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1427                 return NT_STATUS_INVALID_HANDLE;
1428
1429         /* check if the user have enough rights */
1430
1431         /*
1432          * I don't know if it's the right one. not documented.
1433          */
1434         if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
1435                 return NT_STATUS_ACCESS_DENIED;
1436
1437         unistr2_to_ascii(name_asc, &q_u->name, sizeof(name_asc));
1438
1439         DEBUG(10,("_lsa_priv_get_dispname: name = %s\n", name_asc));
1440
1441         description = get_privilege_dispname( name_asc );
1442         
1443         if ( description ) {
1444                 DEBUG(10,("_lsa_priv_get_dispname: display name = %s\n", description));
1445                 
1446                 init_unistr2(&r_u->desc, description, UNI_FLAGS_NONE);
1447                 init_uni_hdr(&r_u->hdr_desc, &r_u->desc);
1448
1449                 r_u->ptr_info = 0xdeadbeef;
1450                 r_u->lang_id = q_u->lang_id;
1451                 
1452                 return NT_STATUS_OK;
1453         } else {
1454                 DEBUG(10,("_lsa_priv_get_dispname: doesn't exist\n"));
1455                 
1456                 r_u->ptr_info = 0;
1457                 
1458                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1459         }
1460 }
1461
1462 /***************************************************************************
1463 _lsa_enum_accounts.
1464  ***************************************************************************/
1465
1466 NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENUM_ACCOUNTS *r_u)
1467 {
1468         struct lsa_info *handle;
1469         DOM_SID *sid_list;
1470         int i, j, num_entries;
1471         LSA_SID_ENUM *sids=&r_u->sids;
1472         NTSTATUS ret;
1473
1474         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1475                 return NT_STATUS_INVALID_HANDLE;
1476
1477         if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
1478                 return NT_STATUS_ACCESS_DENIED;
1479
1480         sid_list = NULL;
1481         num_entries = 0;
1482
1483         /* The only way we can currently find out all the SIDs that have been
1484            privileged is to scan all privileges */
1485
1486         if (!NT_STATUS_IS_OK(ret = privilege_enumerate_accounts(&sid_list, &num_entries))) {
1487                 return ret;
1488         }
1489
1490         if (q_u->enum_context >= num_entries)
1491                 return NT_STATUS_NO_MORE_ENTRIES;
1492
1493         sids->ptr_sid = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_entries-q_u->enum_context);
1494         sids->sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_entries-q_u->enum_context);
1495
1496         if (sids->ptr_sid==NULL || sids->sid==NULL) {
1497                 SAFE_FREE(sid_list);
1498                 return NT_STATUS_NO_MEMORY;
1499         }
1500
1501         for (i = q_u->enum_context, j = 0; i < num_entries; i++, j++) {
1502                 init_dom_sid2(&(*sids).sid[j], &sid_list[i]);
1503                 (*sids).ptr_sid[j] = 1;
1504         }
1505
1506         SAFE_FREE(sid_list);
1507
1508         init_lsa_r_enum_accounts(r_u, num_entries);
1509
1510         return NT_STATUS_OK;
1511 }
1512
1513
1514 NTSTATUS _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u)
1515 {
1516         const char *username, *domname;
1517         user_struct *vuser = get_valid_user_struct(p->vuid);
1518   
1519         if (vuser == NULL)
1520                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1521
1522         if (vuser->guest) {
1523                 /*
1524                  * I'm 99% sure this is not the right place to do this,
1525                  * global_sid_Anonymous should probably be put into the token
1526                  * instead of the guest id -- vl
1527                  */
1528                 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
1529                                 &domname, &username, NULL)) {
1530                         return NT_STATUS_NO_MEMORY;
1531                 }
1532         } else {
1533                 username = vuser->user.smb_name;
1534                 domname = vuser->user.domain;
1535         }
1536   
1537         r_u->ptr_user_name = 1;
1538         init_unistr2(&r_u->uni2_user_name, username, UNI_STR_TERMINATE);
1539         init_uni_hdr(&r_u->hdr_user_name, &r_u->uni2_user_name);
1540
1541         r_u->unk1 = 1;
1542   
1543         r_u->ptr_dom_name = 1;
1544         init_unistr2(&r_u->uni2_dom_name, domname,  UNI_STR_TERMINATE);
1545         init_uni_hdr(&r_u->hdr_dom_name, &r_u->uni2_dom_name);
1546
1547         r_u->status = NT_STATUS_OK;
1548   
1549         return r_u->status;
1550 }
1551
1552 /***************************************************************************
1553  Lsa Create Account 
1554  ***************************************************************************/
1555
1556 NTSTATUS _lsa_create_account(pipes_struct *p, LSA_Q_CREATEACCOUNT *q_u, LSA_R_CREATEACCOUNT *r_u)
1557 {
1558         struct lsa_info *handle;
1559         struct lsa_info *info;
1560
1561         /* find the connection policy handle. */
1562         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1563                 return NT_STATUS_INVALID_HANDLE;
1564
1565         /* check if the user have enough rights */
1566
1567         /*
1568          * I don't know if it's the right one. not documented.
1569          * but guessed with rpcclient.
1570          */
1571         if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION)) {
1572                 DEBUG(10, ("_lsa_create_account: No POLICY_GET_PRIVATE_INFORMATION access right!\n"));
1573                 return NT_STATUS_ACCESS_DENIED;
1574         }
1575
1576         /* check to see if the pipe_user is a Domain Admin since 
1577            account_pol.tdb was already opened as root, this is all we have */
1578            
1579         if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) {
1580                 DEBUG(10, ("_lsa_create_account: The use is not a Domain Admin, deny access!\n"));
1581                 return NT_STATUS_ACCESS_DENIED;
1582         }
1583                 
1584         if ( is_privileged_sid( &q_u->sid.sid ) ) {
1585                 DEBUG(10, ("_lsa_create_account: Policy account already exists!\n"));
1586                 return NT_STATUS_OBJECT_NAME_COLLISION;
1587         }
1588
1589         /* associate the user/group SID with the (unique) handle. */
1590         
1591         if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
1592                 return NT_STATUS_NO_MEMORY;
1593
1594         ZERO_STRUCTP(info);
1595         info->sid = q_u->sid.sid;
1596         info->access = q_u->access;
1597
1598         /* get a (unique) handle.  open a policy on it. */
1599         if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
1600                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1601
1602         DEBUG(10, ("_lsa_create_account: call privileges code to create an account\n"));
1603         return privilege_create_account( &info->sid );
1604 }
1605
1606
1607 /***************************************************************************
1608  Lsa Open Account
1609  ***************************************************************************/
1610
1611 NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENACCOUNT *r_u)
1612 {
1613         struct lsa_info *handle;
1614         struct lsa_info *info;
1615
1616         /* find the connection policy handle. */
1617         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1618                 return NT_STATUS_INVALID_HANDLE;
1619
1620         /* check if the user have enough rights */
1621
1622         /*
1623          * I don't know if it's the right one. not documented.
1624          * but guessed with rpcclient.
1625          */
1626         if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION))
1627                 return NT_STATUS_ACCESS_DENIED;
1628
1629         /* TODO: Fis the parsing routine before reenabling this check! */
1630         #if 0
1631         if (!lookup_sid(&handle->sid, dom_name, name, &type))
1632                 return NT_STATUS_ACCESS_DENIED;
1633         #endif
1634         /* associate the user/group SID with the (unique) handle. */
1635         if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
1636                 return NT_STATUS_NO_MEMORY;
1637
1638         ZERO_STRUCTP(info);
1639         info->sid = q_u->sid.sid;
1640         info->access = q_u->access;
1641
1642         /* get a (unique) handle.  open a policy on it. */
1643         if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
1644                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1645
1646         return NT_STATUS_OK;
1647 }
1648
1649 /***************************************************************************
1650  For a given SID, enumerate all the privilege this account has.
1651  ***************************************************************************/
1652
1653 NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVSACCOUNT *q_u, LSA_R_ENUMPRIVSACCOUNT *r_u)
1654 {
1655         struct lsa_info *info=NULL;
1656         SE_PRIV mask;
1657         PRIVILEGE_SET privileges;
1658
1659         /* find the connection policy handle. */
1660         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1661                 return NT_STATUS_INVALID_HANDLE;
1662
1663         if ( !get_privileges_for_sids( &mask, &info->sid, 1 ) ) 
1664                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1665
1666         privilege_set_init( &privileges );
1667
1668         if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
1669
1670                 DEBUG(10,("_lsa_enum_privsaccount: %s has %d privileges\n", 
1671                         sid_string_static(&info->sid), privileges.count));
1672
1673                 r_u->status = init_lsa_r_enum_privsaccount(ps->mem_ctx, r_u, privileges.set, privileges.count, 0);
1674         }
1675         else
1676                 r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE;
1677
1678         privilege_set_free( &privileges );
1679
1680         return r_u->status;
1681 }
1682
1683 /***************************************************************************
1684  
1685  ***************************************************************************/
1686
1687 NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA_R_GETSYSTEMACCOUNT *r_u)
1688 {
1689         struct lsa_info *info=NULL;
1690
1691         /* find the connection policy handle. */
1692
1693         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1694                 return NT_STATUS_INVALID_HANDLE;
1695
1696         if (!lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, NULL))
1697                 return NT_STATUS_OK;
1698
1699         /*
1700           0x01 -> Log on locally
1701           0x02 -> Access this computer from network
1702           0x04 -> Log on as a batch job
1703           0x10 -> Log on as a service
1704           
1705           they can be ORed together
1706         */
1707
1708         r_u->access = PR_LOG_ON_LOCALLY | PR_ACCESS_FROM_NETWORK;
1709
1710         return NT_STATUS_OK;
1711 }
1712
1713 /***************************************************************************
1714   update the systemaccount information
1715  ***************************************************************************/
1716
1717 NTSTATUS _lsa_setsystemaccount(pipes_struct *p, LSA_Q_SETSYSTEMACCOUNT *q_u, LSA_R_SETSYSTEMACCOUNT *r_u)
1718 {
1719         struct lsa_info *info=NULL;
1720         GROUP_MAP map;
1721         r_u->status = NT_STATUS_OK;
1722
1723         /* find the connection policy handle. */
1724         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1725                 return NT_STATUS_INVALID_HANDLE;
1726
1727         /* check to see if the pipe_user is a Domain Admin since 
1728            account_pol.tdb was already opened as root, this is all we have */
1729            
1730         if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1731                 return NT_STATUS_ACCESS_DENIED;
1732
1733         if (!NT_STATUS_IS_OK(pdb_getgrsid(&map, &info->sid)))
1734                 return NT_STATUS_NO_SUCH_GROUP;
1735
1736         return pdb_update_group_mapping_entry(&map);
1737 }
1738
1739 /***************************************************************************
1740  For a given SID, add some privileges.
1741  ***************************************************************************/
1742
1743 NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u)
1744 {
1745         struct lsa_info *info = NULL;
1746         SE_PRIV mask;
1747         PRIVILEGE_SET *set = NULL;
1748
1749         /* find the connection policy handle. */
1750         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1751                 return NT_STATUS_INVALID_HANDLE;
1752                 
1753         /* check to see if the pipe_user is root or a Domain Admin since 
1754            account_pol.tdb was already opened as root, this is all we have */
1755            
1756         if ( p->pipe_user.ut.uid != sec_initial_uid() 
1757                 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1758         {
1759                 return NT_STATUS_ACCESS_DENIED;
1760         }
1761
1762         set = &q_u->set;
1763
1764         if ( !privilege_set_to_se_priv( &mask, set ) )
1765                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1766
1767         if ( !grant_privilege( &info->sid, &mask ) ) {
1768                 DEBUG(3,("_lsa_addprivs: grant_privilege(%s) failed!\n",
1769                         sid_string_static(&info->sid) ));
1770                 DEBUG(3,("Privilege mask:\n"));
1771                 dump_se_priv( DBGC_ALL, 3, &mask );
1772                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1773         }
1774
1775         return NT_STATUS_OK;
1776 }
1777
1778 /***************************************************************************
1779  For a given SID, remove some privileges.
1780  ***************************************************************************/
1781
1782 NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEPRIVS *r_u)
1783 {
1784         struct lsa_info *info = NULL;
1785         SE_PRIV mask;
1786         PRIVILEGE_SET *set = NULL;
1787
1788         /* find the connection policy handle. */
1789         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1790                 return NT_STATUS_INVALID_HANDLE;
1791
1792         /* check to see if the pipe_user is root or a Domain Admin since 
1793            account_pol.tdb was already opened as root, this is all we have */
1794            
1795         if ( p->pipe_user.ut.uid != sec_initial_uid()
1796                 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) 
1797         {
1798                 return NT_STATUS_ACCESS_DENIED;
1799         }
1800
1801         set = &q_u->set;
1802
1803         if ( !privilege_set_to_se_priv( &mask, set ) )
1804                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1805
1806         if ( !revoke_privilege( &info->sid, &mask ) ) {
1807                 DEBUG(3,("_lsa_removeprivs: revoke_privilege(%s) failed!\n",
1808                         sid_string_static(&info->sid) ));
1809                 DEBUG(3,("Privilege mask:\n"));
1810                 dump_se_priv( DBGC_ALL, 3, &mask );
1811                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1812         }
1813
1814         return NT_STATUS_OK;
1815 }
1816
1817 /***************************************************************************
1818  For a given SID, remove some privileges.
1819  ***************************************************************************/
1820
1821 NTSTATUS _lsa_query_secobj(pipes_struct *p, LSA_Q_QUERY_SEC_OBJ *q_u, LSA_R_QUERY_SEC_OBJ *r_u)
1822 {
1823         struct lsa_info *handle=NULL;
1824         SEC_DESC *psd = NULL;
1825         size_t sd_size;
1826         NTSTATUS status;
1827
1828         r_u->status = NT_STATUS_OK;
1829
1830         /* find the connection policy handle. */
1831         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1832                 return NT_STATUS_INVALID_HANDLE;
1833
1834         /* check if the user have enough rights */
1835         if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
1836                 return NT_STATUS_ACCESS_DENIED;
1837
1838
1839         switch (q_u->sec_info) {
1840         case 1:
1841                 /* SD contains only the owner */
1842
1843                 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
1844                 if(!NT_STATUS_IS_OK(status))
1845                         return NT_STATUS_NO_MEMORY;
1846
1847
1848                 if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1849                         return NT_STATUS_NO_MEMORY;
1850                 break;
1851         case 4:
1852                 /* SD contains only the ACL */
1853
1854                 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
1855                 if(!NT_STATUS_IS_OK(status))
1856                         return NT_STATUS_NO_MEMORY;
1857
1858                 if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1859                         return NT_STATUS_NO_MEMORY;
1860                 break;
1861         default:
1862                 return NT_STATUS_INVALID_LEVEL;
1863         }
1864
1865         r_u->ptr=1;
1866
1867         return r_u->status;
1868 }
1869
1870 #if 0   /* AD DC work in ongoing in Samba 4 */
1871
1872 /***************************************************************************
1873  ***************************************************************************/
1874
1875 NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_INFO2 *r_u)
1876 {
1877         struct lsa_info *handle;
1878         const char *nb_name;
1879         char *dns_name = NULL;
1880         char *forest_name = NULL;
1881         DOM_SID *sid = NULL;
1882         struct uuid guid;
1883         fstring dnsdomname;
1884
1885         ZERO_STRUCT(guid);
1886         r_u->status = NT_STATUS_OK;
1887
1888         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1889                 return NT_STATUS_INVALID_HANDLE;
1890
1891         switch (q_u->info_class) {
1892         case 0x0c:
1893                 /* check if the user have enough rights */
1894                 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
1895                         return NT_STATUS_ACCESS_DENIED;
1896
1897                 /* Request PolicyPrimaryDomainInformation. */
1898                 switch (lp_server_role()) {
1899                         case ROLE_DOMAIN_PDC:
1900                         case ROLE_DOMAIN_BDC:
1901                                 nb_name = get_global_sam_name();
1902                                 /* ugly temp hack for these next two */
1903
1904                                 /* This should be a 'netbios domain -> DNS domain' mapping */
1905                                 dnsdomname[0] = '\0';
1906                                 get_mydnsdomname(dnsdomname);
1907                                 strlower_m(dnsdomname);
1908                                 
1909                                 dns_name = dnsdomname;
1910                                 forest_name = dnsdomname;
1911
1912                                 sid = get_global_sam_sid();
1913                                 secrets_fetch_domain_guid(lp_workgroup(), &guid);
1914                                 break;
1915                         default:
1916                                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1917                 }
1918                 init_dns_dom_info(&r_u->info.dns_dom_info, nb_name, dns_name, 
1919                                   forest_name,&guid,sid);
1920                 break;
1921         default:
1922                 DEBUG(0,("_lsa_query_info2: unknown info level in Lsa Query: %d\n", q_u->info_class));
1923                 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
1924                 break;
1925         }
1926
1927         if (NT_STATUS_IS_OK(r_u->status)) {
1928                 r_u->ptr = 0x1;
1929                 r_u->info_class = q_u->info_class;
1930         }
1931
1932         return r_u->status;
1933 }
1934 #endif  /* AD DC work in ongoing in Samba 4 */
1935
1936 /***************************************************************************
1937  ***************************************************************************/
1938
1939 NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R_ADD_ACCT_RIGHTS *r_u)
1940 {
1941         struct lsa_info *info = NULL;
1942         int i = 0;
1943         DOM_SID sid;
1944         fstring privname;
1945         UNISTR4_ARRAY *uni_privnames = q_u->rights;
1946         
1947
1948         /* find the connection policy handle. */
1949         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1950                 return NT_STATUS_INVALID_HANDLE;
1951                 
1952         /* check to see if the pipe_user is a Domain Admin since 
1953            account_pol.tdb was already opened as root, this is all we have */
1954            
1955         if ( p->pipe_user.ut.uid != sec_initial_uid()
1956                 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) 
1957         {
1958                 return NT_STATUS_ACCESS_DENIED;
1959         }
1960
1961         /* according to an NT4 PDC, you can add privileges to SIDs even without
1962            call_lsa_create_account() first.  And you can use any arbitrary SID. */
1963            
1964         sid_copy( &sid, &q_u->sid.sid );
1965         
1966         /* just a little sanity check */
1967         
1968         if ( q_u->count != uni_privnames->count ) {
1969                 DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n"));
1970                 return NT_STATUS_INVALID_HANDLE;        
1971         }
1972                 
1973         for ( i=0; i<q_u->count; i++ ) {
1974                 UNISTR4 *uni4_str = &uni_privnames->strings[i];
1975
1976                 /* only try to add non-null strings */
1977
1978                 if ( !uni4_str->string )
1979                         continue;
1980
1981                 rpcstr_pull( privname, uni4_str->string->buffer, sizeof(privname), -1, STR_TERMINATE );
1982                 
1983                 if ( !grant_privilege_by_name( &sid, privname ) ) {
1984                         DEBUG(2,("_lsa_add_acct_rights: Failed to add privilege [%s]\n", privname ));
1985                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1986                 }
1987         }
1988
1989         return NT_STATUS_OK;
1990 }
1991
1992 /***************************************************************************
1993  ***************************************************************************/
1994
1995 NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u, LSA_R_REMOVE_ACCT_RIGHTS *r_u)
1996 {
1997         struct lsa_info *info = NULL;
1998         int i = 0;
1999         DOM_SID sid;
2000         fstring privname;
2001         UNISTR4_ARRAY *uni_privnames = q_u->rights;
2002         
2003
2004         /* find the connection policy handle. */
2005         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
2006                 return NT_STATUS_INVALID_HANDLE;
2007                 
2008         /* check to see if the pipe_user is a Domain Admin since 
2009            account_pol.tdb was already opened as root, this is all we have */
2010            
2011         if ( p->pipe_user.ut.uid != sec_initial_uid()
2012                 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
2013         {
2014                 return NT_STATUS_ACCESS_DENIED;
2015         }
2016
2017         sid_copy( &sid, &q_u->sid.sid );
2018
2019         if ( q_u->removeall ) {
2020                 if ( !revoke_all_privileges( &sid ) ) 
2021                         return NT_STATUS_ACCESS_DENIED;
2022         
2023                 return NT_STATUS_OK;
2024         }
2025         
2026         /* just a little sanity check */
2027         
2028         if ( q_u->count != uni_privnames->count ) {
2029                 DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n"));
2030                 return NT_STATUS_INVALID_HANDLE;        
2031         }
2032                 
2033         for ( i=0; i<q_u->count; i++ ) {
2034                 UNISTR4 *uni4_str = &uni_privnames->strings[i];
2035
2036                 /* only try to add non-null strings */
2037
2038                 if ( !uni4_str->string )
2039                         continue;
2040
2041                 rpcstr_pull( privname, uni4_str->string->buffer, sizeof(privname), -1, STR_TERMINATE );
2042                 
2043                 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2044                         DEBUG(2,("_lsa_remove_acct_rights: Failed to revoke privilege [%s]\n", privname ));
2045                         return NT_STATUS_NO_SUCH_PRIVILEGE;
2046                 }
2047         }
2048
2049         return NT_STATUS_OK;
2050 }
2051
2052
2053 /***************************************************************************
2054  ***************************************************************************/
2055
2056 NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA_R_ENUM_ACCT_RIGHTS *r_u)
2057 {
2058         struct lsa_info *info = NULL;
2059         DOM_SID sid;
2060         PRIVILEGE_SET privileges;
2061         SE_PRIV mask;
2062         
2063
2064         /* find the connection policy handle. */
2065         
2066         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
2067                 return NT_STATUS_INVALID_HANDLE;
2068                 
2069         /* according to an NT4 PDC, you can add privileges to SIDs even without
2070            call_lsa_create_account() first.  And you can use any arbitrary SID. */
2071            
2072         sid_copy( &sid, &q_u->sid.sid );
2073         
2074         if ( !get_privileges_for_sids( &mask, &sid, 1 ) )
2075                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2076
2077         privilege_set_init( &privileges );
2078
2079         if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
2080
2081                 DEBUG(10,("_lsa_enum_acct_rights: %s has %d privileges\n", 
2082                         sid_string_static(&sid), privileges.count));
2083
2084                 r_u->status = init_r_enum_acct_rights( r_u, &privileges );
2085         }
2086         else 
2087                 r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE;
2088
2089         privilege_set_free( &privileges );
2090
2091         return r_u->status;
2092 }
2093
2094
2095 /***************************************************************************
2096  ***************************************************************************/
2097
2098 NTSTATUS _lsa_lookup_priv_value(pipes_struct *p, LSA_Q_LOOKUP_PRIV_VALUE *q_u, LSA_R_LOOKUP_PRIV_VALUE *r_u)
2099 {
2100         struct lsa_info *info = NULL;
2101         fstring name;
2102         LUID_ATTR priv_luid;
2103         SE_PRIV mask;
2104         
2105         /* find the connection policy handle. */
2106         
2107         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
2108                 return NT_STATUS_INVALID_HANDLE;
2109                 
2110         unistr2_to_ascii(name, &q_u->privname.unistring, sizeof(name));
2111         
2112         DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
2113
2114         if ( !se_priv_from_name( name, &mask ) )
2115                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2116
2117         priv_luid = get_privilege_luid( &mask );
2118
2119         r_u->luid.low  = priv_luid.luid.low;
2120         r_u->luid.high = priv_luid.luid.high;
2121                 
2122
2123         return NT_STATUS_OK;
2124 }