summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/rpc_reg.h12
-rw-r--r--source3/registry/reg_frontend.c24
-rw-r--r--source3/rpc_client/cli_reg.c2
-rw-r--r--source3/rpc_parse/parse_reg.c17
-rw-r--r--source3/rpc_server/srv_reg_nt.c35
5 files changed, 60 insertions, 30 deletions
diff --git a/source3/include/rpc_reg.h b/source3/include/rpc_reg.h
index c83802b3f5..270ba32f4b 100644
--- a/source3/include/rpc_reg.h
+++ b/source3/include/rpc_reg.h
@@ -96,7 +96,7 @@ typedef struct {
int (*fetch_values) ( char *key, REGVAL_CTR *val );
BOOL (*store_subkeys)( char *key, REGSUBKEY_CTR *subkeys );
BOOL (*store_values)( char *key, REGVAL_CTR *val );
- BOOL (*reg_access_check)( uint32 parent_granted, uint32 requested, uint32 *granted );
+ BOOL (*reg_access_check)( const char *keyname, uint32 requested, uint32 *granted, NT_USER_TOKEN *token );
} REGISTRY_OPS;
typedef struct {
@@ -108,13 +108,11 @@ typedef struct {
/* structure to store the registry handles */
typedef struct _RegistryKey {
-
struct _RegistryKey *prev, *next;
- /* POLICY_HND hnd; */
- pstring name; /* full name of registry key */
- REGISTRY_HOOK *hook;
-
+ pstring name; /* full name of registry key */
+ uint32 access_granted;
+ REGISTRY_HOOK *hook;
} REGISTRY_KEY;
/*
@@ -412,7 +410,7 @@ typedef struct {
} REG_Q_OPEN_ENTRY;
typedef struct {
- POLICY_HND pol;
+ POLICY_HND handle;
WERROR status;
} REG_R_OPEN_ENTRY;
diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c
index 196007d3cb..ab8a02812f 100644
--- a/source3/registry/reg_frontend.c
+++ b/source3/registry/reg_frontend.c
@@ -234,4 +234,28 @@ BOOL fetch_reg_values_specific( REGISTRY_KEY *key, REGISTRY_VALUE **val, uint32
return True;
}
+/***********************************************************************
+ High level access check for passing the required access mask to the
+ underlying registry backend
+ ***********************************************************************/
+
+BOOL regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted, NT_USER_TOKEN *token )
+{
+ /* use the default security check if the backend has not defined its own */
+
+ if ( !(key->hook && key->hook->ops && key->hook->ops->reg_access_check) ) {
+ SEC_DESC *sec_desc;
+ NTSTATUS status;
+
+ if ( !(sec_desc = construct_registry_sd( get_talloc_ctx() )) )
+ return False;
+
+ status = registry_access_check( sec_desc, token, requested, granted );
+
+ return NT_STATUS_IS_OK(status);
+ }
+
+ return key->hook->ops->reg_access_check( key->name, requested, granted, token );
+}
+
diff --git a/source3/rpc_client/cli_reg.c b/source3/rpc_client/cli_reg.c
index 9d7b909d0d..3f5b7652ac 100644
--- a/source3/rpc_client/cli_reg.c
+++ b/source3/rpc_client/cli_reg.c
@@ -621,7 +621,7 @@ WERROR cli_reg_open_entry(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if ( !W_ERROR_IS_OK( out.status ) )
return out.status;
- memcpy( key_hnd, &out.pol, sizeof(POLICY_HND) );
+ memcpy( key_hnd, &out.handle, sizeof(POLICY_HND) );
return out.status;
}
diff --git a/source3/rpc_parse/parse_reg.c b/source3/rpc_parse/parse_reg.c
index 9f50f50acf..5eed245a28 100644
--- a/source3/rpc_parse/parse_reg.c
+++ b/source3/rpc_parse/parse_reg.c
@@ -1459,21 +1459,6 @@ BOOL reg_io_q_open_entry(const char *desc, REG_Q_OPEN_ENTRY *q_u, prs_struct *p
}
/*******************************************************************
- Inits a structure.
-********************************************************************/
-
-void init_reg_r_open_entry(REG_R_OPEN_ENTRY *r_u,
- POLICY_HND *pol, WERROR werr)
-{
- if (W_ERROR_IS_OK(werr)) {
- memcpy(&r_u->pol, pol, sizeof(r_u->pol));
- } else {
- ZERO_STRUCT(r_u->pol);
- }
- r_u->status = werr;
-}
-
-/*******************************************************************
reads or writes a structure.
********************************************************************/
@@ -1488,7 +1473,7 @@ BOOL reg_io_r_open_entry(const char *desc, REG_R_OPEN_ENTRY *r_u, prs_struct *p
if(!prs_align(ps))
return False;
- if(!smb_io_pol_hnd("", &r_u->pol, ps, depth))
+ if(!smb_io_pol_hnd("handle", &r_u->handle, ps, depth))
return False;
if(!prs_werror("status", ps, depth, &r_u->status))
diff --git a/source3/rpc_server/srv_reg_nt.c b/source3/rpc_server/srv_reg_nt.c
index 2a80594128..95af6c15c9 100644
--- a/source3/rpc_server/srv_reg_nt.c
+++ b/source3/rpc_server/srv_reg_nt.c
@@ -197,6 +197,10 @@ static WERROR open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY *
if ( !create_policy_hnd( p, hnd, free_regkey_info, regkey ) )
result = WERR_BADFILE;
}
+
+ /* save the access mask */
+
+ regkey->access_granted = access_granted;
/* clean up */
@@ -402,9 +406,10 @@ WERROR _reg_open_hku(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u
WERROR _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY *r_u)
{
- POLICY_HND pol;
fstring name;
REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->pol);
+ REGISTRY_KEY *newkey;
+ uint32 access_granted;
WERROR result;
DEBUG(5,("reg_open_entry: Enter\n"));
@@ -414,13 +419,31 @@ WERROR _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY
rpcstr_pull( name, q_u->name.string->buffer, sizeof(name), q_u->name.string->uni_str_len*2, 0 );
- result = open_registry_key( p, &pol, key, name, 0x0 );
-
- init_reg_r_open_entry( r_u, &pol, result );
+ /* check granted access first; what is the correct mask here? */
+
+ if ( !(key->access_granted & SEC_RIGHTS_ENUM_SUBKEYS) )
+ return WERR_ACCESS_DENIED;
+
+ /* open the key first to get the appropriate REGISTRY_HOOK
+ and then check the premissions */
+
+ if ( !W_ERROR_IS_OK(result = open_registry_key( p, &r_u->handle, key, name, 0 )) )
+ return result;
- DEBUG(5,("reg_open_entry: Exit\n"));
+ newkey = find_regkey_index_by_hnd(p, &r_u->handle);
- return r_u->status;
+ /* finally allow the backend to check the access for the requested key */
+
+ if ( !regkey_access_check( newkey, q_u->access, &access_granted, p->pipe_user.nt_user_token ) ) {
+ close_registry_key( p, &r_u->handle );
+ return WERR_ACCESS_DENIED;
+ }
+
+ /* if successful, save the granted access mask */
+
+ newkey->access_granted = access_granted;
+
+ return WERR_OK;
}
/*******************************************************************