2007-06-14 15:29:35 +04:00
/*
* Unix SMB / CIFS implementation .
* Registry helper routines
* Copyright ( C ) Volker Lendecke 2006
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the Free
2007-07-09 23:25:36 +04:00
* Software Foundation ; either version 3 of the License , or ( at your option )
2007-06-14 15:29:35 +04:00
* any later version .
*
* This program is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
* more details .
*
* You should have received a copy of the GNU General Public License along with
2007-07-10 09:23:25 +04:00
* this program ; if not , see < http : //www.gnu.org/licenses/>.
2007-06-14 15:29:35 +04:00
*/
# include "includes.h"
2007-09-29 03:05:52 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_REGISTRY
2007-06-14 15:29:35 +04:00
WERROR registry_pull_value ( TALLOC_CTX * mem_ctx ,
struct registry_value * * pvalue ,
enum winreg_Type type , uint8 * data ,
uint32 size , uint32 length )
{
struct registry_value * value ;
WERROR err ;
if ( ! ( value = TALLOC_ZERO_P ( mem_ctx , struct registry_value ) ) ) {
return WERR_NOMEM ;
}
value - > type = type ;
switch ( type ) {
case REG_DWORD :
if ( ( size ! = 4 ) | | ( length ! = 4 ) ) {
err = WERR_INVALID_PARAM ;
goto error ;
}
value - > v . dword = IVAL ( data , 0 ) ;
break ;
case REG_SZ :
case REG_EXPAND_SZ :
{
/*
* Make sure we get a NULL terminated string for
* convert_string_talloc ( ) .
*/
smb_ucs2_t * tmp ;
2007-07-01 03:52:23 +04:00
if ( length = = 1 ) {
/* win2k regedit gives us a string of 1 byte when
* creating a new value of type REG_SZ . this workaround
* replaces the input by using the same string as
* winxp delivers . */
length = 2 ;
if ( ! ( tmp = SMB_MALLOC_ARRAY ( smb_ucs2_t , 2 ) ) ) {
err = WERR_NOMEM ;
goto error ;
}
2007-08-22 01:55:51 +04:00
tmp [ 0 ] = 0 ;
2007-07-01 03:52:23 +04:00
tmp [ 1 ] = 0 ;
2007-08-22 01:57:58 +04:00
DEBUG ( 10 , ( " got REG_SZ value of length 1 - workaround "
" activated. \n " ) ) ;
2007-07-01 03:52:23 +04:00
}
else if ( ( length % 2 ) ! = 0 ) {
2007-06-14 15:29:35 +04:00
err = WERR_INVALID_PARAM ;
goto error ;
}
2007-07-01 03:52:23 +04:00
else {
2007-07-01 04:09:20 +04:00
uint32 num_ucs2 = length / 2 ;
2007-07-01 03:52:23 +04:00
if ( ! ( tmp = SMB_MALLOC_ARRAY ( smb_ucs2_t , num_ucs2 + 1 ) ) ) {
err = WERR_NOMEM ;
goto error ;
}
2007-06-14 15:29:35 +04:00
2007-07-01 03:52:23 +04:00
memcpy ( ( void * ) tmp , ( const void * ) data , length ) ;
tmp [ num_ucs2 ] = 0 ;
2007-06-14 15:29:35 +04:00
}
2007-07-03 00:51:09 +04:00
if ( length + 2 < length ) {
/* Integer wrap. */
2007-07-09 11:55:09 +04:00
SAFE_FREE ( tmp ) ;
2007-07-03 00:51:09 +04:00
err = WERR_INVALID_PARAM ;
goto error ;
}
2008-04-30 01:36:24 +04:00
if ( ! convert_string_talloc ( value , CH_UTF16LE , CH_UNIX , tmp ,
2009-03-02 00:58:46 +03:00
length + 2 , ( void * * ) & value - > v . sz . str ,
2008-04-30 01:36:24 +04:00
& value - > v . sz . len , False ) ) {
SAFE_FREE ( tmp ) ;
2007-06-14 15:29:35 +04:00
err = WERR_INVALID_PARAM ;
goto error ;
}
2008-04-30 01:36:24 +04:00
SAFE_FREE ( tmp ) ;
2007-06-14 15:29:35 +04:00
break ;
}
case REG_MULTI_SZ :
err = reg_pull_multi_sz ( value , ( void * ) data , length ,
& value - > v . multi_sz . num_strings ,
& value - > v . multi_sz . strings ) ;
if ( ! ( W_ERROR_IS_OK ( err ) ) ) {
goto error ;
}
break ;
case REG_BINARY :
2007-07-24 13:42:15 +04:00
value - > v . binary = data_blob_talloc ( mem_ctx , data , length ) ;
2007-06-14 15:29:35 +04:00
break ;
default :
err = WERR_INVALID_PARAM ;
goto error ;
}
* pvalue = value ;
return WERR_OK ;
error :
TALLOC_FREE ( value ) ;
return err ;
}
WERROR registry_push_value ( TALLOC_CTX * mem_ctx ,
const struct registry_value * value ,
DATA_BLOB * presult )
{
switch ( value - > type ) {
case REG_DWORD : {
char buf [ 4 ] ;
SIVAL ( buf , 0 , value - > v . dword ) ;
* presult = data_blob_talloc ( mem_ctx , ( void * ) buf , 4 ) ;
if ( presult - > data = = NULL ) {
return WERR_NOMEM ;
}
break ;
}
case REG_SZ :
case REG_EXPAND_SZ : {
2008-04-30 01:36:24 +04:00
if ( ! convert_string_talloc ( mem_ctx , CH_UNIX , CH_UTF16LE ,
value - > v . sz . str ,
MIN ( value - > v . sz . len ,
strlen ( value - > v . sz . str ) + 1 ) ,
( void * ) & ( presult - > data ) ,
& presult - > length , False ) )
{
2007-06-14 15:29:35 +04:00
return WERR_NOMEM ;
}
break ;
}
2008-04-08 19:44:40 +04:00
case REG_MULTI_SZ : {
uint32_t count ;
size_t len = 0 ;
char * * strings ;
size_t * string_lengths ;
uint32_t ofs ;
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
strings = TALLOC_ARRAY ( tmp_ctx , char * ,
value - > v . multi_sz . num_strings ) ;
if ( strings = = NULL ) {
return WERR_NOMEM ;
}
string_lengths = TALLOC_ARRAY ( tmp_ctx , size_t ,
value - > v . multi_sz . num_strings ) ;
if ( string_lengths = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return WERR_NOMEM ;
}
/* convert the single strings */
for ( count = 0 ; count < value - > v . multi_sz . num_strings ; count + + )
{
2008-04-30 01:36:24 +04:00
if ( ! convert_string_talloc ( strings , CH_UNIX ,
CH_UTF16LE , value - > v . multi_sz . strings [ count ] ,
2008-04-08 19:44:40 +04:00
strlen ( value - > v . multi_sz . strings [ count ] ) + 1 ,
2008-04-30 01:36:24 +04:00
( void * ) & strings [ count ] ,
& string_lengths [ count ] , false ) )
{
2008-04-08 19:44:40 +04:00
TALLOC_FREE ( tmp_ctx ) ;
return WERR_NOMEM ;
}
len + = string_lengths [ count ] ;
}
/* now concatenate all into the data blob */
presult - > data = TALLOC_ARRAY ( mem_ctx , uint8_t , len ) ;
if ( presult - > data = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return WERR_NOMEM ;
}
for ( count = 0 , ofs = 0 ;
count < value - > v . multi_sz . num_strings ;
count + + )
{
memcpy ( presult - > data + ofs , strings [ count ] ,
string_lengths [ count ] ) ;
ofs + = string_lengths [ count ] ;
}
presult - > length = len ;
TALLOC_FREE ( tmp_ctx ) ;
break ;
}
2007-07-24 13:42:15 +04:00
case REG_BINARY :
* presult = data_blob_talloc ( mem_ctx ,
value - > v . binary . data ,
value - > v . binary . length ) ;
break ;
2007-06-14 15:29:35 +04:00
default :
return WERR_INVALID_PARAM ;
}
return WERR_OK ;
}