r7664: add access check hooks to _reg_open_entry which are passed off
authorGerald Carter <jerry@samba.org>
Fri, 17 Jun 2005 01:57:18 +0000 (01:57 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:57:19 +0000 (10:57 -0500)
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()

source/include/rpc_reg.h
source/registry/reg_frontend.c
source/rpc_client/cli_reg.c
source/rpc_parse/parse_reg.c
source/rpc_server/srv_reg_nt.c

index c83802b3f53465d8efdb357c4899c11f879ae263..270ba32f4b9bb2dd5f11e8c705a5bf242d6fd001 100644 (file)
@@ -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;
 
index 196007d3cb6e7073fd08746f4584ae5c1d8c50d0..ab8a02812f92d30496e8ca2a8e05801933788eaf 100644 (file)
@@ -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 );
+}
+
 
index 9d7b909d0dec3522ca7c8db623fa963043763778..3f5b7652ac792389f8ffef86bfdd20d2e6dd9807 100644 (file)
@@ -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;
 }
index 9f50f50acf46ef1a26d78ea367cd9e8778e727ca..5eed245a280708370931ab071c02aadc4d163c65 100644 (file)
@@ -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))
index 2a80594128acc821f4c880094eb375a4beb4f920..95af6c15c91581be304ba61b5810e5179f1cb9a7 100644 (file)
@@ -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;
 }
 
 /*******************************************************************