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_rid2s(TALLOC_CTX *mem_ctx,
138 DOM_R_REF *ref, DOM_RID2 *rid2,
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++) {
157 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
159 /* Split name into domain and user component */
161 full_name = rpcstr_pull_unistr2_talloc(mem_ctx, &name[i]);
162 if (full_name == NULL) {
163 DEBUG(0, ("pull_ucs2_talloc failed\n"));
167 DEBUG(5, ("init_lsa_rid2s: looking up name %s\n", full_name));
169 /* We can ignore the result of lookup_name, it will not touch
170 "type" if it's not successful */
172 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
175 DEBUG(5, ("init_lsa_rid2s: %s\n", status ? "found" :
180 case SID_NAME_DOM_GRP:
181 case SID_NAME_DOMAIN:
183 case SID_NAME_WKN_GRP:
184 /* Leave these unchanged */
187 /* Don't hand out anything but the list above */
188 type = SID_NAME_UNKNOWN;
195 if (type != SID_NAME_UNKNOWN) {
196 sid_split_rid(&sid, &rid);
197 dom_idx = init_dom_ref(ref, domain, &sid);
201 init_dom_rid2(&rid2[i], rid, type, dom_idx);
209 /***************************************************************************
210 init_reply_lookup_names
211 ***************************************************************************/
213 static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
214 DOM_R_REF *ref, uint32 num_entries,
215 DOM_RID2 *rid2, uint32 mapped_count)
217 r_l->ptr_dom_ref = 1;
220 r_l->num_entries = num_entries;
221 r_l->ptr_entries = 1;
222 r_l->num_entries2 = num_entries;
225 r_l->mapped_count = mapped_count;
228 /***************************************************************************
229 Init_reply_lookup_sids.
230 ***************************************************************************/
232 static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
233 DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *names,
236 r_l->ptr_dom_ref = ref ? 1 : 0;
239 r_l->mapped_count = mapped_count;
242 static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size)
244 DOM_SID local_adm_sid;
252 init_sec_access(&mask, POLICY_EXECUTE);
253 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
255 sid_copy(&adm_sid, get_global_sam_sid());
256 sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS);
257 init_sec_access(&mask, POLICY_ALL_ACCESS);
258 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
260 sid_copy(&local_adm_sid, &global_sid_Builtin);
261 sid_append_rid(&local_adm_sid, BUILTIN_ALIAS_RID_ADMINS);
262 init_sec_access(&mask, POLICY_ALL_ACCESS);
263 init_sec_ace(&ace[2], &local_adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
265 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
266 return NT_STATUS_NO_MEMORY;
268 if((*sd = make_sec_desc(mem_ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL, psa, sd_size)) == NULL)
269 return NT_STATUS_NO_MEMORY;
274 #if 0 /* AD DC work in ongoing in Samba 4 */
276 /***************************************************************************
278 ***************************************************************************/
280 static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name,
281 const char *dns_name, const char *forest_name,
282 struct uuid *dom_guid, DOM_SID *dom_sid)
284 if (nb_name && *nb_name) {
285 init_unistr2(&r_l->uni_nb_dom_name, nb_name, UNI_FLAGS_NONE);
286 init_uni_hdr(&r_l->hdr_nb_dom_name, &r_l->uni_nb_dom_name);
287 r_l->hdr_nb_dom_name.uni_max_len += 2;
288 r_l->uni_nb_dom_name.uni_max_len += 1;
291 if (dns_name && *dns_name) {
292 init_unistr2(&r_l->uni_dns_dom_name, dns_name, UNI_FLAGS_NONE);
293 init_uni_hdr(&r_l->hdr_dns_dom_name, &r_l->uni_dns_dom_name);
294 r_l->hdr_dns_dom_name.uni_max_len += 2;
295 r_l->uni_dns_dom_name.uni_max_len += 1;
298 if (forest_name && *forest_name) {
299 init_unistr2(&r_l->uni_forest_name, forest_name, UNI_FLAGS_NONE);
300 init_uni_hdr(&r_l->hdr_forest_name, &r_l->uni_forest_name);
301 r_l->hdr_forest_name.uni_max_len += 2;
302 r_l->uni_forest_name.uni_max_len += 1;
305 /* how do we init the guid ? probably should write an init fn */
307 memcpy(&r_l->dom_guid, dom_guid, sizeof(struct uuid));
311 r_l->ptr_dom_sid = 1;
312 init_dom_sid2(&r_l->dom_sid, dom_sid);
315 #endif /* AD DC work in ongoing in Samba 4 */
318 /***************************************************************************
320 ***************************************************************************/
322 NTSTATUS _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL2 *r_u)
324 struct lsa_info *info;
325 SEC_DESC *psd = NULL;
327 uint32 des_access=q_u->des_access;
332 /* map the generic bits to the lsa policy ones */
333 se_map_generic(&des_access, &lsa_generic_mapping);
335 /* get the generic lsa policy SD until we store it */
336 lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
338 if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
339 if (geteuid() != 0) {
342 DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
343 acc_granted, des_access));
344 DEBUGADD(4,("but overwritten by euid == 0\n"));
347 /* This is needed for lsa_open_account and rpcclient .... :-) */
350 acc_granted = POLICY_ALL_ACCESS;
352 /* associate the domain SID with the (unique) handle. */
353 if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
354 return NT_STATUS_NO_MEMORY;
357 sid_copy(&info->sid,get_global_sam_sid());
358 info->access = acc_granted;
360 /* set up the LSA QUERY INFO response */
361 if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
362 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
367 /***************************************************************************
369 ***************************************************************************/
371 NTSTATUS _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL *r_u)
373 struct lsa_info *info;
374 SEC_DESC *psd = NULL;
376 uint32 des_access=q_u->des_access;
381 /* map the generic bits to the lsa policy ones */
382 se_map_generic(&des_access, &lsa_generic_mapping);
384 /* get the generic lsa policy SD until we store it */
385 lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
387 if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
388 if (geteuid() != 0) {
391 DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
392 acc_granted, des_access));
393 DEBUGADD(4,("but overwritten by euid == 0\n"));
394 acc_granted = des_access;
397 /* associate the domain SID with the (unique) handle. */
398 if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
399 return NT_STATUS_NO_MEMORY;
402 sid_copy(&info->sid,get_global_sam_sid());
403 info->access = acc_granted;
405 /* set up the LSA QUERY INFO response */
406 if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
407 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
412 /***************************************************************************
413 _lsa_enum_trust_dom - this needs fixing to do more than return NULL ! JRA.
415 ***************************************************************************/
417 NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u,
418 LSA_R_ENUM_TRUST_DOM *r_u)
420 struct lsa_info *info;
422 struct trustdom_info **domains;
425 * preferred length is set to 5 as a "our" preferred length
426 * nt sets this parameter to 2
427 * update (20.08.2002): it's not preferred length, but preferred size!
428 * it needs further investigation how to optimally choose this value
430 uint32 max_num_domains =
431 q_u->preferred_len < 5 ? q_u->preferred_len : 10;
436 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
437 return NT_STATUS_INVALID_HANDLE;
439 /* check if the user have enough rights */
440 if (!(info->access & POLICY_VIEW_LOCAL_INFORMATION))
441 return NT_STATUS_ACCESS_DENIED;
443 nt_status = secrets_trusted_domains(p->mem_ctx, &num_domains,
446 if (!NT_STATUS_IS_OK(nt_status)) {
450 if (q_u->enum_context < num_domains) {
451 num_thistime = MIN(num_domains, max_num_domains);
453 r_u->status = STATUS_MORE_ENTRIES;
455 if (q_u->enum_context + num_thistime > num_domains) {
456 num_thistime = num_domains - q_u->enum_context;
457 r_u->status = NT_STATUS_OK;
460 next_idx = q_u->enum_context + num_thistime;
463 next_idx = 0xffffffff;
464 r_u->status = NT_STATUS_NO_MORE_ENTRIES;
467 /* set up the lsa_enum_trust_dom response */
469 init_r_enum_trust_dom(p->mem_ctx, r_u, next_idx,
470 num_thistime, domains+q_u->enum_context);
475 /***************************************************************************
476 _lsa_query_info. See the POLICY_INFOMATION_CLASS docs at msdn.
477 ***************************************************************************/
479 NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO *r_u)
481 struct lsa_info *handle;
482 LSA_INFO_UNION *info = &r_u->dom;
487 r_u->status = NT_STATUS_OK;
489 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
490 return NT_STATUS_INVALID_HANDLE;
492 switch (q_u->info_class) {
496 /* check if the user have enough rights */
497 if (!(handle->access & POLICY_VIEW_AUDIT_INFORMATION))
498 return NT_STATUS_ACCESS_DENIED;
500 /* fake info: We audit everything. ;) */
501 info->id2.auditing_enabled = 1;
502 info->id2.count1 = 7;
503 info->id2.count2 = 7;
504 if ((info->id2.auditsettings = TALLOC_ARRAY(p->mem_ctx,uint32, 7)) == NULL)
505 return NT_STATUS_NO_MEMORY;
506 for (i = 0; i < 7; i++)
507 info->id2.auditsettings[i] = 3;
511 /* check if the user have enough rights */
512 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
513 return NT_STATUS_ACCESS_DENIED;
515 /* Request PolicyPrimaryDomainInformation. */
516 switch (lp_server_role()) {
517 case ROLE_DOMAIN_PDC:
518 case ROLE_DOMAIN_BDC:
519 name = get_global_sam_name();
520 sid = get_global_sam_sid();
522 case ROLE_DOMAIN_MEMBER:
523 name = lp_workgroup();
524 /* We need to return the Domain SID here. */
525 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid))
528 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
530 case ROLE_STANDALONE:
531 name = lp_workgroup();
535 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
537 init_dom_query(&r_u->dom.id3, name, sid);
540 /* check if the user have enough rights */
541 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
542 return NT_STATUS_ACCESS_DENIED;
544 /* Request PolicyAccountDomainInformation. */
545 name = get_global_sam_name();
546 sid = get_global_sam_sid();
547 init_dom_query(&r_u->dom.id5, name, sid);
550 /* check if the user have enough rights */
551 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
552 return NT_STATUS_ACCESS_DENIED;
554 switch (lp_server_role()) {
555 case ROLE_DOMAIN_BDC:
557 * only a BDC is a backup controller
558 * of the domain, it controls.
560 info->id6.server_role = 2;
564 * any other role is a primary
565 * of the domain, it controls.
567 info->id6.server_role = 3;
572 DEBUG(0,("_lsa_query_info: unknown info level in Lsa Query: %d\n", q_u->info_class));
573 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
577 if (NT_STATUS_IS_OK(r_u->status)) {
578 r_u->undoc_buffer = 0x22000000; /* bizarre */
579 r_u->info_class = q_u->info_class;
585 /***************************************************************************
587 ***************************************************************************/
589 NTSTATUS _lsa_lookup_sids(pipes_struct *p,
590 LSA_Q_LOOKUP_SIDS *q_u,
591 LSA_R_LOOKUP_SIDS *r_u)
593 struct lsa_info *handle;
596 const DOM_SID **sids;
597 uint32 mapped_count = 0;
599 struct lsa_dom_info *dom_infos;
600 struct lsa_name_info *name_infos;
602 DOM_R_REF *ref = NULL;
603 LSA_TRANS_NAME_ENUM *names = NULL;
605 names = TALLOC_ZERO_P(p->mem_ctx, LSA_TRANS_NAME_ENUM);
607 if ((q_u->level < 1) || (q_u->level > 6)) {
608 r_u->status = NT_STATUS_INVALID_PARAMETER;
612 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
613 r_u->status = NT_STATUS_INVALID_HANDLE;
617 /* check if the user have enough rights */
618 if (!(handle->access & POLICY_LOOKUP_NAMES)) {
619 r_u->status = NT_STATUS_ACCESS_DENIED;
623 num_sids = q_u->sids.num_entries;
624 if (num_sids > MAX_LOOKUP_SIDS) {
625 DEBUG(5,("_lsa_lookup_sids: limit of %d exceeded, truncating "
626 "SID lookup list to %d\n",
627 MAX_LOOKUP_SIDS, num_sids));
628 r_u->status = NT_STATUS_NONE_MAPPED;
632 ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
634 sids = TALLOC_ARRAY(p->mem_ctx, const DOM_SID *, num_sids);
635 if ((ref == NULL) || (names == NULL) || (sids == NULL)) {
636 r_u->status = NT_STATUS_NO_MEMORY;
640 for (i=0; i<num_sids; i++) {
641 sids[i] = &q_u->sids.sid[i].sid;
644 r_u->status = lookup_sids(p->mem_ctx, num_sids, sids, q_u->level,
645 &dom_infos, &name_infos);
647 if (!NT_STATUS_IS_OK(r_u->status)) {
652 names->name = TALLOC_ARRAY(names, LSA_TRANS_NAME, num_sids);
653 names->uni_name = TALLOC_ARRAY(names, UNISTR2, num_sids);
654 if ((names->name == NULL) || (names->uni_name == NULL)) {
655 r_u->status = NT_STATUS_NO_MEMORY;
660 for (i=0; i<MAX_REF_DOMAINS; i++) {
662 if (!dom_infos[i].valid) {
666 if (init_dom_ref(ref, dom_infos[i].name,
667 &dom_infos[i].sid) != i) {
668 DEBUG(0, ("Domain %s mentioned twice??\n",
670 r_u->status = NT_STATUS_INTERNAL_ERROR;
675 for (i=0; i<num_sids; i++) {
676 struct lsa_name_info *name = &name_infos[i];
678 if (name->type == SID_NAME_UNKNOWN) {
680 name->name = talloc_asprintf(p->mem_ctx, "%8.8x",
682 if (name->name == NULL) {
683 r_u->status = NT_STATUS_NO_MEMORY;
689 init_lsa_trans_name(&names->name[i], &names->uni_name[i],
690 name->type, name->name, name->dom_idx);
693 names->num_entries = num_sids;
694 names->ptr_trans_names = 1;
695 names->num_entries2 = num_sids;
697 r_u->status = NT_STATUS_NONE_MAPPED;
698 if (mapped_count > 0) {
699 r_u->status = (mapped_count < num_sids) ?
700 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
703 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
704 num_sids, mapped_count, nt_errstr(r_u->status)));
707 init_reply_lookup_sids(r_u, ref, names, mapped_count);
712 /***************************************************************************
713 lsa_reply_lookup_names
714 ***************************************************************************/
716 NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_NAMES *r_u)
718 struct lsa_info *handle;
719 UNISTR2 *names = q_u->uni_name;
720 int num_entries = q_u->num_entries;
723 uint32 mapped_count = 0;
726 if (num_entries > MAX_LOOKUP_SIDS) {
727 num_entries = MAX_LOOKUP_SIDS;
728 DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries));
731 /* Probably the lookup_level is some sort of bitmask. */
732 if (q_u->lookup_level == 1) {
733 flags = LOOKUP_NAME_ALL;
736 ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
737 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID2, num_entries);
739 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
740 r_u->status = NT_STATUS_INVALID_HANDLE;
744 /* check if the user have enough rights */
745 if (!(handle->access & POLICY_LOOKUP_NAMES)) {
746 r_u->status = NT_STATUS_ACCESS_DENIED;
751 return NT_STATUS_NO_MEMORY;
753 /* set up the LSA Lookup RIDs response */
754 mapped_count = init_lsa_rid2s(p->mem_ctx, ref, rids, num_entries,
758 if (NT_STATUS_IS_OK(r_u->status)) {
759 if (mapped_count == 0)
760 r_u->status = NT_STATUS_NONE_MAPPED;
761 else if (mapped_count != num_entries)
762 r_u->status = STATUS_SOME_UNMAPPED;
764 init_reply_lookup_names(r_u, ref, num_entries, rids, mapped_count);
769 /***************************************************************************
770 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
771 ***************************************************************************/
773 NTSTATUS _lsa_close(pipes_struct *p, LSA_Q_CLOSE *q_u, LSA_R_CLOSE *r_u)
775 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
776 return NT_STATUS_INVALID_HANDLE;
778 close_policy_hnd(p, &q_u->pol);
782 /***************************************************************************
783 ***************************************************************************/
785 NTSTATUS _lsa_open_secret(pipes_struct *p, LSA_Q_OPEN_SECRET *q_u, LSA_R_OPEN_SECRET *r_u)
787 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
790 /***************************************************************************
791 ***************************************************************************/
793 NTSTATUS _lsa_open_trusted_domain(pipes_struct *p, LSA_Q_OPEN_TRUSTED_DOMAIN *q_u, LSA_R_OPEN_TRUSTED_DOMAIN *r_u)
795 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
798 /***************************************************************************
799 ***************************************************************************/
801 NTSTATUS _lsa_create_trusted_domain(pipes_struct *p, LSA_Q_CREATE_TRUSTED_DOMAIN *q_u, LSA_R_CREATE_TRUSTED_DOMAIN *r_u)
803 return NT_STATUS_ACCESS_DENIED;
806 /***************************************************************************
807 ***************************************************************************/
809 NTSTATUS _lsa_create_secret(pipes_struct *p, LSA_Q_CREATE_SECRET *q_u, LSA_R_CREATE_SECRET *r_u)
811 return NT_STATUS_ACCESS_DENIED;
814 /***************************************************************************
815 ***************************************************************************/
817 NTSTATUS _lsa_set_secret(pipes_struct *p, LSA_Q_SET_SECRET *q_u, LSA_R_SET_SECRET *r_u)
819 return NT_STATUS_ACCESS_DENIED;
822 /***************************************************************************
823 ***************************************************************************/
825 NTSTATUS _lsa_delete_object(pipes_struct *p, LSA_Q_DELETE_OBJECT *q_u, LSA_R_DELETE_OBJECT *r_u)
827 return NT_STATUS_ACCESS_DENIED;
830 /***************************************************************************
832 ***************************************************************************/
834 NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIVS *r_u)
836 struct lsa_info *handle;
838 uint32 enum_context = q_u->enum_context;
839 int num_privs = count_all_privileges();
840 LSA_PRIV_ENTRY *entries = NULL;
843 /* remember that the enum_context starts at 0 and not 1 */
845 if ( enum_context >= num_privs )
846 return NT_STATUS_NO_MORE_ENTRIES;
848 DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n",
849 enum_context, num_privs));
851 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
852 return NT_STATUS_INVALID_HANDLE;
854 /* check if the user have enough rights
855 I don't know if it's the right one. not documented. */
857 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
858 return NT_STATUS_ACCESS_DENIED;
860 if ( !(entries = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_PRIV_ENTRY, num_privs )) )
861 return NT_STATUS_NO_MEMORY;
863 for (i = 0; i < num_privs; i++) {
864 if( i < enum_context) {
865 init_unistr2(&entries[i].name, NULL, UNI_FLAGS_NONE);
866 init_uni_hdr(&entries[i].hdr_name, &entries[i].name);
868 entries[i].luid_low = 0;
869 entries[i].luid_high = 0;
871 init_unistr2(&entries[i].name, privs[i].name, UNI_FLAGS_NONE);
872 init_uni_hdr(&entries[i].hdr_name, &entries[i].name);
874 luid = get_privilege_luid( &privs[i].se_priv );
876 entries[i].luid_low = luid.luid.low;
877 entries[i].luid_high = luid.luid.high;
881 enum_context = num_privs;
883 init_lsa_r_enum_privs(r_u, enum_context, num_privs, entries);
888 /***************************************************************************
889 _lsa_priv_get_dispname.
890 ***************************************************************************/
892 NTSTATUS _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, LSA_R_PRIV_GET_DISPNAME *r_u)
894 struct lsa_info *handle;
896 const char *description;
898 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
899 return NT_STATUS_INVALID_HANDLE;
901 /* check if the user have enough rights */
904 * I don't know if it's the right one. not documented.
906 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
907 return NT_STATUS_ACCESS_DENIED;
909 unistr2_to_ascii(name_asc, &q_u->name, sizeof(name_asc));
911 DEBUG(10,("_lsa_priv_get_dispname: name = %s\n", name_asc));
913 description = get_privilege_dispname( name_asc );
916 DEBUG(10,("_lsa_priv_get_dispname: display name = %s\n", description));
918 init_unistr2(&r_u->desc, description, UNI_FLAGS_NONE);
919 init_uni_hdr(&r_u->hdr_desc, &r_u->desc);
921 r_u->ptr_info = 0xdeadbeef;
922 r_u->lang_id = q_u->lang_id;
926 DEBUG(10,("_lsa_priv_get_dispname: doesn't exist\n"));
930 return NT_STATUS_NO_SUCH_PRIVILEGE;
934 /***************************************************************************
936 ***************************************************************************/
938 NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENUM_ACCOUNTS *r_u)
940 struct lsa_info *handle;
942 int i, j, num_entries;
943 LSA_SID_ENUM *sids=&r_u->sids;
946 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
947 return NT_STATUS_INVALID_HANDLE;
949 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
950 return NT_STATUS_ACCESS_DENIED;
955 /* The only way we can currently find out all the SIDs that have been
956 privileged is to scan all privileges */
958 if (!NT_STATUS_IS_OK(ret = privilege_enumerate_accounts(&sid_list, &num_entries))) {
962 if (q_u->enum_context >= num_entries)
963 return NT_STATUS_NO_MORE_ENTRIES;
965 sids->ptr_sid = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_entries-q_u->enum_context);
966 sids->sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_entries-q_u->enum_context);
968 if (sids->ptr_sid==NULL || sids->sid==NULL) {
970 return NT_STATUS_NO_MEMORY;
973 for (i = q_u->enum_context, j = 0; i < num_entries; i++, j++) {
974 init_dom_sid2(&(*sids).sid[j], &sid_list[i]);
975 (*sids).ptr_sid[j] = 1;
980 init_lsa_r_enum_accounts(r_u, num_entries);
986 NTSTATUS _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u)
988 fstring username, domname;
989 user_struct *vuser = get_valid_user_struct(p->vuid);
992 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
994 fstrcpy(username, vuser->user.smb_name);
995 fstrcpy(domname, vuser->user.domain);
997 r_u->ptr_user_name = 1;
998 init_unistr2(&r_u->uni2_user_name, username, UNI_STR_TERMINATE);
999 init_uni_hdr(&r_u->hdr_user_name, &r_u->uni2_user_name);
1003 r_u->ptr_dom_name = 1;
1004 init_unistr2(&r_u->uni2_dom_name, domname, UNI_STR_TERMINATE);
1005 init_uni_hdr(&r_u->hdr_dom_name, &r_u->uni2_dom_name);
1007 r_u->status = NT_STATUS_OK;
1012 /***************************************************************************
1014 ***************************************************************************/
1016 NTSTATUS _lsa_create_account(pipes_struct *p, LSA_Q_CREATEACCOUNT *q_u, LSA_R_CREATEACCOUNT *r_u)
1018 struct lsa_info *handle;
1019 struct lsa_info *info;
1021 /* find the connection policy handle. */
1022 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1023 return NT_STATUS_INVALID_HANDLE;
1025 /* check if the user have enough rights */
1028 * I don't know if it's the right one. not documented.
1029 * but guessed with rpcclient.
1031 if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION))
1032 return NT_STATUS_ACCESS_DENIED;
1034 /* check to see if the pipe_user is a Domain Admin since
1035 account_pol.tdb was already opened as root, this is all we have */
1037 if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1038 return NT_STATUS_ACCESS_DENIED;
1040 if ( is_privileged_sid( &q_u->sid.sid ) )
1041 return NT_STATUS_OBJECT_NAME_COLLISION;
1043 /* associate the user/group SID with the (unique) handle. */
1045 if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
1046 return NT_STATUS_NO_MEMORY;
1049 info->sid = q_u->sid.sid;
1050 info->access = q_u->access;
1052 /* get a (unique) handle. open a policy on it. */
1053 if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
1054 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1056 return privilege_create_account( &info->sid );
1060 /***************************************************************************
1062 ***************************************************************************/
1064 NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENACCOUNT *r_u)
1066 struct lsa_info *handle;
1067 struct lsa_info *info;
1069 /* find the connection policy handle. */
1070 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1071 return NT_STATUS_INVALID_HANDLE;
1073 /* check if the user have enough rights */
1076 * I don't know if it's the right one. not documented.
1077 * but guessed with rpcclient.
1079 if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION))
1080 return NT_STATUS_ACCESS_DENIED;
1082 /* TODO: Fis the parsing routine before reenabling this check! */
1084 if (!lookup_sid(&handle->sid, dom_name, name, &type))
1085 return NT_STATUS_ACCESS_DENIED;
1087 /* associate the user/group SID with the (unique) handle. */
1088 if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
1089 return NT_STATUS_NO_MEMORY;
1092 info->sid = q_u->sid.sid;
1093 info->access = q_u->access;
1095 /* get a (unique) handle. open a policy on it. */
1096 if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
1097 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1099 return NT_STATUS_OK;
1102 /***************************************************************************
1103 For a given SID, enumerate all the privilege this account has.
1104 ***************************************************************************/
1106 NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVSACCOUNT *q_u, LSA_R_ENUMPRIVSACCOUNT *r_u)
1108 struct lsa_info *info=NULL;
1110 PRIVILEGE_SET privileges;
1112 /* find the connection policy handle. */
1113 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1114 return NT_STATUS_INVALID_HANDLE;
1116 if ( !get_privileges_for_sids( &mask, &info->sid, 1 ) )
1117 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1119 privilege_set_init( &privileges );
1121 if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
1123 DEBUG(10,("_lsa_enum_privsaccount: %s has %d privileges\n",
1124 sid_string_static(&info->sid), privileges.count));
1126 r_u->status = init_lsa_r_enum_privsaccount(ps->mem_ctx, r_u, privileges.set, privileges.count, 0);
1129 r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE;
1131 privilege_set_free( &privileges );
1136 /***************************************************************************
1138 ***************************************************************************/
1140 NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA_R_GETSYSTEMACCOUNT *r_u)
1142 struct lsa_info *info=NULL;
1144 /* find the connection policy handle. */
1146 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1147 return NT_STATUS_INVALID_HANDLE;
1149 if (!lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, NULL))
1150 return NT_STATUS_ACCESS_DENIED;
1153 0x01 -> Log on locally
1154 0x02 -> Access this computer from network
1155 0x04 -> Log on as a batch job
1156 0x10 -> Log on as a service
1158 they can be ORed together
1161 r_u->access = PR_LOG_ON_LOCALLY | PR_ACCESS_FROM_NETWORK;
1163 return NT_STATUS_OK;
1166 /***************************************************************************
1167 update the systemaccount information
1168 ***************************************************************************/
1170 NTSTATUS _lsa_setsystemaccount(pipes_struct *p, LSA_Q_SETSYSTEMACCOUNT *q_u, LSA_R_SETSYSTEMACCOUNT *r_u)
1172 struct lsa_info *info=NULL;
1174 r_u->status = NT_STATUS_OK;
1176 /* find the connection policy handle. */
1177 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1178 return NT_STATUS_INVALID_HANDLE;
1180 /* check to see if the pipe_user is a Domain Admin since
1181 account_pol.tdb was already opened as root, this is all we have */
1183 if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1184 return NT_STATUS_ACCESS_DENIED;
1186 if (!pdb_getgrsid(&map, info->sid))
1187 return NT_STATUS_NO_SUCH_GROUP;
1189 return pdb_update_group_mapping_entry(&map);
1192 /***************************************************************************
1193 For a given SID, add some privileges.
1194 ***************************************************************************/
1196 NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u)
1198 struct lsa_info *info = NULL;
1200 PRIVILEGE_SET *set = NULL;
1201 struct current_user user;
1203 /* find the connection policy handle. */
1204 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1205 return NT_STATUS_INVALID_HANDLE;
1207 /* check to see if the pipe_user is root or a Domain Admin since
1208 account_pol.tdb was already opened as root, this is all we have */
1210 get_current_user( &user, p );
1211 if ( user.ut.uid != sec_initial_uid()
1212 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1214 return NT_STATUS_ACCESS_DENIED;
1219 if ( !privilege_set_to_se_priv( &mask, set ) )
1220 return NT_STATUS_NO_SUCH_PRIVILEGE;
1222 if ( !grant_privilege( &info->sid, &mask ) ) {
1223 DEBUG(3,("_lsa_addprivs: grant_privilege(%s) failed!\n",
1224 sid_string_static(&info->sid) ));
1225 DEBUG(3,("Privilege mask:\n"));
1226 dump_se_priv( DBGC_ALL, 3, &mask );
1227 return NT_STATUS_NO_SUCH_PRIVILEGE;
1230 return NT_STATUS_OK;
1233 /***************************************************************************
1234 For a given SID, remove some privileges.
1235 ***************************************************************************/
1237 NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEPRIVS *r_u)
1239 struct lsa_info *info = NULL;
1241 PRIVILEGE_SET *set = NULL;
1242 struct current_user user;
1244 /* find the connection policy handle. */
1245 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1246 return NT_STATUS_INVALID_HANDLE;
1248 /* check to see if the pipe_user is root or a Domain Admin since
1249 account_pol.tdb was already opened as root, this is all we have */
1251 get_current_user( &user, p );
1252 if ( user.ut.uid != sec_initial_uid()
1253 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1255 return NT_STATUS_ACCESS_DENIED;
1260 if ( !privilege_set_to_se_priv( &mask, set ) )
1261 return NT_STATUS_NO_SUCH_PRIVILEGE;
1263 if ( !revoke_privilege( &info->sid, &mask ) ) {
1264 DEBUG(3,("_lsa_removeprivs: revoke_privilege(%s) failed!\n",
1265 sid_string_static(&info->sid) ));
1266 DEBUG(3,("Privilege mask:\n"));
1267 dump_se_priv( DBGC_ALL, 3, &mask );
1268 return NT_STATUS_NO_SUCH_PRIVILEGE;
1271 return NT_STATUS_OK;
1274 /***************************************************************************
1275 For a given SID, remove some privileges.
1276 ***************************************************************************/
1278 NTSTATUS _lsa_query_secobj(pipes_struct *p, LSA_Q_QUERY_SEC_OBJ *q_u, LSA_R_QUERY_SEC_OBJ *r_u)
1280 struct lsa_info *handle=NULL;
1281 SEC_DESC *psd = NULL;
1285 r_u->status = NT_STATUS_OK;
1287 /* find the connection policy handle. */
1288 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1289 return NT_STATUS_INVALID_HANDLE;
1291 /* check if the user have enough rights */
1292 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
1293 return NT_STATUS_ACCESS_DENIED;
1296 switch (q_u->sec_info) {
1298 /* SD contains only the owner */
1300 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
1301 if(!NT_STATUS_IS_OK(status))
1302 return NT_STATUS_NO_MEMORY;
1305 if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1306 return NT_STATUS_NO_MEMORY;
1309 /* SD contains only the ACL */
1311 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
1312 if(!NT_STATUS_IS_OK(status))
1313 return NT_STATUS_NO_MEMORY;
1315 if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1316 return NT_STATUS_NO_MEMORY;
1319 return NT_STATUS_INVALID_LEVEL;
1327 #if 0 /* AD DC work in ongoing in Samba 4 */
1329 /***************************************************************************
1330 ***************************************************************************/
1332 NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_INFO2 *r_u)
1334 struct lsa_info *handle;
1335 const char *nb_name;
1336 char *dns_name = NULL;
1337 char *forest_name = NULL;
1338 DOM_SID *sid = NULL;
1343 r_u->status = NT_STATUS_OK;
1345 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1346 return NT_STATUS_INVALID_HANDLE;
1348 switch (q_u->info_class) {
1350 /* check if the user have enough rights */
1351 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
1352 return NT_STATUS_ACCESS_DENIED;
1354 /* Request PolicyPrimaryDomainInformation. */
1355 switch (lp_server_role()) {
1356 case ROLE_DOMAIN_PDC:
1357 case ROLE_DOMAIN_BDC:
1358 nb_name = get_global_sam_name();
1359 /* ugly temp hack for these next two */
1361 /* This should be a 'netbios domain -> DNS domain' mapping */
1362 dnsdomname[0] = '\0';
1363 get_mydnsdomname(dnsdomname);
1364 strlower_m(dnsdomname);
1366 dns_name = dnsdomname;
1367 forest_name = dnsdomname;
1369 sid = get_global_sam_sid();
1370 secrets_fetch_domain_guid(lp_workgroup(), &guid);
1373 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1375 init_dns_dom_info(&r_u->info.dns_dom_info, nb_name, dns_name,
1376 forest_name,&guid,sid);
1379 DEBUG(0,("_lsa_query_info2: unknown info level in Lsa Query: %d\n", q_u->info_class));
1380 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
1384 if (NT_STATUS_IS_OK(r_u->status)) {
1386 r_u->info_class = q_u->info_class;
1391 #endif /* AD DC work in ongoing in Samba 4 */
1393 /***************************************************************************
1394 ***************************************************************************/
1396 NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R_ADD_ACCT_RIGHTS *r_u)
1398 struct lsa_info *info = NULL;
1402 UNISTR4_ARRAY *uni_privnames = q_u->rights;
1403 struct current_user user;
1406 /* find the connection policy handle. */
1407 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1408 return NT_STATUS_INVALID_HANDLE;
1410 /* check to see if the pipe_user is a Domain Admin since
1411 account_pol.tdb was already opened as root, this is all we have */
1413 get_current_user( &user, p );
1414 if ( user.ut.uid != sec_initial_uid()
1415 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1417 return NT_STATUS_ACCESS_DENIED;
1420 /* according to an NT4 PDC, you can add privileges to SIDs even without
1421 call_lsa_create_account() first. And you can use any arbitrary SID. */
1423 sid_copy( &sid, &q_u->sid.sid );
1425 /* just a little sanity check */
1427 if ( q_u->count != uni_privnames->count ) {
1428 DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n"));
1429 return NT_STATUS_INVALID_HANDLE;
1432 for ( i=0; i<q_u->count; i++ ) {
1433 UNISTR4 *uni4_str = &uni_privnames->strings[i];
1435 /* only try to add non-null strings */
1437 if ( !uni4_str->string )
1440 rpcstr_pull( privname, uni4_str->string->buffer, sizeof(privname), -1, STR_TERMINATE );
1442 if ( !grant_privilege_by_name( &sid, privname ) ) {
1443 DEBUG(2,("_lsa_add_acct_rights: Failed to add privilege [%s]\n", privname ));
1444 return NT_STATUS_NO_SUCH_PRIVILEGE;
1448 return NT_STATUS_OK;
1451 /***************************************************************************
1452 ***************************************************************************/
1454 NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u, LSA_R_REMOVE_ACCT_RIGHTS *r_u)
1456 struct lsa_info *info = NULL;
1460 UNISTR4_ARRAY *uni_privnames = q_u->rights;
1461 struct current_user user;
1464 /* find the connection policy handle. */
1465 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1466 return NT_STATUS_INVALID_HANDLE;
1468 /* check to see if the pipe_user is a Domain Admin since
1469 account_pol.tdb was already opened as root, this is all we have */
1471 get_current_user( &user, p );
1472 if ( user.ut.uid != sec_initial_uid()
1473 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
1475 return NT_STATUS_ACCESS_DENIED;
1478 sid_copy( &sid, &q_u->sid.sid );
1480 if ( q_u->removeall ) {
1481 if ( !revoke_all_privileges( &sid ) )
1482 return NT_STATUS_ACCESS_DENIED;
1484 return NT_STATUS_OK;
1487 /* just a little sanity check */
1489 if ( q_u->count != uni_privnames->count ) {
1490 DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n"));
1491 return NT_STATUS_INVALID_HANDLE;
1494 for ( i=0; i<q_u->count; i++ ) {
1495 UNISTR4 *uni4_str = &uni_privnames->strings[i];
1497 /* only try to add non-null strings */
1499 if ( !uni4_str->string )
1502 rpcstr_pull( privname, uni4_str->string->buffer, sizeof(privname), -1, STR_TERMINATE );
1504 if ( !revoke_privilege_by_name( &sid, privname ) ) {
1505 DEBUG(2,("_lsa_remove_acct_rights: Failed to revoke privilege [%s]\n", privname ));
1506 return NT_STATUS_NO_SUCH_PRIVILEGE;
1510 return NT_STATUS_OK;
1514 /***************************************************************************
1515 ***************************************************************************/
1517 NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA_R_ENUM_ACCT_RIGHTS *r_u)
1519 struct lsa_info *info = NULL;
1521 PRIVILEGE_SET privileges;
1525 /* find the connection policy handle. */
1527 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1528 return NT_STATUS_INVALID_HANDLE;
1530 /* according to an NT4 PDC, you can add privileges to SIDs even without
1531 call_lsa_create_account() first. And you can use any arbitrary SID. */
1533 sid_copy( &sid, &q_u->sid.sid );
1535 if ( !get_privileges_for_sids( &mask, &sid, 1 ) )
1536 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1538 privilege_set_init( &privileges );
1540 if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
1542 DEBUG(10,("_lsa_enum_acct_rights: %s has %d privileges\n",
1543 sid_string_static(&sid), privileges.count));
1545 r_u->status = init_r_enum_acct_rights( r_u, &privileges );
1548 r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE;
1550 privilege_set_free( &privileges );
1556 /***************************************************************************
1557 ***************************************************************************/
1559 NTSTATUS _lsa_lookup_priv_value(pipes_struct *p, LSA_Q_LOOKUP_PRIV_VALUE *q_u, LSA_R_LOOKUP_PRIV_VALUE *r_u)
1561 struct lsa_info *info = NULL;
1563 LUID_ATTR priv_luid;
1566 /* find the connection policy handle. */
1568 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1569 return NT_STATUS_INVALID_HANDLE;
1571 unistr2_to_ascii(name, &q_u->privname.unistring, sizeof(name));
1573 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
1575 if ( !se_priv_from_name( name, &mask ) )
1576 return NT_STATUS_NO_SUCH_PRIVILEGE;
1578 priv_luid = get_privilege_luid( &mask );
1580 r_u->luid.low = priv_luid.luid.low;
1581 r_u->luid.high = priv_luid.luid.high;
1584 return NT_STATUS_OK;