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.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 /* This is the implementation of the lsa server code. */
28 extern DOM_SID global_sam_sid
;
29 extern fstring global_myworkgroup
;
30 extern pstring global_myname
;
38 struct generic_mapping lsa_generic_mapping
= {
45 /*******************************************************************
46 Function to free the per handle data.
47 ********************************************************************/
49 static void free_lsa_info(void *ptr
)
51 struct lsa_info
*lsa
= (struct lsa_info
*)ptr
;
56 /***************************************************************************
58 ***************************************************************************/
60 static void init_dom_query(DOM_QUERY
*d_q
, char *dom_name
, DOM_SID
*dom_sid
)
62 int domlen
= (dom_name
!= NULL
) ? strlen(dom_name
) : 0;
65 * I'm not sure why this really odd combination of length
66 * values works, but it does appear to. I need to look at
67 * this *much* more closely - but at the moment leave alone
68 * until it's understood. This allows a W2k client to join
69 * a domain with both odd and even length names... JRA.
72 d_q
->uni_dom_str_len
= domlen
? ((domlen
+ 1) * 2) : 0;
73 d_q
->uni_dom_max_len
= domlen
* 2;
74 d_q
->buffer_dom_name
= domlen
!= 0 ? 1 : 0; /* domain buffer pointer */
75 d_q
->buffer_dom_sid
= dom_sid
!= NULL
? 1 : 0; /* domain sid pointer */
77 /* this string is supposed to be character short */
78 init_unistr2(&d_q
->uni_domain_name
, dom_name
, domlen
);
79 d_q
->uni_domain_name
.uni_max_len
++;
82 init_dom_sid2(&d_q
->dom_sid
, dom_sid
);
85 /***************************************************************************
86 init_dom_ref - adds a domain if it's not already in, returns the index.
87 ***************************************************************************/
89 static int init_dom_ref(DOM_R_REF
*ref
, char *dom_name
, DOM_SID
*dom_sid
)
94 if (dom_name
!= NULL
) {
95 for (num
= 0; num
< ref
->num_ref_doms_1
; num
++) {
97 rpcstr_pull(domname
, &ref
->ref_dom
[num
].uni_dom_name
, sizeof(domname
), -1, 0);
98 if (strequal(domname
, dom_name
))
102 num
= ref
->num_ref_doms_1
;
105 if (num
>= MAX_REF_DOMAINS
) {
106 /* index not found, already at maximum domain limit */
110 ref
->num_ref_doms_1
= num
+1;
111 ref
->ptr_ref_dom
= 1;
112 ref
->max_entries
= MAX_REF_DOMAINS
;
113 ref
->num_ref_doms_2
= num
+1;
115 len
= (dom_name
!= NULL
) ? strlen(dom_name
) : 0;
116 if(dom_name
!= NULL
&& len
== 0)
119 init_uni_hdr(&ref
->hdr_ref_dom
[num
].hdr_dom_name
, len
);
120 ref
->hdr_ref_dom
[num
].ptr_dom_sid
= dom_sid
!= NULL
? 1 : 0;
122 init_unistr2(&ref
->ref_dom
[num
].uni_dom_name
, dom_name
, len
);
123 init_dom_sid2(&ref
->ref_dom
[num
].ref_dom
, dom_sid
);
128 /***************************************************************************
130 ***************************************************************************/
132 static void init_lsa_rid2s(DOM_R_REF
*ref
, DOM_RID2
*rid2
,
133 int num_entries
, UNISTR2
*name
,
134 uint32
*mapped_count
, BOOL endian
)
140 SMB_ASSERT(num_entries
<= MAX_LOOKUP_SIDS
);
142 become_root(); /* lookup_name can require root privs */
144 for (i
= 0; i
< num_entries
; i
++) {
147 uint32 rid
= 0xffffffff;
150 fstring dom_name
, user
;
151 enum SID_NAME_USE name_type
= SID_NAME_UNKNOWN
;
153 /* Split name into domain and user component */
155 unistr2_to_ascii(full_name
, &name
[i
], sizeof(full_name
));
156 split_domain_name(full_name
, dom_name
, user
);
160 DEBUG(5, ("init_lsa_rid2s: looking up name %s\n", full_name
));
162 status
= lookup_name(dom_name
, user
, &sid
, &name_type
);
164 DEBUG(5, ("init_lsa_rid2s: %s\n", status
? "found" :
168 sid_split_rid(&sid
, &rid
);
169 dom_idx
= init_dom_ref(ref
, dom_name
, &sid
);
174 name_type
= SID_NAME_UNKNOWN
;
177 init_dom_rid2(&rid2
[total
], rid
, name_type
, dom_idx
);
184 /***************************************************************************
185 init_reply_lookup_names
186 ***************************************************************************/
188 static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES
*r_l
,
189 DOM_R_REF
*ref
, uint32 num_entries
,
190 DOM_RID2
*rid2
, uint32 mapped_count
)
192 r_l
->ptr_dom_ref
= 1;
195 r_l
->num_entries
= num_entries
;
196 r_l
->ptr_entries
= 1;
197 r_l
->num_entries2
= num_entries
;
200 r_l
->mapped_count
= mapped_count
;
202 if (mapped_count
== 0)
203 r_l
->status
= NT_STATUS_NONE_MAPPED
;
205 r_l
->status
= NT_STATUS_OK
;
208 /***************************************************************************
209 Init lsa_trans_names.
210 ***************************************************************************/
212 static void init_lsa_trans_names(TALLOC_CTX
*ctx
, DOM_R_REF
*ref
, LSA_TRANS_NAME_ENUM
*trn
,
213 int num_entries
, DOM_SID2
*sid
,
214 uint32
*mapped_count
)
220 /* Allocate memory for list of names */
222 if (num_entries
> 0) {
223 if (!(trn
->name
= (LSA_TRANS_NAME
*)talloc(ctx
, sizeof(LSA_TRANS_NAME
) *
225 DEBUG(0, ("init_lsa_trans_names(): out of memory\n"));
229 if (!(trn
->uni_name
= (UNISTR2
*)talloc(ctx
, sizeof(UNISTR2
) *
231 DEBUG(0, ("init_lsa_trans_names(): out of memory\n"));
236 for (i
= 0; i
< num_entries
; i
++) {
238 DOM_SID find_sid
= sid
[i
].sid
;
239 uint32 rid
= 0xffffffff;
241 fstring name
, dom_name
;
242 enum SID_NAME_USE sid_name_use
= (enum SID_NAME_USE
)0;
244 sid_to_string(name
, &find_sid
);
245 DEBUG(5, ("init_lsa_trans_names: looking up sid %s\n", name
));
247 /* Lookup sid from winbindd */
249 memset(dom_name
, '\0', sizeof(dom_name
));
250 memset(name
, '\0', sizeof(name
));
252 status
= lookup_sid(&find_sid
, dom_name
, name
, &sid_name_use
);
254 DEBUG(5, ("init_lsa_trans_names: %s\n", status
? "found" :
258 sid_name_use
= SID_NAME_UNKNOWN
;
261 /* Store domain sid in ref array */
263 if (find_sid
.num_auths
== 5) {
264 sid_split_rid(&find_sid
, &rid
);
267 dom_idx
= init_dom_ref(ref
, dom_name
, &find_sid
);
269 DEBUG(10,("init_lsa_trans_names: added user '%s\\%s' to "
270 "referenced list.\n", dom_name
, name
));
274 init_lsa_trans_name(&trn
->name
[total
], &trn
->uni_name
[total
],
275 sid_name_use
, name
, dom_idx
);
279 trn
->num_entries
= total
;
280 trn
->ptr_trans_names
= 1;
281 trn
->num_entries2
= total
;
284 /***************************************************************************
285 Init_reply_lookup_sids.
286 ***************************************************************************/
288 static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS
*r_l
,
289 DOM_R_REF
*ref
, LSA_TRANS_NAME_ENUM
*names
,
292 r_l
->ptr_dom_ref
= 1;
295 r_l
->mapped_count
= mapped_count
;
297 if (mapped_count
== 0)
298 r_l
->status
= NT_STATUS_NONE_MAPPED
;
300 r_l
->status
= NT_STATUS_OK
;
303 static NTSTATUS
lsa_get_generic_sd(TALLOC_CTX
*mem_ctx
, SEC_DESC
**sd
, size_t *sd_size
)
305 extern DOM_SID global_sid_World
;
306 extern DOM_SID global_sid_Builtin
;
307 DOM_SID local_adm_sid
;
315 init_sec_access(&mask
, POLICY_EXECUTE
);
316 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
318 sid_copy(&adm_sid
, &global_sam_sid
);
319 sid_append_rid(&adm_sid
, DOMAIN_GROUP_RID_ADMINS
);
320 init_sec_access(&mask
, POLICY_ALL_ACCESS
);
321 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
323 sid_copy(&local_adm_sid
, &global_sid_Builtin
);
324 sid_append_rid(&local_adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
325 init_sec_access(&mask
, POLICY_ALL_ACCESS
);
326 init_sec_ace(&ace
[2], &local_adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
328 if((psa
= make_sec_acl(mem_ctx
, NT4_ACL_REVISION
, 3, ace
)) == NULL
)
329 return NT_STATUS_NO_MEMORY
;
331 if((*sd
= make_sec_desc(mem_ctx
, SEC_DESC_REVISION
, &adm_sid
, NULL
, NULL
, psa
, sd_size
)) == NULL
)
332 return NT_STATUS_NO_MEMORY
;
337 /***************************************************************************
339 ***************************************************************************/
341 NTSTATUS
_lsa_open_policy2(pipes_struct
*p
, LSA_Q_OPEN_POL2
*q_u
, LSA_R_OPEN_POL2
*r_u
)
343 struct lsa_info
*info
;
344 SEC_DESC
*psd
= NULL
;
346 uint32 des_access
=q_u
->des_access
;
351 /* map the generic bits to the lsa policy ones */
352 se_map_generic(&des_access
, &lsa_generic_mapping
);
354 /* get the generic lsa policy SD until we store it */
355 lsa_get_generic_sd(p
->mem_ctx
, &psd
, &sd_size
);
357 if(!se_access_check(psd
, p
->pipe_user
.nt_user_token
, des_access
, &acc_granted
, &status
))
360 /* associate the domain SID with the (unique) handle. */
361 if ((info
= (struct lsa_info
*)malloc(sizeof(struct lsa_info
))) == NULL
)
362 return NT_STATUS_NO_MEMORY
;
365 info
->sid
= global_sam_sid
;
366 info
->access
= acc_granted
;
368 /* set up the LSA QUERY INFO response */
369 if (!create_policy_hnd(p
, &r_u
->pol
, free_lsa_info
, (void *)info
))
370 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
375 /***************************************************************************
377 ***************************************************************************/
379 NTSTATUS
_lsa_open_policy(pipes_struct
*p
, LSA_Q_OPEN_POL
*q_u
, LSA_R_OPEN_POL
*r_u
)
381 struct lsa_info
*info
;
382 SEC_DESC
*psd
= NULL
;
384 uint32 des_access
=q_u
->des_access
;
389 /* map the generic bits to the lsa policy ones */
390 se_map_generic(&des_access
, &lsa_generic_mapping
);
392 /* get the generic lsa policy SD until we store it */
393 lsa_get_generic_sd(p
->mem_ctx
, &psd
, &sd_size
);
395 if(!se_access_check(psd
, p
->pipe_user
.nt_user_token
, des_access
, &acc_granted
, &status
))
398 /* associate the domain SID with the (unique) handle. */
399 if ((info
= (struct lsa_info
*)malloc(sizeof(struct lsa_info
))) == NULL
)
400 return NT_STATUS_NO_MEMORY
;
403 info
->sid
= global_sam_sid
;
404 info
->access
= acc_granted
;
406 /* set up the LSA QUERY INFO response */
407 if (!create_policy_hnd(p
, &r_u
->pol
, free_lsa_info
, (void *)info
))
408 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
413 /***************************************************************************
414 _lsa_enum_trust_dom - this needs fixing to do more than return NULL ! JRA.
415 ***************************************************************************/
417 NTSTATUS
_lsa_enum_trust_dom(pipes_struct
*p
, LSA_Q_ENUM_TRUST_DOM
*q_u
, LSA_R_ENUM_TRUST_DOM
*r_u
)
419 struct lsa_info
*info
;
420 uint32 enum_context
= 0;
421 char *dom_name
= NULL
;
422 DOM_SID
*dom_sid
= NULL
;
424 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
425 return NT_STATUS_INVALID_HANDLE
;
427 /* check if the user have enough rights */
428 if (!(info
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
429 return NT_STATUS_ACCESS_DENIED
;
431 /* set up the LSA QUERY INFO response */
432 init_r_enum_trust_dom(p
->mem_ctx
, r_u
, enum_context
, dom_name
, dom_sid
,
433 dom_name
!= NULL
? NT_STATUS_OK
: NT_STATUS_NO_MORE_ENTRIES
);
438 /***************************************************************************
439 _lsa_query_info. See the POLICY_INFOMATION_CLASS docs at msdn.
440 ***************************************************************************/
442 NTSTATUS
_lsa_query_info(pipes_struct
*p
, LSA_Q_QUERY_INFO
*q_u
, LSA_R_QUERY_INFO
*r_u
)
444 extern DOM_SID global_sid_nonexistent
;
445 struct lsa_info
*handle
;
446 LSA_INFO_UNION
*info
= &r_u
->dom
;
451 r_u
->status
= NT_STATUS_OK
;
453 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
454 return NT_STATUS_INVALID_HANDLE
;
456 switch (q_u
->info_class
) {
460 /* check if the user have enough rights */
461 if (!(handle
->access
& POLICY_VIEW_AUDIT_INFORMATION
))
462 return NT_STATUS_ACCESS_DENIED
;
464 /* fake info: We audit everything. ;) */
465 info
->id2
.auditing_enabled
= 1;
466 info
->id2
.count1
= 7;
467 info
->id2
.count2
= 7;
468 if ((info
->id2
.auditsettings
= (uint32
*)talloc(p
->mem_ctx
,7*sizeof(uint32
))) == NULL
)
469 return NT_STATUS_NO_MEMORY
;
470 for (i
= 0; i
< 7; i
++)
471 info
->id2
.auditsettings
[i
] = 3;
475 /* check if the user have enough rights */
476 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
477 return NT_STATUS_ACCESS_DENIED
;
479 /* Request PolicyPrimaryDomainInformation. */
480 switch (lp_server_role()) {
481 case ROLE_DOMAIN_PDC
:
482 case ROLE_DOMAIN_BDC
:
483 name
= global_myworkgroup
;
484 sid
= &global_sam_sid
;
486 case ROLE_DOMAIN_MEMBER
:
487 name
= global_myworkgroup
;
488 /* We need to return the Domain SID here. */
489 if (secrets_fetch_domain_sid(global_myworkgroup
,
493 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
495 case ROLE_STANDALONE
:
496 name
= global_myworkgroup
;
497 sid
= &global_sid_nonexistent
;
500 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
502 init_dom_query(&r_u
->dom
.id3
, name
, sid
);
505 /* check if the user have enough rights */
506 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
507 return NT_STATUS_ACCESS_DENIED
;
509 /* Request PolicyAccountDomainInformation. */
510 switch (lp_server_role()) {
511 case ROLE_DOMAIN_PDC
:
512 case ROLE_DOMAIN_BDC
:
513 name
= global_myworkgroup
;
514 sid
= &global_sam_sid
;
516 case ROLE_DOMAIN_MEMBER
:
517 name
= global_myname
;
518 sid
= &global_sam_sid
;
520 case ROLE_STANDALONE
:
521 name
= global_myname
;
522 sid
= &global_sam_sid
;
525 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
527 init_dom_query(&r_u
->dom
.id5
, name
, sid
);
530 /* check if the user have enough rights */
531 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
532 return NT_STATUS_ACCESS_DENIED
;
534 switch (lp_server_role()) {
535 case ROLE_DOMAIN_BDC
:
537 * only a BDC is a backup controller
538 * of the domain, it controls.
540 info
->id6
.server_role
= 2;
544 * any other role is a primary
545 * of the domain, it controls.
547 info
->id6
.server_role
= 3;
552 DEBUG(0,("_lsa_query_info: unknown info level in Lsa Query: %d\n", q_u
->info_class
));
553 r_u
->status
= NT_STATUS_INVALID_INFO_CLASS
;
557 if (NT_STATUS_IS_OK(r_u
->status
)) {
558 r_u
->undoc_buffer
= 0x22000000; /* bizarre */
559 r_u
->info_class
= q_u
->info_class
;
565 /***************************************************************************
567 ***************************************************************************/
569 NTSTATUS
_lsa_lookup_sids(pipes_struct
*p
, LSA_Q_LOOKUP_SIDS
*q_u
, LSA_R_LOOKUP_SIDS
*r_u
)
571 struct lsa_info
*handle
;
572 DOM_SID2
*sid
= q_u
->sids
.sid
;
573 int num_entries
= q_u
->sids
.num_entries
;
574 DOM_R_REF
*ref
= NULL
;
575 LSA_TRANS_NAME_ENUM
*names
= NULL
;
576 uint32 mapped_count
= 0;
578 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
579 return NT_STATUS_INVALID_HANDLE
;
581 /* check if the user have enough rights */
582 if (!(handle
->access
& POLICY_LOOKUP_NAMES
))
583 return NT_STATUS_ACCESS_DENIED
;
585 ref
= (DOM_R_REF
*)talloc_zero(p
->mem_ctx
, sizeof(DOM_R_REF
));
586 names
= (LSA_TRANS_NAME_ENUM
*)talloc_zero(p
->mem_ctx
, sizeof(LSA_TRANS_NAME_ENUM
));
589 return NT_STATUS_NO_MEMORY
;
591 /* set up the LSA Lookup SIDs response */
592 init_lsa_trans_names(p
->mem_ctx
, ref
, names
, num_entries
, sid
, &mapped_count
);
593 init_reply_lookup_sids(r_u
, ref
, names
, mapped_count
);
598 /***************************************************************************
599 lsa_reply_lookup_names
600 ***************************************************************************/
602 NTSTATUS
_lsa_lookup_names(pipes_struct
*p
,LSA_Q_LOOKUP_NAMES
*q_u
, LSA_R_LOOKUP_NAMES
*r_u
)
604 struct lsa_info
*handle
;
605 UNISTR2
*names
= q_u
->uni_name
;
606 int num_entries
= q_u
->num_entries
;
609 uint32 mapped_count
= 0;
611 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
612 return NT_STATUS_INVALID_HANDLE
;
614 /* check if the user have enough rights */
615 if (!(handle
->access
& POLICY_LOOKUP_NAMES
))
616 return NT_STATUS_ACCESS_DENIED
;
618 if (num_entries
> MAX_LOOKUP_SIDS
) {
619 num_entries
= MAX_LOOKUP_SIDS
;
620 DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries
));
623 ref
= (DOM_R_REF
*)talloc_zero(p
->mem_ctx
, sizeof(DOM_R_REF
));
624 rids
= (DOM_RID2
*)talloc_zero(p
->mem_ctx
, sizeof(DOM_RID2
)*num_entries
);
627 return NT_STATUS_NO_MEMORY
;
629 /* set up the LSA Lookup RIDs response */
630 init_lsa_rid2s(ref
, rids
, num_entries
, names
, &mapped_count
, p
->endian
);
631 init_reply_lookup_names(r_u
, ref
, num_entries
, rids
, mapped_count
);
636 /***************************************************************************
637 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
638 ***************************************************************************/
640 NTSTATUS
_lsa_close(pipes_struct
*p
, LSA_Q_CLOSE
*q_u
, LSA_R_CLOSE
*r_u
)
642 if (!find_policy_by_hnd(p
, &q_u
->pol
, NULL
))
643 return NT_STATUS_INVALID_HANDLE
;
645 close_policy_hnd(p
, &q_u
->pol
);
649 /***************************************************************************
650 "No more secrets Marty...." :-).
651 ***************************************************************************/
653 NTSTATUS
_lsa_open_secret(pipes_struct
*p
, LSA_Q_OPEN_SECRET
*q_u
, LSA_R_OPEN_SECRET
*r_u
)
655 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
658 /***************************************************************************
660 ***************************************************************************/
662 NTSTATUS
_lsa_enum_privs(pipes_struct
*p
, LSA_Q_ENUM_PRIVS
*q_u
, LSA_R_ENUM_PRIVS
*r_u
)
664 struct lsa_info
*handle
;
667 uint32 enum_context
=q_u
->enum_context
;
668 LSA_PRIV_ENTRY
*entry
;
669 LSA_PRIV_ENTRY
*entries
=NULL
;
671 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
672 return NT_STATUS_INVALID_HANDLE
;
674 /* check if the user have enough rights */
677 * I don't know if it's the right one. not documented.
679 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
680 return NT_STATUS_ACCESS_DENIED
;
682 if (enum_context
>= PRIV_ALL_INDEX
)
683 return NT_STATUS_NO_MORE_ENTRIES
;
685 entries
= (LSA_PRIV_ENTRY
*)talloc_zero(p
->mem_ctx
, sizeof(LSA_PRIV_ENTRY
) * (PRIV_ALL_INDEX
));
687 return NT_STATUS_NO_MEMORY
;
691 DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n", enum_context
, PRIV_ALL_INDEX
));
693 for (i
= 0; i
< PRIV_ALL_INDEX
; i
++, entry
++) {
694 if( i
<enum_context
) {
695 init_uni_hdr(&entry
->hdr_name
, 0);
696 init_unistr2(&entry
->name
, NULL
, 0 );
698 entry
->luid_high
= 0;
700 init_uni_hdr(&entry
->hdr_name
, strlen(privs
[i
+1].priv
));
701 init_unistr2(&entry
->name
, privs
[i
+1].priv
, strlen(privs
[i
+1].priv
) );
702 entry
->luid_low
= privs
[i
+1].se_priv
;
703 entry
->luid_high
= 0;
707 enum_context
= PRIV_ALL_INDEX
;
708 init_lsa_r_enum_privs(r_u
, enum_context
, PRIV_ALL_INDEX
, entries
);
713 /***************************************************************************
714 _lsa_priv_get_dispname.
715 ***************************************************************************/
717 NTSTATUS
_lsa_priv_get_dispname(pipes_struct
*p
, LSA_Q_PRIV_GET_DISPNAME
*q_u
, LSA_R_PRIV_GET_DISPNAME
*r_u
)
719 struct lsa_info
*handle
;
723 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
724 return NT_STATUS_INVALID_HANDLE
;
726 /* check if the user have enough rights */
729 * I don't know if it's the right one. not documented.
731 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
732 return NT_STATUS_ACCESS_DENIED
;
734 unistr2_to_ascii(name_asc
, &q_u
->name
, sizeof(name_asc
));
736 DEBUG(10,("_lsa_priv_get_dispname: %s", name_asc
));
738 while (privs
[i
].se_priv
!=SE_PRIV_ALL
&& strcmp(name_asc
, privs
[i
].priv
))
741 if (privs
[i
].se_priv
!=SE_PRIV_ALL
) {
742 DEBUG(10,(": %s\n", privs
[i
].description
));
743 init_uni_hdr(&r_u
->hdr_desc
, strlen(privs
[i
].description
));
744 init_unistr2(&r_u
->desc
, privs
[i
].description
, strlen(privs
[i
].description
) );
746 r_u
->ptr_info
=0xdeadbeef;
747 r_u
->lang_id
=q_u
->lang_id
;
750 DEBUG(10,("_lsa_priv_get_dispname: doesn't exist\n"));
752 return NT_STATUS_NO_SUCH_PRIVILEGE
;
756 /***************************************************************************
758 ***************************************************************************/
760 NTSTATUS
_lsa_enum_accounts(pipes_struct
*p
, LSA_Q_ENUM_ACCOUNTS
*q_u
, LSA_R_ENUM_ACCOUNTS
*r_u
)
762 struct lsa_info
*handle
;
765 LSA_SID_ENUM
*sids
=&r_u
->sids
;
768 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
769 return NT_STATUS_INVALID_HANDLE
;
771 /* check if the user have enough rights */
774 * I don't know if it's the right one. not documented.
776 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
777 return NT_STATUS_ACCESS_DENIED
;
779 /* get the list of mapped groups (domain, local, builtin) */
780 if(!enum_group_mapping(SID_NAME_UNKNOWN
, &map
, &num_entries
, ENUM_ONLY_MAPPED
, MAPPING_WITHOUT_PRIV
))
783 if (q_u
->enum_context
>= num_entries
)
784 return NT_STATUS_NO_MORE_ENTRIES
;
786 sids
->ptr_sid
= (uint32
*)talloc_zero(p
->mem_ctx
, (num_entries
-q_u
->enum_context
)*sizeof(uint32
));
787 sids
->sid
= (DOM_SID2
*)talloc_zero(p
->mem_ctx
, (num_entries
-q_u
->enum_context
)*sizeof(DOM_SID2
));
789 if (sids
->ptr_sid
==NULL
|| sids
->sid
==NULL
) {
791 return NT_STATUS_NO_MEMORY
;
794 for (i
=q_u
->enum_context
, j
=0; i
<num_entries
; i
++) {
795 init_dom_sid2( &(*sids
).sid
[j
], &map
[i
].sid
);
796 (*sids
).ptr_sid
[j
]=1;
802 init_lsa_r_enum_accounts(r_u
, j
);
808 NTSTATUS
_lsa_unk_get_connuser(pipes_struct
*p
, LSA_Q_UNK_GET_CONNUSER
*q_u
, LSA_R_UNK_GET_CONNUSER
*r_u
)
810 fstring username
, domname
;
812 user_struct
*vuser
= get_valid_user_struct(p
->vuid
);
815 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
817 fstrcpy(username
, vuser
->user
.smb_name
);
818 fstrcpy(domname
, vuser
->user
.domain
);
820 ulen
= strlen(username
) + 1;
821 dlen
= strlen(domname
) + 1;
823 init_uni_hdr(&r_u
->hdr_user_name
, ulen
);
824 r_u
->ptr_user_name
= 1;
825 init_unistr2(&r_u
->uni2_user_name
, username
, ulen
);
829 init_uni_hdr(&r_u
->hdr_dom_name
, dlen
);
830 r_u
->ptr_dom_name
= 1;
831 init_unistr2(&r_u
->uni2_dom_name
, domname
, dlen
);
833 r_u
->status
= NT_STATUS_OK
;
838 /***************************************************************************
840 ***************************************************************************/
842 NTSTATUS
_lsa_open_account(pipes_struct
*p
, LSA_Q_OPENACCOUNT
*q_u
, LSA_R_OPENACCOUNT
*r_u
)
844 struct lsa_info
*handle
;
845 struct lsa_info
*info
;
847 r_u
->status
= NT_STATUS_OK
;
849 /* find the connection policy handle. */
850 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
851 return NT_STATUS_INVALID_HANDLE
;
853 /* check if the user have enough rights */
856 * I don't know if it's the right one. not documented.
857 * but guessed with rpcclient.
859 if (!(handle
->access
& POLICY_GET_PRIVATE_INFORMATION
))
860 return NT_STATUS_ACCESS_DENIED
;
862 /* associate the user/group SID with the (unique) handle. */
863 if ((info
= (struct lsa_info
*)malloc(sizeof(struct lsa_info
))) == NULL
)
864 return NT_STATUS_NO_MEMORY
;
867 info
->sid
= q_u
->sid
.sid
;
868 info
->access
= q_u
->access
;
870 /* get a (unique) handle. open a policy on it. */
871 if (!create_policy_hnd(p
, &r_u
->pol
, free_lsa_info
, (void *)info
))
872 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
877 /***************************************************************************
878 For a given SID, enumerate all the privilege this account has.
879 ***************************************************************************/
881 NTSTATUS
_lsa_enum_privsaccount(pipes_struct
*p
, LSA_Q_ENUMPRIVSACCOUNT
*q_u
, LSA_R_ENUMPRIVSACCOUNT
*r_u
)
883 struct lsa_info
*info
=NULL
;
889 r_u
->status
= NT_STATUS_OK
;
891 /* find the connection policy handle. */
892 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
893 return NT_STATUS_INVALID_HANDLE
;
895 if (!get_group_map_from_sid(info
->sid
, &map
, MAPPING_WITH_PRIV
))
896 return NT_STATUS_NO_SUCH_GROUP
;
898 DEBUG(10,("_lsa_enum_privsaccount: %d privileges\n", map
.priv_set
.count
));
899 if (map
.priv_set
.count
!=0) {
901 set
=(LUID_ATTR
*)talloc(p
->mem_ctx
, map
.priv_set
.count
*sizeof(LUID_ATTR
));
903 free_privilege(&map
.priv_set
);
904 return NT_STATUS_NO_MEMORY
;
907 for (i
=0; i
<map
.priv_set
.count
; i
++) {
908 set
[i
].luid
.low
=map
.priv_set
.set
[i
].luid
.low
;
909 set
[i
].luid
.high
=map
.priv_set
.set
[i
].luid
.high
;
910 set
[i
].attr
=map
.priv_set
.set
[i
].attr
;
911 DEBUG(10,("_lsa_enum_privsaccount: priv %d: %d:%d:%d\n", i
,
912 set
[i
].luid
.high
, set
[i
].luid
.low
, set
[i
].attr
));
916 init_lsa_r_enum_privsaccount(r_u
, set
, map
.priv_set
.count
, 0);
917 free_privilege(&map
.priv_set
);
922 /***************************************************************************
924 ***************************************************************************/
926 NTSTATUS
_lsa_getsystemaccount(pipes_struct
*p
, LSA_Q_GETSYSTEMACCOUNT
*q_u
, LSA_R_GETSYSTEMACCOUNT
*r_u
)
928 struct lsa_info
*info
=NULL
;
930 r_u
->status
= NT_STATUS_OK
;
932 /* find the connection policy handle. */
933 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
934 return NT_STATUS_INVALID_HANDLE
;
936 if (!get_group_map_from_sid(info
->sid
, &map
, MAPPING_WITHOUT_PRIV
))
937 return NT_STATUS_NO_SUCH_GROUP
;
940 0x01 -> Log on locally
941 0x02 -> Access this computer from network
942 0x04 -> Log on as a batch job
943 0x10 -> Log on as a service
945 they can be ORed together
948 r_u
->access
=map
.systemaccount
;
953 /***************************************************************************
954 update the systemaccount information
955 ***************************************************************************/
957 NTSTATUS
_lsa_setsystemaccount(pipes_struct
*p
, LSA_Q_SETSYSTEMACCOUNT
*q_u
, LSA_R_SETSYSTEMACCOUNT
*r_u
)
959 struct lsa_info
*info
=NULL
;
961 r_u
->status
= NT_STATUS_OK
;
963 /* find the connection policy handle. */
964 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
965 return NT_STATUS_INVALID_HANDLE
;
967 if (!get_group_map_from_sid(info
->sid
, &map
, MAPPING_WITH_PRIV
))
968 return NT_STATUS_NO_SUCH_GROUP
;
970 map
.systemaccount
=q_u
->access
;
972 if(!add_mapping_entry(&map
, TDB_REPLACE
))
973 return NT_STATUS_NO_SUCH_GROUP
;
975 free_privilege(&map
.priv_set
);
980 /***************************************************************************
981 For a given SID, add some privileges.
982 ***************************************************************************/
984 NTSTATUS
_lsa_addprivs(pipes_struct
*p
, LSA_Q_ADDPRIVS
*q_u
, LSA_R_ADDPRIVS
*r_u
)
986 struct lsa_info
*info
=NULL
;
990 LUID_ATTR
*luid_attr
=NULL
;
991 PRIVILEGE_SET
*set
=NULL
;
993 r_u
->status
= NT_STATUS_OK
;
995 /* find the connection policy handle. */
996 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
997 return NT_STATUS_INVALID_HANDLE
;
999 if (!get_group_map_from_sid(info
->sid
, &map
, MAPPING_WITH_PRIV
))
1000 return NT_STATUS_NO_SUCH_GROUP
;
1004 for (i
=0; i
<set
->count
; i
++) {
1005 luid_attr
=&set
->set
[i
];
1007 /* check if the privilege is already there */
1008 if (check_priv_in_privilege(&map
.priv_set
, *luid_attr
)){
1009 free_privilege(&map
.priv_set
);
1010 return NT_STATUS_NO_SUCH_PRIVILEGE
;
1013 add_privilege(&map
.priv_set
, *luid_attr
);
1016 if(!add_mapping_entry(&map
, TDB_REPLACE
))
1017 return NT_STATUS_NO_SUCH_GROUP
;
1019 free_privilege(&map
.priv_set
);
1024 /***************************************************************************
1025 For a given SID, remove some privileges.
1026 ***************************************************************************/
1028 NTSTATUS
_lsa_removeprivs(pipes_struct
*p
, LSA_Q_REMOVEPRIVS
*q_u
, LSA_R_REMOVEPRIVS
*r_u
)
1030 struct lsa_info
*info
=NULL
;
1034 LUID_ATTR
*luid_attr
=NULL
;
1035 PRIVILEGE_SET
*set
=NULL
;
1037 r_u
->status
= NT_STATUS_OK
;
1039 /* find the connection policy handle. */
1040 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1041 return NT_STATUS_INVALID_HANDLE
;
1043 if (!get_group_map_from_sid(info
->sid
, &map
, MAPPING_WITH_PRIV
))
1044 return NT_STATUS_NO_SUCH_GROUP
;
1046 if (q_u
->allrights
!=0) {
1047 /* log it and return, until I see one myself don't do anything */
1048 DEBUG(5,("_lsa_removeprivs: trying to remove all privileges ?\n"));
1049 return NT_STATUS_OK
;
1053 /* log it and return, until I see one myself don't do anything */
1054 DEBUG(5,("_lsa_removeprivs: no privileges to remove ?\n"));
1055 return NT_STATUS_OK
;
1060 for (i
=0; i
<set
->count
; i
++) {
1061 luid_attr
=&set
->set
[i
];
1063 /* if we don't have the privilege, we're trying to remove, give up */
1064 /* what else can we do ??? JFM. */
1065 if (!check_priv_in_privilege(&map
.priv_set
, *luid_attr
)){
1066 free_privilege(&map
.priv_set
);
1067 return NT_STATUS_NO_SUCH_PRIVILEGE
;
1070 remove_privilege(&map
.priv_set
, *luid_attr
);
1073 if(!add_mapping_entry(&map
, TDB_REPLACE
))
1074 return NT_STATUS_NO_SUCH_GROUP
;
1076 free_privilege(&map
.priv_set
);
1081 /***************************************************************************
1082 For a given SID, remove some privileges.
1083 ***************************************************************************/
1085 NTSTATUS
_lsa_query_secobj(pipes_struct
*p
, LSA_Q_QUERY_SEC_OBJ
*q_u
, LSA_R_QUERY_SEC_OBJ
*r_u
)
1087 struct lsa_info
*handle
=NULL
;
1088 SEC_DESC
*psd
= NULL
;
1092 r_u
->status
= NT_STATUS_OK
;
1094 /* find the connection policy handle. */
1095 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&handle
))
1096 return NT_STATUS_INVALID_HANDLE
;
1098 /* check if the user have enough rights */
1099 if (!(handle
->access
& POLICY_VIEW_LOCAL_INFORMATION
))
1100 return NT_STATUS_ACCESS_DENIED
;
1103 switch (q_u
->sec_info
) {
1105 /* SD contains only the owner */
1107 status
=lsa_get_generic_sd(p
->mem_ctx
, &psd
, &sd_size
);
1108 if(!NT_STATUS_IS_OK(status
))
1109 return NT_STATUS_NO_MEMORY
;
1112 if((r_u
->buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
)) == NULL
)
1113 return NT_STATUS_NO_MEMORY
;
1116 /* SD contains only the ACL */
1118 status
=lsa_get_generic_sd(p
->mem_ctx
, &psd
, &sd_size
);
1119 if(!NT_STATUS_IS_OK(status
))
1120 return NT_STATUS_NO_MEMORY
;
1122 if((r_u
->buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
)) == NULL
)
1123 return NT_STATUS_NO_MEMORY
;
1126 return NT_STATUS_INVALID_LEVEL
;