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.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 /* This is the implementation of the lsa server code. */
31 #define DBGC_CLASS DBGC_RPC_SRV
40 struct generic_mapping lsa_generic_mapping = {
47 /*******************************************************************
48 Function to free the per handle data.
49 ********************************************************************/
51 static void free_lsa_info(void *ptr)
53 struct lsa_info *lsa = (struct lsa_info *)ptr;
58 /***************************************************************************
60 ***************************************************************************/
62 static void init_dom_query(DOM_QUERY *d_q, const char *dom_name, DOM_SID *dom_sid)
64 d_q->buffer_dom_name = (dom_name != NULL) ? 1 : 0; /* domain buffer pointer */
65 d_q->buffer_dom_sid = (dom_sid != NULL) ? 1 : 0; /* domain sid pointer */
67 /* this string is supposed to be non-null terminated. */
68 /* But the maxlen in this UNISTR2 must include the terminating null. */
69 init_unistr2(&d_q->uni_domain_name, dom_name, UNI_BROKEN_NON_NULL);
72 * I'm not sure why this really odd combination of length
73 * values works, but it does appear to. I need to look at
74 * this *much* more closely - but at the moment leave alone
75 * until it's understood. This allows a W2k client to join
76 * a domain with both odd and even length names... JRA.
81 * The two fields below probably are reversed in meaning, ie.
82 * the first field is probably the str_len, the second the max
83 * len. Both are measured in bytes anyway.
86 d_q->uni_dom_str_len = d_q->uni_domain_name.uni_max_len * 2;
87 d_q->uni_dom_max_len = d_q->uni_domain_name.uni_str_len * 2;
90 init_dom_sid2(&d_q->dom_sid, dom_sid);
93 /***************************************************************************
94 init_dom_ref - adds a domain if it's not already in, returns the index.
95 ***************************************************************************/
97 static int init_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
101 if (dom_name != NULL) {
102 for (num = 0; num < ref->num_ref_doms_1; num++) {
104 rpcstr_pull(domname, &ref->ref_dom[num].uni_dom_name, sizeof(domname), -1, 0);
105 if (strequal(domname, dom_name))
109 num = ref->num_ref_doms_1;
112 if (num >= MAX_REF_DOMAINS) {
113 /* index not found, already at maximum domain limit */
117 ref->num_ref_doms_1 = num+1;
118 ref->ptr_ref_dom = 1;
119 ref->max_entries = MAX_REF_DOMAINS;
120 ref->num_ref_doms_2 = num+1;
122 ref->hdr_ref_dom[num].ptr_dom_sid = dom_sid != NULL ? 1 : 0;
124 init_unistr2(&ref->ref_dom[num].uni_dom_name, dom_name, UNI_FLAGS_NONE);
125 init_uni_hdr(&ref->hdr_ref_dom[num].hdr_dom_name, &ref->ref_dom[num].uni_dom_name);
127 init_dom_sid2(&ref->ref_dom[num].ref_dom, dom_sid );
132 /***************************************************************************
134 ***************************************************************************/
136 static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2,
137 int num_entries, UNISTR2 *name,
138 uint32 *mapped_count, BOOL endian)
144 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
146 become_root(); /* lookup_name can require root privs */
148 for (i = 0; i < num_entries; i++) {
151 uint32 rid = 0xffffffff;
154 fstring dom_name, user;
155 enum SID_NAME_USE name_type = SID_NAME_UNKNOWN;
157 /* Split name into domain and user component */
159 unistr2_to_ascii(full_name, &name[i], sizeof(full_name));
160 split_domain_name(full_name, dom_name, user);
164 DEBUG(5, ("init_lsa_rid2s: looking up name %s\n", full_name));
166 status = lookup_name(dom_name, user, &sid, &name_type);
168 DEBUG(5, ("init_lsa_rid2s: %s\n", status ? "found" :
171 if (status && name_type != SID_NAME_UNKNOWN) {
172 sid_split_rid(&sid, &rid);
173 dom_idx = init_dom_ref(ref, dom_name, &sid);
178 name_type = SID_NAME_UNKNOWN;
181 init_dom_rid2(&rid2[total], rid, name_type, dom_idx);
188 /***************************************************************************
189 init_reply_lookup_names
190 ***************************************************************************/
192 static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
193 DOM_R_REF *ref, uint32 num_entries,
194 DOM_RID2 *rid2, uint32 mapped_count)
196 r_l->ptr_dom_ref = 1;
199 r_l->num_entries = num_entries;
200 r_l->ptr_entries = 1;
201 r_l->num_entries2 = num_entries;
204 r_l->mapped_count = mapped_count;
207 /***************************************************************************
208 Init lsa_trans_names.
209 ***************************************************************************/
211 static void init_lsa_trans_names(TALLOC_CTX *ctx, DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *trn,
212 int num_entries, DOM_SID2 *sid,
213 uint32 *mapped_count)
219 /* Allocate memory for list of names */
221 if (num_entries > 0) {
222 if (!(trn->name = (LSA_TRANS_NAME *)talloc(ctx, sizeof(LSA_TRANS_NAME) *
224 DEBUG(0, ("init_lsa_trans_names(): out of memory\n"));
228 if (!(trn->uni_name = (UNISTR2 *)talloc(ctx, sizeof(UNISTR2) *
230 DEBUG(0, ("init_lsa_trans_names(): out of memory\n"));
235 become_root(); /* Need root to get to passdb to for local sids */
237 for (i = 0; i < num_entries; i++) {
239 DOM_SID find_sid = sid[i].sid;
240 uint32 rid = 0xffffffff;
242 fstring name, dom_name;
243 enum SID_NAME_USE sid_name_use = (enum SID_NAME_USE)0;
245 sid_to_string(name, &find_sid);
246 DEBUG(5, ("init_lsa_trans_names: looking up sid %s\n", name));
248 /* Lookup sid from winbindd */
250 status = lookup_sid(&find_sid, dom_name, name, &sid_name_use);
252 DEBUG(5, ("init_lsa_trans_names: %s\n", status ? "found" :
256 sid_name_use = SID_NAME_UNKNOWN;
257 memset(dom_name, '\0', sizeof(dom_name));
258 sid_to_string(name, &find_sid);
261 DEBUG(10,("init_lsa_trans_names: added unknown user '%s' to "
262 "referenced list.\n", name ));
265 /* Store domain sid in ref array */
266 if (find_sid.num_auths == 5) {
267 sid_split_rid(&find_sid, &rid);
269 dom_idx = init_dom_ref(ref, dom_name, &find_sid);
271 DEBUG(10,("init_lsa_trans_names: added user '%s\\%s' to "
272 "referenced list.\n", dom_name, name ));
276 init_lsa_trans_name(&trn->name[total], &trn->uni_name[total],
277 sid_name_use, name, dom_idx);
283 trn->num_entries = total;
284 trn->ptr_trans_names = 1;
285 trn->num_entries2 = total;
288 /***************************************************************************
289 Init_reply_lookup_sids.
290 ***************************************************************************/
292 static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
293 DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *names,
296 r_l->ptr_dom_ref = 1;
299 r_l->mapped_count = mapped_count;
302 static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size)
304 extern DOM_SID global_sid_World;
305 extern DOM_SID global_sid_Builtin;
306 DOM_SID local_adm_sid;
314 init_sec_access(&mask, POLICY_EXECUTE);
315 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
317 sid_copy(&adm_sid, get_global_sam_sid());
318 sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS);
319 init_sec_access(&mask, POLICY_ALL_ACCESS);
320 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
322 sid_copy(&local_adm_sid, &global_sid_Builtin);
323 sid_append_rid(&local_adm_sid, BUILTIN_ALIAS_RID_ADMINS);
324 init_sec_access(&mask, POLICY_ALL_ACCESS);
325 init_sec_ace(&ace[2], &local_adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
327 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
328 return NT_STATUS_NO_MEMORY;
330 if((*sd = make_sec_desc(mem_ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL, psa, sd_size)) == NULL)
331 return NT_STATUS_NO_MEMORY;
336 /***************************************************************************
338 ***************************************************************************/
340 static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name,
341 const char *dns_name, const char *forest_name,
342 struct uuid *dom_guid, DOM_SID *dom_sid)
344 if (nb_name && *nb_name) {
345 init_unistr2(&r_l->uni_nb_dom_name, nb_name, UNI_FLAGS_NONE);
346 init_uni_hdr(&r_l->hdr_nb_dom_name, &r_l->uni_nb_dom_name);
347 r_l->hdr_nb_dom_name.uni_max_len += 2;
348 r_l->uni_nb_dom_name.uni_max_len += 1;
351 if (dns_name && *dns_name) {
352 init_unistr2(&r_l->uni_dns_dom_name, dns_name, UNI_FLAGS_NONE);
353 init_uni_hdr(&r_l->hdr_dns_dom_name, &r_l->uni_dns_dom_name);
354 r_l->hdr_dns_dom_name.uni_max_len += 2;
355 r_l->uni_dns_dom_name.uni_max_len += 1;
358 if (forest_name && *forest_name) {
359 init_unistr2(&r_l->uni_forest_name, forest_name, UNI_FLAGS_NONE);
360 init_uni_hdr(&r_l->hdr_forest_name, &r_l->uni_forest_name);
361 r_l->hdr_forest_name.uni_max_len += 2;
362 r_l->uni_forest_name.uni_max_len += 1;
365 /* how do we init the guid ? probably should write an init fn */
367 memcpy(&r_l->dom_guid, dom_guid, sizeof(struct uuid));
371 r_l->ptr_dom_sid = 1;
372 init_dom_sid2(&r_l->dom_sid, dom_sid);
376 /***************************************************************************
378 ***************************************************************************/
380 NTSTATUS _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL2 *r_u)
382 struct lsa_info *info;
383 SEC_DESC *psd = NULL;
385 uint32 des_access=q_u->des_access;
390 /* map the generic bits to the lsa policy ones */
391 se_map_generic(&des_access, &lsa_generic_mapping);
393 /* get the generic lsa policy SD until we store it */
394 lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
396 if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
397 if (geteuid() != 0) {
400 DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
401 acc_granted, des_access));
402 DEBUGADD(4,("but overwritten by euid == 0\n"));
403 acc_granted = des_access;
407 /* associate the domain SID with the (unique) handle. */
408 if ((info = (struct lsa_info *)malloc(sizeof(struct lsa_info))) == NULL)
409 return NT_STATUS_NO_MEMORY;
412 sid_copy(&info->sid,get_global_sam_sid());
413 info->access = acc_granted;
415 /* set up the LSA QUERY INFO response */
416 if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
417 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
422 /***************************************************************************
424 ***************************************************************************/
426 NTSTATUS _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL *r_u)
428 struct lsa_info *info;
429 SEC_DESC *psd = NULL;
431 uint32 des_access=q_u->des_access;
436 /* map the generic bits to the lsa policy ones */
437 se_map_generic(&des_access, &lsa_generic_mapping);
439 /* get the generic lsa policy SD until we store it */
440 lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
442 if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
443 if (geteuid() != 0) {
446 DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
447 acc_granted, des_access));
448 DEBUGADD(4,("but overwritten by euid == 0\n"));
449 acc_granted = des_access;
452 /* associate the domain SID with the (unique) handle. */
453 if ((info = (struct lsa_info *)malloc(sizeof(struct lsa_info))) == NULL)
454 return NT_STATUS_NO_MEMORY;
457 sid_copy(&info->sid,get_global_sam_sid());
458 info->access = acc_granted;
460 /* set up the LSA QUERY INFO response */
461 if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
462 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
467 /***************************************************************************
468 _lsa_enum_trust_dom - this needs fixing to do more than return NULL ! JRA.
470 ***************************************************************************/
472 NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_ENUM_TRUST_DOM *r_u)
474 struct lsa_info *info;
475 uint32 enum_context = q_u->enum_context;
478 * preferred length is set to 5 as a "our" preferred length
479 * nt sets this parameter to 2
480 * update (20.08.2002): it's not preferred length, but preferred size!
481 * it needs further investigation how to optimally choose this value
483 uint32 max_num_domains = q_u->preferred_len < 5 ? q_u->preferred_len : 10;
484 TRUSTDOM **trust_doms;
488 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
489 return NT_STATUS_INVALID_HANDLE;
491 /* check if the user have enough rights */
492 if (!(info->access & POLICY_VIEW_LOCAL_INFORMATION))
493 return NT_STATUS_ACCESS_DENIED;
495 nt_status = secrets_get_trusted_domains(p->mem_ctx, (int *)&enum_context, max_num_domains, (int *)&num_domains, &trust_doms);
497 if (!NT_STATUS_IS_OK(nt_status) &&
498 !NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES) &&
499 !NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_MORE_ENTRIES)) {
502 r_u->status = nt_status;
505 /* set up the lsa_enum_trust_dom response */
506 init_r_enum_trust_dom(p->mem_ctx, r_u, enum_context, max_num_domains, num_domains, trust_doms);
511 /***************************************************************************
512 _lsa_query_info. See the POLICY_INFOMATION_CLASS docs at msdn.
513 ***************************************************************************/
515 NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO *r_u)
517 struct lsa_info *handle;
518 LSA_INFO_UNION *info = &r_u->dom;
523 r_u->status = NT_STATUS_OK;
525 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
526 return NT_STATUS_INVALID_HANDLE;
528 switch (q_u->info_class) {
532 /* check if the user have enough rights */
533 if (!(handle->access & POLICY_VIEW_AUDIT_INFORMATION))
534 return NT_STATUS_ACCESS_DENIED;
536 /* fake info: We audit everything. ;) */
537 info->id2.auditing_enabled = 1;
538 info->id2.count1 = 7;
539 info->id2.count2 = 7;
540 if ((info->id2.auditsettings = (uint32 *)talloc(p->mem_ctx,7*sizeof(uint32))) == NULL)
541 return NT_STATUS_NO_MEMORY;
542 for (i = 0; i < 7; i++)
543 info->id2.auditsettings[i] = 3;
547 /* check if the user have enough rights */
548 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
549 return NT_STATUS_ACCESS_DENIED;
551 /* Request PolicyPrimaryDomainInformation. */
552 switch (lp_server_role()) {
553 case ROLE_DOMAIN_PDC:
554 case ROLE_DOMAIN_BDC:
555 name = get_global_sam_name();
556 sid = get_global_sam_sid();
558 case ROLE_DOMAIN_MEMBER:
559 name = lp_workgroup();
560 /* We need to return the Domain SID here. */
561 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid))
564 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
566 case ROLE_STANDALONE:
567 name = lp_workgroup();
571 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
573 init_dom_query(&r_u->dom.id3, name, sid);
576 /* check if the user have enough rights */
577 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
578 return NT_STATUS_ACCESS_DENIED;
580 /* Request PolicyAccountDomainInformation. */
581 name = get_global_sam_name();
582 sid = get_global_sam_sid();
583 init_dom_query(&r_u->dom.id5, name, sid);
586 /* check if the user have enough rights */
587 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
588 return NT_STATUS_ACCESS_DENIED;
590 switch (lp_server_role()) {
591 case ROLE_DOMAIN_BDC:
593 * only a BDC is a backup controller
594 * of the domain, it controls.
596 info->id6.server_role = 2;
600 * any other role is a primary
601 * of the domain, it controls.
603 info->id6.server_role = 3;
608 DEBUG(0,("_lsa_query_info: unknown info level in Lsa Query: %d\n", q_u->info_class));
609 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
613 if (NT_STATUS_IS_OK(r_u->status)) {
614 r_u->undoc_buffer = 0x22000000; /* bizarre */
615 r_u->info_class = q_u->info_class;
621 /***************************************************************************
623 ***************************************************************************/
625 NTSTATUS _lsa_lookup_sids(pipes_struct *p, LSA_Q_LOOKUP_SIDS *q_u, LSA_R_LOOKUP_SIDS *r_u)
627 struct lsa_info *handle;
628 DOM_SID2 *sid = q_u->sids.sid;
629 int num_entries = q_u->sids.num_entries;
630 DOM_R_REF *ref = NULL;
631 LSA_TRANS_NAME_ENUM *names = NULL;
632 uint32 mapped_count = 0;
634 if (num_entries > MAX_LOOKUP_SIDS) {
635 num_entries = MAX_LOOKUP_SIDS;
636 DEBUG(5,("_lsa_lookup_sids: truncating SID lookup list to %d\n", num_entries));
639 ref = (DOM_R_REF *)talloc_zero(p->mem_ctx, sizeof(DOM_R_REF));
640 names = (LSA_TRANS_NAME_ENUM *)talloc_zero(p->mem_ctx, sizeof(LSA_TRANS_NAME_ENUM));
642 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) {
643 r_u->status = NT_STATUS_INVALID_HANDLE;
647 /* check if the user have enough rights */
648 if (!(handle->access & POLICY_LOOKUP_NAMES)) {
649 r_u->status = NT_STATUS_ACCESS_DENIED;
653 return NT_STATUS_NO_MEMORY;
657 /* set up the LSA Lookup SIDs response */
658 init_lsa_trans_names(p->mem_ctx, ref, names, num_entries, sid, &mapped_count);
659 if (mapped_count == 0)
660 r_u->status = NT_STATUS_NONE_MAPPED;
661 else if (mapped_count != num_entries)
662 r_u->status = STATUS_SOME_UNMAPPED;
664 r_u->status = NT_STATUS_OK;
665 init_reply_lookup_sids(r_u, ref, names, mapped_count);
670 /***************************************************************************
671 lsa_reply_lookup_names
672 ***************************************************************************/
674 NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_NAMES *r_u)
676 struct lsa_info *handle;
677 UNISTR2 *names = q_u->uni_name;
678 int num_entries = q_u->num_entries;
681 uint32 mapped_count = 0;
683 if (num_entries > MAX_LOOKUP_SIDS) {
684 num_entries = MAX_LOOKUP_SIDS;
685 DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries));
688 ref = (DOM_R_REF *)talloc_zero(p->mem_ctx, sizeof(DOM_R_REF));
689 rids = (DOM_RID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_RID2)*num_entries);
691 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) {
692 r_u->status = NT_STATUS_INVALID_HANDLE;
696 /* check if the user have enough rights */
697 if (!(handle->access & POLICY_LOOKUP_NAMES)) {
698 r_u->status = NT_STATUS_ACCESS_DENIED;
703 return NT_STATUS_NO_MEMORY;
707 /* set up the LSA Lookup RIDs response */
708 init_lsa_rid2s(ref, rids, num_entries, names, &mapped_count, p->endian);
709 if (mapped_count == 0)
710 r_u->status = NT_STATUS_NONE_MAPPED;
711 else if (mapped_count != num_entries)
712 r_u->status = STATUS_SOME_UNMAPPED;
714 r_u->status = NT_STATUS_OK;
715 init_reply_lookup_names(r_u, ref, num_entries, rids, mapped_count);
720 /***************************************************************************
721 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
722 ***************************************************************************/
724 NTSTATUS _lsa_close(pipes_struct *p, LSA_Q_CLOSE *q_u, LSA_R_CLOSE *r_u)
726 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
727 return NT_STATUS_INVALID_HANDLE;
729 close_policy_hnd(p, &q_u->pol);
733 /***************************************************************************
734 "No more secrets Marty...." :-).
735 ***************************************************************************/
737 NTSTATUS _lsa_open_secret(pipes_struct *p, LSA_Q_OPEN_SECRET *q_u, LSA_R_OPEN_SECRET *r_u)
739 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
742 /***************************************************************************
744 ***************************************************************************/
746 NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIVS *r_u)
748 struct lsa_info *handle;
751 uint32 enum_context=q_u->enum_context;
752 LSA_PRIV_ENTRY *entry;
753 LSA_PRIV_ENTRY *entries=NULL;
755 if (enum_context >= PRIV_ALL_INDEX)
756 return NT_STATUS_NO_MORE_ENTRIES;
758 entries = (LSA_PRIV_ENTRY *)talloc_zero(p->mem_ctx, sizeof(LSA_PRIV_ENTRY) * (PRIV_ALL_INDEX));
760 return NT_STATUS_NO_MEMORY;
762 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
763 return NT_STATUS_INVALID_HANDLE;
765 /* check if the user have enough rights */
768 * I don't know if it's the right one. not documented.
770 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
771 return NT_STATUS_ACCESS_DENIED;
775 DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n", enum_context, PRIV_ALL_INDEX));
777 for (i = 0; i < PRIV_ALL_INDEX; i++, entry++) {
778 if( i<enum_context) {
779 init_unistr2(&entry->name, NULL, UNI_FLAGS_NONE);
780 init_uni_hdr(&entry->hdr_name, &entry->name);
782 entry->luid_high = 0;
784 init_unistr2(&entry->name, privs[i+1].priv, UNI_FLAGS_NONE);
785 init_uni_hdr(&entry->hdr_name, &entry->name);
786 entry->luid_low = privs[i+1].se_priv;
787 entry->luid_high = 0;
791 enum_context = PRIV_ALL_INDEX;
792 init_lsa_r_enum_privs(r_u, enum_context, PRIV_ALL_INDEX, entries);
797 /***************************************************************************
798 _lsa_priv_get_dispname.
799 ***************************************************************************/
801 NTSTATUS _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, LSA_R_PRIV_GET_DISPNAME *r_u)
803 struct lsa_info *handle;
807 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
808 return NT_STATUS_INVALID_HANDLE;
810 /* check if the user have enough rights */
813 * I don't know if it's the right one. not documented.
815 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
816 return NT_STATUS_ACCESS_DENIED;
818 unistr2_to_ascii(name_asc, &q_u->name, sizeof(name_asc));
820 DEBUG(10,("_lsa_priv_get_dispname: %s", name_asc));
822 while (privs[i].se_priv!=SE_ALL_PRIVS && strcmp(name_asc, privs[i].priv))
825 if (privs[i].se_priv!=SE_ALL_PRIVS) {
826 DEBUG(10,(": %s\n", privs[i].description));
827 init_unistr2(&r_u->desc, privs[i].description, UNI_FLAGS_NONE);
828 init_uni_hdr(&r_u->hdr_desc, &r_u->desc);
830 r_u->ptr_info=0xdeadbeef;
831 r_u->lang_id=q_u->lang_id;
834 DEBUG(10,("_lsa_priv_get_dispname: doesn't exist\n"));
836 return NT_STATUS_NO_SUCH_PRIVILEGE;
840 /***************************************************************************
842 ***************************************************************************/
844 NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENUM_ACCOUNTS *r_u)
846 struct lsa_info *handle;
849 LSA_SID_ENUM *sids=&r_u->sids;
853 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
854 return NT_STATUS_INVALID_HANDLE;
856 /* check if the user have enough rights */
859 * I don't know if it's the right one. not documented.
861 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
862 return NT_STATUS_ACCESS_DENIED;
864 /* get the list of mapped groups (domain, local, builtin) */
866 ret = pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED);
869 DEBUG(3,("_lsa_enum_accounts: enumeration of groups failed!\n"));
874 if (q_u->enum_context >= num_entries)
875 return NT_STATUS_NO_MORE_ENTRIES;
877 sids->ptr_sid = (uint32 *)talloc_zero(p->mem_ctx, (num_entries-q_u->enum_context)*sizeof(uint32));
878 sids->sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, (num_entries-q_u->enum_context)*sizeof(DOM_SID2));
880 if (sids->ptr_sid==NULL || sids->sid==NULL) {
882 return NT_STATUS_NO_MEMORY;
885 for (i=q_u->enum_context, j=0; i<num_entries; i++) {
886 init_dom_sid2( &(*sids).sid[j], &map[i].sid);
887 (*sids).ptr_sid[j]=1;
893 init_lsa_r_enum_accounts(r_u, j);
899 NTSTATUS _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u)
901 fstring username, domname;
902 user_struct *vuser = get_valid_user_struct(p->vuid);
905 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
907 fstrcpy(username, vuser->user.smb_name);
908 fstrcpy(domname, vuser->user.domain);
910 r_u->ptr_user_name = 1;
911 init_unistr2(&r_u->uni2_user_name, username, UNI_STR_TERMINATE);
912 init_uni_hdr(&r_u->hdr_user_name, &r_u->uni2_user_name);
916 r_u->ptr_dom_name = 1;
917 init_unistr2(&r_u->uni2_dom_name, domname, UNI_STR_TERMINATE);
918 init_uni_hdr(&r_u->hdr_dom_name, &r_u->uni2_dom_name);
920 r_u->status = NT_STATUS_OK;
925 /***************************************************************************
927 ***************************************************************************/
929 NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENACCOUNT *r_u)
931 struct lsa_info *handle;
932 struct lsa_info *info;
934 r_u->status = NT_STATUS_OK;
936 /* find the connection policy handle. */
937 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
938 return NT_STATUS_INVALID_HANDLE;
940 /* check if the user have enough rights */
943 * I don't know if it's the right one. not documented.
944 * but guessed with rpcclient.
946 if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION))
947 return NT_STATUS_ACCESS_DENIED;
949 /* associate the user/group SID with the (unique) handle. */
950 if ((info = (struct lsa_info *)malloc(sizeof(struct lsa_info))) == NULL)
951 return NT_STATUS_NO_MEMORY;
954 info->sid = q_u->sid.sid;
955 info->access = q_u->access;
957 /* get a (unique) handle. open a policy on it. */
958 if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
959 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
964 /***************************************************************************
965 For a given SID, enumerate all the privilege this account has.
966 ***************************************************************************/
968 NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVSACCOUNT *q_u, LSA_R_ENUMPRIVSACCOUNT *r_u)
970 struct lsa_info *info=NULL;
974 r_u->status = NT_STATUS_OK;
976 /* find the connection policy handle. */
977 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
978 return NT_STATUS_INVALID_HANDLE;
980 if (!pdb_getgrsid(&map, info->sid))
981 return NT_STATUS_NO_SUCH_GROUP;
983 #if 0 /* privileges currently not implemented! */
984 DEBUG(10,("_lsa_enum_privsaccount: %d privileges\n", map.priv_set->count));
985 if (map.priv_set->count!=0) {
987 set=(LUID_ATTR *)talloc(map.priv_set->mem_ctx, map.priv_set.count*sizeof(LUID_ATTR));
989 destroy_privilege(&map.priv_set);
990 return NT_STATUS_NO_MEMORY;
993 for (i = 0; i < map.priv_set.count; i++) {
994 set[i].luid.low = map.priv_set->set[i].luid.low;
995 set[i].luid.high = map.priv_set->set[i].luid.high;
996 set[i].attr = map.priv_set->set[i].attr;
997 DEBUG(10,("_lsa_enum_privsaccount: priv %d: %d:%d:%d\n", i,
998 set[i].luid.high, set[i].luid.low, set[i].attr));
1002 init_lsa_r_enum_privsaccount(ps->mem_ctx, r_u, set, map.priv_set->count, 0);
1003 destroy_privilege(&map.priv_set);
1006 init_lsa_r_enum_privsaccount(ps->mem_ctx, r_u, set, 0, 0);
1011 /***************************************************************************
1013 ***************************************************************************/
1015 NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA_R_GETSYSTEMACCOUNT *r_u)
1017 struct lsa_info *info=NULL;
1019 r_u->status = NT_STATUS_OK;
1021 /* find the connection policy handle. */
1022 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1023 return NT_STATUS_INVALID_HANDLE;
1025 if (!pdb_getgrsid(&map, info->sid))
1026 return NT_STATUS_NO_SUCH_GROUP;
1029 0x01 -> Log on locally
1030 0x02 -> Access this computer from network
1031 0x04 -> Log on as a batch job
1032 0x10 -> Log on as a service
1034 they can be ORed together
1037 r_u->access = PR_LOG_ON_LOCALLY | PR_ACCESS_FROM_NETWORK;
1042 /***************************************************************************
1043 update the systemaccount information
1044 ***************************************************************************/
1046 NTSTATUS _lsa_setsystemaccount(pipes_struct *p, LSA_Q_SETSYSTEMACCOUNT *q_u, LSA_R_SETSYSTEMACCOUNT *r_u)
1048 struct lsa_info *info=NULL;
1050 r_u->status = NT_STATUS_OK;
1052 /* find the connection policy handle. */
1053 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1054 return NT_STATUS_INVALID_HANDLE;
1056 if (!pdb_getgrsid(&map, info->sid))
1057 return NT_STATUS_NO_SUCH_GROUP;
1059 if(!pdb_update_group_mapping_entry(&map))
1060 return NT_STATUS_NO_SUCH_GROUP;
1065 /***************************************************************************
1066 For a given SID, add some privileges.
1067 ***************************************************************************/
1069 NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u)
1072 struct lsa_info *info = NULL;
1075 LUID_ATTR *luid_attr = NULL;
1076 PRIVILEGE_SET *set = NULL;
1079 r_u->status = NT_STATUS_OK;
1081 #if 0 /* privileges are not implemented */
1082 /* find the connection policy handle. */
1083 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1084 return NT_STATUS_INVALID_HANDLE;
1086 if (!pdb_getgrsid(&map, info->sid))
1087 return NT_STATUS_NO_SUCH_GROUP;
1091 for (i = 0; i < set->count; i++) {
1092 luid_attr = &set->set[i];
1094 /* check if the privilege is already there */
1095 if (check_priv_in_privilege(map.priv_set, *luid_attr)){
1096 destroy_privilege(&map.priv_set);
1097 return NT_STATUS_NO_SUCH_PRIVILEGE;
1100 add_privilege(map.priv_set, *luid_attr);
1103 if(!pdb_update_group_mapping_entry(&map))
1104 return NT_STATUS_NO_SUCH_GROUP;
1106 destroy_privilege(&map.priv_set);
1112 /***************************************************************************
1113 For a given SID, remove some privileges.
1114 ***************************************************************************/
1116 NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEPRIVS *r_u)
1119 struct lsa_info *info = NULL;
1122 LUID_ATTR *luid_attr = NULL;
1123 PRIVILEGE_SET *set = NULL;
1126 r_u->status = NT_STATUS_OK;
1128 #if 0 /* privileges are not implemented */
1129 /* find the connection policy handle. */
1130 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1131 return NT_STATUS_INVALID_HANDLE;
1133 if (!pdb_getgrsid(&map, info->sid))
1134 return NT_STATUS_NO_SUCH_GROUP;
1136 if (q_u->allrights != 0) {
1137 /* log it and return, until I see one myself don't do anything */
1138 DEBUG(5,("_lsa_removeprivs: trying to remove all privileges ?\n"));
1139 return NT_STATUS_OK;
1142 if (q_u->ptr == 0) {
1143 /* log it and return, until I see one myself don't do anything */
1144 DEBUG(5,("_lsa_removeprivs: no privileges to remove ?\n"));
1145 return NT_STATUS_OK;
1150 for (i = 0; i < set->count; i++) {
1151 luid_attr = &set->set[i];
1153 /* if we don't have the privilege, we're trying to remove, give up */
1154 /* what else can we do ??? JFM. */
1155 if (!check_priv_in_privilege(map.priv_set, *luid_attr)){
1156 destroy_privilege(&map.priv_set);
1157 return NT_STATUS_NO_SUCH_PRIVILEGE;
1160 remove_privilege(map.priv_set, *luid_attr);
1163 if(!pdb_update_group_mapping_entry(&map))
1164 return NT_STATUS_NO_SUCH_GROUP;
1166 destroy_privilege(&map.priv_set);
1171 /***************************************************************************
1172 For a given SID, remove some privileges.
1173 ***************************************************************************/
1175 NTSTATUS _lsa_query_secobj(pipes_struct *p, LSA_Q_QUERY_SEC_OBJ *q_u, LSA_R_QUERY_SEC_OBJ *r_u)
1177 struct lsa_info *handle=NULL;
1178 SEC_DESC *psd = NULL;
1182 r_u->status = NT_STATUS_OK;
1184 /* find the connection policy handle. */
1185 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
1186 return NT_STATUS_INVALID_HANDLE;
1188 /* check if the user have enough rights */
1189 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
1190 return NT_STATUS_ACCESS_DENIED;
1193 switch (q_u->sec_info) {
1195 /* SD contains only the owner */
1197 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
1198 if(!NT_STATUS_IS_OK(status))
1199 return NT_STATUS_NO_MEMORY;
1202 if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1203 return NT_STATUS_NO_MEMORY;
1206 /* SD contains only the ACL */
1208 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
1209 if(!NT_STATUS_IS_OK(status))
1210 return NT_STATUS_NO_MEMORY;
1212 if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1213 return NT_STATUS_NO_MEMORY;
1216 return NT_STATUS_INVALID_LEVEL;
1225 NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_INFO2 *r_u)
1227 struct lsa_info *handle;
1228 const char *nb_name;
1229 char *dns_name = NULL;
1230 char *forest_name = NULL;
1231 DOM_SID *sid = NULL;
1236 r_u->status = NT_STATUS_OK;
1238 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
1239 return NT_STATUS_INVALID_HANDLE;
1241 switch (q_u->info_class) {
1243 /* check if the user have enough rights */
1244 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
1245 return NT_STATUS_ACCESS_DENIED;
1247 /* Request PolicyPrimaryDomainInformation. */
1248 switch (lp_server_role()) {
1249 case ROLE_DOMAIN_PDC:
1250 case ROLE_DOMAIN_BDC:
1251 nb_name = get_global_sam_name();
1252 /* ugly temp hack for these next two */
1254 /* This should be a 'netbios domain -> DNS domain' mapping */
1255 dnsdomname[0] = '\0';
1256 get_mydnsdomname(dnsdomname);
1257 strlower_m(dnsdomname);
1259 dns_name = dnsdomname;
1260 forest_name = dnsdomname;
1262 sid = get_global_sam_sid();
1263 secrets_fetch_domain_guid(lp_workgroup(), &guid);
1266 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1268 init_dns_dom_info(&r_u->info.dns_dom_info, nb_name, dns_name,
1269 forest_name,&guid,sid);
1272 DEBUG(0,("_lsa_query_info2: unknown info level in Lsa Query: %d\n", q_u->info_class));
1273 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
1277 if (NT_STATUS_IS_OK(r_u->status)) {
1279 r_u->info_class = q_u->info_class;