2004-03-26 05:39:48 +03:00
/*
Unix SMB / CIFS implementation .
SMB torture tester - charset test routines
Copyright ( C ) Andrew Tridgell 2001
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 Software Foundation ; either version 2 of the License , or
( at your option ) 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 this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2004-11-30 07:33:27 +03:00
# include "librpc/gen_ndr/ndr_security.h"
2004-03-26 05:39:48 +03:00
# define BASEDIR "\\chartest\\"
/*
open a file using a set of unicode code points for the name
the prefix BASEDIR is added before the name
*/
2004-08-04 17:23:35 +04:00
static NTSTATUS unicode_open ( struct smbcli_tree * tree ,
2004-03-26 05:39:48 +03:00
TALLOC_CTX * mem_ctx ,
2004-05-25 20:24:13 +04:00
uint32_t open_disposition ,
const uint32_t * u_name ,
2004-03-26 05:39:48 +03:00
size_t u_name_len )
{
union smb_open io ;
char * fname , * fname2 = NULL , * ucs_name ;
int i ;
NTSTATUS status ;
2005-01-06 06:06:58 +03:00
ucs_name = talloc_size ( mem_ctx , ( 1 + u_name_len ) * 2 ) ;
2004-03-26 05:39:48 +03:00
if ( ! ucs_name ) {
2004-09-23 02:06:21 +04:00
printf ( " Failed to create UCS2 Name - talloc() failure \n " ) ;
2004-03-26 05:39:48 +03:00
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < u_name_len ; i + + ) {
SSVAL ( ucs_name , i * 2 , u_name [ i ] ) ;
}
SSVAL ( ucs_name , i * 2 , 0 ) ;
2004-09-23 02:06:21 +04:00
i = convert_string_talloc ( ucs_name , CH_UTF16 , CH_UNIX , ucs_name , ( 1 + u_name_len ) * 2 , ( void * * ) & fname ) ;
2004-03-26 05:39:48 +03:00
if ( i = = - 1 ) {
2004-09-23 02:06:21 +04:00
printf ( " Failed to convert UCS2 Name into unix - convert_string_talloc() failure \n " ) ;
talloc_free ( ucs_name ) ;
2004-03-26 05:39:48 +03:00
return NT_STATUS_NO_MEMORY ;
}
2004-09-23 02:06:21 +04:00
fname2 = talloc_asprintf ( ucs_name , " %s%s " , BASEDIR , fname ) ;
2004-03-26 05:39:48 +03:00
if ( ! fname2 ) {
2004-09-23 02:06:21 +04:00
talloc_free ( ucs_name ) ;
2004-03-26 05:39:48 +03:00
return NT_STATUS_NO_MEMORY ;
}
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED ;
io . ntcreatex . in . root_fid = 0 ;
2004-12-02 07:37:36 +03:00
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
2004-03-26 05:39:48 +03:00
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_CREATE ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname2 ;
io . ntcreatex . in . open_disposition = open_disposition ;
status = smb_raw_open ( tree , mem_ctx , & io ) ;
2004-09-23 02:06:21 +04:00
talloc_free ( ucs_name ) ;
2004-03-26 05:39:48 +03:00
return status ;
}
/*
see if the server recognises composed characters
*/
2004-08-04 17:23:35 +04:00
static BOOL test_composed ( struct smbcli_state * cli , TALLOC_CTX * mem_ctx )
2004-03-26 05:39:48 +03:00
{
2004-05-25 20:24:13 +04:00
const uint32_t name1 [ ] = { 0x61 , 0x308 } ;
const uint32_t name2 [ ] = { 0xe4 } ;
2004-03-26 05:39:48 +03:00
NTSTATUS status1 , status2 ;
printf ( " Testing composite character (a umlaut) \n " ) ;
status1 = unicode_open ( cli - > tree , mem_ctx , NTCREATEX_DISP_CREATE , name1 , 2 ) ;
if ( ! NT_STATUS_IS_OK ( status1 ) ) {
printf ( " Failed to create composed name - %s \n " ,
nt_errstr ( status1 ) ) ;
return False ;
}
status2 = unicode_open ( cli - > tree , mem_ctx , NTCREATEX_DISP_CREATE , name2 , 1 ) ;
if ( ! NT_STATUS_IS_OK ( status2 ) ) {
printf ( " Failed to create accented character - %s \n " ,
nt_errstr ( status2 ) ) ;
return False ;
}
return True ;
}
/*
see if the server recognises a naked diacritical
*/
2004-08-04 17:23:35 +04:00
static BOOL test_diacritical ( struct smbcli_state * cli , TALLOC_CTX * mem_ctx )
2004-03-26 05:39:48 +03:00
{
2004-05-25 20:24:13 +04:00
const uint32_t name1 [ ] = { 0x308 } ;
const uint32_t name2 [ ] = { 0x308 , 0x308 } ;
2004-03-26 05:39:48 +03:00
NTSTATUS status1 , status2 ;
printf ( " Testing naked diacritical (umlaut) \n " ) ;
status1 = unicode_open ( cli - > tree , mem_ctx , NTCREATEX_DISP_CREATE , name1 , 1 ) ;
if ( ! NT_STATUS_IS_OK ( status1 ) ) {
printf ( " Failed to create naked diacritical - %s \n " ,
nt_errstr ( status1 ) ) ;
return False ;
}
/* try a double diacritical */
status2 = unicode_open ( cli - > tree , mem_ctx , NTCREATEX_DISP_CREATE , name2 , 2 ) ;
if ( ! NT_STATUS_IS_OK ( status2 ) ) {
printf ( " Failed to create double naked diacritical - %s \n " ,
nt_errstr ( status2 ) ) ;
return False ;
}
return True ;
}
/*
see if the server recognises a partial surrogate pair
*/
2004-08-04 17:23:35 +04:00
static BOOL test_surrogate ( struct smbcli_state * cli , TALLOC_CTX * mem_ctx )
2004-03-26 05:39:48 +03:00
{
2004-05-25 20:24:13 +04:00
const uint32_t name1 [ ] = { 0xd800 } ;
const uint32_t name2 [ ] = { 0xdc00 } ;
const uint32_t name3 [ ] = { 0xd800 , 0xdc00 } ;
2004-03-26 05:39:48 +03:00
NTSTATUS status ;
printf ( " Testing partial surrogate \n " ) ;
status = unicode_open ( cli - > tree , mem_ctx , NTCREATEX_DISP_CREATE , name1 , 1 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Failed to create partial surrogate 1 - %s \n " ,
nt_errstr ( status ) ) ;
return False ;
}
status = unicode_open ( cli - > tree , mem_ctx , NTCREATEX_DISP_CREATE , name2 , 1 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Failed to create partial surrogate 2 - %s \n " ,
nt_errstr ( status ) ) ;
return False ;
}
status = unicode_open ( cli - > tree , mem_ctx , NTCREATEX_DISP_CREATE , name3 , 2 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Failed to create full surrogate - %s \n " ,
nt_errstr ( status ) ) ;
return False ;
}
return True ;
}
/*
see if the server recognises wide - a characters
*/
2004-08-04 17:23:35 +04:00
static BOOL test_widea ( struct smbcli_state * cli , TALLOC_CTX * mem_ctx )
2004-03-26 05:39:48 +03:00
{
2004-05-25 20:24:13 +04:00
const uint32_t name1 [ ] = { ' a ' } ;
const uint32_t name2 [ ] = { 0xff41 } ;
const uint32_t name3 [ ] = { 0xff21 } ;
2004-03-26 05:39:48 +03:00
NTSTATUS status ;
printf ( " Testing wide-a \n " ) ;
status = unicode_open ( cli - > tree , mem_ctx , NTCREATEX_DISP_CREATE , name1 , 1 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Failed to create 'a' - %s \n " ,
nt_errstr ( status ) ) ;
return False ;
}
status = unicode_open ( cli - > tree , mem_ctx , NTCREATEX_DISP_CREATE , name2 , 1 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Failed to create wide-a - %s \n " ,
nt_errstr ( status ) ) ;
return False ;
}
status = unicode_open ( cli - > tree , mem_ctx , NTCREATEX_DISP_CREATE , name3 , 1 ) ;
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_OBJECT_NAME_COLLISION ) ) {
printf ( " Expected %s creating wide-A - %s \n " ,
nt_errstr ( NT_STATUS_OBJECT_NAME_COLLISION ) ,
nt_errstr ( status ) ) ;
return False ;
}
return True ;
}
2004-10-28 17:40:50 +04:00
BOOL torture_charset ( void )
2004-03-26 05:39:48 +03:00
{
2004-08-04 17:23:35 +04:00
static struct smbcli_state * cli ;
2004-03-26 05:39:48 +03:00
BOOL ret = True ;
TALLOC_CTX * mem_ctx ;
mem_ctx = talloc_init ( " torture_charset " ) ;
if ( ! torture_open_connection ( & cli ) ) {
return False ;
}
printf ( " Starting charset tests \n " ) ;
2004-11-12 12:37:59 +03:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2004-03-26 05:39:48 +03:00
return False ;
}
if ( ! test_composed ( cli , mem_ctx ) ) {
ret = False ;
}
if ( ! test_diacritical ( cli , mem_ctx ) ) {
ret = False ;
}
if ( ! test_surrogate ( cli , mem_ctx ) ) {
ret = False ;
}
if ( ! test_widea ( cli , mem_ctx ) ) {
ret = False ;
}
return ret ;
}