diff options
-rw-r--r-- | source3/include/rpc_reg.h | 12 | ||||
-rw-r--r-- | source3/registry/reg_frontend.c | 24 | ||||
-rw-r--r-- | source3/rpc_client/cli_reg.c | 2 | ||||
-rw-r--r-- | source3/rpc_parse/parse_reg.c | 17 | ||||
-rw-r--r-- | source3/rpc_server/srv_reg_nt.c | 35 |
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; } /******************************************************************* |