mirror of
https://github.com/samba-team/samba.git
synced 2025-02-05 21:57:51 +03:00
r7664: add access check hooks to _reg_open_entry which are passed off
to the reg_XXX backend. If the backend does not define a regkey_access_check() function, we default to using the standard registry_access_check()
This commit is contained in:
parent
f3319e224d
commit
2f08a904ee
@ -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;
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -1458,21 +1458,6 @@ BOOL reg_io_q_open_entry(const char *desc, REG_Q_OPEN_ENTRY *q_u, prs_struct *p
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
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))
|
||||
|
@ -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 );
|
||||
/* 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;
|
||||
|
||||
newkey = find_regkey_index_by_hnd(p, &r_u->handle);
|
||||
|
||||
/* 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;
|
||||
|
||||
init_reg_r_open_entry( r_u, &pol, result );
|
||||
|
||||
DEBUG(5,("reg_open_entry: Exit\n"));
|
||||
|
||||
return r_u->status;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
|
Loading…
x
Reference in New Issue
Block a user