diff options
author | Gerald Carter <jerry@samba.org> | 2005-06-17 18:57:37 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 10:57:19 -0500 |
commit | c25b67b24d3c7ec04a58410aaa05c1aae9688e32 (patch) | |
tree | 4c58725f37a14273333371b15a96dc02fa2a70ae | |
parent | 5c9963c287e20a4a4b8bbaa088328438eb4f942c (diff) | |
download | samba-c25b67b24d3c7ec04a58410aaa05c1aae9688e32.tar.gz samba-c25b67b24d3c7ec04a58410aaa05c1aae9688e32.tar.bz2 samba-c25b67b24d3c7ec04a58410aaa05c1aae9688e32.zip |
r7698: * clean upserver frontend for RegDeleteKey()
* implement RegDeleteKey() for reg_db backend
(This used to be commit 91b81a23b8e2a096747e02fd9392ef590e7f0d61)
-rw-r--r-- | source3/registry/reg_db.c | 43 | ||||
-rw-r--r-- | source3/registry/reg_objects.c | 65 | ||||
-rw-r--r-- | source3/rpc_server/srv_reg_nt.c | 76 |
3 files changed, 147 insertions, 37 deletions
diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c index ce44e490ab..1ae1d6be54 100644 --- a/source3/registry/reg_db.c +++ b/source3/registry/reg_db.c @@ -163,16 +163,22 @@ BOOL init_registry_db( void ) return True; } +/********************************************************************** + The full path to the registry key is used as database after the + \'s are converted to /'s. Key string is also normalized to UPPER + case. +**********************************************************************/ +static void normalize_reg_path( pstring keyname ) +{ + pstring_sub( keyname, "\\", "/" ); + strupper_m( keyname ); +} /*********************************************************************** Add subkey strings to the registry tdb under a defined key fmt is the same format as tdb_pack except this function only supports fstrings - - The full path to the registry key is used as database after the - \'s are converted to /'s. Key string is also normalized to UPPER - case. ***********************************************************************/ static BOOL regdb_store_reg_keys_internal( char *key, REGSUBKEY_CTR *ctr ) @@ -189,12 +195,8 @@ static BOOL regdb_store_reg_keys_internal( char *key, REGSUBKEY_CTR *ctr ) return False; pstrcpy( keyname, key ); - - /* convert to key format */ - - pstring_sub( keyname, "\\", "/" ); - strupper_m( keyname ); - + normalize_reg_path( keyname ); + /* allocate some initial memory */ buffer = SMB_MALLOC(sizeof(pstring)); @@ -249,7 +251,13 @@ static BOOL regdb_store_reg_keys( char *key, REGSUBKEY_CTR *ctr ) { int num_subkeys, i; pstring path; - REGSUBKEY_CTR subkeys; + REGSUBKEY_CTR subkeys, old_subkeys; + char *oldkeyname; + + /* fetch a list of the old subkeys so we can difure out if any were deleted */ + + regsubkey_ctr_init( &old_subkeys ); + regdb_fetch_reg_keys( key, &old_subkeys ); /* store the subkey list for the parent */ @@ -258,6 +266,18 @@ static BOOL regdb_store_reg_keys( char *key, REGSUBKEY_CTR *ctr ) return False; } + /* now delete removed keys */ + + num_subkeys = regsubkey_ctr_numkeys( &old_subkeys ); + for ( i=0; i<num_subkeys; i++ ) { + oldkeyname = regsubkey_ctr_specific_key( &old_subkeys, i ); + if ( !regsubkey_ctr_key_exists( ctr, oldkeyname ) ) { + pstr_sprintf( path, "%s%c%s", key, '/', oldkeyname ); + normalize_reg_path( path ); + tdb_delete_bystring( tdb_reg, path ); + } + } + /* now create records for any subkeys that don't already exist */ num_subkeys = regsubkey_ctr_numkeys( ctr ); @@ -268,6 +288,7 @@ static BOOL regdb_store_reg_keys( char *key, REGSUBKEY_CTR *ctr ) /* create a record with 0 subkeys */ if ( !regdb_store_reg_keys_internal( path, &subkeys ) ) { DEBUG(0,("regdb_store_reg_keys: Failed to store new record for key [%s}\n", path )); + regsubkey_ctr_destroy( &subkeys ); return False; } } diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index 2dd61f515f..582a696529 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -43,22 +43,16 @@ void regsubkey_ctr_init( REGSUBKEY_CTR *ctr ) int regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname ) { - uint32 len; char **pp; - int i; - + if ( !keyname ) return ctr->num_subkeys; - len = strlen( keyname ); - /* make sure the keyname is not already there */ - for ( i=0; i<ctr->num_subkeys; i++ ) { - if ( strequal( ctr->subkeys[i], keyname ) ) - return ctr->num_subkeys; - } - + if ( regsubkey_ctr_key_exists( ctr, keyname ) ) + return ctr->num_subkeys; + /* allocate a space for the char* in the array */ if ( ctr->subkeys == 0 ) @@ -71,13 +65,58 @@ int regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname ) /* allocate the string and save it in the array */ - ctr->subkeys[ctr->num_subkeys] = TALLOC( ctr->ctx, len+1 ); - strncpy( ctr->subkeys[ctr->num_subkeys], keyname, len+1 ); + ctr->subkeys[ctr->num_subkeys] = talloc_strdup( ctr->ctx, keyname ); ctr->num_subkeys++; return ctr->num_subkeys; } + /*********************************************************************** + Add a new key to the array + **********************************************************************/ + +int regsubkey_ctr_delkey( REGSUBKEY_CTR *ctr, const char *keyname ) +{ + int i; + + if ( !keyname ) + return ctr->num_subkeys; + + /* make sure the keyname is actually already there */ + + for ( i=0; i<ctr->num_subkeys; i++ ) { + if ( strequal( ctr->subkeys[i], keyname ) ) + break; + } + + if ( i == ctr->num_subkeys ) + return ctr->num_subkeys; + + /* update if we have any keys left */ + ctr->num_subkeys--; + if ( ctr->num_subkeys ) + memmove( &ctr->subkeys[i], &ctr->subkeys[i+1], sizeof(char*) * (ctr->num_subkeys-i) ); + + return ctr->num_subkeys; +} + +/*********************************************************************** + Check for the existance of a key + **********************************************************************/ + +BOOL regsubkey_ctr_key_exists( REGSUBKEY_CTR *ctr, const char *keyname ) +{ + int i; + + for ( i=0; i<ctr->num_subkeys; i++ ) { + if ( strequal( ctr->subkeys[i],keyname ) ) + return True; + } + + return False; + +} + /*********************************************************************** How many keys does the container hold ? **********************************************************************/ @@ -351,7 +390,7 @@ int regval_ctr_delvalue( REGVAL_CTR *ctr, const char *name ) } /*********************************************************************** - Delete a single value from the registry container. + Retrieve single value from the registry container. No need to free memory since it is talloc'd. **********************************************************************/ diff --git a/source3/rpc_server/srv_reg_nt.c b/source3/rpc_server/srv_reg_nt.c index 3491cc2c76..a3ab63d06e 100644 --- a/source3/rpc_server/srv_reg_nt.c +++ b/source3/rpc_server/srv_reg_nt.c @@ -1304,40 +1304,90 @@ WERROR _reg_set_value(pipes_struct *p, REG_Q_SET_VALUE *q_u, REG_R_SET_VALUE *r WERROR _reg_delete_key(pipes_struct *p, REG_Q_DELETE_KEY *q_u, REG_R_DELETE_KEY *r_u) { REGISTRY_KEY *parent = find_regkey_index_by_hnd(p, &q_u->handle); + REGISTRY_KEY *newparent; + POLICY_HND newparent_handle; REGSUBKEY_CTR subkeys; BOOL write_result; - fstring name; + pstring name; + WERROR result; if ( !parent ) return WERR_BADFID; rpcstr_pull( name, q_u->name.string->buffer, sizeof(name), q_u->name.string->uni_str_len*2, 0 ); + + /* ok. Here's what we do. */ + + if ( strrchr( name, '\\' ) ) { + pstring newkeyname; + char *ptr; + uint32 access_granted; + + /* (1) check for enumerate rights on the parent handle. CLients can try + create things like 'SOFTWARE\Samba' on the HKLM handle. + (2) open the path to the child parent key if necessary */ - /* access checks first */ - - if ( !(parent->access_granted & SEC_RIGHTS_CREATE_SUBKEY) ) - return WERR_ACCESS_DENIED; + if ( !(parent->access_granted & SEC_RIGHTS_ENUM_SUBKEYS) ) + return WERR_ACCESS_DENIED; + pstrcpy( newkeyname, name ); + ptr = strrchr( newkeyname, '\\' ); + *ptr = '\0'; + + result = open_registry_key( p, &newparent_handle, parent, newkeyname, 0 ); + if ( !W_ERROR_IS_OK(result) ) + return result; + + newparent = find_regkey_index_by_hnd(p, &newparent_handle); + SMB_ASSERT( newparent != NULL ); + + if ( !regkey_access_check( newparent, REG_KEY_READ|REG_KEY_WRITE, &access_granted, p->pipe_user.nt_user_token ) ) { + result = WERR_ACCESS_DENIED; + goto done; + } + + newparent->access_granted = access_granted; + + /* copy the new key name (just the lower most keyname) */ + + pstrcpy( name, ptr+1 ); + } + else { + /* use the existing open key information */ + newparent = parent; + memcpy( &newparent_handle, &q_u->handle, sizeof(POLICY_HND) ); + } + + /* (3) check for create subkey rights on the correct parent */ + + if ( !(newparent->access_granted & STD_RIGHT_DELETE_ACCESS) ) { + result = WERR_ACCESS_DENIED; + goto done; + } + regsubkey_ctr_init( &subkeys ); - /* lookup the current keys and add the new one */ + /* lookup the current keys and delete the new one */ - fetch_reg_keys( parent, &subkeys ); + fetch_reg_keys( newparent, &subkeys ); - /* FIXME!!! regsubkey_ctr_delkey( &subkeys, name ); */ + regsubkey_ctr_delkey( &subkeys, name ); /* now write to the registry backend */ - write_result = store_reg_keys( parent, &subkeys ); + write_result = store_reg_keys( newparent, &subkeys ); regsubkey_ctr_destroy( &subkeys ); - if ( !write_result ) - return WERR_REG_IO_FAILURE; - +done: + /* close any intermediate key handles */ + + if ( newparent != parent ) + close_registry_key( p, &newparent_handle ); + /* rpc_reg.h says there is a POLICY_HDN in the reply...no idea if that is correct */ - return WERR_OK; + return write_result ? WERR_OK : WERR_REG_IO_FAILURE; } |