diff options
-rw-r--r-- | source3/include/proto.h | 1 | ||||
-rw-r--r-- | source3/lib/util_sid.c | 11 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr_nt.c | 64 | ||||
-rw-r--r-- | source3/utils/net_rpc.c | 11 |
4 files changed, 71 insertions, 16 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 9b3950229e..9b555e6db2 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1466,6 +1466,7 @@ void del_sid_from_array(const DOM_SID *sid, DOM_SID **sids, size_t *num); bool add_rid_to_array_unique(TALLOC_CTX *mem_ctx, uint32 rid, uint32 **pp_rids, size_t *p_num); bool is_null_sid(const DOM_SID *sid); +bool is_sid_in_token(const NT_USER_TOKEN *token, const DOM_SID *sid); NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx, const struct netr_SamInfo3 *info3, DOM_SID **user_sids, diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c index 53614ed1ac..f656bb13dc 100644 --- a/source3/lib/util_sid.c +++ b/source3/lib/util_sid.c @@ -664,6 +664,17 @@ bool is_null_sid(const DOM_SID *sid) return sid_equal(sid, &null_sid); } +bool is_sid_in_token(const NT_USER_TOKEN *token, const DOM_SID *sid) +{ + int i; + + for (i=0; i<token->num_sids; i++) { + if (sid_compare(sid, &token->user_sids[i]) == 0) + return true; + } + return false; +} + NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx, const struct netr_SamInfo3 *info3, DOM_SID **user_sids, diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 261d77ca65..221ad29144 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -5,7 +5,7 @@ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Paul Ashton 1997, * Copyright (C) Marc Jacobsen 1999, - * Copyright (C) Jeremy Allison 2001-2005, + * Copyright (C) Jeremy Allison 2001-2008, * Copyright (C) Jean François Micouleau 1998-2001, * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002, * Copyright (C) Gerald (Jerry) Carter 2003-2004, @@ -248,6 +248,48 @@ static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_requir } /******************************************************************* + Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set. +********************************************************************/ + +static void map_max_allowed_access(const NT_USER_TOKEN *token, + uint32_t *pacc_requested) +{ + if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) { + return; + } + *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS; + + /* At least try for generic read. */ + *pacc_requested = GENERIC_READ_ACCESS; + + /* root gets anything. */ + if (geteuid() == sec_initial_uid()) { + *pacc_requested |= GENERIC_ALL_ACCESS; + return; + } + + /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */ + + if (is_sid_in_token(token, &global_sid_Builtin_Administrators) || + is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) { + *pacc_requested |= GENERIC_ALL_ACCESS; + return; + } + + /* Full access for DOMAIN\Domain Admins. */ + if ( IS_DC ) { + DOM_SID domadmin_sid; + sid_copy( &domadmin_sid, get_global_sam_sid() ); + sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS ); + if (is_sid_in_token(token, &domadmin_sid)) { + *pacc_requested |= GENERIC_ALL_ACCESS; + return; + } + } + /* TODO ! Check privileges. */ +} + +/******************************************************************* Fetch or create a dispinfo struct. ********************************************************************/ @@ -585,6 +627,7 @@ NTSTATUS _samr_OpenDomain(pipes_struct *p, return status; /*check if access can be granted as requested by client. */ + map_max_allowed_access(p->pipe_user.nt_user_token, &des_access); make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 ); se_map_generic( &des_access, &dom_generic_mapping ); @@ -2178,6 +2221,8 @@ NTSTATUS _samr_OpenUser(pipes_struct *p, /* check if access can be granted as requested by client. */ + map_max_allowed_access(p->pipe_user.nt_user_token, &des_access); + make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW); se_map_generic(&des_access, &usr_generic_mapping); @@ -3255,6 +3300,8 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p, sid_compose(&sid, get_global_sam_sid(), *r->out.rid); + map_max_allowed_access(p->pipe_user.nt_user_token, &des_access); + make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW); se_map_generic(&des_access, &usr_generic_mapping); @@ -3316,10 +3363,7 @@ NTSTATUS _samr_Connect(pipes_struct *p, was observed from a win98 client trying to enumerate users (when configured user level access control on shares) --jerry */ - if (des_access == MAXIMUM_ALLOWED_ACCESS) { - /* Map to max possible knowing we're filtered below. */ - des_access = GENERIC_ALL_ACCESS; - } + map_max_allowed_access(p->pipe_user.nt_user_token, &des_access); se_map_generic( &des_access, &sam_generic_mapping ); info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN); @@ -3355,6 +3399,8 @@ NTSTATUS _samr_Connect2(pipes_struct *p, return NT_STATUS_ACCESS_DENIED; } + map_max_allowed_access(p->pipe_user.nt_user_token, &des_access); + make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0); se_map_generic(&des_access, &sam_generic_mapping); @@ -3404,6 +3450,8 @@ NTSTATUS _samr_Connect4(pipes_struct *p, return NT_STATUS_ACCESS_DENIED; } + map_max_allowed_access(p->pipe_user.nt_user_token, &des_access); + make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0); se_map_generic(&des_access, &sam_generic_mapping); @@ -3453,6 +3501,8 @@ NTSTATUS _samr_Connect5(pipes_struct *p, return NT_STATUS_ACCESS_DENIED; } + map_max_allowed_access(p->pipe_user.nt_user_token, &des_access); + make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0); se_map_generic(&des_access, &sam_generic_mapping); @@ -3620,6 +3670,8 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p, /*check if access can be granted as requested by client. */ + map_max_allowed_access(p->pipe_user.nt_user_token, &des_access); + make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0); se_map_generic(&des_access,&ali_generic_mapping); @@ -5514,6 +5566,8 @@ NTSTATUS _samr_OpenGroup(pipes_struct *p, return status; /*check if access can be granted as requested by client. */ + map_max_allowed_access(p->pipe_user.nt_user_token, &des_access); + make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0); se_map_generic(&des_access,&grp_generic_mapping); diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 5f5a21dfbb..94feeafa69 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -3956,17 +3956,6 @@ static void free_user_token(NT_USER_TOKEN *token) SAFE_FREE(token->user_sids); } -static bool is_sid_in_token(NT_USER_TOKEN *token, DOM_SID *sid) -{ - int i; - - for (i=0; i<token->num_sids; i++) { - if (sid_compare(sid, &token->user_sids[i]) == 0) - return true; - } - return false; -} - static void add_sid_to_token(NT_USER_TOKEN *token, DOM_SID *sid) { if (is_sid_in_token(token, sid)) |