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