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.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 /* This is the implementation of the lsa server code. */
32 #define DBGC_CLASS DBGC_RPC_SRV
41 struct generic_mapping lsa_generic_mapping
= {
48 /*******************************************************************
49 Function to free the per handle data.
50 ********************************************************************/
52 static void free_lsa_info(void *ptr
)
54 struct lsa_info
*lsa
= (struct lsa_info
*)ptr
;
59 /***************************************************************************
61 ***************************************************************************/
63 static void init_dom_query(DOM_QUERY
*d_q
, const char *dom_name
, DOM_SID
*dom_sid
)
65 d_q
->buffer_dom_name
= (dom_name
!= NULL
) ? 1 : 0; /* domain buffer pointer */
66 d_q
->buffer_dom_sid
= (dom_sid
!= NULL
) ? 1 : 0; /* domain sid pointer */
68 /* this string is supposed to be non-null terminated. */
69 /* But the maxlen in this UNISTR2 must include the terminating null. */
70 init_unistr2(&d_q
->uni_domain_name
, dom_name
, UNI_BROKEN_NON_NULL
);
73 * I'm not sure why this really odd combination of length
74 * values works, but it does appear to. I need to look at
75 * this *much* more closely - but at the moment leave alone
76 * until it's understood. This allows a W2k client to join
77 * a domain with both odd and even length names... JRA.
82 * The two fields below probably are reversed in meaning, ie.
83 * the first field is probably the str_len, the second the max
84 * len. Both are measured in bytes anyway.
87 d_q
->uni_dom_str_len
= d_q
->uni_domain_name
.uni_max_len
* 2;
88 d_q
->uni_dom_max_len
= d_q
->uni_domain_name
.uni_str_len
* 2;
91 init_dom_sid2(&d_q
->dom_sid
, dom_sid
);
94 /***************************************************************************
95 init_dom_ref - adds a domain if it's not already in, returns the index.
96 ***************************************************************************/
98 static int init_dom_ref(DOM_R_REF
*ref
, char *dom_name
, DOM_SID
*dom_sid
)
102 if (dom_name
!= NULL
) {
103 for (num
= 0; num
< ref
->num_ref_doms_1
; num
++) {
105 rpcstr_pull(domname
, ref
->ref_dom
[num
].uni_dom_name
.buffer
, sizeof(domname
), -1, 0);
106 if (strequal(domname
, dom_name
))
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 void init_lsa_rid2s(DOM_R_REF
*ref
, DOM_RID2
*rid2
,
138 int num_entries
, UNISTR2
*name
,
139 uint32
*mapped_count
, BOOL endian
)
145 SMB_ASSERT(num_entries
<= MAX_LOOKUP_SIDS
);
147 become_root(); /* lookup_name can require root privs */
149 for (i
= 0; i
< num_entries
; i
++) {
152 uint32 rid
= 0xffffffff;
155 fstring dom_name
, user
;
156 enum SID_NAME_USE name_type
= SID_NAME_UNKNOWN
;
158 /* Split name into domain and user component */
160 unistr2_to_ascii(full_name
, &name
[i
], sizeof(full_name
));
161 split_domain_name(full_name
, dom_name
, user
);
165 DEBUG(5, ("init_lsa_rid2s: looking up name %s\n", full_name
));
167 status
= lookup_name(dom_name
, user
, &sid
, &name_type
);
169 if((name_type
== SID_NAME_UNKNOWN
) && (lp_server_role() == ROLE_DOMAIN_MEMBER
) && (strncmp(dom_name
, full_name
, strlen(dom_name
)) != 0)) {
170 DEBUG(5, ("init_lsa_rid2s: domain name not provided and local account not found, using member domain\n"));
171 fstrcpy(dom_name
, lp_workgroup());
172 status
= lookup_name(dom_name
, user
, &sid
, &name_type
);
175 #if 0 /* This is not true. */
176 if (name_type
== SID_NAME_WKN_GRP
) {
177 /* BUILTIN aliases are still aliases :-) */
178 name_type
= SID_NAME_ALIAS
;
182 DEBUG(5, ("init_lsa_rid2s: %s\n", status
? "found" :
185 if (status
&& name_type
!= SID_NAME_UNKNOWN
) {
186 sid_split_rid(&sid
, &rid
);
187 dom_idx
= init_dom_ref(ref
, dom_name
, &sid
);
192 name_type
= SID_NAME_UNKNOWN
;
195 init_dom_rid2(&rid2
[total
], rid
, name_type
, dom_idx
);
202 /***************************************************************************
203 init_reply_lookup_names
204 ***************************************************************************/
206 static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES
*r_l
,
207 DOM_R_REF
*ref
, uint32 num_entries
,
208 DOM_RID2
*rid2
, uint32 mapped_count
)
210 r_l
->ptr_dom_ref
= 1;
213 r_l
->num_entries
= num_entries
;
214 r_l
->ptr_entries
= 1;
215 r_l
->num_entries2
= num_entries
;
218 r_l
->mapped_count
= mapped_count
;
221 /***************************************************************************
222 Init lsa_trans_names.
223 ***************************************************************************/
225 static void init_lsa_trans_names(TALLOC_CTX
*ctx
, DOM_R_REF
*ref
, LSA_TRANS_NAME_ENUM
*trn
,
226 int num_entries
, DOM_SID2
*sid
,
227 uint32
*mapped_count
)
233 /* Allocate memory for list of names */
235 if (num_entries
> 0) {
236 if (!(trn
->name
= TALLOC_ARRAY(ctx
, LSA_TRANS_NAME
, num_entries
))) {
237 DEBUG(0, ("init_lsa_trans_names(): out of memory\n"));
241 if (!(trn
->uni_name
= TALLOC_ARRAY(ctx
, UNISTR2
, num_entries
))) {
242 DEBUG(0, ("init_lsa_trans_names(): out of memory\n"));
247 become_root(); /* Need root to get to passdb to for local sids */
249 for (i
= 0; i
< num_entries
; i
++) {
251 DOM_SID find_sid
= sid
[i
].sid
;
252 uint32 rid
= 0xffffffff;
254 fstring name
, dom_name
;
255 enum SID_NAME_USE sid_name_use
= (enum SID_NAME_USE
)0;
257 sid_to_string(name
, &find_sid
);
258 DEBUG(5, ("init_lsa_trans_names: looking up sid %s\n", name
));
260 /* Lookup sid from winbindd */
262 status
= lookup_sid(&find_sid
, dom_name
, name
, &sid_name_use
);
264 DEBUG(5, ("init_lsa_trans_names: %s\n", status
? "found" :
268 sid_name_use
= SID_NAME_UNKNOWN
;
269 memset(dom_name
, '\0', sizeof(dom_name
));
270 sid_to_string(name
, &find_sid
);
273 DEBUG(10,("init_lsa_trans_names: added unknown user '%s' to "
274 "referenced list.\n", name
));
277 /* Store domain sid in ref array */
278 if (find_sid
.num_auths
== 5) {
279 sid_split_rid(&find_sid
, &rid
);
281 dom_idx
= init_dom_ref(ref
, dom_name
, &find_sid
);
283 DEBUG(10,("init_lsa_trans_names: added %s '%s\\%s' (%d) to referenced list.\n",
284 sid_type_lookup(sid_name_use
), dom_name
, name
, sid_name_use
));
288 init_lsa_trans_name(&trn
->name
[total
], &trn
->uni_name
[total
],
289 sid_name_use
, name
, dom_idx
);
295 trn
->num_entries
= total
;
296 trn
->ptr_trans_names
= 1;
297 trn
->num_entries2
= total
;
300 /***************************************************************************
301 Init_reply_lookup_sids.
302 ***************************************************************************/
304 static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS
*r_l
,
305 DOM_R_REF
*ref
, LSA_TRANS_NAME_ENUM
*names
,
308 r_l
->ptr_dom_ref
= 1;
311 r_l
->mapped_count
= mapped_count
;
314 static NTSTATUS
lsa_get_generic_sd(TALLOC_CTX
*mem_ctx
, SEC_DESC
**sd
, size_t *sd_size
)
316 extern DOM_SID global_sid_World
;
317 extern DOM_SID global_sid_Builtin
;
318 DOM_SID local_adm_sid
;
326 init_sec_access(&mask
, POLICY_EXECUTE
);
327 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
329 sid_copy(&adm_sid
, get_global_sam_sid());
330 sid_append_rid(&adm_sid
, DOMAIN_GROUP_RID_ADMINS
);
331 init_sec_access(&mask
, POLICY_ALL_ACCESS
);
332 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
334 sid_copy(&local_adm_sid
, &global_sid_Builtin
);
335 sid_append_rid(&local_adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
336 init_sec_access(&mask
, POLICY_ALL_ACCESS
);
337 init_sec_ace(&ace
[2], &local_adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
339 if((psa
= make_sec_acl(mem_ctx
, NT4_ACL_REVISION
, 3, ace
)) == NULL
)
340 return NT_STATUS_NO_MEMORY
;
342 if((*sd
= make_sec_desc(mem_ctx
, SEC_DESC_REVISION
, SEC_DESC_SELF_RELATIVE
, &adm_sid
, NULL
, NULL
, psa
, sd_size
)) == NULL
)
343 return NT_STATUS_NO_MEMORY
;
348 /***************************************************************************
350 ***************************************************************************/
352 static void init_dns_dom_info(LSA_DNS_DOM_INFO
*r_l
, const char *nb_name
,
353 const char *dns_name
, const char *forest_name
,
354 struct uuid
*dom_guid
, DOM_SID
*dom_sid
)
356 if (nb_name
&& *nb_name
) {
357 init_unistr2(&r_l
->uni_nb_dom_name
, nb_name
, UNI_FLAGS_NONE
);
358 init_uni_hdr(&r_l
->hdr_nb_dom_name
, &r_l
->uni_nb_dom_name
);
359 r_l
->hdr_nb_dom_name
.uni_max_len
+= 2;
360 r_l
->uni_nb_dom_name
.uni_max_len
+= 1;
363 if (dns_name
&& *dns_name
) {
364 init_unistr2(&r_l
->uni_dns_dom_name
, dns_name
, UNI_FLAGS_NONE
);
365 init_uni_hdr(&r_l
->hdr_dns_dom_name
, &r_l
->uni_dns_dom_name
);
366 r_l
->hdr_dns_dom_name
.uni_max_len
+= 2;
367 r_l
->uni_dns_dom_name
.uni_max_len
+= 1;
370 if (forest_name
&& *forest_name
) {
371 init_unistr2(&r_l
->uni_forest_name
, forest_name
, UNI_FLAGS_NONE
);
372 init_uni_hdr(&r_l
->hdr_forest_name
, &r_l
->uni_forest_name
);
373 r_l
->hdr_forest_name
.uni_max_len
+= 2;
374 r_l
->uni_forest_name
.uni_max_len
+= 1;
377 /* how do we init the guid ? probably should write an init fn */
379 memcpy(&r_l
->dom_guid
, dom_guid
, sizeof(struct uuid
));
383 r_l
->ptr_dom_sid
= 1;
384 init_dom_sid2(&r_l
->dom_sid
, dom_sid
);
388 /***************************************************************************
390 ***************************************************************************/
392 NTSTATUS
_lsa_open_policy2(pipes_struct
*p
, LSA_Q_OPEN_POL2
*q_u
, LSA_R_OPEN_POL2
*r_u
)
394 struct lsa_info
*info
;
395 SEC_DESC
*psd
= NULL
;
397 uint32 des_access
=q_u
->des_access
;
402 /* map the generic bits to the lsa policy ones */
403 se_map_generic(&des_access
, &lsa_generic_mapping
);
405 /* get the generic lsa policy SD until we store it */
406 lsa_get_generic_sd(p
->mem_ctx
, &psd
, &sd_size
);
408 if(!se_access_check(psd
, p
->pipe_user
.nt_user_token
, des_access
, &acc_granted
, &status
)) {
409 if (geteuid() != 0) {
412 DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
413 acc_granted
, des_access
));
414 DEBUGADD(4,("but overwritten by euid == 0\n"));
417 /* This is needed for lsa_open_account and rpcclient .... :-) */
420 acc_granted
= POLICY_ALL_ACCESS
;
422 /* associate the domain SID with the (unique) handle. */
423 if ((info
= SMB_MALLOC_P(struct lsa_info
)) == NULL
)
424 return NT_STATUS_NO_MEMORY
;
427 sid_copy(&info
->sid
,get_global_sam_sid());
428 info
->access
= acc_granted
;
430 /* set up the LSA QUERY INFO response */
431 if (!create_policy_hnd(p
, &r_u
->pol
, free_lsa_info
, (void *)info
))
432 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
437 /***************************************************************************
439 ***************************************************************************/
441 NTSTATUS
_lsa_open_policy(pipes_struct
*p
, LSA_Q_OPEN_POL
*q_u
, LSA_R_OPEN_POL
*r_u
)
443 struct lsa_info
*info
;
444 SEC_DESC
*psd
= NULL
;
446 uint32 des_access
=q_u
->des_access
;
451 /* map the generic bits to the lsa policy ones */
452 se_map_generic(&des_access
, &lsa_generic_mapping
);
454 /* get the generic lsa policy SD until we store it */
455 lsa_get_generic_sd(p
->mem_ctx
, &psd
, &sd_size
);
457 if(!se_access_check(psd
, p
->pipe_user
.nt_user_token
, des_access
, &acc_granted
, &status
)) {
458 if (geteuid() != 0) {
461 DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
462 acc_granted
, des_access
));
463 DEBUGADD(4,("but overwritten by euid == 0\n"));
464 acc_granted
= des_access
;
467 /* associate the domain SID with the (unique) handle. */
468 if ((info
= SMB_MALLOC_P(struct lsa_info
)) == NULL
)
469 return NT_STATUS_NO_MEMORY
;
472 sid_copy(&info
->sid
,get_global_sam_sid());
473 info
->access
= acc_granted
;
475 /* set up the LSA QUERY INFO response */
476 if (!create_policy_hnd(p
, &r_u
->pol
, free_lsa_info
, (void *)info
))
477 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
482 /***************************************************************************
483 _lsa_enum_trust_dom - this needs fixing to do more than return NULL ! JRA.
485 ***************************************************************************/
487 NTSTATUS
_lsa_enum_trust_dom(pipes_struct
*p
, LSA_Q_ENUM_TRUST_DOM
*q_u
, LSA_R_ENUM_TRUST_DOM
*r_u
)
489 struct lsa_info
*info
;
490 uint32 enum_context
= q_u
->enum_context
;
493 * preferred length is set to 5 as a "our" preferred length
494 * nt sets this parameter to 2
495 * update (20.08.2002): it's not preferred length, but preferred size!
496 * it needs further investigation how to optimally choose this value
498 uint32 max_num_domains
= q_u
->preferred_len
< 5 ? q_u
->preferred_len
: 10;
499 TRUSTDOM
**trust_doms
;
503 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
504 return NT_STATUS_INVALID_HANDLE
;
506 /* check if the user have enough rights */
507 if (!(info
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
508 return NT_STATUS_ACCESS_DENIED
;
510 nt_status
= secrets_get_trusted_domains(p
->mem_ctx
, (int *)&enum_context
, max_num_domains
, (int *)&num_domains
, &trust_doms
);
512 if (!NT_STATUS_IS_OK(nt_status
) &&
513 !NT_STATUS_EQUAL(nt_status
, STATUS_MORE_ENTRIES
) &&
514 !NT_STATUS_EQUAL(nt_status
, NT_STATUS_NO_MORE_ENTRIES
)) {
517 r_u
->status
= nt_status
;
520 /* set up the lsa_enum_trust_dom response */
521 init_r_enum_trust_dom(p
->mem_ctx
, r_u
, enum_context
, max_num_domains
, num_domains
, trust_doms
);
526 /***************************************************************************
527 _lsa_query_info. See the POLICY_INFOMATION_CLASS docs at msdn.
528 ***************************************************************************/
530 NTSTATUS
_lsa_query_info(pipes_struct
*p
, LSA_Q_QUERY_INFO
*q_u
, LSA_R_QUERY_INFO
*r_u
)
532 struct lsa_info
*handle
;
533 LSA_INFO_UNION
*info
= &r_u
->dom
;
538 r_u
->status
= NT_STATUS_OK
;
540 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
541 return NT_STATUS_INVALID_HANDLE
;
543 switch (q_u
->info_class
) {
547 /* check if the user have enough rights */
548 if (!(handle
->access
& POLICY_VIEW_AUDIT_INFORMATION
))
549 return NT_STATUS_ACCESS_DENIED
;
551 /* fake info: We audit everything. ;) */
552 info
->id2
.auditing_enabled
= 1;
553 info
->id2
.count1
= 7;
554 info
->id2
.count2
= 7;
555 if ((info
->id2
.auditsettings
= TALLOC_ARRAY(p
->mem_ctx
,uint32
, 7)) == NULL
)
556 return NT_STATUS_NO_MEMORY
;
557 for (i
= 0; i
< 7; i
++)
558 info
->id2
.auditsettings
[i
] = 3;
562 /* check if the user have enough rights */
563 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
564 return NT_STATUS_ACCESS_DENIED
;
566 /* Request PolicyPrimaryDomainInformation. */
567 switch (lp_server_role()) {
568 case ROLE_DOMAIN_PDC
:
569 case ROLE_DOMAIN_BDC
:
570 name
= get_global_sam_name();
571 sid
= get_global_sam_sid();
573 case ROLE_DOMAIN_MEMBER
:
574 name
= lp_workgroup();
575 /* We need to return the Domain SID here. */
576 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid
))
579 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
581 case ROLE_STANDALONE
:
582 name
= lp_workgroup();
586 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
588 init_dom_query(&r_u
->dom
.id3
, name
, sid
);
591 /* check if the user have enough rights */
592 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
593 return NT_STATUS_ACCESS_DENIED
;
595 /* Request PolicyAccountDomainInformation. */
596 name
= get_global_sam_name();
597 sid
= get_global_sam_sid();
598 init_dom_query(&r_u
->dom
.id5
, name
, sid
);
601 /* check if the user have enough rights */
602 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
603 return NT_STATUS_ACCESS_DENIED
;
605 switch (lp_server_role()) {
606 case ROLE_DOMAIN_BDC
:
608 * only a BDC is a backup controller
609 * of the domain, it controls.
611 info
->id6
.server_role
= 2;
615 * any other role is a primary
616 * of the domain, it controls.
618 info
->id6
.server_role
= 3;
623 DEBUG(0,("_lsa_query_info: unknown info level in Lsa Query: %d\n", q_u
->info_class
));
624 r_u
->status
= NT_STATUS_INVALID_INFO_CLASS
;
628 if (NT_STATUS_IS_OK(r_u
->status
)) {
629 r_u
->undoc_buffer
= 0x22000000; /* bizarre */
630 r_u
->info_class
= q_u
->info_class
;
636 /***************************************************************************
638 ***************************************************************************/
640 NTSTATUS
_lsa_lookup_sids(pipes_struct
*p
, LSA_Q_LOOKUP_SIDS
*q_u
, LSA_R_LOOKUP_SIDS
*r_u
)
642 struct lsa_info
*handle
;
643 DOM_SID2
*sid
= q_u
->sids
.sid
;
644 int num_entries
= q_u
->sids
.num_entries
;
645 DOM_R_REF
*ref
= NULL
;
646 LSA_TRANS_NAME_ENUM
*names
= NULL
;
647 uint32 mapped_count
= 0;
649 if (num_entries
> MAX_LOOKUP_SIDS
) {
651 DEBUG(5,("_lsa_lookup_sids: limit of %d exceeded, truncating SID lookup list to %d\n", MAX_LOOKUP_SIDS
, num_entries
));
652 r_u
->status
= NT_STATUS_NONE_MAPPED
;
655 ref
= TALLOC_ZERO_P(p
->mem_ctx
, DOM_R_REF
);
656 names
= TALLOC_ZERO_P(p
->mem_ctx
, LSA_TRANS_NAME_ENUM
);
658 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
)) {
659 r_u
->status
= NT_STATUS_INVALID_HANDLE
;
663 /* check if the user have enough rights */
664 if (!(handle
->access
& POLICY_LOOKUP_NAMES
)) {
665 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
669 return NT_STATUS_NO_MEMORY
;
673 /* set up the LSA Lookup SIDs response */
674 init_lsa_trans_names(p
->mem_ctx
, ref
, names
, num_entries
, sid
, &mapped_count
);
675 if (NT_STATUS_IS_OK(r_u
->status
)) {
676 if (mapped_count
== 0)
677 r_u
->status
= NT_STATUS_NONE_MAPPED
;
678 else if (mapped_count
!= num_entries
)
679 r_u
->status
= STATUS_SOME_UNMAPPED
;
681 init_reply_lookup_sids(r_u
, ref
, names
, mapped_count
);
686 /***************************************************************************
687 lsa_reply_lookup_names
688 ***************************************************************************/
690 NTSTATUS
_lsa_lookup_names(pipes_struct
*p
,LSA_Q_LOOKUP_NAMES
*q_u
, LSA_R_LOOKUP_NAMES
*r_u
)
692 struct lsa_info
*handle
;
693 UNISTR2
*names
= q_u
->uni_name
;
694 int num_entries
= q_u
->num_entries
;
697 uint32 mapped_count
= 0;
699 if (num_entries
> MAX_LOOKUP_SIDS
) {
700 num_entries
= MAX_LOOKUP_SIDS
;
701 DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries
));
704 ref
= TALLOC_ZERO_P(p
->mem_ctx
, DOM_R_REF
);
705 rids
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, DOM_RID2
, num_entries
);
707 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
)) {
708 r_u
->status
= NT_STATUS_INVALID_HANDLE
;
712 /* check if the user have enough rights */
713 if (!(handle
->access
& POLICY_LOOKUP_NAMES
)) {
714 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
719 return NT_STATUS_NO_MEMORY
;
723 /* set up the LSA Lookup RIDs response */
724 init_lsa_rid2s(ref
, rids
, num_entries
, names
, &mapped_count
, p
->endian
);
725 if (NT_STATUS_IS_OK(r_u
->status
)) {
726 if (mapped_count
== 0)
727 r_u
->status
= NT_STATUS_NONE_MAPPED
;
728 else if (mapped_count
!= num_entries
)
729 r_u
->status
= STATUS_SOME_UNMAPPED
;
731 init_reply_lookup_names(r_u
, ref
, num_entries
, rids
, mapped_count
);
736 /***************************************************************************
737 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
738 ***************************************************************************/
740 NTSTATUS
_lsa_close(pipes_struct
*p
, LSA_Q_CLOSE
*q_u
, LSA_R_CLOSE
*r_u
)
742 if (!find_policy_by_hnd(p
, &q_u
->pol
, NULL
))
743 return NT_STATUS_INVALID_HANDLE
;
745 close_policy_hnd(p
, &q_u
->pol
);
749 /***************************************************************************
750 "No more secrets Marty...." :-).
751 ***************************************************************************/
753 NTSTATUS
_lsa_open_secret(pipes_struct
*p
, LSA_Q_OPEN_SECRET
*q_u
, LSA_R_OPEN_SECRET
*r_u
)
755 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
758 /***************************************************************************
760 ***************************************************************************/
762 NTSTATUS
_lsa_enum_privs(pipes_struct
*p
, LSA_Q_ENUM_PRIVS
*q_u
, LSA_R_ENUM_PRIVS
*r_u
)
764 struct lsa_info
*handle
;
766 uint32 enum_context
= q_u
->enum_context
;
767 int num_privs
= count_all_privileges();
768 LSA_PRIV_ENTRY
*entries
= NULL
;
771 /* remember that the enum_context starts at 0 and not 1 */
773 if ( enum_context
>= num_privs
)
774 return NT_STATUS_NO_MORE_ENTRIES
;
776 DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n",
777 enum_context
, num_privs
));
779 if ( !(entries
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, LSA_PRIV_ENTRY
, num_privs
+ 1)))
780 return NT_STATUS_NO_MEMORY
;
782 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
783 return NT_STATUS_INVALID_HANDLE
;
785 /* check if the user have enough rights
786 I don't know if it's the right one. not documented. */
788 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
789 return NT_STATUS_ACCESS_DENIED
;
791 if ( !(entries
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, LSA_PRIV_ENTRY
, num_privs
)) )
792 return NT_STATUS_NO_MEMORY
;
795 for (i
= 0; i
< num_privs
; i
++) {
796 if( i
< enum_context
) {
797 init_unistr2(&entries
[i
].name
, NULL
, UNI_FLAGS_NONE
);
798 init_uni_hdr(&entries
[i
].hdr_name
, &entries
[i
].name
);
800 entries
[i
].luid_low
= 0;
801 entries
[i
].luid_high
= 0;
803 init_unistr2(&entries
[i
].name
, privs
[i
].name
, UNI_FLAGS_NONE
);
804 init_uni_hdr(&entries
[i
].hdr_name
, &entries
[i
].name
);
806 luid
= get_privilege_luid( &privs
[i
].se_priv
);
808 entries
[i
].luid_low
= luid
.luid
.low
;
809 entries
[i
].luid_high
= luid
.luid
.high
;
813 enum_context
= num_privs
;
815 init_lsa_r_enum_privs(r_u
, enum_context
, num_privs
, entries
);
820 /***************************************************************************
821 _lsa_priv_get_dispname.
822 ***************************************************************************/
824 NTSTATUS
_lsa_priv_get_dispname(pipes_struct
*p
, LSA_Q_PRIV_GET_DISPNAME
*q_u
, LSA_R_PRIV_GET_DISPNAME
*r_u
)
826 struct lsa_info
*handle
;
828 const char *description
;
830 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
831 return NT_STATUS_INVALID_HANDLE
;
833 /* check if the user have enough rights */
836 * I don't know if it's the right one. not documented.
838 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
839 return NT_STATUS_ACCESS_DENIED
;
841 unistr2_to_ascii(name_asc
, &q_u
->name
, sizeof(name_asc
));
843 DEBUG(10,("_lsa_priv_get_dispname: name = %s\n", name_asc
));
845 description
= get_privilege_dispname( name_asc
);
848 DEBUG(10,("_lsa_priv_get_dispname: display name = %s\n", description
));
850 init_unistr2(&r_u
->desc
, description
, UNI_FLAGS_NONE
);
851 init_uni_hdr(&r_u
->hdr_desc
, &r_u
->desc
);
853 r_u
->ptr_info
= 0xdeadbeef;
854 r_u
->lang_id
= q_u
->lang_id
;
858 DEBUG(10,("_lsa_priv_get_dispname: doesn't exist\n"));
862 return NT_STATUS_NO_SUCH_PRIVILEGE
;
866 /***************************************************************************
868 ***************************************************************************/
870 NTSTATUS
_lsa_enum_accounts(pipes_struct
*p
, LSA_Q_ENUM_ACCOUNTS
*q_u
, LSA_R_ENUM_ACCOUNTS
*r_u
)
872 struct lsa_info
*handle
;
874 int i
, j
, num_entries
;
875 LSA_SID_ENUM
*sids
=&r_u
->sids
;
878 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
879 return NT_STATUS_INVALID_HANDLE
;
881 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
882 return NT_STATUS_ACCESS_DENIED
;
887 /* The only way we can currently find out all the SIDs that have been
888 privileged is to scan all privileges */
890 if (!NT_STATUS_IS_OK(ret
= privilege_enumerate_accounts(&sid_list
, &num_entries
))) {
894 if (q_u
->enum_context
>= num_entries
)
895 return NT_STATUS_NO_MORE_ENTRIES
;
897 sids
->ptr_sid
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, uint32
, num_entries
-q_u
->enum_context
);
898 sids
->sid
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, DOM_SID2
, num_entries
-q_u
->enum_context
);
900 if (sids
->ptr_sid
==NULL
|| sids
->sid
==NULL
) {
902 return NT_STATUS_NO_MEMORY
;
905 for (i
= q_u
->enum_context
, j
= 0; i
< num_entries
; i
++, j
++) {
906 init_dom_sid2(&(*sids
).sid
[j
], &sid_list
[i
]);
907 (*sids
).ptr_sid
[j
] = 1;
912 init_lsa_r_enum_accounts(r_u
, num_entries
);
918 NTSTATUS
_lsa_unk_get_connuser(pipes_struct
*p
, LSA_Q_UNK_GET_CONNUSER
*q_u
, LSA_R_UNK_GET_CONNUSER
*r_u
)
920 fstring username
, domname
;
921 user_struct
*vuser
= get_valid_user_struct(p
->vuid
);
924 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
926 fstrcpy(username
, vuser
->user
.smb_name
);
927 fstrcpy(domname
, vuser
->user
.domain
);
929 r_u
->ptr_user_name
= 1;
930 init_unistr2(&r_u
->uni2_user_name
, username
, UNI_STR_TERMINATE
);
931 init_uni_hdr(&r_u
->hdr_user_name
, &r_u
->uni2_user_name
);
935 r_u
->ptr_dom_name
= 1;
936 init_unistr2(&r_u
->uni2_dom_name
, domname
, UNI_STR_TERMINATE
);
937 init_uni_hdr(&r_u
->hdr_dom_name
, &r_u
->uni2_dom_name
);
939 r_u
->status
= NT_STATUS_OK
;
944 /***************************************************************************
946 ***************************************************************************/
948 NTSTATUS
_lsa_create_account(pipes_struct
*p
, LSA_Q_CREATEACCOUNT
*q_u
, LSA_R_CREATEACCOUNT
*r_u
)
950 struct lsa_info
*handle
;
951 struct lsa_info
*info
;
953 /* find the connection policy handle. */
954 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
955 return NT_STATUS_INVALID_HANDLE
;
957 /* check if the user have enough rights */
960 * I don't know if it's the right one. not documented.
961 * but guessed with rpcclient.
963 if (!(handle
->access
& POLICY_GET_PRIVATE_INFORMATION
))
964 return NT_STATUS_ACCESS_DENIED
;
966 /* check to see if the pipe_user is a Domain Admin since
967 account_pol.tdb was already opened as root, this is all we have */
969 if ( !nt_token_check_domain_rid( p
->pipe_user
.nt_user_token
, DOMAIN_GROUP_RID_ADMINS
) )
970 return NT_STATUS_ACCESS_DENIED
;
972 if ( is_privileged_sid( &q_u
->sid
.sid
) )
973 return NT_STATUS_OBJECT_NAME_COLLISION
;
975 /* associate the user/group SID with the (unique) handle. */
977 if ((info
= SMB_MALLOC_P(struct lsa_info
)) == NULL
)
978 return NT_STATUS_NO_MEMORY
;
981 info
->sid
= q_u
->sid
.sid
;
982 info
->access
= q_u
->access
;
984 /* get a (unique) handle. open a policy on it. */
985 if (!create_policy_hnd(p
, &r_u
->pol
, free_lsa_info
, (void *)info
))
986 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
988 return privilege_create_account( &info
->sid
);
992 /***************************************************************************
994 ***************************************************************************/
996 NTSTATUS
_lsa_open_account(pipes_struct
*p
, LSA_Q_OPENACCOUNT
*q_u
, LSA_R_OPENACCOUNT
*r_u
)
998 struct lsa_info
*handle
;
999 struct lsa_info
*info
;
1001 /* find the connection policy handle. */
1002 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
1003 return NT_STATUS_INVALID_HANDLE
;
1005 /* check if the user have enough rights */
1008 * I don't know if it's the right one. not documented.
1009 * but guessed with rpcclient.
1011 if (!(handle
->access
& POLICY_GET_PRIVATE_INFORMATION
))
1012 return NT_STATUS_ACCESS_DENIED
;
1014 /* TODO: Fis the parsing routine before reenabling this check! */
1016 if (!lookup_sid(&handle
->sid
, dom_name
, name
, &type
))
1017 return NT_STATUS_ACCESS_DENIED
;
1019 /* associate the user/group SID with the (unique) handle. */
1020 if ((info
= SMB_MALLOC_P(struct lsa_info
)) == NULL
)
1021 return NT_STATUS_NO_MEMORY
;
1024 info
->sid
= q_u
->sid
.sid
;
1025 info
->access
= q_u
->access
;
1027 /* get a (unique) handle. open a policy on it. */
1028 if (!create_policy_hnd(p
, &r_u
->pol
, free_lsa_info
, (void *)info
))
1029 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1031 return NT_STATUS_OK
;
1034 /***************************************************************************
1035 For a given SID, enumerate all the privilege this account has.
1036 ***************************************************************************/
1038 NTSTATUS
_lsa_enum_privsaccount(pipes_struct
*p
, prs_struct
*ps
, LSA_Q_ENUMPRIVSACCOUNT
*q_u
, LSA_R_ENUMPRIVSACCOUNT
*r_u
)
1040 struct lsa_info
*info
=NULL
;
1042 PRIVILEGE_SET privileges
;
1044 /* find the connection policy handle. */
1045 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1046 return NT_STATUS_INVALID_HANDLE
;
1048 if ( !get_privileges_for_sids( &mask
, &info
->sid
, 1 ) )
1049 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1051 privilege_set_init( &privileges
);
1053 if ( se_priv_to_privilege_set( &privileges
, &mask
) ) {
1055 DEBUG(10,("_lsa_enum_privsaccount: %s has %d privileges\n",
1056 sid_string_static(&info
->sid
), privileges
.count
));
1058 r_u
->status
= init_lsa_r_enum_privsaccount(ps
->mem_ctx
, r_u
, privileges
.set
, privileges
.count
, 0);
1061 r_u
->status
= NT_STATUS_NO_SUCH_PRIVILEGE
;
1063 privilege_set_free( &privileges
);
1068 /***************************************************************************
1070 ***************************************************************************/
1072 NTSTATUS
_lsa_getsystemaccount(pipes_struct
*p
, LSA_Q_GETSYSTEMACCOUNT
*q_u
, LSA_R_GETSYSTEMACCOUNT
*r_u
)
1074 struct lsa_info
*info
=NULL
;
1075 fstring name
, dom_name
;
1076 enum SID_NAME_USE type
;
1078 /* find the connection policy handle. */
1080 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1081 return NT_STATUS_INVALID_HANDLE
;
1083 if (!lookup_sid(&info
->sid
, dom_name
, name
, &type
))
1084 return NT_STATUS_ACCESS_DENIED
;
1087 0x01 -> Log on locally
1088 0x02 -> Access this computer from network
1089 0x04 -> Log on as a batch job
1090 0x10 -> Log on as a service
1092 they can be ORed together
1095 r_u
->access
= PR_LOG_ON_LOCALLY
| PR_ACCESS_FROM_NETWORK
;
1097 return NT_STATUS_OK
;
1100 /***************************************************************************
1101 update the systemaccount information
1102 ***************************************************************************/
1104 NTSTATUS
_lsa_setsystemaccount(pipes_struct
*p
, LSA_Q_SETSYSTEMACCOUNT
*q_u
, LSA_R_SETSYSTEMACCOUNT
*r_u
)
1106 struct lsa_info
*info
=NULL
;
1108 r_u
->status
= NT_STATUS_OK
;
1110 /* find the connection policy handle. */
1111 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1112 return NT_STATUS_INVALID_HANDLE
;
1114 /* check to see if the pipe_user is a Domain Admin since
1115 account_pol.tdb was already opened as root, this is all we have */
1117 if ( !nt_token_check_domain_rid( p
->pipe_user
.nt_user_token
, DOMAIN_GROUP_RID_ADMINS
) )
1118 return NT_STATUS_ACCESS_DENIED
;
1120 if (!pdb_getgrsid(&map
, info
->sid
))
1121 return NT_STATUS_NO_SUCH_GROUP
;
1123 if(!pdb_update_group_mapping_entry(&map
))
1124 return NT_STATUS_NO_SUCH_GROUP
;
1129 /***************************************************************************
1130 For a given SID, add some privileges.
1131 ***************************************************************************/
1133 NTSTATUS
_lsa_addprivs(pipes_struct
*p
, LSA_Q_ADDPRIVS
*q_u
, LSA_R_ADDPRIVS
*r_u
)
1135 struct lsa_info
*info
= NULL
;
1137 PRIVILEGE_SET
*set
= NULL
;
1138 struct current_user user
;
1140 /* find the connection policy handle. */
1141 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1142 return NT_STATUS_INVALID_HANDLE
;
1144 /* check to see if the pipe_user is root or a Domain Admin since
1145 account_pol.tdb was already opened as root, this is all we have */
1147 get_current_user( &user
, p
);
1148 if ( user
.uid
!= sec_initial_uid()
1149 && !nt_token_check_domain_rid( p
->pipe_user
.nt_user_token
, DOMAIN_GROUP_RID_ADMINS
) )
1151 return NT_STATUS_ACCESS_DENIED
;
1156 if ( !privilege_set_to_se_priv( &mask
, set
) )
1157 return NT_STATUS_NO_SUCH_PRIVILEGE
;
1159 if ( !grant_privilege( &info
->sid
, &mask
) ) {
1160 DEBUG(3,("_lsa_addprivs: grant_privilege(%s) failed!\n",
1161 sid_string_static(&info
->sid
) ));
1162 DEBUG(3,("Privilege mask:\n"));
1163 dump_se_priv( DBGC_ALL
, 3, &mask
);
1164 return NT_STATUS_NO_SUCH_PRIVILEGE
;
1167 return NT_STATUS_OK
;
1170 /***************************************************************************
1171 For a given SID, remove some privileges.
1172 ***************************************************************************/
1174 NTSTATUS
_lsa_removeprivs(pipes_struct
*p
, LSA_Q_REMOVEPRIVS
*q_u
, LSA_R_REMOVEPRIVS
*r_u
)
1176 struct lsa_info
*info
= NULL
;
1178 PRIVILEGE_SET
*set
= NULL
;
1179 struct current_user user
;
1181 /* find the connection policy handle. */
1182 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1183 return NT_STATUS_INVALID_HANDLE
;
1185 /* check to see if the pipe_user is root or a Domain Admin since
1186 account_pol.tdb was already opened as root, this is all we have */
1188 get_current_user( &user
, p
);
1189 if ( user
.uid
!= sec_initial_uid()
1190 && !nt_token_check_domain_rid( p
->pipe_user
.nt_user_token
, DOMAIN_GROUP_RID_ADMINS
) )
1192 return NT_STATUS_ACCESS_DENIED
;
1197 if ( !privilege_set_to_se_priv( &mask
, set
) )
1198 return NT_STATUS_NO_SUCH_PRIVILEGE
;
1200 if ( !revoke_privilege( &info
->sid
, &mask
) ) {
1201 DEBUG(3,("_lsa_removeprivs: revoke_privilege(%s) failed!\n",
1202 sid_string_static(&info
->sid
) ));
1203 DEBUG(3,("Privilege mask:\n"));
1204 dump_se_priv( DBGC_ALL
, 3, &mask
);
1205 return NT_STATUS_NO_SUCH_PRIVILEGE
;
1208 return NT_STATUS_OK
;
1211 /***************************************************************************
1212 For a given SID, remove some privileges.
1213 ***************************************************************************/
1215 NTSTATUS
_lsa_query_secobj(pipes_struct
*p
, LSA_Q_QUERY_SEC_OBJ
*q_u
, LSA_R_QUERY_SEC_OBJ
*r_u
)
1217 struct lsa_info
*handle
=NULL
;
1218 SEC_DESC
*psd
= NULL
;
1222 r_u
->status
= NT_STATUS_OK
;
1224 /* find the connection policy handle. */
1225 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
1226 return NT_STATUS_INVALID_HANDLE
;
1228 /* check if the user have enough rights */
1229 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
1230 return NT_STATUS_ACCESS_DENIED
;
1233 switch (q_u
->sec_info
) {
1235 /* SD contains only the owner */
1237 status
=lsa_get_generic_sd(p
->mem_ctx
, &psd
, &sd_size
);
1238 if(!NT_STATUS_IS_OK(status
))
1239 return NT_STATUS_NO_MEMORY
;
1242 if((r_u
->buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
)) == NULL
)
1243 return NT_STATUS_NO_MEMORY
;
1246 /* SD contains only the ACL */
1248 status
=lsa_get_generic_sd(p
->mem_ctx
, &psd
, &sd_size
);
1249 if(!NT_STATUS_IS_OK(status
))
1250 return NT_STATUS_NO_MEMORY
;
1252 if((r_u
->buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
)) == NULL
)
1253 return NT_STATUS_NO_MEMORY
;
1256 return NT_STATUS_INVALID_LEVEL
;
1264 /***************************************************************************
1265 ***************************************************************************/
1267 NTSTATUS
_lsa_query_info2(pipes_struct
*p
, LSA_Q_QUERY_INFO2
*q_u
, LSA_R_QUERY_INFO2
*r_u
)
1269 struct lsa_info
*handle
;
1270 const char *nb_name
;
1271 char *dns_name
= NULL
;
1272 char *forest_name
= NULL
;
1273 DOM_SID
*sid
= NULL
;
1278 r_u
->status
= NT_STATUS_OK
;
1280 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
1281 return NT_STATUS_INVALID_HANDLE
;
1283 switch (q_u
->info_class
) {
1285 /* check if the user have enough rights */
1286 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
1287 return NT_STATUS_ACCESS_DENIED
;
1289 /* Request PolicyPrimaryDomainInformation. */
1290 switch (lp_server_role()) {
1291 case ROLE_DOMAIN_PDC
:
1292 case ROLE_DOMAIN_BDC
:
1293 nb_name
= get_global_sam_name();
1294 /* ugly temp hack for these next two */
1296 /* This should be a 'netbios domain -> DNS domain' mapping */
1297 dnsdomname
[0] = '\0';
1298 get_mydnsdomname(dnsdomname
);
1299 strlower_m(dnsdomname
);
1301 dns_name
= dnsdomname
;
1302 forest_name
= dnsdomname
;
1304 sid
= get_global_sam_sid();
1305 secrets_fetch_domain_guid(lp_workgroup(), &guid
);
1308 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
1310 init_dns_dom_info(&r_u
->info
.dns_dom_info
, nb_name
, dns_name
,
1311 forest_name
,&guid
,sid
);
1314 DEBUG(0,("_lsa_query_info2: unknown info level in Lsa Query: %d\n", q_u
->info_class
));
1315 r_u
->status
= NT_STATUS_INVALID_INFO_CLASS
;
1319 if (NT_STATUS_IS_OK(r_u
->status
)) {
1321 r_u
->info_class
= q_u
->info_class
;
1327 /***************************************************************************
1328 ***************************************************************************/
1330 NTSTATUS
_lsa_add_acct_rights(pipes_struct
*p
, LSA_Q_ADD_ACCT_RIGHTS
*q_u
, LSA_R_ADD_ACCT_RIGHTS
*r_u
)
1332 struct lsa_info
*info
= NULL
;
1336 UNISTR2_ARRAY
*uni_privnames
= &q_u
->rights
;
1337 struct current_user user
;
1340 /* find the connection policy handle. */
1341 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1342 return NT_STATUS_INVALID_HANDLE
;
1344 /* check to see if the pipe_user is a Domain Admin since
1345 account_pol.tdb was already opened as root, this is all we have */
1347 get_current_user( &user
, p
);
1348 if ( user
.uid
!= sec_initial_uid()
1349 && !nt_token_check_domain_rid( p
->pipe_user
.nt_user_token
, DOMAIN_GROUP_RID_ADMINS
) )
1351 return NT_STATUS_ACCESS_DENIED
;
1354 /* according to an NT4 PDC, you can add privileges to SIDs even without
1355 call_lsa_create_account() first. And you can use any arbitrary SID. */
1357 sid_copy( &sid
, &q_u
->sid
.sid
);
1359 /* just a little sanity check */
1361 if ( q_u
->count
!= uni_privnames
->count
) {
1362 DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n"));
1363 return NT_STATUS_INVALID_HANDLE
;
1366 for ( i
=0; i
<q_u
->count
; i
++ ) {
1367 unistr2_to_ascii( privname
, &uni_privnames
->strings
[i
].string
, sizeof(fstring
)-1 );
1369 /* only try to add non-null strings */
1371 if ( *privname
&& !grant_privilege_by_name( &sid
, privname
) ) {
1372 DEBUG(2,("_lsa_add_acct_rights: Failed to add privilege [%s]\n", privname
));
1373 return NT_STATUS_NO_SUCH_PRIVILEGE
;
1377 return NT_STATUS_OK
;
1380 /***************************************************************************
1381 ***************************************************************************/
1383 NTSTATUS
_lsa_remove_acct_rights(pipes_struct
*p
, LSA_Q_REMOVE_ACCT_RIGHTS
*q_u
, LSA_R_REMOVE_ACCT_RIGHTS
*r_u
)
1385 struct lsa_info
*info
= NULL
;
1389 UNISTR2_ARRAY
*uni_privnames
= &q_u
->rights
;
1390 struct current_user user
;
1393 /* find the connection policy handle. */
1394 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1395 return NT_STATUS_INVALID_HANDLE
;
1397 /* check to see if the pipe_user is a Domain Admin since
1398 account_pol.tdb was already opened as root, this is all we have */
1400 get_current_user( &user
, p
);
1401 if ( user
.uid
!= sec_initial_uid()
1402 && !nt_token_check_domain_rid( p
->pipe_user
.nt_user_token
, DOMAIN_GROUP_RID_ADMINS
) )
1404 return NT_STATUS_ACCESS_DENIED
;
1407 sid_copy( &sid
, &q_u
->sid
.sid
);
1409 if ( q_u
->removeall
) {
1410 if ( !revoke_all_privileges( &sid
) )
1411 return NT_STATUS_ACCESS_DENIED
;
1413 return NT_STATUS_OK
;
1416 /* just a little sanity check */
1418 if ( q_u
->count
!= uni_privnames
->count
) {
1419 DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n"));
1420 return NT_STATUS_INVALID_HANDLE
;
1423 for ( i
=0; i
<q_u
->count
; i
++ ) {
1424 unistr2_to_ascii( privname
, &uni_privnames
->strings
[i
].string
, sizeof(fstring
)-1 );
1426 /* only try to add non-null strings */
1428 if ( *privname
&& !revoke_privilege_by_name( &sid
, privname
) ) {
1429 DEBUG(2,("_lsa_remove_acct_rights: Failed to revoke privilege [%s]\n", privname
));
1430 return NT_STATUS_NO_SUCH_PRIVILEGE
;
1434 return NT_STATUS_OK
;
1438 NTSTATUS
_lsa_enum_acct_rights(pipes_struct
*p
, LSA_Q_ENUM_ACCT_RIGHTS
*q_u
, LSA_R_ENUM_ACCT_RIGHTS
*r_u
)
1440 struct lsa_info
*info
= NULL
;
1442 PRIVILEGE_SET privileges
;
1446 /* find the connection policy handle. */
1448 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1449 return NT_STATUS_INVALID_HANDLE
;
1451 /* according to an NT4 PDC, you can add privileges to SIDs even without
1452 call_lsa_create_account() first. And you can use any arbitrary SID. */
1454 sid_copy( &sid
, &q_u
->sid
.sid
);
1456 if ( !get_privileges_for_sids( &mask
, &sid
, 1 ) )
1457 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1459 privilege_set_init( &privileges
);
1461 if ( se_priv_to_privilege_set( &privileges
, &mask
) ) {
1463 DEBUG(10,("_lsa_enum_acct_rights: %s has %d privileges\n",
1464 sid_string_static(&sid
), privileges
.count
));
1466 r_u
->status
= init_r_enum_acct_rights( r_u
, &privileges
);
1469 r_u
->status
= NT_STATUS_NO_SUCH_PRIVILEGE
;
1471 privilege_set_free( &privileges
);