mirror of
https://github.com/samba-team/samba.git
synced 2025-01-26 10:04:02 +03:00
r7698: * clean upserver frontend for RegDeleteKey()
* implement RegDeleteKey() for reg_db backend (This used to be commit 91b81a23b8e2a096747e02fd9392ef590e7f0d61)
This commit is contained in:
parent
5c9963c287
commit
c25b67b24d
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
**********************************************************************/
|
||||
|
||||
|
@ -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 );
|
||||
|
||||
/* access checks first */
|
||||
|
||||
if ( !(parent->access_granted & SEC_RIGHTS_CREATE_SUBKEY) )
|
||||
return WERR_ACCESS_DENIED;
|
||||
|
||||
/* 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 */
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user