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