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 if (name_type
== SID_NAME_WKN_GRP
) {
169 /* BUILTIN aliases are still aliases :-) */
170 name_type
= SID_NAME_ALIAS
;
173 DEBUG(5, ("init_lsa_rid2s: %s\n", status
? "found" :
176 if (status
&& name_type
!= SID_NAME_UNKNOWN
) {
177 sid_split_rid(&sid
, &rid
);
178 dom_idx
= init_dom_ref(ref
, dom_name
, &sid
);
183 name_type
= SID_NAME_UNKNOWN
;
186 init_dom_rid2(&rid2
[total
], rid
, name_type
, dom_idx
);
193 /***************************************************************************
194 init_reply_lookup_names
195 ***************************************************************************/
197 static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES
*r_l
,
198 DOM_R_REF
*ref
, uint32 num_entries
,
199 DOM_RID2
*rid2
, uint32 mapped_count
)
201 r_l
->ptr_dom_ref
= 1;
204 r_l
->num_entries
= num_entries
;
205 r_l
->ptr_entries
= 1;
206 r_l
->num_entries2
= num_entries
;
209 r_l
->mapped_count
= mapped_count
;
212 /***************************************************************************
213 Init lsa_trans_names.
214 ***************************************************************************/
216 static void init_lsa_trans_names(TALLOC_CTX
*ctx
, DOM_R_REF
*ref
, LSA_TRANS_NAME_ENUM
*trn
,
217 int num_entries
, DOM_SID2
*sid
,
218 uint32
*mapped_count
)
224 /* Allocate memory for list of names */
226 if (num_entries
> 0) {
227 if (!(trn
->name
= (LSA_TRANS_NAME
*)talloc(ctx
, sizeof(LSA_TRANS_NAME
) *
229 DEBUG(0, ("init_lsa_trans_names(): out of memory\n"));
233 if (!(trn
->uni_name
= (UNISTR2
*)talloc(ctx
, sizeof(UNISTR2
) *
235 DEBUG(0, ("init_lsa_trans_names(): out of memory\n"));
240 become_root(); /* Need root to get to passdb to for local sids */
242 for (i
= 0; i
< num_entries
; i
++) {
244 DOM_SID find_sid
= sid
[i
].sid
;
245 uint32 rid
= 0xffffffff;
247 fstring name
, dom_name
;
248 enum SID_NAME_USE sid_name_use
= (enum SID_NAME_USE
)0;
250 sid_to_string(name
, &find_sid
);
251 DEBUG(5, ("init_lsa_trans_names: looking up sid %s\n", name
));
253 /* Lookup sid from winbindd */
255 status
= lookup_sid(&find_sid
, dom_name
, name
, &sid_name_use
);
257 DEBUG(5, ("init_lsa_trans_names: %s\n", status
? "found" :
261 sid_name_use
= SID_NAME_UNKNOWN
;
262 memset(dom_name
, '\0', sizeof(dom_name
));
263 sid_to_string(name
, &find_sid
);
266 DEBUG(10,("init_lsa_trans_names: added unknown user '%s' to "
267 "referenced list.\n", name
));
270 /* Store domain sid in ref array */
271 if (find_sid
.num_auths
== 5) {
272 sid_split_rid(&find_sid
, &rid
);
274 dom_idx
= init_dom_ref(ref
, dom_name
, &find_sid
);
276 DEBUG(10,("init_lsa_trans_names: added user '%s\\%s' to "
277 "referenced list.\n", dom_name
, name
));
281 init_lsa_trans_name(&trn
->name
[total
], &trn
->uni_name
[total
],
282 sid_name_use
, name
, dom_idx
);
288 trn
->num_entries
= total
;
289 trn
->ptr_trans_names
= 1;
290 trn
->num_entries2
= total
;
293 /***************************************************************************
294 Init_reply_lookup_sids.
295 ***************************************************************************/
297 static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS
*r_l
,
298 DOM_R_REF
*ref
, LSA_TRANS_NAME_ENUM
*names
,
301 r_l
->ptr_dom_ref
= 1;
304 r_l
->mapped_count
= mapped_count
;
307 static NTSTATUS
lsa_get_generic_sd(TALLOC_CTX
*mem_ctx
, SEC_DESC
**sd
, size_t *sd_size
)
309 extern DOM_SID global_sid_World
;
310 extern DOM_SID global_sid_Builtin
;
311 DOM_SID local_adm_sid
;
319 init_sec_access(&mask
, POLICY_EXECUTE
);
320 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
322 sid_copy(&adm_sid
, get_global_sam_sid());
323 sid_append_rid(&adm_sid
, DOMAIN_GROUP_RID_ADMINS
);
324 init_sec_access(&mask
, POLICY_ALL_ACCESS
);
325 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
327 sid_copy(&local_adm_sid
, &global_sid_Builtin
);
328 sid_append_rid(&local_adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
329 init_sec_access(&mask
, POLICY_ALL_ACCESS
);
330 init_sec_ace(&ace
[2], &local_adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
332 if((psa
= make_sec_acl(mem_ctx
, NT4_ACL_REVISION
, 3, ace
)) == NULL
)
333 return NT_STATUS_NO_MEMORY
;
335 if((*sd
= make_sec_desc(mem_ctx
, SEC_DESC_REVISION
, SEC_DESC_SELF_RELATIVE
, &adm_sid
, NULL
, NULL
, psa
, sd_size
)) == NULL
)
336 return NT_STATUS_NO_MEMORY
;
341 /***************************************************************************
343 ***************************************************************************/
345 static void init_dns_dom_info(LSA_DNS_DOM_INFO
*r_l
, const char *nb_name
,
346 const char *dns_name
, const char *forest_name
,
347 struct uuid
*dom_guid
, DOM_SID
*dom_sid
)
349 if (nb_name
&& *nb_name
) {
350 init_unistr2(&r_l
->uni_nb_dom_name
, nb_name
, UNI_FLAGS_NONE
);
351 init_uni_hdr(&r_l
->hdr_nb_dom_name
, &r_l
->uni_nb_dom_name
);
352 r_l
->hdr_nb_dom_name
.uni_max_len
+= 2;
353 r_l
->uni_nb_dom_name
.uni_max_len
+= 1;
356 if (dns_name
&& *dns_name
) {
357 init_unistr2(&r_l
->uni_dns_dom_name
, dns_name
, UNI_FLAGS_NONE
);
358 init_uni_hdr(&r_l
->hdr_dns_dom_name
, &r_l
->uni_dns_dom_name
);
359 r_l
->hdr_dns_dom_name
.uni_max_len
+= 2;
360 r_l
->uni_dns_dom_name
.uni_max_len
+= 1;
363 if (forest_name
&& *forest_name
) {
364 init_unistr2(&r_l
->uni_forest_name
, forest_name
, UNI_FLAGS_NONE
);
365 init_uni_hdr(&r_l
->hdr_forest_name
, &r_l
->uni_forest_name
);
366 r_l
->hdr_forest_name
.uni_max_len
+= 2;
367 r_l
->uni_forest_name
.uni_max_len
+= 1;
370 /* how do we init the guid ? probably should write an init fn */
372 memcpy(&r_l
->dom_guid
, dom_guid
, sizeof(struct uuid
));
376 r_l
->ptr_dom_sid
= 1;
377 init_dom_sid2(&r_l
->dom_sid
, dom_sid
);
381 /***************************************************************************
383 ***************************************************************************/
385 NTSTATUS
_lsa_open_policy2(pipes_struct
*p
, LSA_Q_OPEN_POL2
*q_u
, LSA_R_OPEN_POL2
*r_u
)
387 struct lsa_info
*info
;
388 SEC_DESC
*psd
= NULL
;
390 uint32 des_access
=q_u
->des_access
;
395 /* map the generic bits to the lsa policy ones */
396 se_map_generic(&des_access
, &lsa_generic_mapping
);
398 /* get the generic lsa policy SD until we store it */
399 lsa_get_generic_sd(p
->mem_ctx
, &psd
, &sd_size
);
401 if(!se_access_check(psd
, p
->pipe_user
.nt_user_token
, des_access
, &acc_granted
, &status
)) {
402 if (geteuid() != 0) {
405 DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
406 acc_granted
, des_access
));
407 DEBUGADD(4,("but overwritten by euid == 0\n"));
410 /* This is needed for lsa_open_account and rpcclient .... :-) */
413 acc_granted
= POLICY_ALL_ACCESS
;
415 /* associate the domain SID with the (unique) handle. */
416 if ((info
= (struct lsa_info
*)malloc(sizeof(struct lsa_info
))) == NULL
)
417 return NT_STATUS_NO_MEMORY
;
420 sid_copy(&info
->sid
,get_global_sam_sid());
421 info
->access
= acc_granted
;
423 /* set up the LSA QUERY INFO response */
424 if (!create_policy_hnd(p
, &r_u
->pol
, free_lsa_info
, (void *)info
))
425 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
430 /***************************************************************************
432 ***************************************************************************/
434 NTSTATUS
_lsa_open_policy(pipes_struct
*p
, LSA_Q_OPEN_POL
*q_u
, LSA_R_OPEN_POL
*r_u
)
436 struct lsa_info
*info
;
437 SEC_DESC
*psd
= NULL
;
439 uint32 des_access
=q_u
->des_access
;
444 /* map the generic bits to the lsa policy ones */
445 se_map_generic(&des_access
, &lsa_generic_mapping
);
447 /* get the generic lsa policy SD until we store it */
448 lsa_get_generic_sd(p
->mem_ctx
, &psd
, &sd_size
);
450 if(!se_access_check(psd
, p
->pipe_user
.nt_user_token
, des_access
, &acc_granted
, &status
)) {
451 if (geteuid() != 0) {
454 DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
455 acc_granted
, des_access
));
456 DEBUGADD(4,("but overwritten by euid == 0\n"));
457 acc_granted
= des_access
;
460 /* associate the domain SID with the (unique) handle. */
461 if ((info
= (struct lsa_info
*)malloc(sizeof(struct lsa_info
))) == NULL
)
462 return NT_STATUS_NO_MEMORY
;
465 sid_copy(&info
->sid
,get_global_sam_sid());
466 info
->access
= acc_granted
;
468 /* set up the LSA QUERY INFO response */
469 if (!create_policy_hnd(p
, &r_u
->pol
, free_lsa_info
, (void *)info
))
470 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
475 /***************************************************************************
476 _lsa_enum_trust_dom - this needs fixing to do more than return NULL ! JRA.
478 ***************************************************************************/
480 NTSTATUS
_lsa_enum_trust_dom(pipes_struct
*p
, LSA_Q_ENUM_TRUST_DOM
*q_u
, LSA_R_ENUM_TRUST_DOM
*r_u
)
482 struct lsa_info
*info
;
483 uint32 enum_context
= q_u
->enum_context
;
486 * preferred length is set to 5 as a "our" preferred length
487 * nt sets this parameter to 2
488 * update (20.08.2002): it's not preferred length, but preferred size!
489 * it needs further investigation how to optimally choose this value
491 uint32 max_num_domains
= q_u
->preferred_len
< 5 ? q_u
->preferred_len
: 10;
492 TRUSTDOM
**trust_doms
;
496 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
497 return NT_STATUS_INVALID_HANDLE
;
499 /* check if the user have enough rights */
500 if (!(info
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
501 return NT_STATUS_ACCESS_DENIED
;
503 nt_status
= secrets_get_trusted_domains(p
->mem_ctx
, (int *)&enum_context
, max_num_domains
, (int *)&num_domains
, &trust_doms
);
505 if (!NT_STATUS_IS_OK(nt_status
) &&
506 !NT_STATUS_EQUAL(nt_status
, STATUS_MORE_ENTRIES
) &&
507 !NT_STATUS_EQUAL(nt_status
, NT_STATUS_NO_MORE_ENTRIES
)) {
510 r_u
->status
= nt_status
;
513 /* set up the lsa_enum_trust_dom response */
514 init_r_enum_trust_dom(p
->mem_ctx
, r_u
, enum_context
, max_num_domains
, num_domains
, trust_doms
);
519 /***************************************************************************
520 _lsa_query_info. See the POLICY_INFOMATION_CLASS docs at msdn.
521 ***************************************************************************/
523 NTSTATUS
_lsa_query_info(pipes_struct
*p
, LSA_Q_QUERY_INFO
*q_u
, LSA_R_QUERY_INFO
*r_u
)
525 struct lsa_info
*handle
;
526 LSA_INFO_UNION
*info
= &r_u
->dom
;
531 r_u
->status
= NT_STATUS_OK
;
533 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
534 return NT_STATUS_INVALID_HANDLE
;
536 switch (q_u
->info_class
) {
540 /* check if the user have enough rights */
541 if (!(handle
->access
& POLICY_VIEW_AUDIT_INFORMATION
))
542 return NT_STATUS_ACCESS_DENIED
;
544 /* fake info: We audit everything. ;) */
545 info
->id2
.auditing_enabled
= 1;
546 info
->id2
.count1
= 7;
547 info
->id2
.count2
= 7;
548 if ((info
->id2
.auditsettings
= (uint32
*)talloc(p
->mem_ctx
,7*sizeof(uint32
))) == NULL
)
549 return NT_STATUS_NO_MEMORY
;
550 for (i
= 0; i
< 7; i
++)
551 info
->id2
.auditsettings
[i
] = 3;
555 /* check if the user have enough rights */
556 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
557 return NT_STATUS_ACCESS_DENIED
;
559 /* Request PolicyPrimaryDomainInformation. */
560 switch (lp_server_role()) {
561 case ROLE_DOMAIN_PDC
:
562 case ROLE_DOMAIN_BDC
:
563 name
= get_global_sam_name();
564 sid
= get_global_sam_sid();
566 case ROLE_DOMAIN_MEMBER
:
567 name
= lp_workgroup();
568 /* We need to return the Domain SID here. */
569 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid
))
572 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
574 case ROLE_STANDALONE
:
575 name
= lp_workgroup();
579 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
581 init_dom_query(&r_u
->dom
.id3
, name
, sid
);
584 /* check if the user have enough rights */
585 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
586 return NT_STATUS_ACCESS_DENIED
;
588 /* Request PolicyAccountDomainInformation. */
589 name
= get_global_sam_name();
590 sid
= get_global_sam_sid();
591 init_dom_query(&r_u
->dom
.id5
, name
, sid
);
594 /* check if the user have enough rights */
595 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
596 return NT_STATUS_ACCESS_DENIED
;
598 switch (lp_server_role()) {
599 case ROLE_DOMAIN_BDC
:
601 * only a BDC is a backup controller
602 * of the domain, it controls.
604 info
->id6
.server_role
= 2;
608 * any other role is a primary
609 * of the domain, it controls.
611 info
->id6
.server_role
= 3;
616 DEBUG(0,("_lsa_query_info: unknown info level in Lsa Query: %d\n", q_u
->info_class
));
617 r_u
->status
= NT_STATUS_INVALID_INFO_CLASS
;
621 if (NT_STATUS_IS_OK(r_u
->status
)) {
622 r_u
->undoc_buffer
= 0x22000000; /* bizarre */
623 r_u
->info_class
= q_u
->info_class
;
629 /***************************************************************************
631 ***************************************************************************/
633 NTSTATUS
_lsa_lookup_sids(pipes_struct
*p
, LSA_Q_LOOKUP_SIDS
*q_u
, LSA_R_LOOKUP_SIDS
*r_u
)
635 struct lsa_info
*handle
;
636 DOM_SID2
*sid
= q_u
->sids
.sid
;
637 int num_entries
= q_u
->sids
.num_entries
;
638 DOM_R_REF
*ref
= NULL
;
639 LSA_TRANS_NAME_ENUM
*names
= NULL
;
640 uint32 mapped_count
= 0;
642 if (num_entries
> MAX_LOOKUP_SIDS
) {
643 num_entries
= MAX_LOOKUP_SIDS
;
644 DEBUG(5,("_lsa_lookup_sids: truncating SID lookup list to %d\n", num_entries
));
647 ref
= (DOM_R_REF
*)talloc_zero(p
->mem_ctx
, sizeof(DOM_R_REF
));
648 names
= (LSA_TRANS_NAME_ENUM
*)talloc_zero(p
->mem_ctx
, sizeof(LSA_TRANS_NAME_ENUM
));
650 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
)) {
651 r_u
->status
= NT_STATUS_INVALID_HANDLE
;
655 /* check if the user have enough rights */
656 if (!(handle
->access
& POLICY_LOOKUP_NAMES
)) {
657 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
661 return NT_STATUS_NO_MEMORY
;
665 /* set up the LSA Lookup SIDs response */
666 init_lsa_trans_names(p
->mem_ctx
, ref
, names
, num_entries
, sid
, &mapped_count
);
667 if (mapped_count
== 0)
668 r_u
->status
= NT_STATUS_NONE_MAPPED
;
669 else if (mapped_count
!= num_entries
)
670 r_u
->status
= STATUS_SOME_UNMAPPED
;
672 r_u
->status
= NT_STATUS_OK
;
673 init_reply_lookup_sids(r_u
, ref
, names
, mapped_count
);
678 /***************************************************************************
679 lsa_reply_lookup_names
680 ***************************************************************************/
682 NTSTATUS
_lsa_lookup_names(pipes_struct
*p
,LSA_Q_LOOKUP_NAMES
*q_u
, LSA_R_LOOKUP_NAMES
*r_u
)
684 struct lsa_info
*handle
;
685 UNISTR2
*names
= q_u
->uni_name
;
686 int num_entries
= q_u
->num_entries
;
689 uint32 mapped_count
= 0;
691 if (num_entries
> MAX_LOOKUP_SIDS
) {
692 num_entries
= MAX_LOOKUP_SIDS
;
693 DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries
));
696 ref
= (DOM_R_REF
*)talloc_zero(p
->mem_ctx
, sizeof(DOM_R_REF
));
697 rids
= (DOM_RID2
*)talloc_zero(p
->mem_ctx
, sizeof(DOM_RID2
)*num_entries
);
699 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
)) {
700 r_u
->status
= NT_STATUS_INVALID_HANDLE
;
704 /* check if the user have enough rights */
705 if (!(handle
->access
& POLICY_LOOKUP_NAMES
)) {
706 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
711 return NT_STATUS_NO_MEMORY
;
715 /* set up the LSA Lookup RIDs response */
716 init_lsa_rid2s(ref
, rids
, num_entries
, names
, &mapped_count
, p
->endian
);
717 if (mapped_count
== 0)
718 r_u
->status
= NT_STATUS_NONE_MAPPED
;
719 else if (mapped_count
!= num_entries
)
720 r_u
->status
= STATUS_SOME_UNMAPPED
;
722 r_u
->status
= NT_STATUS_OK
;
723 init_reply_lookup_names(r_u
, ref
, num_entries
, rids
, mapped_count
);
728 /***************************************************************************
729 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
730 ***************************************************************************/
732 NTSTATUS
_lsa_close(pipes_struct
*p
, LSA_Q_CLOSE
*q_u
, LSA_R_CLOSE
*r_u
)
734 if (!find_policy_by_hnd(p
, &q_u
->pol
, NULL
))
735 return NT_STATUS_INVALID_HANDLE
;
737 close_policy_hnd(p
, &q_u
->pol
);
741 /***************************************************************************
742 "No more secrets Marty...." :-).
743 ***************************************************************************/
745 NTSTATUS
_lsa_open_secret(pipes_struct
*p
, LSA_Q_OPEN_SECRET
*q_u
, LSA_R_OPEN_SECRET
*r_u
)
747 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
750 /***************************************************************************
752 ***************************************************************************/
754 NTSTATUS
_lsa_enum_privs(pipes_struct
*p
, LSA_Q_ENUM_PRIVS
*q_u
, LSA_R_ENUM_PRIVS
*r_u
)
756 struct lsa_info
*handle
;
759 uint32 enum_context
=q_u
->enum_context
;
760 LSA_PRIV_ENTRY
*entry
;
761 LSA_PRIV_ENTRY
*entries
=NULL
;
763 if (enum_context
>= PRIV_ALL_INDEX
-2)
764 return NT_STATUS_NO_MORE_ENTRIES
;
766 entries
= (LSA_PRIV_ENTRY
*)talloc_zero(p
->mem_ctx
, sizeof(LSA_PRIV_ENTRY
) * (PRIV_ALL_INDEX
));
768 return NT_STATUS_NO_MEMORY
;
770 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
771 return NT_STATUS_INVALID_HANDLE
;
773 /* check if the user have enough rights */
776 * I don't know if it's the right one. not documented.
778 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
779 return NT_STATUS_ACCESS_DENIED
;
783 DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n", enum_context
, PRIV_ALL_INDEX
));
785 for (i
= 1; i
< PRIV_ALL_INDEX
-1; i
++, entry
++) {
786 if( i
<enum_context
) {
787 init_unistr2(&entry
->name
, NULL
, UNI_FLAGS_NONE
);
788 init_uni_hdr(&entry
->hdr_name
, &entry
->name
);
790 entry
->luid_high
= 0;
792 init_unistr2(&entry
->name
, privs
[i
].priv
, UNI_FLAGS_NONE
);
793 init_uni_hdr(&entry
->hdr_name
, &entry
->name
);
794 entry
->luid_low
= privs
[i
].se_priv
;
795 entry
->luid_high
= 0;
799 enum_context
= PRIV_ALL_INDEX
-2;
800 init_lsa_r_enum_privs(r_u
, enum_context
, PRIV_ALL_INDEX
-2, entries
);
805 /***************************************************************************
806 _lsa_priv_get_dispname.
807 ***************************************************************************/
809 NTSTATUS
_lsa_priv_get_dispname(pipes_struct
*p
, LSA_Q_PRIV_GET_DISPNAME
*q_u
, LSA_R_PRIV_GET_DISPNAME
*r_u
)
811 struct lsa_info
*handle
;
815 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
816 return NT_STATUS_INVALID_HANDLE
;
818 /* check if the user have enough rights */
821 * I don't know if it's the right one. not documented.
823 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
824 return NT_STATUS_ACCESS_DENIED
;
826 unistr2_to_ascii(name_asc
, &q_u
->name
, sizeof(name_asc
));
828 DEBUG(10,("_lsa_priv_get_dispname: %s", name_asc
));
830 while (privs
[i
].se_priv
!=SE_ALL_PRIVS
&& strcmp(name_asc
, privs
[i
].priv
))
833 if (privs
[i
].se_priv
!=SE_ALL_PRIVS
) {
834 DEBUG(10,(": %s\n", privs
[i
].description
));
835 init_unistr2(&r_u
->desc
, privs
[i
].description
, UNI_FLAGS_NONE
);
836 init_uni_hdr(&r_u
->hdr_desc
, &r_u
->desc
);
838 r_u
->ptr_info
=0xdeadbeef;
839 r_u
->lang_id
=q_u
->lang_id
;
842 DEBUG(10,("_lsa_priv_get_dispname: doesn't exist\n"));
844 return NT_STATUS_NO_SUCH_PRIVILEGE
;
848 /***************************************************************************
850 ***************************************************************************/
852 NTSTATUS
_lsa_enum_accounts(pipes_struct
*p
, LSA_Q_ENUM_ACCOUNTS
*q_u
, LSA_R_ENUM_ACCOUNTS
*r_u
)
854 struct lsa_info
*handle
;
856 int i
, j
, num_entries
;
857 LSA_SID_ENUM
*sids
=&r_u
->sids
;
859 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
860 return NT_STATUS_INVALID_HANDLE
;
862 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
863 return NT_STATUS_ACCESS_DENIED
;
868 /* The only way we can currently find out all the SIDs that have been
869 privileged is to scan all privileges */
871 for (i
=1; i
<PRIV_ALL_INDEX
-1; i
++) {
872 DOM_SID
*priv_sids
= NULL
;
873 int num_priv_sids
= 0;
875 if (!get_sids_from_priv(privs
[i
].priv
, &priv_sids
,
879 for (j
=0; j
<num_priv_sids
; j
++) {
880 add_sid_to_array_unique(&priv_sids
[j
], &sid_list
,
883 SAFE_FREE(priv_sids
);
886 if (q_u
->enum_context
>= num_entries
)
887 return NT_STATUS_NO_MORE_ENTRIES
;
889 sids
->ptr_sid
= (uint32
*)talloc_zero(p
->mem_ctx
, (num_entries
-q_u
->enum_context
)*sizeof(uint32
));
890 sids
->sid
= (DOM_SID2
*)talloc_zero(p
->mem_ctx
, (num_entries
-q_u
->enum_context
)*sizeof(DOM_SID2
));
892 if (sids
->ptr_sid
==NULL
|| sids
->sid
==NULL
) {
894 return NT_STATUS_NO_MEMORY
;
897 for (i
=q_u
->enum_context
, j
=0; i
<num_entries
; i
++) {
898 init_dom_sid2( &(*sids
).sid
[j
], &sid_list
[i
]);
899 (*sids
).ptr_sid
[j
]=1;
905 init_lsa_r_enum_accounts(r_u
, num_entries
);
911 NTSTATUS
_lsa_unk_get_connuser(pipes_struct
*p
, LSA_Q_UNK_GET_CONNUSER
*q_u
, LSA_R_UNK_GET_CONNUSER
*r_u
)
913 fstring username
, domname
;
914 user_struct
*vuser
= get_valid_user_struct(p
->vuid
);
917 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
919 fstrcpy(username
, vuser
->user
.smb_name
);
920 fstrcpy(domname
, vuser
->user
.domain
);
922 r_u
->ptr_user_name
= 1;
923 init_unistr2(&r_u
->uni2_user_name
, username
, UNI_STR_TERMINATE
);
924 init_uni_hdr(&r_u
->hdr_user_name
, &r_u
->uni2_user_name
);
928 r_u
->ptr_dom_name
= 1;
929 init_unistr2(&r_u
->uni2_dom_name
, domname
, UNI_STR_TERMINATE
);
930 init_uni_hdr(&r_u
->hdr_dom_name
, &r_u
->uni2_dom_name
);
932 r_u
->status
= NT_STATUS_OK
;
937 /***************************************************************************
940 FIXME: Actually the code is just a copy of lsa_open_account
941 TODO: Check and code what this function should exactly do
942 ***************************************************************************/
944 NTSTATUS
_lsa_create_account(pipes_struct
*p
, LSA_Q_CREATEACCOUNT
*q_u
, LSA_R_CREATEACCOUNT
*r_u
)
946 struct lsa_info
*handle
;
947 struct lsa_info
*info
;
949 r_u
->status
= NT_STATUS_OK
;
951 /* find the connection policy handle. */
952 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
953 return NT_STATUS_INVALID_HANDLE
;
955 /* check if the user have enough rights */
958 * I don't know if it's the right one. not documented.
959 * but guessed with rpcclient.
961 if (!(handle
->access
& POLICY_GET_PRIVATE_INFORMATION
))
962 return NT_STATUS_ACCESS_DENIED
;
964 /* associate the user/group SID with the (unique) handle. */
965 if ((info
= (struct lsa_info
*)malloc(sizeof(struct lsa_info
))) == NULL
)
966 return NT_STATUS_NO_MEMORY
;
969 info
->sid
= q_u
->sid
.sid
;
970 info
->access
= q_u
->access
;
972 /* get a (unique) handle. open a policy on it. */
973 if (!create_policy_hnd(p
, &r_u
->pol
, free_lsa_info
, (void *)info
))
974 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
980 /***************************************************************************
982 ***************************************************************************/
984 NTSTATUS
_lsa_open_account(pipes_struct
*p
, LSA_Q_OPENACCOUNT
*q_u
, LSA_R_OPENACCOUNT
*r_u
)
986 struct lsa_info
*handle
;
987 struct lsa_info
*info
;
989 r_u
->status
= NT_STATUS_OK
;
991 /* find the connection policy handle. */
992 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
993 return NT_STATUS_INVALID_HANDLE
;
995 /* check if the user have enough rights */
998 * I don't know if it's the right one. not documented.
999 * but guessed with rpcclient.
1001 if (!(handle
->access
& POLICY_GET_PRIVATE_INFORMATION
))
1002 return NT_STATUS_ACCESS_DENIED
;
1004 /* associate the user/group SID with the (unique) handle. */
1005 if ((info
= (struct lsa_info
*)malloc(sizeof(struct lsa_info
))) == NULL
)
1006 return NT_STATUS_NO_MEMORY
;
1009 info
->sid
= q_u
->sid
.sid
;
1010 info
->access
= q_u
->access
;
1012 /* get a (unique) handle. open a policy on it. */
1013 if (!create_policy_hnd(p
, &r_u
->pol
, free_lsa_info
, (void *)info
))
1014 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1019 /***************************************************************************
1020 For a given SID, enumerate all the privilege this account has.
1021 ***************************************************************************/
1023 NTSTATUS
_lsa_enum_privsaccount(pipes_struct
*p
, prs_struct
*ps
, LSA_Q_ENUMPRIVSACCOUNT
*q_u
, LSA_R_ENUMPRIVSACCOUNT
*r_u
)
1025 struct lsa_info
*info
=NULL
;
1026 LUID_ATTR
*set
=NULL
;
1027 PRIVILEGE_SET
*priv
;
1029 r_u
->status
= NT_STATUS_OK
;
1031 /* find the connection policy handle. */
1032 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1033 return NT_STATUS_INVALID_HANDLE
;
1035 init_privilege(&priv
);
1037 if (!get_priv_for_sid(&info
->sid
, priv
)) {
1038 /* This is probably wrong... */
1039 return NT_STATUS_INVALID_HANDLE
;
1042 DEBUG(10,("_lsa_enum_privsaccount: %d privileges\n", priv
->count
));
1044 if (priv
->count
> 0) {
1046 set
=(LUID_ATTR
*)talloc(ps
->mem_ctx
,
1047 priv
->count
*sizeof(LUID_ATTR
));
1049 destroy_privilege(&priv
);
1050 return NT_STATUS_NO_MEMORY
;
1053 for (i
= 0; i
< priv
->count
; i
++) {
1054 set
[i
].luid
.low
= priv
->set
[i
].luid
.low
;
1055 set
[i
].luid
.high
= priv
->set
[i
].luid
.high
;
1056 set
[i
].attr
= priv
->set
[i
].attr
;
1057 DEBUG(10,("_lsa_enum_privsaccount: %d: %d:%d:%d\n", i
,
1058 set
[i
].luid
.high
, set
[i
].luid
.low
,
1063 init_lsa_r_enum_privsaccount(ps
->mem_ctx
, r_u
, set
, priv
->count
, 0);
1064 destroy_privilege(&priv
);
1069 /***************************************************************************
1071 ***************************************************************************/
1073 NTSTATUS
_lsa_getsystemaccount(pipes_struct
*p
, LSA_Q_GETSYSTEMACCOUNT
*q_u
, LSA_R_GETSYSTEMACCOUNT
*r_u
)
1075 struct lsa_info
*info
=NULL
;
1076 r_u
->status
= NT_STATUS_OK
;
1077 fstring name
, dom_name
;
1078 enum SID_NAME_USE type
;
1080 /* find the connection policy handle. */
1081 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1082 return NT_STATUS_INVALID_HANDLE
;
1084 if (!lookup_sid(&info
->sid
, dom_name
, name
, &type
))
1085 return NT_STATUS_INVALID_HANDLE
;
1088 0x01 -> Log on locally
1089 0x02 -> Access this computer from network
1090 0x04 -> Log on as a batch job
1091 0x10 -> Log on as a service
1093 they can be ORed together
1096 r_u
->access
= PR_LOG_ON_LOCALLY
| PR_ACCESS_FROM_NETWORK
;
1101 /***************************************************************************
1102 update the systemaccount information
1103 ***************************************************************************/
1105 NTSTATUS
_lsa_setsystemaccount(pipes_struct
*p
, LSA_Q_SETSYSTEMACCOUNT
*q_u
, LSA_R_SETSYSTEMACCOUNT
*r_u
)
1107 struct lsa_info
*info
=NULL
;
1109 r_u
->status
= NT_STATUS_OK
;
1111 /* find the connection policy handle. */
1112 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1113 return NT_STATUS_INVALID_HANDLE
;
1115 if (!pdb_getgrsid(&map
, info
->sid
))
1116 return NT_STATUS_NO_SUCH_GROUP
;
1118 if(!pdb_update_group_mapping_entry(&map
))
1119 return NT_STATUS_NO_SUCH_GROUP
;
1124 /***************************************************************************
1125 For a given SID, add some privileges.
1126 ***************************************************************************/
1128 NTSTATUS
_lsa_addprivs(pipes_struct
*p
, LSA_Q_ADDPRIVS
*q_u
, LSA_R_ADDPRIVS
*r_u
)
1131 struct lsa_info
*info
= NULL
;
1134 LUID_ATTR
*luid_attr
= NULL
;
1135 PRIVILEGE_SET
*set
= NULL
;
1138 r_u
->status
= NT_STATUS_OK
;
1140 #if 0 /* privileges are not implemented */
1141 /* find the connection policy handle. */
1142 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1143 return NT_STATUS_INVALID_HANDLE
;
1145 if (!pdb_getgrsid(&map
, info
->sid
))
1146 return NT_STATUS_NO_SUCH_GROUP
;
1150 for (i
= 0; i
< set
->count
; i
++) {
1151 luid_attr
= &set
->set
[i
];
1153 /* check if the privilege is already there */
1154 if (check_priv_in_privilege(map
.priv_set
, *luid_attr
)){
1155 destroy_privilege(&map
.priv_set
);
1156 return NT_STATUS_NO_SUCH_PRIVILEGE
;
1159 add_privilege(map
.priv_set
, *luid_attr
);
1162 if(!pdb_update_group_mapping_entry(&map
))
1163 return NT_STATUS_NO_SUCH_GROUP
;
1165 destroy_privilege(&map
.priv_set
);
1171 /***************************************************************************
1172 For a given SID, remove some privileges.
1173 ***************************************************************************/
1175 NTSTATUS
_lsa_removeprivs(pipes_struct
*p
, LSA_Q_REMOVEPRIVS
*q_u
, LSA_R_REMOVEPRIVS
*r_u
)
1178 struct lsa_info
*info
= NULL
;
1181 LUID_ATTR
*luid_attr
= NULL
;
1182 PRIVILEGE_SET
*set
= NULL
;
1185 r_u
->status
= NT_STATUS_OK
;
1187 #if 0 /* privileges are not implemented */
1188 /* find the connection policy handle. */
1189 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1190 return NT_STATUS_INVALID_HANDLE
;
1192 if (!pdb_getgrsid(&map
, info
->sid
))
1193 return NT_STATUS_NO_SUCH_GROUP
;
1195 if (q_u
->allrights
!= 0) {
1196 /* log it and return, until I see one myself don't do anything */
1197 DEBUG(5,("_lsa_removeprivs: trying to remove all privileges ?\n"));
1198 return NT_STATUS_OK
;
1201 if (q_u
->ptr
== 0) {
1202 /* log it and return, until I see one myself don't do anything */
1203 DEBUG(5,("_lsa_removeprivs: no privileges to remove ?\n"));
1204 return NT_STATUS_OK
;
1209 for (i
= 0; i
< set
->count
; i
++) {
1210 luid_attr
= &set
->set
[i
];
1212 /* if we don't have the privilege, we're trying to remove, give up */
1213 /* what else can we do ??? JFM. */
1214 if (!check_priv_in_privilege(map
.priv_set
, *luid_attr
)){
1215 destroy_privilege(&map
.priv_set
);
1216 return NT_STATUS_NO_SUCH_PRIVILEGE
;
1219 remove_privilege(map
.priv_set
, *luid_attr
);
1222 if(!pdb_update_group_mapping_entry(&map
))
1223 return NT_STATUS_NO_SUCH_GROUP
;
1225 destroy_privilege(&map
.priv_set
);
1230 /***************************************************************************
1231 For a given SID, remove some privileges.
1232 ***************************************************************************/
1234 NTSTATUS
_lsa_query_secobj(pipes_struct
*p
, LSA_Q_QUERY_SEC_OBJ
*q_u
, LSA_R_QUERY_SEC_OBJ
*r_u
)
1236 struct lsa_info
*handle
=NULL
;
1237 SEC_DESC
*psd
= NULL
;
1241 r_u
->status
= NT_STATUS_OK
;
1243 /* find the connection policy handle. */
1244 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
1245 return NT_STATUS_INVALID_HANDLE
;
1247 /* check if the user have enough rights */
1248 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
1249 return NT_STATUS_ACCESS_DENIED
;
1252 switch (q_u
->sec_info
) {
1254 /* SD contains only the owner */
1256 status
=lsa_get_generic_sd(p
->mem_ctx
, &psd
, &sd_size
);
1257 if(!NT_STATUS_IS_OK(status
))
1258 return NT_STATUS_NO_MEMORY
;
1261 if((r_u
->buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
)) == NULL
)
1262 return NT_STATUS_NO_MEMORY
;
1265 /* SD contains only the ACL */
1267 status
=lsa_get_generic_sd(p
->mem_ctx
, &psd
, &sd_size
);
1268 if(!NT_STATUS_IS_OK(status
))
1269 return NT_STATUS_NO_MEMORY
;
1271 if((r_u
->buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
)) == NULL
)
1272 return NT_STATUS_NO_MEMORY
;
1275 return NT_STATUS_INVALID_LEVEL
;
1284 NTSTATUS
_lsa_query_info2(pipes_struct
*p
, LSA_Q_QUERY_INFO2
*q_u
, LSA_R_QUERY_INFO2
*r_u
)
1286 struct lsa_info
*handle
;
1287 const char *nb_name
;
1288 char *dns_name
= NULL
;
1289 char *forest_name
= NULL
;
1290 DOM_SID
*sid
= NULL
;
1295 r_u
->status
= NT_STATUS_OK
;
1297 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
1298 return NT_STATUS_INVALID_HANDLE
;
1300 switch (q_u
->info_class
) {
1302 /* check if the user have enough rights */
1303 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
1304 return NT_STATUS_ACCESS_DENIED
;
1306 /* Request PolicyPrimaryDomainInformation. */
1307 switch (lp_server_role()) {
1308 case ROLE_DOMAIN_PDC
:
1309 case ROLE_DOMAIN_BDC
:
1310 nb_name
= get_global_sam_name();
1311 /* ugly temp hack for these next two */
1313 /* This should be a 'netbios domain -> DNS domain' mapping */
1314 dnsdomname
[0] = '\0';
1315 get_mydnsdomname(dnsdomname
);
1316 strlower_m(dnsdomname
);
1318 dns_name
= dnsdomname
;
1319 forest_name
= dnsdomname
;
1321 sid
= get_global_sam_sid();
1322 secrets_fetch_domain_guid(lp_workgroup(), &guid
);
1325 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
1327 init_dns_dom_info(&r_u
->info
.dns_dom_info
, nb_name
, dns_name
,
1328 forest_name
,&guid
,sid
);
1331 DEBUG(0,("_lsa_query_info2: unknown info level in Lsa Query: %d\n", q_u
->info_class
));
1332 r_u
->status
= NT_STATUS_INVALID_INFO_CLASS
;
1336 if (NT_STATUS_IS_OK(r_u
->status
)) {
1338 r_u
->info_class
= q_u
->info_class
;