The branch, v3-2-test has been updated
via 82ec832f7edffe2fcfd1bb067e092c159bed2973 (commit)
via 34db58061bf0ec1d495579ac40bc6315b76f5b6c (commit)
via b848f96d747fb41c074dd073f24f186539257d71 (commit)
from e7b0d1c984a37600a234c1f4c95b06e9b5898f30 (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-2-test
- Log -----------------------------------------------------------------
commit 82ec832f7edffe2fcfd1bb067e092c159bed2973
Author: Jeremy Allison <[EMAIL PROTECTED]>
Date: Tue Oct 21 17:06:53 2008 -0700
Cope with MAXIMUM_ALLOWED_ACCESS requests when opening handles.
Jeremy.
commit 34db58061bf0ec1d495579ac40bc6315b76f5b6c
Merge: b848f96d747fb41c074dd073f24f186539257d71
e7b0d1c984a37600a234c1f4c95b06e9b5898f30
Author: Jeremy Allison <[EMAIL PROTECTED]>
Date: Tue Oct 21 12:20:00 2008 -0700
Merge branch 'v3-2-test' of ssh://[EMAIL PROTECTED]/data/git/samba into
v3-2-test
commit b848f96d747fb41c074dd073f24f186539257d71
Author: Jeremy Allison <[EMAIL PROTECTED]>
Date: Mon Oct 20 16:53:05 2008 -0700
Remove the requirement for ldap call made as root. Add in security
checks for all SAMR calls.
Jeremy.
-----------------------------------------------------------------------
Summary of changes:
source/lib/smbldap.c | 7 --
source/lib/util_sid.c | 11 +++
source/rpc_server/srv_samr_nt.c | 131 ++++++++++++++++++++++++++++++++++++---
source/utils/net_rpc.c | 11 ---
4 files changed, 133 insertions(+), 27 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source/lib/smbldap.c b/source/lib/smbldap.c
index bcde53c..315b1e3 100644
--- a/source/lib/smbldap.c
+++ b/source/lib/smbldap.c
@@ -1023,13 +1023,6 @@ static int smbldap_open(struct smbldap_state *ldap_state)
int rc, opt_rc;
bool reopen = False;
SMB_ASSERT(ldap_state);
-
-#ifndef NO_LDAP_SECURITY
- if (geteuid() != 0) {
- DEBUG(0, ("smbldap_open: cannot access LDAP when not root\n"));
- return LDAP_INSUFFICIENT_ACCESS;
- }
-#endif
if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping +
SMBLDAP_DONT_PING_TIME) < time(NULL))) {
diff --git a/source/lib/util_sid.c b/source/lib/util_sid.c
index 53614ed..f656bb1 100644
--- a/source/lib/util_sid.c
+++ b/source/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/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c
index c59a46c..a085aa7 100644
--- a/source/rpc_server/srv_samr_nt.c
+++ b/source/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 <[EMAIL PROTECTED]> 2002,
* Copyright (C) Gerald (Jerry) Carter 2003-2004,
@@ -249,6 +249,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.
********************************************************************/
@@ -586,6 +628,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 );
@@ -826,6 +869,13 @@ NTSTATUS _samr_QuerySecurity(pipes_struct *p,
DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
sid_string_dbg(&pol_sid)));
+ status = access_check_samr_function(acc_granted,
+ STD_RIGHT_READ_CONTROL_ACCESS,
+ "_samr_QuerySecurity");
+ if (NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
/* Check what typ of SID is beeing queried (e.g Domain SID, User SID,
Group SID) */
/* To query the security of the SAM it self an invalid SID with S-0-0
is passed to this function */
@@ -1154,6 +1204,9 @@ NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
return NT_STATUS_INVALID_HANDLE;
+ DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
+ sid_string_dbg(&info->sid)));
+
status = access_check_samr_function(info->acc_granted,
SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
"_samr_EnumDomainAliases");
@@ -1161,9 +1214,6 @@ NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
return status;
}
- DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
- sid_string_dbg(&info->sid)));
-
samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
if (!samr_array) {
return NT_STATUS_NO_MEMORY;
@@ -1430,6 +1480,13 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
return NT_STATUS_INVALID_HANDLE;
+ status = access_check_samr_function(info->acc_granted,
+ SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
+ "_samr_QueryDisplayInfo");
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
/*
* calculate how many entries we will return.
* based on
@@ -2063,6 +2120,13 @@ NTSTATUS _samr_LookupRids(pipes_struct *p,
if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid,
&acc_granted, NULL))
return NT_STATUS_INVALID_HANDLE;
+ status = access_check_samr_function(acc_granted,
+ SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
+ "_samr__LookupRids");
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
if (num_rids > 1000) {
DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
"to samba4 idl this is not possible\n", num_rids));
@@ -2158,6 +2222,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);
@@ -2633,6 +2699,13 @@ NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
return NT_STATUS_INVALID_HANDLE;
+ status = access_check_samr_function(info->acc_granted,
+ SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
+ "_samr_QueryUserInfo");
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
domain_sid = info->sid;
sid_split_rid(&domain_sid, &rid);
@@ -2881,6 +2954,13 @@ static NTSTATUS samr_QueryDomainInfo_internal(const char
*fn_name,
return NT_STATUS_INVALID_HANDLE;
}
+ status = access_check_samr_function(info->acc_granted,
+ SA_RIGHT_SAM_OPEN_DOMAIN,
+ "_samr_QueryDomainInfo_internal" );
+
+ if ( !NT_STATUS_IS_OK(status) )
+ return status;
+
switch (level) {
case 0x01:
@@ -3221,6 +3301,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);
@@ -3282,10 +3364,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);
@@ -3321,6 +3400,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);
@@ -3370,6 +3451,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);
@@ -3419,6 +3502,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);
@@ -3586,6 +3671,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);
@@ -5478,6 +5565,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);
@@ -5604,16 +5693,32 @@ NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
struct samr_SetDomainInfo *r)
{
+ struct samr_info *info = NULL;
time_t u_expire, u_min_age;
time_t u_logout;
time_t u_lock_duration, u_reset_time;
+ NTSTATUS result;
DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
/* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, r->in.domain_handle, NULL))
+ if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
return NT_STATUS_INVALID_HANDLE;
+ /* We do have different access bits for info
+ * levels here, but we're really just looking for
+ * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
+ * this maps to different specific bits. So
+ * assume if we have SA_RIGHT_DOMAIN_SET_INFO_1
+ * set we are ok. */
+
+ result = access_check_samr_function(info->acc_granted,
+ SA_RIGHT_DOMAIN_SET_INFO_1,
+ "_samr_SetDomainInfo");
+
+ if (!NT_STATUS_IS_OK(result))
+ return result;
+
DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
switch (r->in.level) {
@@ -5671,6 +5776,7 @@ NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
int i;
uint32_t num_account = 0;
struct samr_displayentry *entries = NULL;
+ NTSTATUS status;
DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
@@ -5679,6 +5785,13 @@ NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct
*p,
return NT_STATUS_INVALID_HANDLE;
}
+ status = access_check_samr_function(info->acc_granted,
+ SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
+ "_samr_GetDisplayEnumerationIndex");
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
if ((r->in.level < 1) || (r->in.level > 3)) {
DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
"Unknown info level (%u)\n",
diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c
index a5c2de0..ef1ebd3 100644
--- a/source/utils/net_rpc.c
+++ b/source/utils/net_rpc.c
@@ -4187,17 +4187,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))
--
Samba Shared Repository