diff options
author | Gerald Carter <jerry@samba.org> | 2005-09-30 17:13:37 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:04:48 -0500 |
commit | 54abd2aa66069e6baf7769c496f46d9dba18db39 (patch) | |
tree | 9cf8e88168011797319ba9e9866749201b1eac1e /source3/rpc_server/srv_reg_nt.c | |
parent | 4a2cc231d22a82ed21771a72508f15d21ed63227 (diff) | |
download | samba-54abd2aa66069e6baf7769c496f46d9dba18db39.tar.gz samba-54abd2aa66069e6baf7769c496f46d9dba18db39.tar.bz2 samba-54abd2aa66069e6baf7769c496f46d9dba18db39.zip |
r10656: BIG merge from trunk. Features not copied over
* \PIPE\unixinfo
* winbindd's {group,alias}membership new functions
* winbindd's lookupsids() functionality
* swat (trunk changes to be reverted as per discussion with Deryck)
(This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3)
Diffstat (limited to 'source3/rpc_server/srv_reg_nt.c')
-rw-r--r-- | source3/rpc_server/srv_reg_nt.c | 436 |
1 files changed, 177 insertions, 259 deletions
diff --git a/source3/rpc_server/srv_reg_nt.c b/source3/rpc_server/srv_reg_nt.c index a405948864..4db5ed0ed6 100644 --- a/source3/rpc_server/srv_reg_nt.c +++ b/source3/rpc_server/srv_reg_nt.c @@ -33,62 +33,9 @@ #define OUR_HANDLE(hnd) (((hnd)==NULL)?"NULL":(IVAL((hnd)->data5,4)==(uint32)sys_getpid()?"OURS":"OTHER")), \ ((unsigned int)IVAL((hnd)->data5,4)),((unsigned int)sys_getpid()) +static struct generic_mapping reg_generic_map = + { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL }; -static struct generic_mapping reg_generic_map = { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL }; - -/******************************************************************** -********************************************************************/ - -NTSTATUS registry_access_check( SEC_DESC *sec_desc, NT_USER_TOKEN *token, - uint32 access_desired, uint32 *access_granted ) -{ - NTSTATUS result; - - if ( geteuid() == sec_initial_uid() ) { - DEBUG(5,("registry_access_check: access check bypassed for 'root'\n")); - *access_granted = REG_KEY_ALL; - return NT_STATUS_OK; - } - - se_map_generic( &access_desired, ®_generic_map ); - se_access_check( sec_desc, token, access_desired, access_granted, &result ); - - return result; -} - -/******************************************************************** -********************************************************************/ - -SEC_DESC* construct_registry_sd( TALLOC_CTX *ctx ) -{ - SEC_ACE ace[2]; - SEC_ACCESS mask; - size_t i = 0; - SEC_DESC *sd; - SEC_ACL *acl; - uint32 sd_size; - - /* basic access for Everyone */ - - init_sec_access(&mask, REG_KEY_READ ); - init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - /* Full Access 'BUILTIN\Administrators' */ - - init_sec_access(&mask, REG_KEY_ALL ); - init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - - /* create the security descriptor */ - - if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) ) - return NULL; - - if ( !(sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, acl, &sd_size)) ) - return NULL; - - return sd; -} /****************************************************************** free() function for REGISTRY_KEY @@ -96,9 +43,7 @@ SEC_DESC* construct_registry_sd( TALLOC_CTX *ctx ) static void free_regkey_info(void *ptr) { - REGISTRY_KEY *info = (REGISTRY_KEY*)ptr; - - SAFE_FREE(info); + TALLOC_FREE( ptr ); } /****************************************************************** @@ -126,89 +71,38 @@ static REGISTRY_KEY *find_regkey_index_by_hnd(pipes_struct *p, POLICY_HND *hnd) HK[LM|U]\<key>\<key>\... *******************************************************************/ -static WERROR open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY *parent, - const char *subkeyname, uint32 access_granted ) +static WERROR open_registry_key( pipes_struct *p, POLICY_HND *hnd, + REGISTRY_KEY **keyinfo, REGISTRY_KEY *parent, + const char *subkeyname, uint32 access_desired ) { - REGISTRY_KEY *regkey = NULL; + pstring keypath; + int path_len; WERROR result = WERR_OK; - REGSUBKEY_CTR *subkeys = NULL; - pstring subkeyname2; - int subkey_len; - - DEBUG(7,("open_registry_key: name = [%s][%s]\n", - parent ? parent->name : "NULL", subkeyname)); - - /* strip any trailing '\'s */ - pstrcpy( subkeyname2, subkeyname ); - subkey_len = strlen ( subkeyname2 ); - if ( subkey_len && subkeyname2[subkey_len-1] == '\\' ) - subkeyname2[subkey_len-1] = '\0'; - if ((regkey=SMB_MALLOC_P(REGISTRY_KEY)) == NULL) - return WERR_NOMEM; - - ZERO_STRUCTP( regkey ); - - /* - * very crazy, but regedit.exe on Win2k will attempt to call - * REG_OPEN_ENTRY with a keyname of "". We should return a new - * (second) handle here on the key->name. regedt32.exe does - * not do this stupidity. --jerry - */ - - if ( !subkey_len ) { - pstrcpy( regkey->name, parent->name ); - } - else { - pstrcpy( regkey->name, "" ); - if ( parent ) { - pstrcat( regkey->name, parent->name ); - pstrcat( regkey->name, "\\" ); - } - pstrcat( regkey->name, subkeyname2 ); - } + /* create a full registry path and strip any trailing '\' + characters */ + + pstr_sprintf( keypath, "%s%s%s", + parent ? parent->name : "", + parent ? "\\" : "", + subkeyname ); - /* Look up the table of registry I/O operations */ - - if ( !(regkey->hook = reghook_cache_find( regkey->name )) ) { - DEBUG(0,("open_registry_key: Failed to assigned a REGISTRY_HOOK to [%s]\n", - regkey->name )); - result = WERR_BADFILE; - goto done; - } + path_len = strlen( keypath ); + if ( path_len && keypath[path_len-1] == '\\' ) + keypath[path_len-1] = '\0'; - /* check if the path really exists; failed is indicated by -1 */ - /* if the subkey count failed, bail out */ - - if ( !(subkeys = TALLOC_ZERO_P( p->mem_ctx, REGSUBKEY_CTR )) ) { - result = WERR_NOMEM; - goto done; - } - - if ( fetch_reg_keys( regkey, subkeys ) == -1 ) { - result = WERR_BADFILE; - goto done; - } + /* now do the internal open */ - if ( !create_policy_hnd( p, hnd, free_regkey_info, regkey ) ) { + result = regkey_open_internal( keyinfo, keypath, p->pipe_user.nt_user_token, access_desired ); + if ( !W_ERROR_IS_OK(result) ) + return result; + + if ( !create_policy_hnd( p, hnd, free_regkey_info, *keyinfo ) ) { result = WERR_BADFILE; - goto done; + TALLOC_FREE( *keyinfo ); } - /* save the access mask */ - - regkey->access_granted = access_granted; - -done: - /* clean up */ - - TALLOC_FREE( subkeys ); - - if ( ! NT_STATUS_IS_OK(result) ) - SAFE_FREE( regkey ); - DEBUG(7,("open_registry_key: exit\n")); - return result; } @@ -332,43 +226,39 @@ WERROR _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u) WERROR _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u) { - SEC_DESC *sec_desc; - uint32 access_granted = 0; - NTSTATUS status; + REGISTRY_KEY *keyinfo; - /* perform access checks */ - /* top level keys are done here without passing through the REGISTRY_HOOK api */ + return open_registry_key( p, &r_u->pol, &keyinfo, NULL, KEY_HKLM, q_u->access ); +} + +/******************************************************************* + ********************************************************************/ + +WERROR _reg_open_hkpd(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u) +{ + REGISTRY_KEY *keyinfo; - if ( !(sec_desc = construct_registry_sd( p->mem_ctx )) ) - return WERR_NOMEM; - - status = registry_access_check( sec_desc, p->pipe_user.nt_user_token, q_u->access, &access_granted ); - if ( !NT_STATUS_IS_OK(status) ) - return ntstatus_to_werror( status ); - - return open_registry_key( p, &r_u->pol, NULL, KEY_HKLM, access_granted ); + return open_registry_key( p, &r_u->pol, &keyinfo, NULL, KEY_HKPD, q_u->access ); } /******************************************************************* ********************************************************************/ -WERROR _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u) +WERROR _reg_open_hkpt(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u) { - SEC_DESC *sec_desc; - uint32 access_granted = 0; - NTSTATUS status; + REGISTRY_KEY *keyinfo; - /* perform access checks */ - /* top level keys are done here without passing through the REGISTRY_HOOK api */ + return open_registry_key( p, &r_u->pol, &keyinfo, NULL, KEY_HKPT, q_u->access ); +} + +/******************************************************************* + ********************************************************************/ + +WERROR _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u) +{ + REGISTRY_KEY *keyinfo; - if ( !(sec_desc = construct_registry_sd( p->mem_ctx )) ) - return WERR_NOMEM; - - status = registry_access_check( sec_desc, p->pipe_user.nt_user_token, q_u->access, &access_granted ); - if ( !NT_STATUS_IS_OK(status) ) - return ntstatus_to_werror( status ); - - return open_registry_key( p, &r_u->pol, NULL, KEY_HKCR, access_granted ); + return open_registry_key( p, &r_u->pol, &keyinfo, NULL, KEY_HKCR, q_u->access ); } /******************************************************************* @@ -376,21 +266,9 @@ WERROR _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_ WERROR _reg_open_hku(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u) { - SEC_DESC *sec_desc; - uint32 access_granted = 0; - NTSTATUS status; - - /* perform access checks */ - /* top level keys are done here without passing through the REGISTRY_HOOK api */ + REGISTRY_KEY *keyinfo; - if ( !(sec_desc = construct_registry_sd( p->mem_ctx )) ) - return WERR_NOMEM; - - status = registry_access_check( sec_desc, p->pipe_user.nt_user_token, q_u->access, &access_granted ); - if ( !NT_STATUS_IS_OK(status) ) - return ntstatus_to_werror( status ); - - return open_registry_key( p, &r_u->pol, NULL, KEY_HKU, access_granted ); + return open_registry_key( p, &r_u->pol, &keyinfo, NULL, KEY_HKU, q_u->access ); } /******************************************************************* @@ -401,9 +279,8 @@ WERROR _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY { fstring name; REGISTRY_KEY *parent = find_regkey_index_by_hnd(p, &q_u->pol); - REGISTRY_KEY *newkey; - uint32 access_granted; - WERROR result; + REGISTRY_KEY *newkey = NULL; + uint32 check_rights; if ( !parent ) return WERR_BADFID; @@ -412,29 +289,22 @@ WERROR _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY /* check granted access first; what is the correct mask here? */ - if ( !(parent->access_granted & (SEC_RIGHTS_ENUM_SUBKEYS|SEC_RIGHTS_CREATE_SUBKEY|SEC_RIGHTS_QUERY_VALUE|SEC_RIGHTS_SET_VALUE)) ) + check_rights = ( SEC_RIGHTS_ENUM_SUBKEYS| + SEC_RIGHTS_CREATE_SUBKEY| + SEC_RIGHTS_QUERY_VALUE| + SEC_RIGHTS_SET_VALUE); + + if ( !(parent->access_granted & check_rights) ) 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, parent, 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; - - return WERR_OK; + /* + * very crazy, but regedit.exe on Win2k will attempt to call + * REG_OPEN_ENTRY with a keyname of "". We should return a new + * (second) handle here on the key->name. regedt32.exe does + * not do this stupidity. --jerry + */ + + return open_registry_key( p, &r_u->handle, &newkey, parent, name, q_u->access ); } /******************************************************************* @@ -454,16 +324,93 @@ WERROR _reg_query_value(pipes_struct *p, REG_Q_QUERY_VALUE *q_u, REG_R_QUERY_VAL return WERR_BADFID; DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->name)); + DEBUG(7,("_reg_info: policy key type = [%08x]\n", regkey->type)); rpcstr_pull(name, q_u->name.string->buffer, sizeof(name), q_u->name.string->uni_str_len*2, 0); - DEBUG(5,("reg_info: looking up value: [%s]\n", name)); + DEBUG(5,("_reg_info: looking up value: [%s]\n", name)); if ( !(regvals = TALLOC_P( p->mem_ctx, REGVAL_CTR )) ) return WERR_NOMEM; - for ( i=0; fetch_reg_values_specific(regkey, &val, i); i++ ) + /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */ + if(regkey->type == REG_KEY_HKPD) + { + if(strequal(name, "Global")) + { + uint32 outbuf_len; + prs_struct prs_hkpd; + prs_init(&prs_hkpd, q_u->bufsize, p->mem_ctx, MARSHALL); + status = reg_perfcount_get_hkpd(&prs_hkpd, q_u->bufsize, &outbuf_len, NULL); + regval_ctr_addvalue(regvals, "HKPD", REG_BINARY, + prs_hkpd.data_p, outbuf_len); + val = dup_registry_value(regval_ctr_specific_value(regvals, 0)); + prs_mem_free(&prs_hkpd); + } + else if(strequal(name, "Counter 009")) + { + uint32 base_index; + uint32 buffer_size; + char *buffer; + + buffer = NULL; + base_index = reg_perfcount_get_base_index(); + buffer_size = reg_perfcount_get_counter_names(base_index, &buffer); + regval_ctr_addvalue(regvals, "Counter 009", + REG_MULTI_SZ, buffer, buffer_size); + + val = dup_registry_value(regval_ctr_specific_value(regvals, 0)); + + if(buffer_size > 0) + { + SAFE_FREE(buffer); + status = WERR_OK; + } + } + else if(strequal(name, "Explain 009")) + { + uint32 base_index; + uint32 buffer_size; + char *buffer; + + buffer = NULL; + base_index = reg_perfcount_get_base_index(); + buffer_size = reg_perfcount_get_counter_help(base_index, &buffer); + regval_ctr_addvalue(regvals, "Explain 009", + REG_MULTI_SZ, buffer, buffer_size); + + val = dup_registry_value(regval_ctr_specific_value(regvals, 0)); + + if(buffer_size > 0) + { + SAFE_FREE(buffer); + status = WERR_OK; + } + } + else if(isdigit(name[0])) + { + /* we probably have a request for a specific object here */ + uint32 outbuf_len; + prs_struct prs_hkpd; + prs_init(&prs_hkpd, q_u->bufsize, p->mem_ctx, MARSHALL); + status = reg_perfcount_get_hkpd(&prs_hkpd, q_u->bufsize, &outbuf_len, name); + regval_ctr_addvalue(regvals, "HKPD", REG_BINARY, + prs_hkpd.data_p, outbuf_len); + + val = dup_registry_value(regval_ctr_specific_value(regvals, 0)); + prs_mem_free(&prs_hkpd); + } + else + { + DEBUG(3,("Unsupported key name [%s] for HKPD.\n", name)); + return WERR_BADFILE; + } + } + /* HKPT calls can be handled out of reg_dynamic.c with the hkpt_params handler */ + else { + for ( i=0; fetch_reg_values_specific(regkey, &val, i); i++ ) + { DEBUG(10,("_reg_info: Testing value [%s]\n", val->valuename)); if ( strequal( val->valuename, name ) ) { DEBUG(10,("_reg_info: Found match for value [%s]\n", name)); @@ -472,6 +419,7 @@ WERROR _reg_query_value(pipes_struct *p, REG_Q_QUERY_VALUE *q_u, REG_R_QUERY_VAL } free_registry_value( val ); + } } init_reg_r_query_value(q_u->ptr_buf, r_u, val, status); @@ -482,7 +430,6 @@ WERROR _reg_query_value(pipes_struct *p, REG_Q_QUERY_VALUE *q_u, REG_R_QUERY_VAL return status; } - /***************************************************************************** Implementation of REG_QUERY_KEY ****************************************************************************/ @@ -998,7 +945,7 @@ static WERROR make_default_reg_sd( TALLOC_CTX *ctx, SEC_DESC **psd ) SEC_ACE ace[2]; /* at most 2 entries */ SEC_ACCESS mask; SEC_ACL *psa = NULL; - uint32 sd_size; + size_t sd_size; /* set the owner to BUILTIN\Administrator */ @@ -1092,7 +1039,7 @@ WERROR _reg_save_key(pipes_struct *p, REG_Q_SAVE_KEY *q_u, REG_R_SAVE_KEY *r_u) WERROR _reg_create_key_ex(pipes_struct *p, REG_Q_CREATE_KEY_EX *q_u, REG_R_CREATE_KEY_EX *r_u) { REGISTRY_KEY *parent = find_regkey_index_by_hnd(p, &q_u->handle); - REGISTRY_KEY *newparent; + REGISTRY_KEY *newparentinfo, *keyinfo; POLICY_HND newparent_handle; REGSUBKEY_CTR *subkeys; BOOL write_result; @@ -1109,7 +1056,6 @@ WERROR _reg_create_key_ex(pipes_struct *p, REG_Q_CREATE_KEY_EX *q_u, REG_R_CREAT 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. @@ -1122,19 +1068,11 @@ WERROR _reg_create_key_ex(pipes_struct *p, REG_Q_CREATE_KEY_EX *q_u, REG_R_CREAT ptr = strrchr( newkeyname, '\\' ); *ptr = '\0'; - result = open_registry_key( p, &newparent_handle, parent, newkeyname, 0 ); + result = open_registry_key( p, &newparent_handle, &newparentinfo, + parent, newkeyname, (REG_KEY_READ|REG_KEY_WRITE) ); + 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) */ @@ -1142,13 +1080,13 @@ WERROR _reg_create_key_ex(pipes_struct *p, REG_Q_CREATE_KEY_EX *q_u, REG_R_CREAT } else { /* use the existing open key information */ - newparent = parent; + newparentinfo = parent; memcpy( &newparent_handle, &q_u->handle, sizeof(POLICY_HND) ); } /* (3) check for create subkey rights on the correct parent */ - if ( !(newparent->access_granted & SEC_RIGHTS_CREATE_SUBKEY) ) { + if ( !(newparentinfo->access_granted & SEC_RIGHTS_CREATE_SUBKEY) ) { result = WERR_ACCESS_DENIED; goto done; } @@ -1160,12 +1098,12 @@ WERROR _reg_create_key_ex(pipes_struct *p, REG_Q_CREATE_KEY_EX *q_u, REG_R_CREAT /* (4) lookup the current keys and add the new one */ - fetch_reg_keys( newparent, subkeys ); + fetch_reg_keys( newparentinfo, subkeys ); regsubkey_ctr_addkey( subkeys, name ); /* now write to the registry backend */ - write_result = store_reg_keys( newparent, subkeys ); + write_result = store_reg_keys( newparentinfo, subkeys ); TALLOC_FREE( subkeys ); @@ -1173,16 +1111,15 @@ WERROR _reg_create_key_ex(pipes_struct *p, REG_Q_CREATE_KEY_EX *q_u, REG_R_CREAT return WERR_REG_IO_FAILURE; /* (5) open the new key and return the handle. Note that it is probably - not correct to grant full access on this open handle. We should pass - the new open through the regkey_access_check() like we do for - _reg_open_entry() but this is ok for now. */ + not correct to grant full access on this open handle. */ - result = open_registry_key( p, &r_u->handle, newparent, name, REG_KEY_ALL ); + result = open_registry_key( p, &r_u->handle, &keyinfo, newparentinfo, name, REG_KEY_READ ); + keyinfo->access_granted = REG_KEY_ALL; done: /* close any intermediate key handles */ - if ( newparent != parent ) + if ( newparentinfo != parent ) close_registry_key( p, &newparent_handle ); return result; @@ -1243,7 +1180,7 @@ 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; + REGISTRY_KEY *newparentinfo; POLICY_HND newparent_handle; REGSUBKEY_CTR *subkeys; BOOL write_result; @@ -1252,6 +1189,15 @@ WERROR _reg_delete_key(pipes_struct *p, REG_Q_DELETE_KEY *q_u, REG_R_DELETE_KEY if ( !parent ) return WERR_BADFID; + + /* MSDN says parent the handle must have been opened with DELETE access */ + + /* (1) check for delete rights on the parent */ + + if ( !(parent->access_granted & STD_RIGHT_DELETE_ACCESS) ) { + result = WERR_ACCESS_DENIED; + goto done; + } rpcstr_pull( name, q_u->name.string->buffer, sizeof(name), q_u->name.string->uni_str_len*2, 0 ); @@ -1260,50 +1206,24 @@ WERROR _reg_delete_key(pipes_struct *p, REG_Q_DELETE_KEY *q_u, REG_R_DELETE_KEY 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 */ + /* (2) open the path to the child parent key if necessary */ + /* split the registry path and save the subkeyname */ - if ( !(parent->access_granted & SEC_RIGHTS_ENUM_SUBKEYS) ) - return WERR_ACCESS_DENIED; - pstrcpy( newkeyname, name ); ptr = strrchr( newkeyname, '\\' ); *ptr = '\0'; + pstrcpy( name, ptr+1 ); - result = open_registry_key( p, &newparent_handle, parent, newkeyname, 0 ); + result = open_registry_key( p, &newparent_handle, &newparentinfo, parent, newkeyname, (REG_KEY_READ|REG_KEY_WRITE) ); 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) ); + newparentinfo = parent; } - /* (3) check for create subkey rights on the correct parent */ - - if ( !(newparent->access_granted & STD_RIGHT_DELETE_ACCESS) ) { - result = WERR_ACCESS_DENIED; - goto done; - } - if ( !(subkeys = TALLOC_ZERO_P( p->mem_ctx, REGSUBKEY_CTR )) ) { result = WERR_NOMEM; goto done; @@ -1311,13 +1231,13 @@ WERROR _reg_delete_key(pipes_struct *p, REG_Q_DELETE_KEY *q_u, REG_R_DELETE_KEY /* lookup the current keys and delete the new one */ - fetch_reg_keys( newparent, subkeys ); + fetch_reg_keys( newparentinfo, subkeys ); regsubkey_ctr_delkey( subkeys, name ); /* now write to the registry backend */ - write_result = store_reg_keys( newparent, subkeys ); + write_result = store_reg_keys( newparentinfo, subkeys ); TALLOC_FREE( subkeys ); @@ -1326,7 +1246,7 @@ WERROR _reg_delete_key(pipes_struct *p, REG_Q_DELETE_KEY *q_u, REG_R_DELETE_KEY done: /* close any intermediate key handles */ - if ( newparent != parent ) + if ( newparentinfo != parent ) close_registry_key( p, &newparent_handle ); return result; @@ -1414,5 +1334,3 @@ WERROR _reg_set_key_sec(pipes_struct *p, REG_Q_SET_KEY_SEC *q_u, REG_R_SET_KEY_ return WERR_ACCESS_DENIED; } - - |