2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Jeremy Allison 2001,
8 * Copyright (C) Rafal Szczesniak 2002,
9 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
10 * Copyright (C) Simo Sorce 2003.
11 * Copyright (C) Gerald (Jerry) Carter 2005.
12 * Copyright (C) Volker Lendecke 2005.
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.
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.
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.
29 /* This is the implementation of the lsa server code. */
34 #define DBGC_CLASS DBGC_RPC_SRV
43 struct generic_mapping lsa_generic_mapping = {
50 /*******************************************************************
51 Function to free the per handle data.
52 ********************************************************************/
54 static void free_lsa_info(void *ptr)
56 struct lsa_info *lsa = (struct lsa_info *)ptr;
61 /***************************************************************************
63 ***************************************************************************/
65 static void init_dom_query(DOM_QUERY *d_q, const char *dom_name, DOM_SID *dom_sid)
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 */
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);
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.
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.
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;
93 init_dom_sid2(&d_q->dom_sid, dom_sid);
96 /***************************************************************************
97 init_dom_ref - adds a domain if it's not already in, returns the index.
98 ***************************************************************************/
100 static int init_dom_ref(DOM_R_REF *ref, const char *dom_name, DOM_SID *dom_sid)
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))
110 num = ref->num_ref_doms_1;
113 if (num >= MAX_REF_DOMAINS) {
114 /* index not found, already at maximum domain limit */
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;
123 ref->hdr_ref_dom[num].ptr_dom_sid = dom_sid != NULL ? 1 : 0;
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);
128 init_dom_sid2(&ref->ref_dom[num].ref_dom, dom_sid );
133 /***************************************************************************
135 ***************************************************************************/
137 static int init_lsa_rids(TALLOC_CTX *mem_ctx,
138 DOM_R_REF *ref, DOM_RID *prid,
139 int num_entries, UNISTR2 *name,
144 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
148 become_root(); /* lookup_name can require root privs */
150 for (i = 0; i < num_entries; i++) {
156 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
158 /* Split name into domain and user component */
160 full_name = rpcstr_pull_unistr2_talloc(mem_ctx, &name[i]);
161 if (full_name == NULL) {
162 DEBUG(0, ("pull_ucs2_talloc failed\n"));
166 DEBUG(5, ("init_lsa_rids: looking up name %s\n", full_name));
168 /* We can ignore the result of lookup_name, it will not touch
169 "type" if it's not successful */
171 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
177 case SID_NAME_DOM_GRP:
178 case SID_NAME_DOMAIN:
180 case SID_NAME_WKN_GRP:
181 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
182 /* Leave these unchanged */
185 /* Don't hand out anything but the list above */
186 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
187 type = SID_NAME_UNKNOWN;
194 if (type != SID_NAME_UNKNOWN) {
195 sid_split_rid(&sid, &rid);
196 dom_idx = init_dom_ref(ref, domain, &sid);
200 init_dom_rid(&prid[i], rid, type, dom_idx);
208 /***************************************************************************
209 init_reply_lookup_names
210 ***************************************************************************/
212 static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
213 DOM_R_REF *ref, uint32 num_entries,
214 DOM_RID *rid, uint32 mapped_count)
216 r_l->ptr_dom_ref = 1;
219 r_l->num_entries = num_entries;
220 r_l->ptr_entries = 1;
221 r_l->num_entries2 = num_entries;
224 r_l->mapped_count = mapped_count;
227 /***************************************************************************
228 init_reply_lookup_names2
229 ***************************************************************************/
231 static void init_reply_lookup_names2(LSA_R_LOOKUP_NAMES2 *r_l,
232 DOM_R_REF *ref, uint32 num_entries,
233 DOM_RID2 *rid, uint32 mapped_count)
235 r_l->ptr_dom_ref = 1;
238 r_l->num_entries = num_entries;
239 r_l->ptr_entries = 1;
240 r_l->num_entries2 = num_entries;
243 r_l->mapped_count = mapped_count;
246 /***************************************************************************
247 Init_reply_lookup_sids.
248 ***************************************************************************/
250 static void init_reply_lookup_sids2(LSA_R_LOOKUP_SIDS2 *r_l,
252 LSA_TRANS_NAME_ENUM2 *names,
255 r_l->ptr_dom_ref = ref ? 1 : 0;
258 r_l->mapped_count = mapped_count;
261 /***************************************************************************
262 Init_reply_lookup_sids.
263 ***************************************************************************/
265 static void init_reply_lookup_sids3(LSA_R_LOOKUP_SIDS3 *r_l,
267 LSA_TRANS_NAME_ENUM2 *names,
270 r_l->ptr_dom_ref = ref ? 1 : 0;
273 r_l->mapped_count = mapped_count;
276 /***************************************************************************
277 Init_reply_lookup_sids.
278 ***************************************************************************/
280 static NTSTATUS init_reply_lookup_sids(TALLOC_CTX *mem_ctx,
281 LSA_R_LOOKUP_SIDS *r_l,
283 LSA_TRANS_NAME_ENUM2 *names,
286 LSA_TRANS_NAME_ENUM *oldnames = TALLOC_ZERO_P(mem_ctx, LSA_TRANS_NAME_ENUM);
289 return NT_STATUS_NO_MEMORY;
292 oldnames->num_entries = names->num_entries;
293 oldnames->ptr_trans_names = names->ptr_trans_names;
294 oldnames->num_entries2 = names->num_entries2;
295 oldnames->uni_name = names->uni_name;
297 if (names->num_entries) {
300 oldnames->name = TALLOC_ARRAY(oldnames, LSA_TRANS_NAME, names->num_entries);
302 if (!oldnames->name) {
303 return NT_STATUS_NO_MEMORY;
305 for (i = 0; i < names->num_entries; i++) {
306 oldnames->name[i].sid_name_use = names->name[i].sid_name_use;
307 oldnames->name[i].hdr_name = names->name[i].hdr_name;
308 oldnames->name[i].domain_idx = names->name[i].domain_idx;
312 r_l->ptr_dom_ref = ref ? 1 : 0;
314 r_l->names = oldnames;
315 r_l->mapped_count = mapped_count;
319 static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size)
321 DOM_SID local_adm_sid;
329 init_sec_access(&mask, POLICY_EXECUTE);
330 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
332 sid_copy(&adm_sid, get_global_sam_sid());
333 sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS);
334 init_sec_access(&mask, POLICY_ALL_ACCESS);
335 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
337 sid_copy(&local_adm_sid, &global_sid_Builtin);
338 sid_append_rid(&local_adm_sid, BUILTIN_ALIAS_RID_ADMINS);
339 init_sec_access(&mask, POLICY_ALL_ACCESS);
340 init_sec_ace(&ace[2], &local_adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
342 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
343 return NT_STATUS_NO_MEMORY;
345 if((*sd = make_sec_desc(mem_ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL, psa, sd_size)) == NULL)
346 return NT_STATUS_NO_MEMORY;
351 #if 0 /* AD DC work in ongoing in Samba 4 */
353 /***************************************************************************
355 ***************************************************************************/
357 static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name,
358 const char *dns_name, const char *forest_name,
359 struct uuid *dom_guid, DOM_SID *dom_sid)
361 if (nb_name && *nb_name) {
362 init_unistr2(&r_l->uni_nb_dom_name, nb_name, UNI_FLAGS_NONE);
363 init_uni_hdr(&r_l->hdr_nb_dom_name, &r_l->uni_nb_dom_name);
364 r_l->hdr_nb_dom_name.uni_max_len += 2;
365 r_l->uni_nb_dom_name.uni_max_len += 1;
368 if (dns_name && *dns_name) {
369 init_unistr2(&r_l->uni_dns_dom_name, dns_name, UNI_FLAGS_NONE);
370 init_uni_hdr(&r_l->hdr_dns_dom_name, &r_l->uni_dns_dom_name);
371 r_l->hdr_dns_dom_name.uni_max_len += 2;
372 r_l->uni_dns_dom_name.uni_max_len += 1;
375 if (forest_name && *forest_name) {
376 init_unistr2(&r_l->uni_forest_name, forest_name, UNI_FLAGS_NONE);
377 init_uni_hdr(&r_l->hdr_forest_name, &r_l->uni_forest_name);
378 r_l->hdr_forest_name.uni_max_len += 2;
379 r_l->uni_forest_name.uni_max_len += 1;
382 /* how do we init the guid ? probably should write an init fn */
384 memcpy(&r_l->dom_guid, dom_guid, sizeof(struct uuid));
388 r_l->ptr_dom_sid = 1;
389 init_dom_sid2(&r_l->dom_sid, dom_sid);
392 #endif /* AD DC work in ongoing in Samba 4 */
395 /***************************************************************************
397 ***************************************************************************/
399 NTSTATUS _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL2 *r_u)
401 struct lsa_info *info;
402 SEC_DESC *psd = NULL;
404 uint32 des_access=q_u->des_access;
409 /* map the generic bits to the lsa policy ones */
410 se_map_generic(&des_access, &lsa_generic_mapping);
412 /* get the generic lsa policy SD until we store it */
413 lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
415 if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
416 if (geteuid() != 0) {
419 DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
420 acc_granted, des_access));
421 DEBUGADD(4,("but overwritten by euid == 0\n"));
424 /* This is needed for lsa_open_account and rpcclient .... :-) */
427 acc_granted = POLICY_ALL_ACCESS;
429 /* associate the domain SID with the (unique) handle. */
430 if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
431 return NT_STATUS_NO_MEMORY;
434 sid_copy(&info->sid,get_global_sam_sid());
435 info->access = acc_granted;
437 /* set up the LSA QUERY INFO response */
438 if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
439 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
444 /***************************************************************************
446 ***************************************************************************/
448 NTSTATUS _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL *r_u)
450 struct lsa_info *info;
451 SEC_DESC *psd = NULL;
453 uint32 des_access=q_u->des_access;
458 /* map the generic bits to the lsa policy ones */
459 se_map_generic(&des_access, &lsa_generic_mapping);
461 /* get the generic lsa policy SD until we store it */
462 lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
464 if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
465 if (geteuid() != 0) {
468 DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
469 acc_granted, des_access));
470 DEBUGADD(4,("but overwritten by euid == 0\n"));
471 acc_granted = des_access;
474 /* associate the domain SID with the (unique) handle. */
475 if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
476 return NT_STATUS_NO_MEMORY;
479 sid_copy(&info->sid,get_global_sam_sid());
480 info->access = acc_granted;
482 /* set up the LSA QUERY INFO response */
483 if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
484 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
489 /***************************************************************************
490 _lsa_enum_trust_dom - this needs fixing to do more than return NULL ! JRA.
492 ***************************************************************************/
494 NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u,
495 LSA_R_ENUM_TRUST_DOM *r_u)
497 struct lsa_info *info;
499 struct trustdom_info **domains;
502 * preferred length is set to 5 as a "our" preferred length
503 * nt sets this parameter to 2
504 * update (20.08.2002): it's not preferred length, but preferred size!
505 * it needs further investigation how to optimally choose this value
507 uint32 max_num_domains =
508 q_u->preferred_len < 5 ? q_u->preferred_len : 10;
513 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
514 return NT_STATUS_INVALID_HANDLE;
516 /* check if the user have enough rights */
517 if (!(info->access & POLICY_VIEW_LOCAL_INFORMATION))
518 return NT_STATUS_ACCESS_DENIED;
520 nt_status = secrets_trusted_domains(p->mem_ctx, &num_domains,
523 if (!NT_STATUS_IS_OK(nt_status)) {
527 if (q_u->enum_context < num_domains) {
528 num_thistime = MIN(num_domains, max_num_domains);
530 r_u->status = STATUS_MORE_ENTRIES;
532 if (q_u->enum_context + num_thistime > num_domains) {
533 num_thistime = num_domains - q_u->enum_context;
534 r_u->status = NT_STATUS_OK;
537 next_idx = q_u->enum_context + num_thistime;
540 next_idx = 0xffffffff;
541 r_u->status = NT_STATUS_NO_MORE_ENTRIES;
544 /* set up the lsa_enum_trust_dom response */
546 init_r_enum_trust_dom(p->mem_ctx, r_u, next_idx,
547 num_thistime, domains+q_u->enum_context);
552 /***************************************************************************
553 _lsa_query_info. See the POLICY_INFOMATION_CLASS docs at msdn.
554 ***************************************************************************/
556 NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO *r_u)
558 struct lsa_info *handle;
559 LSA_INFO_UNION *info = &r_u->dom;
564 r_u->status = NT_STATUS_OK;
566 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
567 return NT_STATUS_INVALID_HANDLE;
569 switch (q_u->info_class) {
573 /* check if the user have enough rights */
574 if (!(handle->access & POLICY_VIEW_AUDIT_INFORMATION))
575 return NT_STATUS_ACCESS_DENIED;
577 /* fake info: We audit everything. ;) */
578 info->id2.auditing_enabled = 1;
579 info->id2.count1 = 7;
580 info->id2.count2 = 7;
581 if ((info->id2.auditsettings = TALLOC_ARRAY(p->mem_ctx,uint32, 7)) == NULL)
582 return NT_STATUS_NO_MEMORY;
583 for (i = 0; i < 7; i++)
584 info->id2.auditsettings[i] = 3;
588 /* check if the user have enough rights */
589 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
590 return NT_STATUS_ACCESS_DENIED;
592 /* Request PolicyPrimaryDomainInformation. */
593 switch (lp_server_role()) {
594 case ROLE_DOMAIN_PDC:
595 case ROLE_DOMAIN_BDC:
596 name = get_global_sam_name();
597 sid = get_global_sam_sid();
599 case ROLE_DOMAIN_MEMBER:
600 name = lp_workgroup();
601 /* We need to return the Domain SID here. */
602 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid))
605 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
607 case ROLE_STANDALONE:
608 name = lp_workgroup();
612 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
614 init_dom_query(&r_u->dom.id3, name, sid);
617 /* check if the user have enough rights */
618 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
619 return NT_STATUS_ACCESS_DENIED;
621 /* Request PolicyAccountDomainInformation. */
622 name = get_global_sam_name();
623 sid = get_global_sam_sid();
624 init_dom_query(&r_u->dom.id5, name, sid);
627 /* check if the user have enough rights */
628 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
629 return NT_STATUS_ACCESS_DENIED;
631 switch (lp_server_role()) {
632 case ROLE_DOMAIN_BDC:
634 * only a BDC is a backup controller
635 * of the domain, it controls.
637 info->id6.server_role = 2;
641 * any other role is a primary
642 * of the domain, it controls.
644 info->id6.server_role = 3;
649 DEBUG(0,("_lsa_query_info: unknown info level in Lsa Query: %d\n", q_u->info_class));
650 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
654 if (NT_STATUS_IS_OK(r_u->status)) {
655 r_u->undoc_buffer = 0x22000000; /* bizarre */
656 r_u->info_class = q_u->info_class;
662 /***************************************************************************
663 _lsa_lookup_sids_internal
664 ***************************************************************************/
666 static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p,
667 uint16 level, /* input */
668 int num_sids, /* input */
669 const DOM_SID2 *sid, /* input */
670 DOM_R_REF **pp_ref, /* output */
671 LSA_TRANS_NAME_ENUM2 **pp_names, /* output */
672 uint32 *pp_mapped_count)
676 const DOM_SID **sids = NULL;
677 LSA_TRANS_NAME_ENUM2 *names = NULL;
678 DOM_R_REF *ref = NULL;
679 uint32 mapped_count = 0;
680 struct lsa_dom_info *dom_infos = NULL;
681 struct lsa_name_info *name_infos = NULL;
683 *pp_mapped_count = 0;
687 names = TALLOC_ZERO_P(p->mem_ctx, LSA_TRANS_NAME_ENUM2);
688 sids = TALLOC_ARRAY(p->mem_ctx, const DOM_SID *, num_sids);
689 ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
691 if (sids == NULL || names == NULL || ref == NULL) {
692 return NT_STATUS_NO_MEMORY;
695 for (i=0; i<num_sids; i++) {
696 sids[i] = &sid[i].sid;
699 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
700 &dom_infos, &name_infos);
702 if (!NT_STATUS_IS_OK(status)) {
707 names->name = TALLOC_ARRAY(names, LSA_TRANS_NAME2, num_sids);
708 names->uni_name = TALLOC_ARRAY(names, UNISTR2, num_sids);
709 if ((names->name == NULL) || (names->uni_name == NULL)) {
710 return NT_STATUS_NO_MEMORY;
714 for (i=0; i<MAX_REF_DOMAINS; i++) {
716 if (!dom_infos[i].valid) {
720 if (init_dom_ref(ref, dom_infos[i].name,
721 &dom_infos[i].sid) != i) {
722 DEBUG(0, ("Domain %s mentioned twice??\n",
724 return NT_STATUS_INTERNAL_ERROR;
728 for (i=0; i<num_sids; i++) {
729 struct lsa_name_info *name = &name_infos[i];
731 if (name->type == SID_NAME_UNKNOWN) {
733 name->name = talloc_asprintf(p->mem_ctx, "%8.8x",
735 if (name->name == NULL) {
736 return NT_STATUS_NO_MEMORY;
741 init_lsa_trans_name2(&names->name[i], &names->uni_name[i],
742 name->type, name->name, name->dom_idx);
745 names->num_entries = num_sids;
746 names->ptr_trans_names = 1;
747 names->num_entries2 = num_sids;
749 status = NT_STATUS_NONE_MAPPED;
750 if (mapped_count > 0) {
751 status = (mapped_count < num_sids) ?
752 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
755 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
756 num_sids, mapped_count, nt_errstr(status)));
758 *pp_mapped_count = mapped_count;
765 /***************************************************************************
767 ***************************************************************************/
769 NTSTATUS _lsa_lookup_sids(pipes_struct *p,
770 LSA_Q_LOOKUP_SIDS *q_u,
771 LSA_R_LOOKUP_SIDS *r_u)
773 struct lsa_info *handle;
774 int num_sids = q_u->sids.num_entries;
775 uint32 mapped_count = 0;
776 DOM_R_REF *ref = NULL;
777 LSA_TRANS_NAME_ENUM2 *names = NULL;
780 if ((q_u->level < 1) || (q_u->level > 6)) {
781 return NT_STATUS_INVALID_PARAMETER;
784 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
785 return NT_STATUS_INVALID_HANDLE;
788 /* check if the user has enough rights */
789 if (!(handle->access & POLICY_LOOKUP_NAMES)) {
790 return NT_STATUS_ACCESS_DENIED;
793 if (num_sids > MAX_LOOKUP_SIDS) {
794 DEBUG(5,("_lsa_lookup_sids: limit of %d exceeded, requested %d\n",
795 MAX_LOOKUP_SIDS, num_sids));
796 return NT_STATUS_NONE_MAPPED;
799 r_u->status = _lsa_lookup_sids_internal(p,
807 /* Convert from LSA_TRANS_NAME_ENUM2 to LSA_TRANS_NAME_ENUM */
809 status = init_reply_lookup_sids(p->mem_ctx, r_u, ref, names, mapped_count);
810 if (!NT_STATUS_IS_OK(status)) {
816 /***************************************************************************
818 ***************************************************************************/
820 NTSTATUS _lsa_lookup_sids2(pipes_struct *p,
821 LSA_Q_LOOKUP_SIDS2 *q_u,
822 LSA_R_LOOKUP_SIDS2 *r_u)
824 struct lsa_info *handle;
825 int num_sids = q_u->sids.num_entries;
826 uint32 mapped_count = 0;
827 DOM_R_REF *ref = NULL;
828 LSA_TRANS_NAME_ENUM2 *names = NULL;
830 if ((q_u->level < 1) || (q_u->level > 6)) {
831 return NT_STATUS_INVALID_PARAMETER;
834 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
835 return NT_STATUS_INVALID_HANDLE;
838 /* check if the user have enough rights */
839 if (!(handle->access & POLICY_LOOKUP_NAMES)) {
840 return NT_STATUS_ACCESS_DENIED;
843 if (num_sids > MAX_LOOKUP_SIDS) {
844 DEBUG(5,("_lsa_lookup_sids2: limit of %d exceeded, requested %d\n",
845 MAX_LOOKUP_SIDS, num_sids));
846 return NT_STATUS_NONE_MAPPED;
849 r_u->status = _lsa_lookup_sids_internal(p,
857 init_reply_lookup_sids2(r_u, ref, names, mapped_count);
861 /***************************************************************************
863 ***************************************************************************/
865 NTSTATUS _lsa_lookup_sids3(pipes_struct *p,
866 LSA_Q_LOOKUP_SIDS3 *q_u,
867 LSA_R_LOOKUP_SIDS3 *r_u)
869 int num_sids = q_u->sids.num_entries;
870 uint32 mapped_count = 0;
871 DOM_R_REF *ref = NULL;
872 LSA_TRANS_NAME_ENUM2 *names = NULL;
874 if ((q_u->level < 1) || (q_u->level > 6)) {
875 return NT_STATUS_INVALID_PARAMETER;
878 /* No policy handle on this call. Restrict to crypto connections. */
879 if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
880 DEBUG(0,("_lsa_lookup_sids3: client %s not using schannel for netlogon\n",
881 get_remote_machine_name() ));
882 return NT_STATUS_INVALID_PARAMETER;
885 if (num_sids > MAX_LOOKUP_SIDS) {
886 DEBUG(5,("_lsa_lookup_sids3: limit of %d exceeded, requested %d\n",
887 MAX_LOOKUP_SIDS, num_sids));
888 return NT_STATUS_NONE_MAPPED;
891 r_u->status = _lsa_lookup_sids_internal(p,
899 init_reply_lookup_sids3(r_u, ref, names, mapped_count);
903 /***************************************************************************
904 lsa_reply_lookup_names
905 ***************************************************************************/
907 NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_NAMES *r_u)
909 struct lsa_info *handle;
910 UNISTR2 *names = q_u->uni_name;
911 int num_entries = q_u->num_entries;
914 uint32 mapped_count = 0;
917 if (num_entries > MAX_LOOKUP_SIDS) {
918 num_entries = MAX_LOOKUP_SIDS;
919 DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries));
922 /* Probably the lookup_level is some sort of bitmask. */
923 if (q_u->lookup_level == 1) {
924 flags = LOOKUP_NAME_ALL;
927 ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
928 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID, num_entries);
930 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
931 r_u->status = NT_STATUS_INVALID_HANDLE;
935 /* check if the user have enough rights */
936 if (!(handle->access & POLICY_LOOKUP_NAMES)) {
937 r_u->status = NT_STATUS_ACCESS_DENIED;
942 return NT_STATUS_NO_MEMORY;
944 /* set up the LSA Lookup RIDs response */
945 mapped_count = init_lsa_rids(p->mem_ctx, ref, rids, num_entries,
949 if (NT_STATUS_IS_OK(r_u->status)) {
950 if (mapped_count == 0)
951 r_u->status = NT_STATUS_NONE_MAPPED;
952 else if (mapped_count != num_entries)
953 r_u->status = STATUS_SOME_UNMAPPED;
955 init_reply_lookup_names(r_u, ref, num_entries, rids, mapped_count);
960 /***************************************************************************
961 lsa_reply_lookup_names2
962 ***************************************************************************/
964 NTSTATUS _lsa_lookup_names2(pipes_struct *p, LSA_Q_LOOKUP_NAMES2 *q_u, LSA_R_LOOKUP_NAMES2 *r_u)
966 struct lsa_info *handle;
967 UNISTR2 *names = q_u->uni_name;
968 int num_entries = q_u->num_entries;
973 uint32 mapped_count = 0;
976 if (num_entries > MAX_LOOKUP_SIDS) {
977 num_entries = MAX_LOOKUP_SIDS;
978 DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries));
981 /* Probably the lookup_level is some sort of bitmask. */
982 if (q_u->lookup_level == 1) {
983 flags = LOOKUP_NAME_ALL;
986 ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
987 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID, num_entries);
988 rids2 = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID2, num_entries);
990 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
991 r_u->status = NT_STATUS_INVALID_HANDLE;
995 /* check if the user have enough rights */
996 if (!(handle->access & POLICY_LOOKUP_NAMES)) {
997 r_u->status = NT_STATUS_ACCESS_DENIED;
1001 if (!ref || !rids || !rids2)
1002 return NT_STATUS_NO_MEMORY;
1004 /* set up the LSA Lookup RIDs response */
1005 mapped_count = init_lsa_rids(p->mem_ctx, ref, rids, num_entries,
1009 if (NT_STATUS_IS_OK(r_u->status)) {
1010 if (mapped_count == 0)
1011 r_u->status = NT_STATUS_NONE_MAPPED;
1012 else if (mapped_count != num_entries)
1013 r_u->status = STATUS_SOME_UNMAPPED;
1016 /* Convert the rids array to rids2. */
1017 for (i = 0; i < num_entries; i++) {
1018 rids2[i].type = rids[i].type;
1019 rids2[i].rid = rids[i].rid;
1020 rids2[i].rid_idx = rids[i].rid_idx;
1021 rids2[i].unknown = 0;
1024 init_reply_lookup_names2(r_u, ref, num_entries, rids2, mapped_count);
1029 /***************************************************************************
1030 lsa_reply_lookup_names3 - stub for now.
1031 ***************************************************************************/
1033 NTSTATUS _lsa_lookup_names3(pipes_struct *p, LSA_Q_LOOKUP_NAMES3 *q_u, LSA_R_LOOKUP_NAMES3 *r_u)
1035 return NT_STATUS_ACCESS_DENIED;
1038 /***************************************************************************
1039 lsa_reply_lookup_names4 - stub for now.
1040 ***************************************************************************/
1042 NTSTATUS _lsa_lookup_names4(pipes_struct *p, LSA_Q_LOOKUP_NAMES4 *q_u, LSA_R_LOOKUP_NAMES4 *r_u)
1044 return NT_STATUS_ACCESS_DENIED;
1047 /***************************************************************************
1048 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1049 ***************************************************************************/
1051 NTSTATUS _lsa_close(pipes_struct *p, LSA_Q_CLOSE *q_u, LSA_R_CLOSE *r_u)
1053 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
1054 return NT_STATUS_INVALID_HANDLE;
1056 close_policy_hnd(p, &q_u->pol);
1057 return NT_STATUS_OK;
1060 /***************************************************************************
1061 ***************************************************************************/
1063 NTSTATUS _lsa_open_secret(pipes_struct *p, LSA_Q_OPEN_SECRET *q_u, LSA_R_OPEN_SECRET *r_u)
1065 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1068 /***************************************************************************
1069 ***************************************************************************/
1071 NTSTATUS _lsa_open_trusted_domain(pipes_struct *p, LSA_Q_OPEN_TRUSTED_DOMAIN *q_u, LSA_R_OPEN_TRUSTED_DOMAIN *r_u)
1073 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1076 /***************************************************************************
1077 ***************************************************************************/
1079 NTSTATUS _lsa_create_trusted_domain(pipes_struct *p, LSA_Q_CREATE_TRUSTED_DOMAIN *q_u, LSA_R_CREATE_TRUSTED_DOMAIN *r_u)
1081 return NT_STATUS_ACCESS_DENIED;
1084 /***************************************************************************
1085 ***************************************************************************/
1087 NTSTATUS _lsa_create_secret(pipes_struct *p, LSA_Q_CREATE_SECRET *q_u, LSA_R_CREATE_SECRET *r_u)
1089 return NT_STATUS_ACCESS_DENIED;
1092 /***************************************************************************
1093 ***************************************************************************/
1095 NTSTATUS _lsa_set_secret(pipes_struct *p, LSA_Q_SET_SECRET *q_u, LSA_R_SET_SECRET *r_u)
1097 return NT_STATUS_ACCESS_DENIED;
1100 /***************************************************************************
1101 ***************************************************************************/
1103 NTSTATUS _lsa_delete_object(pipes_struct *p, LSA_Q_DELETE_OBJECT *q_u, LSA_R_DELETE_OBJECT *r_u)
1105 return NT_STATUS_ACCESS_DENIED;
1108 /***************************************************************************
1110 ***************************************************************************/
1112 NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIVS *r_u)
1114 struct lsa_info *handle;
1116 uint32 enum_context = q_u->enum_context;
1117 int num_privs = count_all_privileges();
1118 LSA_PRIV_ENTRY *entries = NULL;
1121 /* remember that the enum_context starts at 0 and not 1 */
1123 if ( enum_context >= num_privs )
1124 return NT_STATUS_NO_MORE_ENTRIES;
1126 DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n",
1127 enum_context, num_privs));
1129 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1130 return NT_STATUS_INVALID_HANDLE;
1132 /* check if the user have enough rights
1133 I don't know if it's the right one. not documented. */
1135 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
1136 return NT_STATUS_ACCESS_DENIED;
1138 if ( !(entries = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_PRIV_ENTRY, num_privs )) )
1139 return NT_STATUS_NO_MEMORY;
1141 for (i = 0; i < num_privs; i++) {
1142 if( i < enum_context) {
1143 init_unistr2(&entries[i].name, NULL, UNI_FLAGS_NONE);
1144 init_uni_hdr(&entries[i].hdr_name, &entries[i].name);
1146 entries[i].luid_low = 0;
1147 entries[i].luid_high = 0;
1149 init_unistr2(&entries[i].name, privs[i].name, UNI_FLAGS_NONE);
1150 init_uni_hdr(&entries[i].hdr_name, &entries[i].name);
1152 luid = get_privilege_luid( &privs[i].se_priv );
1154 entries[i].luid_low = luid.luid.low;
1155 entries[i].luid_high = luid.luid.high;
1159 enum_context = num_privs;
1161 init_lsa_r_enum_privs(r_u, enum_context, num_privs, entries);
1163 return NT_STATUS_OK;
1166 /***************************************************************************
1167 _lsa_priv_get_dispname.
1168 ***************************************************************************/
1170 NTSTATUS _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, LSA_R_PRIV_GET_DISPNAME *r_u)
1172 struct lsa_info *handle;
1174 const char *description;
1176 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1177 return NT_STATUS_INVALID_HANDLE;
1179 /* check if the user have enough rights */
1182 * I don't know if it's the right one. not documented.
1184 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
1185 return NT_STATUS_ACCESS_DENIED;
1187 unistr2_to_ascii(name_asc, &q_u->name, sizeof(name_asc));
1189 DEBUG(10,("_lsa_priv_get_dispname: name = %s\n", name_asc));
1191 description = get_privilege_dispname( name_asc );
1193 if ( description ) {
1194 DEBUG(10,("_lsa_priv_get_dispname: display name = %s\n", description));
1196 init_unistr2(&r_u->desc, description, UNI_FLAGS_NONE);
1197 init_uni_hdr(&r_u->hdr_desc, &r_u->desc);
1199 r_u->ptr_info = 0xdeadbeef;
1200 r_u->lang_id = q_u->lang_id;
1202 return NT_STATUS_OK;
1204 DEBUG(10,("_lsa_priv_get_dispname: doesn't exist\n"));
1208 return NT_STATUS_NO_SUCH_PRIVILEGE;
1212 /***************************************************************************
1214 ***************************************************************************/
1216 NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENUM_ACCOUNTS *r_u)
1218 struct lsa_info *handle;
1220 int i, j, num_entries;
1221 LSA_SID_ENUM *sids=&r_u->sids;
1224 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1225 return NT_STATUS_INVALID_HANDLE;
1227 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
1228 return NT_STATUS_ACCESS_DENIED;
1233 /* The only way we can currently find out all the SIDs that have been
1234 privileged is to scan all privileges */
1236 if (!NT_STATUS_IS_OK(ret = privilege_enumerate_accounts(&sid_list, &num_entries))) {
1240 if (q_u->enum_context >= num_entries)
1241 return NT_STATUS_NO_MORE_ENTRIES;
1243 sids->ptr_sid = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_entries-q_u->enum_context);
1244 sids->sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_entries-q_u->enum_context);
1246 if (sids->ptr_sid==NULL || sids->sid==NULL) {
1247 SAFE_FREE(sid_list);
1248 return NT_STATUS_NO_MEMORY;
1251 for (i = q_u->enum_context, j = 0; i < num_entries; i++, j++) {
1252 init_dom_sid2(&(*sids).sid[j], &sid_list[i]);
1253 (*sids).ptr_sid[j] = 1;
1256 SAFE_FREE(sid_list);
1258 init_lsa_r_enum_accounts(r_u, num_entries);
1260 return NT_STATUS_OK;
1264 NTSTATUS _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u)
1266 fstring username, domname;
1267 user_struct *vuser = get_valid_user_struct(p->vuid);
1270 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1272 fstrcpy(username, vuser->user.smb_name);
1273 fstrcpy(domname, vuser->user.domain);
1275 r_u->ptr_user_name = 1;
1276 init_unistr2(&r_u->uni2_user_name, username, UNI_STR_TERMINATE);
1277 init_uni_hdr(&r_u->hdr_user_name, &r_u->uni2_user_name);
1281 r_u->ptr_dom_name = 1;
1282 init_unistr2(&r_u->uni2_dom_name, domname, UNI_STR_TERMINATE);
1283 init_uni_hdr(&r_u->hdr_dom_name, &r_u->uni2_dom_name);
1285 r_u->status = NT_STATUS_OK;
1290 /***************************************************************************
1292 ***************************************************************************/
1294 NTSTATUS _lsa_create_account(pipes_struct *p, LSA_Q_CREATEACCOUNT *q_u, LSA_R_CREATEACCOUNT *r_u)
1296 struct lsa_info *handle;
1297 struct lsa_info *info;
1299 /* find the connection policy handle. */
1300 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1301 return NT_STATUS_INVALID_HANDLE;
1303 /* check if the user have enough rights */
1306 * I don't know if it's the right one. not documented.
1307 * but guessed with rpcclient.
1309 if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION))
1310 return NT_STATUS_ACCESS_DENIED;
1312 /* check to see if the pipe_user is a Domain Admin since
1313 account_pol.tdb was already opened as root, this is all we have */
1315 if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1316 return NT_STATUS_ACCESS_DENIED;
1318 if ( is_privileged_sid( &q_u->sid.sid ) )
1319 return NT_STATUS_OBJECT_NAME_COLLISION;
1321 /* associate the user/group SID with the (unique) handle. */
1323 if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
1324 return NT_STATUS_NO_MEMORY;
1327 info->sid = q_u->sid.sid;
1328 info->access = q_u->access;
1330 /* get a (unique) handle. open a policy on it. */
1331 if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
1332 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1334 return privilege_create_account( &info->sid );
1338 /***************************************************************************
1340 ***************************************************************************/
1342 NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENACCOUNT *r_u)
1344 struct lsa_info *handle;
1345 struct lsa_info *info;
1347 /* find the connection policy handle. */
1348 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1349 return NT_STATUS_INVALID_HANDLE;
1351 /* check if the user have enough rights */
1354 * I don't know if it's the right one. not documented.
1355 * but guessed with rpcclient.
1357 if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION))
1358 return NT_STATUS_ACCESS_DENIED;
1360 /* TODO: Fis the parsing routine before reenabling this check! */
1362 if (!lookup_sid(&handle->sid, dom_name, name, &type))
1363 return NT_STATUS_ACCESS_DENIED;
1365 /* associate the user/group SID with the (unique) handle. */
1366 if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
1367 return NT_STATUS_NO_MEMORY;
1370 info->sid = q_u->sid.sid;
1371 info->access = q_u->access;
1373 /* get a (unique) handle. open a policy on it. */
1374 if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
1375 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1377 return NT_STATUS_OK;
1380 /***************************************************************************
1381 For a given SID, enumerate all the privilege this account has.
1382 ***************************************************************************/
1384 NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVSACCOUNT *q_u, LSA_R_ENUMPRIVSACCOUNT *r_u)
1386 struct lsa_info *info=NULL;
1388 PRIVILEGE_SET privileges;
1390 /* find the connection policy handle. */
1391 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1392 return NT_STATUS_INVALID_HANDLE;
1394 if ( !get_privileges_for_sids( &mask, &info->sid, 1 ) )
1395 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1397 privilege_set_init( &privileges );
1399 if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
1401 DEBUG(10,("_lsa_enum_privsaccount: %s has %d privileges\n",
1402 sid_string_static(&info->sid), privileges.count));
1404 r_u->status = init_lsa_r_enum_privsaccount(ps->mem_ctx, r_u, privileges.set, privileges.count, 0);
1407 r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE;
1409 privilege_set_free( &privileges );
1414 /***************************************************************************
1416 ***************************************************************************/
1418 NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA_R_GETSYSTEMACCOUNT *r_u)
1420 struct lsa_info *info=NULL;
1422 /* find the connection policy handle. */
1424 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1425 return NT_STATUS_INVALID_HANDLE;
1427 if (!lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, NULL))
1428 return NT_STATUS_ACCESS_DENIED;
1431 0x01 -> Log on locally
1432 0x02 -> Access this computer from network
1433 0x04 -> Log on as a batch job
1434 0x10 -> Log on as a service
1436 they can be ORed together
1439 r_u->access = PR_LOG_ON_LOCALLY | PR_ACCESS_FROM_NETWORK;
1441 return NT_STATUS_OK;
1444 /***************************************************************************
1445 update the systemaccount information
1446 ***************************************************************************/
1448 NTSTATUS _lsa_setsystemaccount(pipes_struct *p, LSA_Q_SETSYSTEMACCOUNT *q_u, LSA_R_SETSYSTEMACCOUNT *r_u)
1450 struct lsa_info *info=NULL;
1452 r_u->status = NT_STATUS_OK;
1454 /* find the connection policy handle. */
1455 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1456 return NT_STATUS_INVALID_HANDLE;
1458 /* check to see if the pipe_user is a Domain Admin since
1459 account_pol.tdb was already opened as root, this is all we have */
1461 if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1462 return NT_STATUS_ACCESS_DENIED;
1464 if (!pdb_getgrsid(&map, info->sid))
1465 return NT_STATUS_NO_SUCH_GROUP;
1467 return pdb_update_group_mapping_entry(&map);
1470 /***************************************************************************
1471 For a given SID, add some privileges.
1472 ***************************************************************************/
1474 NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u)
1476 struct lsa_info *info = NULL;
1478 PRIVILEGE_SET *set = NULL;
1479 struct current_user user;
1481 /* find the connection policy handle. */
1482 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1483 return NT_STATUS_INVALID_HANDLE;
1485 /* check to see if the pipe_user is root or a Domain Admin since
1486 account_pol.tdb was already opened as root, this is all we have */
1488 get_current_user( &user, p );
1489 if ( user.ut.uid != sec_initial_uid()
1490 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1492 return NT_STATUS_ACCESS_DENIED;
1497 if ( !privilege_set_to_se_priv( &mask, set ) )
1498 return NT_STATUS_NO_SUCH_PRIVILEGE;
1500 if ( !grant_privilege( &info->sid, &mask ) ) {
1501 DEBUG(3,("_lsa_addprivs: grant_privilege(%s) failed!\n",
1502 sid_string_static(&info->sid) ));
1503 DEBUG(3,("Privilege mask:\n"));
1504 dump_se_priv( DBGC_ALL, 3, &mask );
1505 return NT_STATUS_NO_SUCH_PRIVILEGE;
1508 return NT_STATUS_OK;
1511 /***************************************************************************
1512 For a given SID, remove some privileges.
1513 ***************************************************************************/
1515 NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEPRIVS *r_u)
1517 struct lsa_info *info = NULL;
1519 PRIVILEGE_SET *set = NULL;
1520 struct current_user user;
1522 /* find the connection policy handle. */
1523 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1524 return NT_STATUS_INVALID_HANDLE;
1526 /* check to see if the pipe_user is root or a Domain Admin since
1527 account_pol.tdb was already opened as root, this is all we have */
1529 get_current_user( &user, p );
1530 if ( user.ut.uid != sec_initial_uid()
1531 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1533 return NT_STATUS_ACCESS_DENIED;
1538 if ( !privilege_set_to_se_priv( &mask, set ) )
1539 return NT_STATUS_NO_SUCH_PRIVILEGE;
1541 if ( !revoke_privilege( &info->sid, &mask ) ) {
1542 DEBUG(3,("_lsa_removeprivs: revoke_privilege(%s) failed!\n",
1543 sid_string_static(&info->sid) ));
1544 DEBUG(3,("Privilege mask:\n"));
1545 dump_se_priv( DBGC_ALL, 3, &mask );
1546 return NT_STATUS_NO_SUCH_PRIVILEGE;
1549 return NT_STATUS_OK;
1552 /***************************************************************************
1553 For a given SID, remove some privileges.
1554 ***************************************************************************/
1556 NTSTATUS _lsa_query_secobj(pipes_struct *p, LSA_Q_QUERY_SEC_OBJ *q_u, LSA_R_QUERY_SEC_OBJ *r_u)
1558 struct lsa_info *handle=NULL;
1559 SEC_DESC *psd = NULL;
1563 r_u->status = NT_STATUS_OK;
1565 /* find the connection policy handle. */
1566 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1567 return NT_STATUS_INVALID_HANDLE;
1569 /* check if the user have enough rights */
1570 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
1571 return NT_STATUS_ACCESS_DENIED;
1574 switch (q_u->sec_info) {
1576 /* SD contains only the owner */
1578 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
1579 if(!NT_STATUS_IS_OK(status))
1580 return NT_STATUS_NO_MEMORY;
1583 if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1584 return NT_STATUS_NO_MEMORY;
1587 /* SD contains only the ACL */
1589 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
1590 if(!NT_STATUS_IS_OK(status))
1591 return NT_STATUS_NO_MEMORY;
1593 if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1594 return NT_STATUS_NO_MEMORY;
1597 return NT_STATUS_INVALID_LEVEL;
1605 #if 0 /* AD DC work in ongoing in Samba 4 */
1607 /***************************************************************************
1608 ***************************************************************************/
1610 NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_INFO2 *r_u)
1612 struct lsa_info *handle;
1613 const char *nb_name;
1614 char *dns_name = NULL;
1615 char *forest_name = NULL;
1616 DOM_SID *sid = NULL;
1621 r_u->status = NT_STATUS_OK;
1623 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1624 return NT_STATUS_INVALID_HANDLE;
1626 switch (q_u->info_class) {
1628 /* check if the user have enough rights */
1629 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
1630 return NT_STATUS_ACCESS_DENIED;
1632 /* Request PolicyPrimaryDomainInformation. */
1633 switch (lp_server_role()) {
1634 case ROLE_DOMAIN_PDC:
1635 case ROLE_DOMAIN_BDC:
1636 nb_name = get_global_sam_name();
1637 /* ugly temp hack for these next two */
1639 /* This should be a 'netbios domain -> DNS domain' mapping */
1640 dnsdomname[0] = '\0';
1641 get_mydnsdomname(dnsdomname);
1642 strlower_m(dnsdomname);
1644 dns_name = dnsdomname;
1645 forest_name = dnsdomname;
1647 sid = get_global_sam_sid();
1648 secrets_fetch_domain_guid(lp_workgroup(), &guid);
1651 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1653 init_dns_dom_info(&r_u->info.dns_dom_info, nb_name, dns_name,
1654 forest_name,&guid,sid);
1657 DEBUG(0,("_lsa_query_info2: unknown info level in Lsa Query: %d\n", q_u->info_class));
1658 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
1662 if (NT_STATUS_IS_OK(r_u->status)) {
1664 r_u->info_class = q_u->info_class;
1669 #endif /* AD DC work in ongoing in Samba 4 */
1671 /***************************************************************************
1672 ***************************************************************************/
1674 NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R_ADD_ACCT_RIGHTS *r_u)
1676 struct lsa_info *info = NULL;
1680 UNISTR4_ARRAY *uni_privnames = q_u->rights;
1681 struct current_user user;
1684 /* find the connection policy handle. */
1685 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1686 return NT_STATUS_INVALID_HANDLE;
1688 /* check to see if the pipe_user is a Domain Admin since
1689 account_pol.tdb was already opened as root, this is all we have */
1691 get_current_user( &user, p );
1692 if ( user.ut.uid != sec_initial_uid()
1693 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1695 return NT_STATUS_ACCESS_DENIED;
1698 /* according to an NT4 PDC, you can add privileges to SIDs even without
1699 call_lsa_create_account() first. And you can use any arbitrary SID. */
1701 sid_copy( &sid, &q_u->sid.sid );
1703 /* just a little sanity check */
1705 if ( q_u->count != uni_privnames->count ) {
1706 DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n"));
1707 return NT_STATUS_INVALID_HANDLE;
1710 for ( i=0; i<q_u->count; i++ ) {
1711 UNISTR4 *uni4_str = &uni_privnames->strings[i];
1713 /* only try to add non-null strings */
1715 if ( !uni4_str->string )
1718 rpcstr_pull( privname, uni4_str->string->buffer, sizeof(privname), -1, STR_TERMINATE );
1720 if ( !grant_privilege_by_name( &sid, privname ) ) {
1721 DEBUG(2,("_lsa_add_acct_rights: Failed to add privilege [%s]\n", privname ));
1722 return NT_STATUS_NO_SUCH_PRIVILEGE;
1726 return NT_STATUS_OK;
1729 /***************************************************************************
1730 ***************************************************************************/
1732 NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u, LSA_R_REMOVE_ACCT_RIGHTS *r_u)
1734 struct lsa_info *info = NULL;
1738 UNISTR4_ARRAY *uni_privnames = q_u->rights;
1739 struct current_user user;
1742 /* find the connection policy handle. */
1743 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1744 return NT_STATUS_INVALID_HANDLE;
1746 /* check to see if the pipe_user is a Domain Admin since
1747 account_pol.tdb was already opened as root, this is all we have */
1749 get_current_user( &user, p );
1750 if ( user.ut.uid != sec_initial_uid()
1751 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1753 return NT_STATUS_ACCESS_DENIED;
1756 sid_copy( &sid, &q_u->sid.sid );
1758 if ( q_u->removeall ) {
1759 if ( !revoke_all_privileges( &sid ) )
1760 return NT_STATUS_ACCESS_DENIED;
1762 return NT_STATUS_OK;
1765 /* just a little sanity check */
1767 if ( q_u->count != uni_privnames->count ) {
1768 DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n"));
1769 return NT_STATUS_INVALID_HANDLE;
1772 for ( i=0; i<q_u->count; i++ ) {
1773 UNISTR4 *uni4_str = &uni_privnames->strings[i];
1775 /* only try to add non-null strings */
1777 if ( !uni4_str->string )
1780 rpcstr_pull( privname, uni4_str->string->buffer, sizeof(privname), -1, STR_TERMINATE );
1782 if ( !revoke_privilege_by_name( &sid, privname ) ) {
1783 DEBUG(2,("_lsa_remove_acct_rights: Failed to revoke privilege [%s]\n", privname ));
1784 return NT_STATUS_NO_SUCH_PRIVILEGE;
1788 return NT_STATUS_OK;
1792 /***************************************************************************
1793 ***************************************************************************/
1795 NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA_R_ENUM_ACCT_RIGHTS *r_u)
1797 struct lsa_info *info = NULL;
1799 PRIVILEGE_SET privileges;
1803 /* find the connection policy handle. */
1805 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1806 return NT_STATUS_INVALID_HANDLE;
1808 /* according to an NT4 PDC, you can add privileges to SIDs even without
1809 call_lsa_create_account() first. And you can use any arbitrary SID. */
1811 sid_copy( &sid, &q_u->sid.sid );
1813 if ( !get_privileges_for_sids( &mask, &sid, 1 ) )
1814 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1816 privilege_set_init( &privileges );
1818 if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
1820 DEBUG(10,("_lsa_enum_acct_rights: %s has %d privileges\n",
1821 sid_string_static(&sid), privileges.count));
1823 r_u->status = init_r_enum_acct_rights( r_u, &privileges );
1826 r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE;
1828 privilege_set_free( &privileges );
1834 /***************************************************************************
1835 ***************************************************************************/
1837 NTSTATUS _lsa_lookup_priv_value(pipes_struct *p, LSA_Q_LOOKUP_PRIV_VALUE *q_u, LSA_R_LOOKUP_PRIV_VALUE *r_u)
1839 struct lsa_info *info = NULL;
1841 LUID_ATTR priv_luid;
1844 /* find the connection policy handle. */
1846 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1847 return NT_STATUS_INVALID_HANDLE;
1849 unistr2_to_ascii(name, &q_u->privname.unistring, sizeof(name));
1851 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
1853 if ( !se_priv_from_name( name, &mask ) )
1854 return NT_STATUS_NO_SUCH_PRIVILEGE;
1856 priv_luid = get_privilege_luid( &mask );
1858 r_u->luid.low = priv_luid.luid.low;
1859 r_u->luid.high = priv_luid.luid.high;
1862 return NT_STATUS_OK;