r6334: revert 3.0.15pre1 changes. roll back to 3.0.14.
[Samba.git] / source / rpc_server / srv_lsa_nt.c
blob7ea35a91faf35845f552a9ff73fd2b1fe8872d1b
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Jeremy Allison 2001,
8 * Copyright (C) Rafal Szczesniak 2002,
9 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
10 * Copyright (C) Simo Sorce 2003.
11 * Copyright (C) Gerald (Jerry) Carter 2005.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 /* This is the implementation of the lsa server code. */
30 #include "includes.h"
32 #undef DBGC_CLASS
33 #define DBGC_CLASS DBGC_RPC_SRV
35 extern PRIVS privs[];
37 struct lsa_info {
38 DOM_SID sid;
39 uint32 access;
42 struct generic_mapping lsa_generic_mapping = {
43 POLICY_READ,
44 POLICY_WRITE,
45 POLICY_EXECUTE,
46 POLICY_ALL_ACCESS
49 /*******************************************************************
50 Function to free the per handle data.
51 ********************************************************************/
53 static void free_lsa_info(void *ptr)
55 struct lsa_info *lsa = (struct lsa_info *)ptr;
57 SAFE_FREE(lsa);
60 /***************************************************************************
61 Init dom_query
62 ***************************************************************************/
64 static void init_dom_query(DOM_QUERY *d_q, const char *dom_name, DOM_SID *dom_sid)
66 d_q->buffer_dom_name = (dom_name != NULL) ? 1 : 0; /* domain buffer pointer */
67 d_q->buffer_dom_sid = (dom_sid != NULL) ? 1 : 0; /* domain sid pointer */
69 /* this string is supposed to be non-null terminated. */
70 /* But the maxlen in this UNISTR2 must include the terminating null. */
71 init_unistr2(&d_q->uni_domain_name, dom_name, UNI_BROKEN_NON_NULL);
74 * I'm not sure why this really odd combination of length
75 * values works, but it does appear to. I need to look at
76 * this *much* more closely - but at the moment leave alone
77 * until it's understood. This allows a W2k client to join
78 * a domain with both odd and even length names... JRA.
82 * IMPORTANT NOTE !!!!
83 * The two fields below probably are reversed in meaning, ie.
84 * the first field is probably the str_len, the second the max
85 * len. Both are measured in bytes anyway.
88 d_q->uni_dom_str_len = d_q->uni_domain_name.uni_max_len * 2;
89 d_q->uni_dom_max_len = d_q->uni_domain_name.uni_str_len * 2;
91 if (dom_sid != NULL)
92 init_dom_sid2(&d_q->dom_sid, dom_sid);
95 /***************************************************************************
96 init_dom_ref - adds a domain if it's not already in, returns the index.
97 ***************************************************************************/
99 static int init_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
101 int num = 0;
103 if (dom_name != NULL) {
104 for (num = 0; num < ref->num_ref_doms_1; num++) {
105 fstring domname;
106 rpcstr_pull(domname, ref->ref_dom[num].uni_dom_name.buffer, sizeof(domname), -1, 0);
107 if (strequal(domname, dom_name))
108 return num;
110 } else {
111 num = ref->num_ref_doms_1;
114 if (num >= MAX_REF_DOMAINS) {
115 /* index not found, already at maximum domain limit */
116 return -1;
119 ref->num_ref_doms_1 = num+1;
120 ref->ptr_ref_dom = 1;
121 ref->max_entries = MAX_REF_DOMAINS;
122 ref->num_ref_doms_2 = num+1;
124 ref->hdr_ref_dom[num].ptr_dom_sid = dom_sid != NULL ? 1 : 0;
126 init_unistr2(&ref->ref_dom[num].uni_dom_name, dom_name, UNI_FLAGS_NONE);
127 init_uni_hdr(&ref->hdr_ref_dom[num].hdr_dom_name, &ref->ref_dom[num].uni_dom_name);
129 init_dom_sid2(&ref->ref_dom[num].ref_dom, dom_sid );
131 return num;
134 /***************************************************************************
135 init_lsa_rid2s
136 ***************************************************************************/
138 static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2,
139 int num_entries, UNISTR2 *name,
140 uint32 *mapped_count, BOOL endian)
142 int i;
143 int total = 0;
144 *mapped_count = 0;
146 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
148 become_root(); /* lookup_name can require root privs */
150 for (i = 0; i < num_entries; i++) {
151 BOOL status = False;
152 DOM_SID sid;
153 uint32 rid = 0xffffffff;
154 int dom_idx = -1;
155 pstring full_name;
156 fstring dom_name, user;
157 enum SID_NAME_USE name_type = SID_NAME_UNKNOWN;
159 /* Split name into domain and user component */
161 unistr2_to_ascii(full_name, &name[i], sizeof(full_name));
162 split_domain_name(full_name, dom_name, user);
164 /* Lookup name */
166 DEBUG(5, ("init_lsa_rid2s: looking up name %s\n", full_name));
168 status = lookup_name(dom_name, user, &sid, &name_type);
170 if((name_type == SID_NAME_UNKNOWN) && (lp_server_role() == ROLE_DOMAIN_MEMBER) && (strncmp(dom_name, full_name, strlen(dom_name)) != 0)) {
171 DEBUG(5, ("init_lsa_rid2s: domain name not provided and local account not found, using member domain\n"));
172 fstrcpy(dom_name, lp_workgroup());
173 status = lookup_name(dom_name, user, &sid, &name_type);
176 #if 0 /* This is not true. */
177 if (name_type == SID_NAME_WKN_GRP) {
178 /* BUILTIN aliases are still aliases :-) */
179 name_type = SID_NAME_ALIAS;
181 #endif
183 DEBUG(5, ("init_lsa_rid2s: %s\n", status ? "found" :
184 "not found"));
186 if (status && name_type != SID_NAME_UNKNOWN) {
187 sid_split_rid(&sid, &rid);
188 dom_idx = init_dom_ref(ref, dom_name, &sid);
189 (*mapped_count)++;
190 } else {
191 dom_idx = -1;
192 rid = 0;
193 name_type = SID_NAME_UNKNOWN;
196 init_dom_rid2(&rid2[total], rid, name_type, dom_idx);
197 total++;
200 unbecome_root();
203 /***************************************************************************
204 init_reply_lookup_names
205 ***************************************************************************/
207 static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
208 DOM_R_REF *ref, uint32 num_entries,
209 DOM_RID2 *rid2, uint32 mapped_count)
211 r_l->ptr_dom_ref = 1;
212 r_l->dom_ref = ref;
214 r_l->num_entries = num_entries;
215 r_l->ptr_entries = 1;
216 r_l->num_entries2 = num_entries;
217 r_l->dom_rid = rid2;
219 r_l->mapped_count = mapped_count;
222 /***************************************************************************
223 Init lsa_trans_names.
224 ***************************************************************************/
226 static void init_lsa_trans_names(TALLOC_CTX *ctx, DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *trn,
227 int num_entries, DOM_SID2 *sid,
228 uint32 *mapped_count)
230 int i;
231 int total = 0;
232 *mapped_count = 0;
234 /* Allocate memory for list of names */
236 if (num_entries > 0) {
237 if (!(trn->name = TALLOC_ARRAY(ctx, LSA_TRANS_NAME, num_entries))) {
238 DEBUG(0, ("init_lsa_trans_names(): out of memory\n"));
239 return;
242 if (!(trn->uni_name = TALLOC_ARRAY(ctx, UNISTR2, num_entries))) {
243 DEBUG(0, ("init_lsa_trans_names(): out of memory\n"));
244 return;
248 become_root(); /* Need root to get to passdb to for local sids */
250 for (i = 0; i < num_entries; i++) {
251 BOOL status = False;
252 DOM_SID find_sid = sid[i].sid;
253 uint32 rid = 0xffffffff;
254 int dom_idx = -1;
255 fstring name, dom_name;
256 enum SID_NAME_USE sid_name_use = (enum SID_NAME_USE)0;
258 sid_to_string(name, &find_sid);
259 DEBUG(5, ("init_lsa_trans_names: looking up sid %s\n", name));
261 /* Lookup sid from winbindd */
263 status = lookup_sid(&find_sid, dom_name, name, &sid_name_use);
265 DEBUG(5, ("init_lsa_trans_names: %s\n", status ? "found" :
266 "not found"));
268 if (!status) {
269 sid_name_use = SID_NAME_UNKNOWN;
270 memset(dom_name, '\0', sizeof(dom_name));
271 sid_to_string(name, &find_sid);
272 dom_idx = -1;
274 DEBUG(10,("init_lsa_trans_names: added unknown user '%s' to "
275 "referenced list.\n", name ));
276 } else {
277 (*mapped_count)++;
278 /* Store domain sid in ref array */
279 if (find_sid.num_auths == 5) {
280 sid_split_rid(&find_sid, &rid);
282 dom_idx = init_dom_ref(ref, dom_name, &find_sid);
284 DEBUG(10,("init_lsa_trans_names: added %s '%s\\%s' (%d) to referenced list.\n",
285 sid_type_lookup(sid_name_use), dom_name, name, sid_name_use ));
289 init_lsa_trans_name(&trn->name[total], &trn->uni_name[total],
290 sid_name_use, name, dom_idx);
291 total++;
294 unbecome_root();
296 trn->num_entries = total;
297 trn->ptr_trans_names = 1;
298 trn->num_entries2 = total;
301 /***************************************************************************
302 Init_reply_lookup_sids.
303 ***************************************************************************/
305 static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
306 DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *names,
307 uint32 mapped_count)
309 r_l->ptr_dom_ref = 1;
310 r_l->dom_ref = ref;
311 r_l->names = names;
312 r_l->mapped_count = mapped_count;
315 static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size)
317 extern DOM_SID global_sid_World;
318 extern DOM_SID global_sid_Builtin;
319 DOM_SID local_adm_sid;
320 DOM_SID adm_sid;
322 SEC_ACE ace[3];
323 SEC_ACCESS mask;
325 SEC_ACL *psa = NULL;
327 init_sec_access(&mask, POLICY_EXECUTE);
328 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
330 sid_copy(&adm_sid, get_global_sam_sid());
331 sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS);
332 init_sec_access(&mask, POLICY_ALL_ACCESS);
333 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
335 sid_copy(&local_adm_sid, &global_sid_Builtin);
336 sid_append_rid(&local_adm_sid, BUILTIN_ALIAS_RID_ADMINS);
337 init_sec_access(&mask, POLICY_ALL_ACCESS);
338 init_sec_ace(&ace[2], &local_adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
340 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
341 return NT_STATUS_NO_MEMORY;
343 if((*sd = make_sec_desc(mem_ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL, psa, sd_size)) == NULL)
344 return NT_STATUS_NO_MEMORY;
346 return NT_STATUS_OK;
349 #if 0 /* AD DC work in ongoing in Samba 4 */
351 /***************************************************************************
352 Init_dns_dom_info.
353 ***************************************************************************/
355 static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name,
356 const char *dns_name, const char *forest_name,
357 struct uuid *dom_guid, DOM_SID *dom_sid)
359 if (nb_name && *nb_name) {
360 init_unistr2(&r_l->uni_nb_dom_name, nb_name, UNI_FLAGS_NONE);
361 init_uni_hdr(&r_l->hdr_nb_dom_name, &r_l->uni_nb_dom_name);
362 r_l->hdr_nb_dom_name.uni_max_len += 2;
363 r_l->uni_nb_dom_name.uni_max_len += 1;
366 if (dns_name && *dns_name) {
367 init_unistr2(&r_l->uni_dns_dom_name, dns_name, UNI_FLAGS_NONE);
368 init_uni_hdr(&r_l->hdr_dns_dom_name, &r_l->uni_dns_dom_name);
369 r_l->hdr_dns_dom_name.uni_max_len += 2;
370 r_l->uni_dns_dom_name.uni_max_len += 1;
373 if (forest_name && *forest_name) {
374 init_unistr2(&r_l->uni_forest_name, forest_name, UNI_FLAGS_NONE);
375 init_uni_hdr(&r_l->hdr_forest_name, &r_l->uni_forest_name);
376 r_l->hdr_forest_name.uni_max_len += 2;
377 r_l->uni_forest_name.uni_max_len += 1;
380 /* how do we init the guid ? probably should write an init fn */
381 if (dom_guid) {
382 memcpy(&r_l->dom_guid, dom_guid, sizeof(struct uuid));
385 if (dom_sid) {
386 r_l->ptr_dom_sid = 1;
387 init_dom_sid2(&r_l->dom_sid, dom_sid);
390 #endif /* AD DC work in ongoing in Samba 4 */
393 /***************************************************************************
394 _lsa_open_policy2.
395 ***************************************************************************/
397 NTSTATUS _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL2 *r_u)
399 struct lsa_info *info;
400 SEC_DESC *psd = NULL;
401 size_t sd_size;
402 uint32 des_access=q_u->des_access;
403 uint32 acc_granted;
404 NTSTATUS status;
407 /* map the generic bits to the lsa policy ones */
408 se_map_generic(&des_access, &lsa_generic_mapping);
410 /* get the generic lsa policy SD until we store it */
411 lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
413 if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
414 if (geteuid() != 0) {
415 return status;
417 DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
418 acc_granted, des_access));
419 DEBUGADD(4,("but overwritten by euid == 0\n"));
422 /* This is needed for lsa_open_account and rpcclient .... :-) */
424 if (geteuid() == 0)
425 acc_granted = POLICY_ALL_ACCESS;
427 /* associate the domain SID with the (unique) handle. */
428 if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
429 return NT_STATUS_NO_MEMORY;
431 ZERO_STRUCTP(info);
432 sid_copy(&info->sid,get_global_sam_sid());
433 info->access = acc_granted;
435 /* set up the LSA QUERY INFO response */
436 if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
437 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
439 return NT_STATUS_OK;
442 /***************************************************************************
443 _lsa_open_policy
444 ***************************************************************************/
446 NTSTATUS _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL *r_u)
448 struct lsa_info *info;
449 SEC_DESC *psd = NULL;
450 size_t sd_size;
451 uint32 des_access=q_u->des_access;
452 uint32 acc_granted;
453 NTSTATUS status;
456 /* map the generic bits to the lsa policy ones */
457 se_map_generic(&des_access, &lsa_generic_mapping);
459 /* get the generic lsa policy SD until we store it */
460 lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
462 if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
463 if (geteuid() != 0) {
464 return status;
466 DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
467 acc_granted, des_access));
468 DEBUGADD(4,("but overwritten by euid == 0\n"));
469 acc_granted = des_access;
472 /* associate the domain SID with the (unique) handle. */
473 if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
474 return NT_STATUS_NO_MEMORY;
476 ZERO_STRUCTP(info);
477 sid_copy(&info->sid,get_global_sam_sid());
478 info->access = acc_granted;
480 /* set up the LSA QUERY INFO response */
481 if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
482 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
484 return NT_STATUS_OK;
487 /***************************************************************************
488 _lsa_enum_trust_dom - this needs fixing to do more than return NULL ! JRA.
489 ufff, done :) mimir
490 ***************************************************************************/
492 NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_ENUM_TRUST_DOM *r_u)
494 struct lsa_info *info;
495 uint32 enum_context = q_u->enum_context;
498 * preferred length is set to 5 as a "our" preferred length
499 * nt sets this parameter to 2
500 * update (20.08.2002): it's not preferred length, but preferred size!
501 * it needs further investigation how to optimally choose this value
503 uint32 max_num_domains = q_u->preferred_len < 5 ? q_u->preferred_len : 10;
504 TRUSTDOM **trust_doms;
505 uint32 num_domains;
506 NTSTATUS nt_status;
508 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
509 return NT_STATUS_INVALID_HANDLE;
511 /* check if the user have enough rights */
512 if (!(info->access & POLICY_VIEW_LOCAL_INFORMATION))
513 return NT_STATUS_ACCESS_DENIED;
515 nt_status = secrets_get_trusted_domains(p->mem_ctx, (int *)&enum_context, max_num_domains, (int *)&num_domains, &trust_doms);
517 if (!NT_STATUS_IS_OK(nt_status) &&
518 !NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES) &&
519 !NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_MORE_ENTRIES)) {
520 return nt_status;
521 } else {
522 r_u->status = nt_status;
525 /* set up the lsa_enum_trust_dom response */
526 init_r_enum_trust_dom(p->mem_ctx, r_u, enum_context, max_num_domains, num_domains, trust_doms);
528 return r_u->status;
531 /***************************************************************************
532 _lsa_query_info. See the POLICY_INFOMATION_CLASS docs at msdn.
533 ***************************************************************************/
535 NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO *r_u)
537 struct lsa_info *handle;
538 LSA_INFO_UNION *info = &r_u->dom;
539 DOM_SID domain_sid;
540 const char *name;
541 DOM_SID *sid = NULL;
543 r_u->status = NT_STATUS_OK;
545 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
546 return NT_STATUS_INVALID_HANDLE;
548 switch (q_u->info_class) {
549 case 0x02:
551 unsigned int i;
552 /* check if the user have enough rights */
553 if (!(handle->access & POLICY_VIEW_AUDIT_INFORMATION))
554 return NT_STATUS_ACCESS_DENIED;
556 /* fake info: We audit everything. ;) */
557 info->id2.auditing_enabled = 1;
558 info->id2.count1 = 7;
559 info->id2.count2 = 7;
560 if ((info->id2.auditsettings = TALLOC_ARRAY(p->mem_ctx,uint32, 7)) == NULL)
561 return NT_STATUS_NO_MEMORY;
562 for (i = 0; i < 7; i++)
563 info->id2.auditsettings[i] = 3;
564 break;
566 case 0x03:
567 /* check if the user have enough rights */
568 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
569 return NT_STATUS_ACCESS_DENIED;
571 /* Request PolicyPrimaryDomainInformation. */
572 switch (lp_server_role()) {
573 case ROLE_DOMAIN_PDC:
574 case ROLE_DOMAIN_BDC:
575 name = get_global_sam_name();
576 sid = get_global_sam_sid();
577 break;
578 case ROLE_DOMAIN_MEMBER:
579 name = lp_workgroup();
580 /* We need to return the Domain SID here. */
581 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid))
582 sid = &domain_sid;
583 else
584 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
585 break;
586 case ROLE_STANDALONE:
587 name = lp_workgroup();
588 sid = NULL;
589 break;
590 default:
591 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
593 init_dom_query(&r_u->dom.id3, name, sid);
594 break;
595 case 0x05:
596 /* check if the user have enough rights */
597 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
598 return NT_STATUS_ACCESS_DENIED;
600 /* Request PolicyAccountDomainInformation. */
601 name = get_global_sam_name();
602 sid = get_global_sam_sid();
603 init_dom_query(&r_u->dom.id5, name, sid);
604 break;
605 case 0x06:
606 /* check if the user have enough rights */
607 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
608 return NT_STATUS_ACCESS_DENIED;
610 switch (lp_server_role()) {
611 case ROLE_DOMAIN_BDC:
613 * only a BDC is a backup controller
614 * of the domain, it controls.
616 info->id6.server_role = 2;
617 break;
618 default:
620 * any other role is a primary
621 * of the domain, it controls.
623 info->id6.server_role = 3;
624 break;
626 break;
627 default:
628 DEBUG(0,("_lsa_query_info: unknown info level in Lsa Query: %d\n", q_u->info_class));
629 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
630 break;
633 if (NT_STATUS_IS_OK(r_u->status)) {
634 r_u->undoc_buffer = 0x22000000; /* bizarre */
635 r_u->info_class = q_u->info_class;
638 return r_u->status;
641 /***************************************************************************
642 _lsa_lookup_sids
643 ***************************************************************************/
645 NTSTATUS _lsa_lookup_sids(pipes_struct *p, LSA_Q_LOOKUP_SIDS *q_u, LSA_R_LOOKUP_SIDS *r_u)
647 struct lsa_info *handle;
648 DOM_SID2 *sid = q_u->sids.sid;
649 int num_entries = q_u->sids.num_entries;
650 DOM_R_REF *ref = NULL;
651 LSA_TRANS_NAME_ENUM *names = NULL;
652 uint32 mapped_count = 0;
654 if (num_entries > MAX_LOOKUP_SIDS) {
655 num_entries = 0;
656 DEBUG(5,("_lsa_lookup_sids: limit of %d exceeded, truncating SID lookup list to %d\n", MAX_LOOKUP_SIDS, num_entries));
657 r_u->status = NT_STATUS_NONE_MAPPED;
660 ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
661 names = TALLOC_ZERO_P(p->mem_ctx, LSA_TRANS_NAME_ENUM);
663 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) {
664 r_u->status = NT_STATUS_INVALID_HANDLE;
665 goto done;
668 /* check if the user have enough rights */
669 if (!(handle->access & POLICY_LOOKUP_NAMES)) {
670 r_u->status = NT_STATUS_ACCESS_DENIED;
671 goto done;
673 if (!ref || !names)
674 return NT_STATUS_NO_MEMORY;
676 done:
678 /* set up the LSA Lookup SIDs response */
679 init_lsa_trans_names(p->mem_ctx, ref, names, num_entries, sid, &mapped_count);
680 if (NT_STATUS_IS_OK(r_u->status)) {
681 if (mapped_count == 0)
682 r_u->status = NT_STATUS_NONE_MAPPED;
683 else if (mapped_count != num_entries)
684 r_u->status = STATUS_SOME_UNMAPPED;
686 init_reply_lookup_sids(r_u, ref, names, mapped_count);
688 return r_u->status;
691 /***************************************************************************
692 lsa_reply_lookup_names
693 ***************************************************************************/
695 NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_NAMES *r_u)
697 struct lsa_info *handle;
698 UNISTR2 *names = q_u->uni_name;
699 int num_entries = q_u->num_entries;
700 DOM_R_REF *ref;
701 DOM_RID2 *rids;
702 uint32 mapped_count = 0;
704 if (num_entries > MAX_LOOKUP_SIDS) {
705 num_entries = MAX_LOOKUP_SIDS;
706 DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries));
709 ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
710 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID2, num_entries);
712 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) {
713 r_u->status = NT_STATUS_INVALID_HANDLE;
714 goto done;
717 /* check if the user have enough rights */
718 if (!(handle->access & POLICY_LOOKUP_NAMES)) {
719 r_u->status = NT_STATUS_ACCESS_DENIED;
720 goto done;
723 if (!ref || !rids)
724 return NT_STATUS_NO_MEMORY;
726 done:
728 /* set up the LSA Lookup RIDs response */
729 init_lsa_rid2s(ref, rids, num_entries, names, &mapped_count, p->endian);
730 if (NT_STATUS_IS_OK(r_u->status)) {
731 if (mapped_count == 0)
732 r_u->status = NT_STATUS_NONE_MAPPED;
733 else if (mapped_count != num_entries)
734 r_u->status = STATUS_SOME_UNMAPPED;
736 init_reply_lookup_names(r_u, ref, num_entries, rids, mapped_count);
738 return r_u->status;
741 /***************************************************************************
742 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
743 ***************************************************************************/
745 NTSTATUS _lsa_close(pipes_struct *p, LSA_Q_CLOSE *q_u, LSA_R_CLOSE *r_u)
747 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
748 return NT_STATUS_INVALID_HANDLE;
750 close_policy_hnd(p, &q_u->pol);
751 return NT_STATUS_OK;
754 /***************************************************************************
755 "No more secrets Marty...." :-).
756 ***************************************************************************/
758 NTSTATUS _lsa_open_secret(pipes_struct *p, LSA_Q_OPEN_SECRET *q_u, LSA_R_OPEN_SECRET *r_u)
760 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
763 /***************************************************************************
764 _lsa_enum_privs.
765 ***************************************************************************/
767 NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIVS *r_u)
769 struct lsa_info *handle;
770 uint32 i;
771 uint32 enum_context = q_u->enum_context;
772 int num_privs = count_all_privileges();
773 LSA_PRIV_ENTRY *entries = NULL;
774 LUID_ATTR luid;
776 /* remember that the enum_context starts at 0 and not 1 */
778 if ( enum_context >= num_privs )
779 return NT_STATUS_NO_MORE_ENTRIES;
781 DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n",
782 enum_context, num_privs));
784 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
785 return NT_STATUS_INVALID_HANDLE;
787 /* check if the user have enough rights
788 I don't know if it's the right one. not documented. */
790 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
791 return NT_STATUS_ACCESS_DENIED;
793 if ( !(entries = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_PRIV_ENTRY, num_privs )) )
794 return NT_STATUS_NO_MEMORY;
796 for (i = 0; i < num_privs; i++) {
797 if( i < enum_context) {
798 init_unistr2(&entries[i].name, NULL, UNI_FLAGS_NONE);
799 init_uni_hdr(&entries[i].hdr_name, &entries[i].name);
801 entries[i].luid_low = 0;
802 entries[i].luid_high = 0;
803 } else {
804 init_unistr2(&entries[i].name, privs[i].name, UNI_FLAGS_NONE);
805 init_uni_hdr(&entries[i].hdr_name, &entries[i].name);
807 luid = get_privilege_luid( &privs[i].se_priv );
809 entries[i].luid_low = luid.luid.low;
810 entries[i].luid_high = luid.luid.high;
814 enum_context = num_privs;
816 init_lsa_r_enum_privs(r_u, enum_context, num_privs, entries);
818 return NT_STATUS_OK;
821 /***************************************************************************
822 _lsa_priv_get_dispname.
823 ***************************************************************************/
825 NTSTATUS _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, LSA_R_PRIV_GET_DISPNAME *r_u)
827 struct lsa_info *handle;
828 fstring name_asc;
829 const char *description;
831 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
832 return NT_STATUS_INVALID_HANDLE;
834 /* check if the user have enough rights */
837 * I don't know if it's the right one. not documented.
839 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
840 return NT_STATUS_ACCESS_DENIED;
842 unistr2_to_ascii(name_asc, &q_u->name, sizeof(name_asc));
844 DEBUG(10,("_lsa_priv_get_dispname: name = %s\n", name_asc));
846 description = get_privilege_dispname( name_asc );
848 if ( description ) {
849 DEBUG(10,("_lsa_priv_get_dispname: display name = %s\n", description));
851 init_unistr2(&r_u->desc, description, UNI_FLAGS_NONE);
852 init_uni_hdr(&r_u->hdr_desc, &r_u->desc);
854 r_u->ptr_info = 0xdeadbeef;
855 r_u->lang_id = q_u->lang_id;
857 return NT_STATUS_OK;
858 } else {
859 DEBUG(10,("_lsa_priv_get_dispname: doesn't exist\n"));
861 r_u->ptr_info = 0;
863 return NT_STATUS_NO_SUCH_PRIVILEGE;
867 /***************************************************************************
868 _lsa_enum_accounts.
869 ***************************************************************************/
871 NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENUM_ACCOUNTS *r_u)
873 struct lsa_info *handle;
874 DOM_SID *sid_list;
875 int i, j, num_entries;
876 LSA_SID_ENUM *sids=&r_u->sids;
877 NTSTATUS ret;
879 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
880 return NT_STATUS_INVALID_HANDLE;
882 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
883 return NT_STATUS_ACCESS_DENIED;
885 sid_list = NULL;
886 num_entries = 0;
888 /* The only way we can currently find out all the SIDs that have been
889 privileged is to scan all privileges */
891 if (!NT_STATUS_IS_OK(ret = privilege_enumerate_accounts(&sid_list, &num_entries))) {
892 return ret;
895 if (q_u->enum_context >= num_entries)
896 return NT_STATUS_NO_MORE_ENTRIES;
898 sids->ptr_sid = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_entries-q_u->enum_context);
899 sids->sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_entries-q_u->enum_context);
901 if (sids->ptr_sid==NULL || sids->sid==NULL) {
902 SAFE_FREE(sid_list);
903 return NT_STATUS_NO_MEMORY;
906 for (i = q_u->enum_context, j = 0; i < num_entries; i++, j++) {
907 init_dom_sid2(&(*sids).sid[j], &sid_list[i]);
908 (*sids).ptr_sid[j] = 1;
911 SAFE_FREE(sid_list);
913 init_lsa_r_enum_accounts(r_u, num_entries);
915 return NT_STATUS_OK;
919 NTSTATUS _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u)
921 fstring username, domname;
922 user_struct *vuser = get_valid_user_struct(p->vuid);
924 if (vuser == NULL)
925 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
927 fstrcpy(username, vuser->user.smb_name);
928 fstrcpy(domname, vuser->user.domain);
930 r_u->ptr_user_name = 1;
931 init_unistr2(&r_u->uni2_user_name, username, UNI_STR_TERMINATE);
932 init_uni_hdr(&r_u->hdr_user_name, &r_u->uni2_user_name);
934 r_u->unk1 = 1;
936 r_u->ptr_dom_name = 1;
937 init_unistr2(&r_u->uni2_dom_name, domname, UNI_STR_TERMINATE);
938 init_uni_hdr(&r_u->hdr_dom_name, &r_u->uni2_dom_name);
940 r_u->status = NT_STATUS_OK;
942 return r_u->status;
945 /***************************************************************************
946 Lsa Create Account
947 ***************************************************************************/
949 NTSTATUS _lsa_create_account(pipes_struct *p, LSA_Q_CREATEACCOUNT *q_u, LSA_R_CREATEACCOUNT *r_u)
951 struct lsa_info *handle;
952 struct lsa_info *info;
954 /* find the connection policy handle. */
955 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
956 return NT_STATUS_INVALID_HANDLE;
958 /* check if the user have enough rights */
961 * I don't know if it's the right one. not documented.
962 * but guessed with rpcclient.
964 if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION))
965 return NT_STATUS_ACCESS_DENIED;
967 /* check to see if the pipe_user is a Domain Admin since
968 account_pol.tdb was already opened as root, this is all we have */
970 if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
971 return NT_STATUS_ACCESS_DENIED;
973 if ( is_privileged_sid( &q_u->sid.sid ) )
974 return NT_STATUS_OBJECT_NAME_COLLISION;
976 /* associate the user/group SID with the (unique) handle. */
978 if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
979 return NT_STATUS_NO_MEMORY;
981 ZERO_STRUCTP(info);
982 info->sid = q_u->sid.sid;
983 info->access = q_u->access;
985 /* get a (unique) handle. open a policy on it. */
986 if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
987 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
989 return privilege_create_account( &info->sid );
993 /***************************************************************************
994 Lsa Open Account
995 ***************************************************************************/
997 NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENACCOUNT *r_u)
999 struct lsa_info *handle;
1000 struct lsa_info *info;
1002 /* find the connection policy handle. */
1003 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
1004 return NT_STATUS_INVALID_HANDLE;
1006 /* check if the user have enough rights */
1009 * I don't know if it's the right one. not documented.
1010 * but guessed with rpcclient.
1012 if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION))
1013 return NT_STATUS_ACCESS_DENIED;
1015 /* TODO: Fis the parsing routine before reenabling this check! */
1016 #if 0
1017 if (!lookup_sid(&handle->sid, dom_name, name, &type))
1018 return NT_STATUS_ACCESS_DENIED;
1019 #endif
1020 /* associate the user/group SID with the (unique) handle. */
1021 if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
1022 return NT_STATUS_NO_MEMORY;
1024 ZERO_STRUCTP(info);
1025 info->sid = q_u->sid.sid;
1026 info->access = q_u->access;
1028 /* get a (unique) handle. open a policy on it. */
1029 if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
1030 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1032 return NT_STATUS_OK;
1035 /***************************************************************************
1036 For a given SID, enumerate all the privilege this account has.
1037 ***************************************************************************/
1039 NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVSACCOUNT *q_u, LSA_R_ENUMPRIVSACCOUNT *r_u)
1041 struct lsa_info *info=NULL;
1042 SE_PRIV mask;
1043 PRIVILEGE_SET privileges;
1045 /* find the connection policy handle. */
1046 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1047 return NT_STATUS_INVALID_HANDLE;
1049 if ( !get_privileges_for_sids( &mask, &info->sid, 1 ) )
1050 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1052 privilege_set_init( &privileges );
1054 if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
1056 DEBUG(10,("_lsa_enum_privsaccount: %s has %d privileges\n",
1057 sid_string_static(&info->sid), privileges.count));
1059 r_u->status = init_lsa_r_enum_privsaccount(ps->mem_ctx, r_u, privileges.set, privileges.count, 0);
1061 else
1062 r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE;
1064 privilege_set_free( &privileges );
1066 return r_u->status;
1069 /***************************************************************************
1071 ***************************************************************************/
1073 NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA_R_GETSYSTEMACCOUNT *r_u)
1075 struct lsa_info *info=NULL;
1076 fstring name, dom_name;
1077 enum SID_NAME_USE type;
1079 /* find the connection policy handle. */
1081 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1082 return NT_STATUS_INVALID_HANDLE;
1084 if (!lookup_sid(&info->sid, dom_name, name, &type))
1085 return NT_STATUS_ACCESS_DENIED;
1088 0x01 -> Log on locally
1089 0x02 -> Access this computer from network
1090 0x04 -> Log on as a batch job
1091 0x10 -> Log on as a service
1093 they can be ORed together
1096 r_u->access = PR_LOG_ON_LOCALLY | PR_ACCESS_FROM_NETWORK;
1098 return NT_STATUS_OK;
1101 /***************************************************************************
1102 update the systemaccount information
1103 ***************************************************************************/
1105 NTSTATUS _lsa_setsystemaccount(pipes_struct *p, LSA_Q_SETSYSTEMACCOUNT *q_u, LSA_R_SETSYSTEMACCOUNT *r_u)
1107 struct lsa_info *info=NULL;
1108 GROUP_MAP map;
1109 r_u->status = NT_STATUS_OK;
1111 /* find the connection policy handle. */
1112 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1113 return NT_STATUS_INVALID_HANDLE;
1115 /* check to see if the pipe_user is a Domain Admin since
1116 account_pol.tdb was already opened as root, this is all we have */
1118 if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1119 return NT_STATUS_ACCESS_DENIED;
1121 if (!pdb_getgrsid(&map, info->sid))
1122 return NT_STATUS_NO_SUCH_GROUP;
1124 if(!pdb_update_group_mapping_entry(&map))
1125 return NT_STATUS_NO_SUCH_GROUP;
1127 return r_u->status;
1130 /***************************************************************************
1131 For a given SID, add some privileges.
1132 ***************************************************************************/
1134 NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u)
1136 struct lsa_info *info = NULL;
1137 SE_PRIV mask;
1138 PRIVILEGE_SET *set = NULL;
1139 struct current_user user;
1141 /* find the connection policy handle. */
1142 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1143 return NT_STATUS_INVALID_HANDLE;
1145 /* check to see if the pipe_user is root or a Domain Admin since
1146 account_pol.tdb was already opened as root, this is all we have */
1148 get_current_user( &user, p );
1149 if ( user.uid != sec_initial_uid()
1150 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1152 return NT_STATUS_ACCESS_DENIED;
1155 set = &q_u->set;
1157 if ( !privilege_set_to_se_priv( &mask, set ) )
1158 return NT_STATUS_NO_SUCH_PRIVILEGE;
1160 if ( !grant_privilege( &info->sid, &mask ) ) {
1161 DEBUG(3,("_lsa_addprivs: grant_privilege(%s) failed!\n",
1162 sid_string_static(&info->sid) ));
1163 DEBUG(3,("Privilege mask:\n"));
1164 dump_se_priv( DBGC_ALL, 3, &mask );
1165 return NT_STATUS_NO_SUCH_PRIVILEGE;
1168 return NT_STATUS_OK;
1171 /***************************************************************************
1172 For a given SID, remove some privileges.
1173 ***************************************************************************/
1175 NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEPRIVS *r_u)
1177 struct lsa_info *info = NULL;
1178 SE_PRIV mask;
1179 PRIVILEGE_SET *set = NULL;
1180 struct current_user user;
1182 /* find the connection policy handle. */
1183 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1184 return NT_STATUS_INVALID_HANDLE;
1186 /* check to see if the pipe_user is root or a Domain Admin since
1187 account_pol.tdb was already opened as root, this is all we have */
1189 get_current_user( &user, p );
1190 if ( user.uid != sec_initial_uid()
1191 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1193 return NT_STATUS_ACCESS_DENIED;
1196 set = &q_u->set;
1198 if ( !privilege_set_to_se_priv( &mask, set ) )
1199 return NT_STATUS_NO_SUCH_PRIVILEGE;
1201 if ( !revoke_privilege( &info->sid, &mask ) ) {
1202 DEBUG(3,("_lsa_removeprivs: revoke_privilege(%s) failed!\n",
1203 sid_string_static(&info->sid) ));
1204 DEBUG(3,("Privilege mask:\n"));
1205 dump_se_priv( DBGC_ALL, 3, &mask );
1206 return NT_STATUS_NO_SUCH_PRIVILEGE;
1209 return NT_STATUS_OK;
1212 /***************************************************************************
1213 For a given SID, remove some privileges.
1214 ***************************************************************************/
1216 NTSTATUS _lsa_query_secobj(pipes_struct *p, LSA_Q_QUERY_SEC_OBJ *q_u, LSA_R_QUERY_SEC_OBJ *r_u)
1218 struct lsa_info *handle=NULL;
1219 SEC_DESC *psd = NULL;
1220 size_t sd_size;
1221 NTSTATUS status;
1223 r_u->status = NT_STATUS_OK;
1225 /* find the connection policy handle. */
1226 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
1227 return NT_STATUS_INVALID_HANDLE;
1229 /* check if the user have enough rights */
1230 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
1231 return NT_STATUS_ACCESS_DENIED;
1234 switch (q_u->sec_info) {
1235 case 1:
1236 /* SD contains only the owner */
1238 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
1239 if(!NT_STATUS_IS_OK(status))
1240 return NT_STATUS_NO_MEMORY;
1243 if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1244 return NT_STATUS_NO_MEMORY;
1245 break;
1246 case 4:
1247 /* SD contains only the ACL */
1249 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
1250 if(!NT_STATUS_IS_OK(status))
1251 return NT_STATUS_NO_MEMORY;
1253 if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1254 return NT_STATUS_NO_MEMORY;
1255 break;
1256 default:
1257 return NT_STATUS_INVALID_LEVEL;
1260 r_u->ptr=1;
1262 return r_u->status;
1265 #if 0 /* AD DC work in ongoing in Samba 4 */
1267 /***************************************************************************
1268 ***************************************************************************/
1270 NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_INFO2 *r_u)
1272 struct lsa_info *handle;
1273 const char *nb_name;
1274 char *dns_name = NULL;
1275 char *forest_name = NULL;
1276 DOM_SID *sid = NULL;
1277 struct uuid guid;
1278 fstring dnsdomname;
1280 ZERO_STRUCT(guid);
1281 r_u->status = NT_STATUS_OK;
1283 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
1284 return NT_STATUS_INVALID_HANDLE;
1286 switch (q_u->info_class) {
1287 case 0x0c:
1288 /* check if the user have enough rights */
1289 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
1290 return NT_STATUS_ACCESS_DENIED;
1292 /* Request PolicyPrimaryDomainInformation. */
1293 switch (lp_server_role()) {
1294 case ROLE_DOMAIN_PDC:
1295 case ROLE_DOMAIN_BDC:
1296 nb_name = get_global_sam_name();
1297 /* ugly temp hack for these next two */
1299 /* This should be a 'netbios domain -> DNS domain' mapping */
1300 dnsdomname[0] = '\0';
1301 get_mydnsdomname(dnsdomname);
1302 strlower_m(dnsdomname);
1304 dns_name = dnsdomname;
1305 forest_name = dnsdomname;
1307 sid = get_global_sam_sid();
1308 secrets_fetch_domain_guid(lp_workgroup(), &guid);
1309 break;
1310 default:
1311 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1313 init_dns_dom_info(&r_u->info.dns_dom_info, nb_name, dns_name,
1314 forest_name,&guid,sid);
1315 break;
1316 default:
1317 DEBUG(0,("_lsa_query_info2: unknown info level in Lsa Query: %d\n", q_u->info_class));
1318 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
1319 break;
1322 if (NT_STATUS_IS_OK(r_u->status)) {
1323 r_u->ptr = 0x1;
1324 r_u->info_class = q_u->info_class;
1327 return r_u->status;
1329 #endif /* AD DC work in ongoing in Samba 4 */
1331 /***************************************************************************
1332 ***************************************************************************/
1334 NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R_ADD_ACCT_RIGHTS *r_u)
1336 struct lsa_info *info = NULL;
1337 int i = 0;
1338 DOM_SID sid;
1339 fstring privname;
1340 UNISTR2_ARRAY *uni_privnames = &q_u->rights;
1341 struct current_user user;
1344 /* find the connection policy handle. */
1345 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1346 return NT_STATUS_INVALID_HANDLE;
1348 /* check to see if the pipe_user is a Domain Admin since
1349 account_pol.tdb was already opened as root, this is all we have */
1351 get_current_user( &user, p );
1352 if ( user.uid != sec_initial_uid()
1353 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1355 return NT_STATUS_ACCESS_DENIED;
1358 /* according to an NT4 PDC, you can add privileges to SIDs even without
1359 call_lsa_create_account() first. And you can use any arbitrary SID. */
1361 sid_copy( &sid, &q_u->sid.sid );
1363 /* just a little sanity check */
1365 if ( q_u->count != uni_privnames->count ) {
1366 DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n"));
1367 return NT_STATUS_INVALID_HANDLE;
1370 for ( i=0; i<q_u->count; i++ ) {
1371 unistr2_to_ascii( privname, &uni_privnames->strings[i].string, sizeof(fstring)-1 );
1373 /* only try to add non-null strings */
1375 if ( *privname && !grant_privilege_by_name( &sid, privname ) ) {
1376 DEBUG(2,("_lsa_add_acct_rights: Failed to add privilege [%s]\n", privname ));
1377 return NT_STATUS_NO_SUCH_PRIVILEGE;
1381 return NT_STATUS_OK;
1384 /***************************************************************************
1385 ***************************************************************************/
1387 NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u, LSA_R_REMOVE_ACCT_RIGHTS *r_u)
1389 struct lsa_info *info = NULL;
1390 int i = 0;
1391 DOM_SID sid;
1392 fstring privname;
1393 UNISTR2_ARRAY *uni_privnames = &q_u->rights;
1394 struct current_user user;
1397 /* find the connection policy handle. */
1398 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1399 return NT_STATUS_INVALID_HANDLE;
1401 /* check to see if the pipe_user is a Domain Admin since
1402 account_pol.tdb was already opened as root, this is all we have */
1404 get_current_user( &user, p );
1405 if ( user.uid != sec_initial_uid()
1406 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1408 return NT_STATUS_ACCESS_DENIED;
1411 sid_copy( &sid, &q_u->sid.sid );
1413 if ( q_u->removeall ) {
1414 if ( !revoke_all_privileges( &sid ) )
1415 return NT_STATUS_ACCESS_DENIED;
1417 return NT_STATUS_OK;
1420 /* just a little sanity check */
1422 if ( q_u->count != uni_privnames->count ) {
1423 DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n"));
1424 return NT_STATUS_INVALID_HANDLE;
1427 for ( i=0; i<q_u->count; i++ ) {
1428 unistr2_to_ascii( privname, &uni_privnames->strings[i].string, sizeof(fstring)-1 );
1430 /* only try to add non-null strings */
1432 if ( *privname && !revoke_privilege_by_name( &sid, privname ) ) {
1433 DEBUG(2,("_lsa_remove_acct_rights: Failed to revoke privilege [%s]\n", privname ));
1434 return NT_STATUS_NO_SUCH_PRIVILEGE;
1438 return NT_STATUS_OK;
1442 NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA_R_ENUM_ACCT_RIGHTS *r_u)
1444 struct lsa_info *info = NULL;
1445 DOM_SID sid;
1446 PRIVILEGE_SET privileges;
1447 SE_PRIV mask;
1450 /* find the connection policy handle. */
1452 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1453 return NT_STATUS_INVALID_HANDLE;
1455 /* according to an NT4 PDC, you can add privileges to SIDs even without
1456 call_lsa_create_account() first. And you can use any arbitrary SID. */
1458 sid_copy( &sid, &q_u->sid.sid );
1460 if ( !get_privileges_for_sids( &mask, &sid, 1 ) )
1461 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1463 privilege_set_init( &privileges );
1465 if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
1467 DEBUG(10,("_lsa_enum_acct_rights: %s has %d privileges\n",
1468 sid_string_static(&sid), privileges.count));
1470 r_u->status = init_r_enum_acct_rights( r_u, &privileges );
1472 else
1473 r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE;
1475 privilege_set_free( &privileges );
1477 return r_u->status;
1481 NTSTATUS _lsa_lookup_priv_value(pipes_struct *p, LSA_Q_LOOKUP_PRIV_VALUE *q_u, LSA_R_LOOKUP_PRIV_VALUE *r_u)
1483 struct lsa_info *info = NULL;
1484 fstring name;
1485 LUID_ATTR priv_luid;
1486 SE_PRIV mask;
1488 /* find the connection policy handle. */
1490 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1491 return NT_STATUS_INVALID_HANDLE;
1493 unistr2_to_ascii(name, &q_u->privname.unistring, sizeof(name));
1495 DEBUG(10,("_lsa_priv_get_dispname: name = %s\n", name));
1497 if ( !se_priv_from_name( name, &mask ) )
1498 return NT_STATUS_NO_SUCH_PRIVILEGE;
1500 priv_luid = get_privilege_luid( &mask );
1502 r_u->luid.low = priv_luid.luid.low;
1503 r_u->luid.high = priv_luid.luid.high;
1506 return NT_STATUS_OK;