📄 srv_reg_nt.c
字号:
if ( !reg_split_key( key_tmp, &parentpath, &keyname ) ) return WERR_OBJECT_PATH_INVALID; if ( !keyname ) keyname = parentpath; /* we need a REGISTRY_KEY object here to enumerate subkeys and values */ ZERO_STRUCT( registry_key ); pstrcpy( registry_key.name, keypath ); if ( !(registry_key.hook = reghook_cache_find( registry_key.name )) ) return WERR_BADFILE; /* lookup the values and subkeys */ if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) ) return WERR_NOMEM; if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) return WERR_NOMEM; fetch_reg_keys( ®istry_key, subkeys ); fetch_reg_values( ®istry_key, values ); /* write out this key */ if ( !(key = regfio_write_key( regfile, keyname, values, subkeys, sec_desc, parent )) ) { result = WERR_CAN_NOT_COMPLETE; goto done; } /* write each one of the subkeys out */ num_subkeys = regsubkey_ctr_numkeys( subkeys ); for ( i=0; i<num_subkeys; i++ ) { subkeyname = regsubkey_ctr_specific_key( subkeys, i ); pstr_sprintf( subkeypath, "%s\\%s", keypath, subkeyname ); result = reg_write_tree( regfile, subkeypath, key, sec_desc ); if ( !W_ERROR_IS_OK(result) ) goto done; } DEBUG(6,("reg_write_tree: wrote key [%s]\n", keypath ));done: TALLOC_FREE( subkeys ); return result;}/******************************************************************* ********************************************************************/static WERROR make_default_reg_sd( TALLOC_CTX *ctx, SEC_DESC **psd ){ DOM_SID adm_sid, owner_sid; SEC_ACE ace[2]; /* at most 2 entries */ SEC_ACCESS mask; SEC_ACL *psa = NULL; size_t sd_size; /* set the owner to BUILTIN\Administrator */ sid_copy(&owner_sid, &global_sid_Builtin); sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN ); /* basic access for Everyone */ init_sec_access(&mask, reg_generic_map.generic_execute | reg_generic_map.generic_read ); init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); /* add Full Access 'BUILTIN\Administrators' */ init_sec_access(&mask, reg_generic_map.generic_all); sid_copy(&adm_sid, &global_sid_Builtin); sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS); init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); /* create the security descriptor */ if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 2, ace)) == NULL) return WERR_NOMEM; if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &owner_sid, NULL, NULL, psa, &sd_size)) == NULL) return WERR_NOMEM; return WERR_OK;}/******************************************************************* ********************************************************************/static WERROR backup_registry_key ( REGISTRY_KEY *krecord, const char *fname ){ REGF_FILE *regfile; WERROR result; SEC_DESC *sd = NULL; /* open the registry file....fail if the file already exists */ if ( !(regfile = regfio_open( fname, (O_RDWR|O_CREAT|O_EXCL), (S_IREAD|S_IWRITE) )) ) { DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n", fname, strerror(errno) )); return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) ); } if ( !W_ERROR_IS_OK(result = make_default_reg_sd( regfile->mem_ctx, &sd )) ) { regfio_close( regfile ); return result; } /* write the registry tree to the file */ result = reg_write_tree( regfile, krecord->name, NULL, sd ); /* cleanup */ regfio_close( regfile ); return result;}/******************************************************************* ********************************************************************/WERROR _reg_save_key(pipes_struct *p, REG_Q_SAVE_KEY *q_u, REG_R_SAVE_KEY *r_u){ REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol ); pstring filename; int snum; if ( !regkey ) return WERR_BADFID; rpcstr_pull(filename, q_u->filename.string->buffer, sizeof(filename), q_u->filename.string->uni_str_len*2, STR_TERMINATE); DEBUG(8,("_reg_save_key: verifying backup of key [%s] to \"%s\"\n", regkey->name, filename)); if ( (snum = validate_reg_filename( filename )) == -1 ) return WERR_OBJECT_PATH_INVALID; DEBUG(2,("_reg_save_key: Saving [%s] to %s in share %s\n", regkey->name, filename, lp_servicename(snum) )); return backup_registry_key( regkey, filename );}/******************************************************************* ********************************************************************/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 *newparentinfo, *keyinfo; POLICY_HND newparent_handle; REGSUBKEY_CTR *subkeys; BOOL write_result; 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; /* (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, &newparentinfo, parent, newkeyname, (REG_KEY_READ|REG_KEY_WRITE) ); if ( !W_ERROR_IS_OK(result) ) return result; /* copy the new key name (just the lower most keyname) */ pstrcpy( name, ptr+1 ); } else { /* use the existing open key information */ newparentinfo = parent; memcpy( &newparent_handle, &q_u->handle, sizeof(POLICY_HND) ); } /* (3) check for create subkey rights on the correct parent */ if ( !(newparentinfo->access_granted & SEC_RIGHTS_CREATE_SUBKEY) ) { result = WERR_ACCESS_DENIED; goto done; } if ( !(subkeys = TALLOC_ZERO_P( p->mem_ctx, REGSUBKEY_CTR )) ) { result = WERR_NOMEM; goto done; } /* (4) lookup the current keys and add the new one */ fetch_reg_keys( newparentinfo, subkeys ); regsubkey_ctr_addkey( subkeys, name ); /* now write to the registry backend */ write_result = store_reg_keys( newparentinfo, subkeys ); TALLOC_FREE( subkeys ); if ( !write_result ) 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. */ 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 ( newparentinfo != parent ) close_registry_key( p, &newparent_handle ); return result;}/******************************************************************* ********************************************************************/WERROR _reg_set_value(pipes_struct *p, REG_Q_SET_VALUE *q_u, REG_R_SET_VALUE *r_u){ REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->handle); REGVAL_CTR *values; BOOL write_result; fstring valuename; if ( !key ) return WERR_BADFID; /* access checks first */ if ( !(key->access_granted & SEC_RIGHTS_SET_VALUE) ) return WERR_ACCESS_DENIED; rpcstr_pull( valuename, q_u->name.string->buffer, sizeof(valuename), q_u->name.string->uni_str_len*2, 0 ); /* verify the name */ if ( !*valuename ) return WERR_INVALID_PARAM; DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n", key->name, valuename)); if ( !(values = TALLOC_ZERO_P( p->mem_ctx, REGVAL_CTR )) ) return WERR_NOMEM; /* lookup the current values and add the new one */ fetch_reg_values( key, values ); regval_ctr_addvalue( values, valuename, q_u->type, (char*)q_u->value.buffer, q_u->value.buf_len ); /* now write to the registry backend */ write_result = store_reg_values( key, values ); TALLOC_FREE( values ); if ( !write_result ) return WERR_REG_IO_FAILURE; return WERR_OK;}/******************************************************************* ********************************************************************/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 *newparentinfo; POLICY_HND newparent_handle; REGSUBKEY_CTR *subkeys; BOOL write_result; pstring name; WERROR result; 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 ); /* ok. Here's what we do. */ if ( strrchr( name, '\\' ) ) { pstring newkeyname; char *ptr; /* (2) open the path to the child parent key if necessary */ /* split the registry path and save the subkeyname */ pstrcpy( newkeyname, name ); ptr = strrchr( newkeyname, '\\' ); *ptr = '\0'; pstrcpy( name, ptr+1 ); result = open_registry_key( p, &newparent_handle, &newparentinfo, parent, newkeyname, (REG_KEY_READ|REG_KEY_WRITE) ); if ( !W_ERROR_IS_OK(result) ) return result; } else { /* use the existing open key information */ newparentinfo = parent; } if ( !(subkeys = TALLOC_ZERO_P( p->mem_ctx, REGSUBKEY_CTR )) ) { result = WERR_NOMEM; goto done; } /* lookup the current keys and delete the new one */ fetch_reg_keys( newparentinfo, subkeys ); regsubkey_ctr_delkey( subkeys, name ); /* now write to the registry backend */ write_result = store_reg_keys( newparentinfo, subkeys ); TALLOC_FREE( subkeys ); result = write_result ? WERR_OK : WERR_REG_IO_FAILURE; done: /* close any intermediate key handles */ if ( newparentinfo != parent ) close_registry_key( p, &newparent_handle ); return result;}/******************************************************************* ********************************************************************/WERROR _reg_delete_value(pipes_struct *p, REG_Q_DELETE_VALUE *q_u, REG_R_DELETE_VALUE *r_u){ REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->handle); REGVAL_CTR *values; BOOL write_result; fstring valuename; if ( !key ) return WERR_BADFID; /* access checks first */ if ( !(key->access_granted & SEC_RIGHTS_SET_VALUE) ) return WERR_ACCESS_DENIED; rpcstr_pull( valuename, q_u->name.string->buffer, sizeof(valuename), q_u->name.string->uni_str_len*2, 0 ); if ( !*valuename ) return WERR_INVALID_PARAM; DEBUG(8,("_reg_delete_value: Setting value for [%s:%s]\n", key->name, valuename)); if ( !(values = TALLOC_ZERO_P( p->mem_ctx, REGVAL_CTR )) ) return WERR_NOMEM; /* lookup the current values and add the new one */ fetch_reg_values( key, values ); regval_ctr_delvalue( values, valuename ); /* now write to the registry backend */ write_result = store_reg_values( key, values ); TALLOC_FREE( values ); if ( !write_result ) return WERR_REG_IO_FAILURE; return WERR_OK;}/******************************************************************* ********************************************************************/WERROR _reg_get_key_sec(pipes_struct *p, REG_Q_GET_KEY_SEC *q_u, REG_R_GET_KEY_SEC *r_u){ REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->handle); if ( !key ) return WERR_BADFID; /* access checks first */ if ( !(key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) ) return WERR_ACCESS_DENIED; return WERR_ACCESS_DENIED;}/******************************************************************* ********************************************************************/WERROR _reg_set_key_sec(pipes_struct *p, REG_Q_SET_KEY_SEC *q_u, REG_R_SET_KEY_SEC *r_u){ REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->handle); if ( !key ) return WERR_BADFID; /* access checks first */ if ( !(key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) ) return WERR_ACCESS_DENIED; return WERR_ACCESS_DENIED;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -