2003-08-13 05:53:07 +04:00
/*
Unix SMB / CIFS implementation .
RAW_FILEINFO_ * individual test suite
Copyright ( C ) Andrew Tridgell 2003
2007-05-15 04:10:18 +04:00
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2007
2003-08-13 05:53:07 +04:00
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
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2003-08-13 05:53:07 +04:00
( 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
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2003-08-13 05:53:07 +04:00
*/
# include "includes.h"
2004-11-01 04:03:22 +03:00
# include "libcli/raw/libcliraw.h"
2008-04-02 06:53:27 +04:00
# include "libcli/raw/raw_proto.h"
2006-01-03 18:40:05 +03:00
# include "libcli/libcli.h"
2006-03-17 20:59:58 +03:00
# include "torture/util.h"
2010-04-14 00:06:51 +04:00
# include "torture/rpc/torture_rpc.h"
2008-01-02 07:05:13 +03:00
# include "param/param.h"
2003-08-13 05:53:07 +04:00
static struct {
const char * name ;
2004-07-19 14:35:05 +04:00
enum smb_fileinfo_level level ;
2010-01-05 20:42:54 +03:00
unsigned int only_paths : 1 ;
unsigned int only_handles : 1 ;
2004-05-25 20:24:13 +04:00
uint32_t capability_mask ;
2010-01-05 20:42:54 +03:00
unsigned int expected_ipc_access_denied : 1 ;
2007-05-15 04:10:18 +04:00
NTSTATUS expected_ipc_fnum_status ;
2003-08-13 05:53:07 +04:00
NTSTATUS fnum_status , fname_status ;
union smb_fileinfo fnum_finfo , fname_finfo ;
} levels [ ] = {
2007-05-15 04:10:18 +04:00
{ . name = " GETATTR " ,
. level = RAW_FILEINFO_GETATTR ,
. only_paths = 1 ,
. only_handles = 0 ,
. expected_ipc_access_denied = 1 } ,
{ . name = " GETATTRE " ,
. level = RAW_FILEINFO_GETATTRE ,
. only_paths = 0 ,
. only_handles = 1 } ,
{ . name = " STANDARD " ,
. level = RAW_FILEINFO_STANDARD , } ,
{ . name = " EA_SIZE " ,
. level = RAW_FILEINFO_EA_SIZE } ,
{ . name = " ALL_EAS " ,
. level = RAW_FILEINFO_ALL_EAS ,
. expected_ipc_fnum_status = NT_STATUS_ACCESS_DENIED ,
} ,
{ . name = " IS_NAME_VALID " ,
. level = RAW_FILEINFO_IS_NAME_VALID ,
. only_paths = 1 ,
. only_handles = 0 } ,
{ . name = " BASIC_INFO " ,
. level = RAW_FILEINFO_BASIC_INFO } ,
{ . name = " STANDARD_INFO " ,
. level = RAW_FILEINFO_STANDARD_INFO } ,
{ . name = " EA_INFO " ,
. level = RAW_FILEINFO_EA_INFO } ,
{ . name = " NAME_INFO " ,
. level = RAW_FILEINFO_NAME_INFO } ,
{ . name = " ALL_INFO " ,
. level = RAW_FILEINFO_ALL_INFO } ,
{ . name = " ALT_NAME_INFO " ,
. level = RAW_FILEINFO_ALT_NAME_INFO ,
. expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
} ,
{ . name = " STREAM_INFO " ,
. level = RAW_FILEINFO_STREAM_INFO ,
. expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
} ,
{ . name = " COMPRESSION_INFO " ,
. level = RAW_FILEINFO_COMPRESSION_INFO ,
. expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
} ,
{ . name = " UNIX_BASIC_INFO " ,
. level = RAW_FILEINFO_UNIX_BASIC ,
. only_paths = 0 ,
. only_handles = 0 ,
. capability_mask = CAP_UNIX } ,
{ . name = " UNIX_LINK_INFO " ,
. level = RAW_FILEINFO_UNIX_LINK ,
. only_paths = 0 ,
. only_handles = 0 ,
. capability_mask = CAP_UNIX } ,
{ . name = " BASIC_INFORMATION " ,
. level = RAW_FILEINFO_BASIC_INFORMATION } ,
{ . name = " STANDARD_INFORMATION " ,
. level = RAW_FILEINFO_STANDARD_INFORMATION } ,
{ . name = " INTERNAL_INFORMATION " ,
. level = RAW_FILEINFO_INTERNAL_INFORMATION } ,
{ . name = " EA_INFORMATION " ,
. level = RAW_FILEINFO_EA_INFORMATION } ,
{ . name = " ACCESS_INFORMATION " ,
. level = RAW_FILEINFO_ACCESS_INFORMATION } ,
{ . name = " NAME_INFORMATION " ,
. level = RAW_FILEINFO_NAME_INFORMATION } ,
{ . name = " POSITION_INFORMATION " ,
. level = RAW_FILEINFO_POSITION_INFORMATION } ,
{ . name = " MODE_INFORMATION " ,
. level = RAW_FILEINFO_MODE_INFORMATION } ,
{ . name = " ALIGNMENT_INFORMATION " ,
. level = RAW_FILEINFO_ALIGNMENT_INFORMATION } ,
{ . name = " ALL_INFORMATION " ,
. level = RAW_FILEINFO_ALL_INFORMATION } ,
{ . name = " ALT_NAME_INFORMATION " ,
. level = RAW_FILEINFO_ALT_NAME_INFORMATION ,
. expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
} ,
{ . name = " STREAM_INFORMATION " ,
. level = RAW_FILEINFO_STREAM_INFORMATION ,
. expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
} ,
{ . name = " COMPRESSION_INFORMATION " ,
. level = RAW_FILEINFO_COMPRESSION_INFORMATION ,
. expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
} ,
{ . name = " NETWORK_OPEN_INFORMATION " ,
. level = RAW_FILEINFO_NETWORK_OPEN_INFORMATION ,
. expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
} ,
{ . name = " ATTRIBUTE_TAG_INFORMATION " ,
. level = RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION ,
. expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
} ,
{ NULL }
2003-08-13 05:53:07 +04:00
} ;
/*
compare a dos time ( 2 second resolution ) to a nt time
*/
2004-05-25 17:57:39 +04:00
static int dos_nt_time_cmp ( time_t t , NTTIME nt )
2003-08-13 05:53:07 +04:00
{
time_t t2 = nt_time_to_unix ( nt ) ;
2006-04-24 18:20:44 +04:00
if ( abs ( t2 - t ) < = 2 ) return 0 ;
2009-12-20 02:27:17 +03:00
return t2 > t ? 1 : - 1 ;
2003-08-13 05:53:07 +04:00
}
/*
find a level in the levels [ ] table
*/
static union smb_fileinfo * fnum_find ( const char * name )
{
int i ;
for ( i = 0 ; levels [ i ] . name ; i + + ) {
if ( NT_STATUS_IS_OK ( levels [ i ] . fnum_status ) & &
strcmp ( name , levels [ i ] . name ) = = 0 & &
! levels [ i ] . only_paths ) {
return & levels [ i ] . fnum_finfo ;
}
}
return NULL ;
}
/*
find a level in the levels [ ] table
*/
2007-05-15 04:10:18 +04:00
static union smb_fileinfo * fname_find ( bool is_ipc , const char * name )
2003-08-13 05:53:07 +04:00
{
int i ;
2007-05-14 09:53:26 +04:00
if ( is_ipc ) {
return NULL ;
}
2003-08-13 05:53:07 +04:00
for ( i = 0 ; levels [ i ] . name ; i + + ) {
if ( NT_STATUS_IS_OK ( levels [ i ] . fname_status ) & &
strcmp ( name , levels [ i ] . name ) = = 0 & &
! levels [ i ] . only_handles ) {
return & levels [ i ] . fname_finfo ;
}
}
return NULL ;
}
/* local macros to make the code below more readable */
# define VAL_EQUAL(n1, v1, n2, v2) do {if (s1->n1.out.v1 != s2->n2.out.v2) { \
printf ( " %s/%s [%u] != %s/%s [%u] at %s(%d) \n " , \
2010-01-05 20:42:54 +03:00
# n1, #v1, (unsigned int)s1->n1.out.v1, \
# n2, #v2, (unsigned int)s2->n2.out.v2, \
2003-08-13 05:53:07 +04:00
__FILE__ , __LINE__ ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} } while ( 0 )
2004-10-25 05:16:35 +04:00
# define STR_EQUAL(n1, v1, n2, v2) do {if (strcmp_safe(s1->n1.out.v1.s, s2->n2.out.v2.s) || \
2003-08-13 05:53:07 +04:00
s1 - > n1 . out . v1 . private_length ! = s2 - > n2 . out . v2 . private_length ) { \
printf ( " %s/%s [%s/%d] != %s/%s [%s/%d] at %s(%d) \n " , \
# n1, #v1, s1->n1.out.v1.s, s1->n1.out.v1.private_length, \
# n2, #v2, s2->n2.out.v2.s, s2->n2.out.v2.private_length, \
__FILE__ , __LINE__ ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} } while ( 0 )
# define STRUCT_EQUAL(n1, v1, n2, v2) do {if (memcmp(&s1->n1.out.v1,&s2->n2.out.v2,sizeof(s1->n1.out.v1))) { \
printf ( " %s/%s != %s/%s at %s(%d) \n " , \
# n1, #v1, \
# n2, #v2, \
__FILE__ , __LINE__ ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} } while ( 0 )
/* used to find hints on unknown values - and to make sure
we zero - fill */
2006-08-24 13:51:41 +04:00
#if 0 /* unused */
2003-08-13 05:53:07 +04:00
# define VAL_UNKNOWN(n1, v1) do {if (s1->n1.out.v1 != 0) { \
printf ( " %s/%s non-zero unknown - %u (0x%x) at %s(%d) \n " , \
# n1, #v1, \
2010-01-05 20:42:54 +03:00
( unsigned int ) s1 - > n1 . out . v1 , \
( unsigned int ) s1 - > n1 . out . v1 , \
2003-08-13 05:53:07 +04:00
__FILE__ , __LINE__ ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} } while ( 0 )
2006-08-24 13:51:41 +04:00
# endif
2003-08-13 05:53:07 +04:00
/* basic testing of all RAW_FILEINFO_* calls
for each call we test that it succeeds , and where possible test
for consistency between the calls .
*/
2007-09-02 06:35:11 +04:00
static bool torture_raw_qfileinfo_internals ( struct torture_context * torture ,
2007-08-28 16:54:27 +04:00
TALLOC_CTX * mem_ctx ,
struct smbcli_tree * tree ,
int fnum , const char * fname ,
bool is_ipc )
2003-08-13 05:53:07 +04:00
{
int i ;
2007-10-07 02:28:14 +04:00
bool ret = true ;
2003-08-13 05:53:07 +04:00
int count ;
union smb_fileinfo * s1 , * s2 ;
NTTIME correct_time ;
2004-05-25 17:57:39 +04:00
uint64_t correct_size ;
2004-05-25 20:24:13 +04:00
uint32_t correct_attrib ;
2003-08-13 05:53:07 +04:00
const char * correct_name ;
2007-10-07 02:28:14 +04:00
bool skip_streams = false ;
2003-08-13 05:53:07 +04:00
/* scan all the fileinfo and pathinfo levels */
for ( i = 0 ; levels [ i ] . name ; i + + ) {
if ( ! levels [ i ] . only_paths ) {
levels [ i ] . fnum_finfo . generic . level = levels [ i ] . level ;
2006-03-13 01:48:25 +03:00
levels [ i ] . fnum_finfo . generic . in . file . fnum = fnum ;
2007-05-14 09:53:26 +04:00
levels [ i ] . fnum_status = smb_raw_fileinfo ( tree , mem_ctx ,
2003-08-13 05:53:07 +04:00
& levels [ i ] . fnum_finfo ) ;
}
if ( ! levels [ i ] . only_handles ) {
levels [ i ] . fname_finfo . generic . level = levels [ i ] . level ;
2006-03-13 01:48:25 +03:00
levels [ i ] . fname_finfo . generic . in . file . path = talloc_strdup ( mem_ctx , fname ) ;
2007-05-14 09:53:26 +04:00
levels [ i ] . fname_status = smb_raw_pathinfo ( tree , mem_ctx ,
2003-08-13 05:53:07 +04:00
& levels [ i ] . fname_finfo ) ;
}
}
/* check for completely broken levels */
for ( count = i = 0 ; levels [ i ] . name ; i + + ) {
2007-05-14 09:53:26 +04:00
uint32_t cap = tree - > session - > transport - > negotiate . capabilities ;
2003-08-13 05:53:07 +04:00
/* see if this server claims to support this level */
if ( ( cap & levels [ i ] . capability_mask ) ! = levels [ i ] . capability_mask ) {
continue ;
}
2007-05-15 04:10:18 +04:00
if ( is_ipc ) {
if ( levels [ i ] . expected_ipc_access_denied & & NT_STATUS_EQUAL ( NT_STATUS_ACCESS_DENIED , levels [ i ] . fname_status ) ) {
2009-12-15 20:22:07 +03:00
} else if ( ! levels [ i ] . only_handles & &
NT_STATUS_EQUAL ( levels [ i ] . fname_status ,
NT_STATUS_NOT_SUPPORTED ) ) {
torture_warning ( torture , " fname level %s %s " ,
levels [ i ] . name ,
nt_errstr ( levels [ i ] . fname_status ) ) ;
continue ;
2007-05-15 04:10:18 +04:00
} else if ( ! levels [ i ] . only_handles & & ! NT_STATUS_EQUAL ( NT_STATUS_INVALID_DEVICE_REQUEST , levels [ i ] . fname_status ) ) {
printf ( " ERROR: fname level %s failed, expected NT_STATUS_INVALID_DEVICE_REQUEST - %s \n " ,
levels [ i ] . name , nt_errstr ( levels [ i ] . fname_status ) ) ;
count + + ;
}
2009-12-15 20:22:07 +03:00
if ( ! levels [ i ] . only_paths & &
2010-06-22 21:42:20 +04:00
( NT_STATUS_EQUAL ( levels [ i ] . fnum_status ,
NT_STATUS_NOT_SUPPORTED ) | |
2009-12-15 20:22:07 +03:00
NT_STATUS_EQUAL ( levels [ i ] . fnum_status ,
2010-06-22 21:42:20 +04:00
NT_STATUS_NOT_IMPLEMENTED ) ) ) {
2009-12-15 20:22:07 +03:00
torture_warning ( torture , " fnum level %s %s " ,
levels [ i ] . name ,
nt_errstr ( levels [ i ] . fnum_status ) ) ;
continue ;
}
2007-05-15 04:10:18 +04:00
if ( ! levels [ i ] . only_paths & & ! NT_STATUS_EQUAL ( levels [ i ] . expected_ipc_fnum_status , levels [ i ] . fnum_status ) ) {
printf ( " ERROR: fnum level %s failed, expected %s - %s \n " ,
levels [ i ] . name , nt_errstr ( levels [ i ] . expected_ipc_fnum_status ) ,
nt_errstr ( levels [ i ] . fnum_status ) ) ;
count + + ;
}
} else {
2009-12-15 20:22:07 +03:00
if ( ! levels [ i ] . only_paths & &
2010-06-22 21:42:20 +04:00
( NT_STATUS_EQUAL ( levels [ i ] . fnum_status ,
NT_STATUS_NOT_SUPPORTED ) | |
2009-12-15 20:22:07 +03:00
NT_STATUS_EQUAL ( levels [ i ] . fnum_status ,
2010-06-22 21:42:20 +04:00
NT_STATUS_NOT_IMPLEMENTED ) ) ) {
2009-12-15 20:22:07 +03:00
torture_warning ( torture , " fnum level %s %s " ,
levels [ i ] . name ,
nt_errstr ( levels [ i ] . fnum_status ) ) ;
continue ;
}
if ( ! levels [ i ] . only_handles & &
2010-06-22 21:42:20 +04:00
( NT_STATUS_EQUAL ( levels [ i ] . fname_status ,
NT_STATUS_NOT_SUPPORTED ) | |
2009-12-15 20:22:07 +03:00
NT_STATUS_EQUAL ( levels [ i ] . fname_status ,
2010-06-22 21:42:20 +04:00
NT_STATUS_NOT_IMPLEMENTED ) ) ) {
2009-12-15 20:22:07 +03:00
torture_warning ( torture , " fname level %s %s " ,
levels [ i ] . name ,
nt_errstr ( levels [ i ] . fname_status ) ) ;
continue ;
}
2007-05-15 04:10:18 +04:00
if ( ! levels [ i ] . only_paths & & ! NT_STATUS_IS_OK ( levels [ i ] . fnum_status ) ) {
printf ( " ERROR: fnum level %s failed - %s \n " ,
levels [ i ] . name , nt_errstr ( levels [ i ] . fnum_status ) ) ;
count + + ;
}
if ( ! levels [ i ] . only_handles & & ! NT_STATUS_IS_OK ( levels [ i ] . fname_status ) ) {
printf ( " ERROR: fname level %s failed - %s \n " ,
levels [ i ] . name , nt_errstr ( levels [ i ] . fname_status ) ) ;
count + + ;
}
2003-08-13 05:53:07 +04:00
}
2007-05-15 04:10:18 +04:00
2003-08-13 05:53:07 +04:00
}
if ( count ! = 0 ) {
2007-10-07 02:28:14 +04:00
ret = false ;
2003-08-13 05:53:07 +04:00
printf ( " %d levels failed \n " , count ) ;
2004-01-21 06:30:03 +03:00
if ( count > 35 ) {
2007-09-02 06:35:11 +04:00
torture_fail ( torture , " too many level failures - giving up " ) ;
2003-08-13 05:53:07 +04:00
}
}
/* see if we can do streams */
s1 = fnum_find ( " STREAM_INFO " ) ;
if ( ! s1 | | s1 - > stream_info . out . num_streams = = 0 ) {
2007-05-14 09:53:26 +04:00
if ( ! is_ipc ) {
printf ( " STREAM_INFO broken (%d) - skipping streams checks \n " ,
s1 ? s1 - > stream_info . out . num_streams : - 1 ) ;
}
2007-10-07 02:28:14 +04:00
skip_streams = true ;
2003-08-13 05:53:07 +04:00
}
/* this code is incredibly repititive but doesn't lend itself to loops, so
we use lots of macros to make it less painful */
/* first off we check the levels that are supposed to be aliases. It will be quite rare for
this code to fail , but we need to check it for completeness */
# define ALIAS_CHECK(sname1, sname2) \
do { \
s1 = fnum_find ( sname1 ) ; s2 = fnum_find ( sname2 ) ; \
if ( s1 & & s2 ) { INFO_CHECK } \
2007-05-15 04:10:18 +04:00
s1 = fname_find ( is_ipc , sname1 ) ; s2 = fname_find ( is_ipc , sname2 ) ; \
2003-08-13 05:53:07 +04:00
if ( s1 & & s2 ) { INFO_CHECK } \
2007-05-15 04:10:18 +04:00
s1 = fnum_find ( sname1 ) ; s2 = fname_find ( is_ipc , sname2 ) ; \
2003-08-13 05:53:07 +04:00
if ( s1 & & s2 ) { INFO_CHECK } \
} while ( 0 )
# define INFO_CHECK \
STRUCT_EQUAL ( basic_info , create_time , basic_info , create_time ) ; \
STRUCT_EQUAL ( basic_info , access_time , basic_info , access_time ) ; \
STRUCT_EQUAL ( basic_info , write_time , basic_info , write_time ) ; \
STRUCT_EQUAL ( basic_info , change_time , basic_info , change_time ) ; \
VAL_EQUAL ( basic_info , attrib , basic_info , attrib ) ;
ALIAS_CHECK ( " BASIC_INFO " , " BASIC_INFORMATION " ) ;
# undef INFO_CHECK
# define INFO_CHECK \
VAL_EQUAL ( standard_info , alloc_size , standard_info , alloc_size ) ; \
VAL_EQUAL ( standard_info , size , standard_info , size ) ; \
VAL_EQUAL ( standard_info , nlink , standard_info , nlink ) ; \
VAL_EQUAL ( standard_info , delete_pending , standard_info , delete_pending ) ; \
VAL_EQUAL ( standard_info , directory , standard_info , directory ) ;
ALIAS_CHECK ( " STANDARD_INFO " , " STANDARD_INFORMATION " ) ;
# undef INFO_CHECK
# define INFO_CHECK \
VAL_EQUAL ( ea_info , ea_size , ea_info , ea_size ) ;
ALIAS_CHECK ( " EA_INFO " , " EA_INFORMATION " ) ;
# undef INFO_CHECK
# define INFO_CHECK \
STR_EQUAL ( name_info , fname , name_info , fname ) ;
ALIAS_CHECK ( " NAME_INFO " , " NAME_INFORMATION " ) ;
# undef INFO_CHECK
# define INFO_CHECK \
STRUCT_EQUAL ( all_info , create_time , all_info , create_time ) ; \
STRUCT_EQUAL ( all_info , access_time , all_info , access_time ) ; \
STRUCT_EQUAL ( all_info , write_time , all_info , write_time ) ; \
STRUCT_EQUAL ( all_info , change_time , all_info , change_time ) ; \
VAL_EQUAL ( all_info , attrib , all_info , attrib ) ; \
VAL_EQUAL ( all_info , alloc_size , all_info , alloc_size ) ; \
VAL_EQUAL ( all_info , size , all_info , size ) ; \
VAL_EQUAL ( all_info , nlink , all_info , nlink ) ; \
VAL_EQUAL ( all_info , delete_pending , all_info , delete_pending ) ; \
VAL_EQUAL ( all_info , directory , all_info , directory ) ; \
VAL_EQUAL ( all_info , ea_size , all_info , ea_size ) ; \
STR_EQUAL ( all_info , fname , all_info , fname ) ;
ALIAS_CHECK ( " ALL_INFO " , " ALL_INFORMATION " ) ;
# undef INFO_CHECK
# define INFO_CHECK \
VAL_EQUAL ( compression_info , compressed_size , compression_info , compressed_size ) ; \
VAL_EQUAL ( compression_info , format , compression_info , format ) ; \
VAL_EQUAL ( compression_info , unit_shift , compression_info , unit_shift ) ; \
VAL_EQUAL ( compression_info , chunk_shift , compression_info , chunk_shift ) ; \
VAL_EQUAL ( compression_info , cluster_shift , compression_info , cluster_shift ) ;
ALIAS_CHECK ( " COMPRESSION_INFO " , " COMPRESSION_INFORMATION " ) ;
# undef INFO_CHECK
# define INFO_CHECK \
STR_EQUAL ( alt_name_info , fname , alt_name_info , fname ) ;
ALIAS_CHECK ( " ALT_NAME_INFO " , " ALT_NAME_INFORMATION " ) ;
# define TIME_CHECK_NT(sname, stype, tfield) do { \
s1 = fnum_find ( sname ) ; \
if ( s1 & & memcmp ( & s1 - > stype . out . tfield , & correct_time , sizeof ( correct_time ) ) ! = 0 ) { \
printf ( " (%d) handle %s/%s incorrect - %s should be %s \n " , __LINE__ , # stype , # tfield , \
2004-05-25 17:57:39 +04:00
nt_time_string ( mem_ctx , s1 - > stype . out . tfield ) , \
nt_time_string ( mem_ctx , correct_time ) ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} \
2007-05-15 04:10:18 +04:00
s1 = fname_find ( is_ipc , sname ) ; \
2003-08-13 05:53:07 +04:00
if ( s1 & & memcmp ( & s1 - > stype . out . tfield , & correct_time , sizeof ( correct_time ) ) ! = 0 ) { \
printf ( " (%d) path %s/%s incorrect - %s should be %s \n " , __LINE__ , # stype , # tfield , \
2004-05-25 17:57:39 +04:00
nt_time_string ( mem_ctx , s1 - > stype . out . tfield ) , \
nt_time_string ( mem_ctx , correct_time ) ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} } while ( 0 )
# define TIME_CHECK_DOS(sname, stype, tfield) do { \
s1 = fnum_find ( sname ) ; \
2004-05-25 17:57:39 +04:00
if ( s1 & & dos_nt_time_cmp ( s1 - > stype . out . tfield , correct_time ) ! = 0 ) { \
2003-08-13 05:53:07 +04:00
printf ( " (%d) handle %s/%s incorrect - %s should be %s \n " , __LINE__ , # stype , # tfield , \
2004-04-11 00:18:22 +04:00
timestring ( mem_ctx , s1 - > stype . out . tfield ) , \
2004-05-25 17:57:39 +04:00
nt_time_string ( mem_ctx , correct_time ) ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} \
2007-05-15 04:10:18 +04:00
s1 = fname_find ( is_ipc , sname ) ; \
2004-05-25 17:57:39 +04:00
if ( s1 & & dos_nt_time_cmp ( s1 - > stype . out . tfield , correct_time ) ! = 0 ) { \
2003-08-13 05:53:07 +04:00
printf ( " (%d) path %s/%s incorrect - %s should be %s \n " , __LINE__ , # stype , # tfield , \
2004-04-11 00:18:22 +04:00
timestring ( mem_ctx , s1 - > stype . out . tfield ) , \
2004-05-25 17:57:39 +04:00
nt_time_string ( mem_ctx , correct_time ) ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} } while ( 0 )
2006-08-24 13:51:41 +04:00
#if 0 /* unused */
2003-08-13 05:53:07 +04:00
# define TIME_CHECK_UNX(sname, stype, tfield) do { \
s1 = fnum_find ( sname ) ; \
2004-05-25 17:57:39 +04:00
if ( s1 & & unx_nt_time_cmp ( s1 - > stype . out . tfield , correct_time ) ! = 0 ) { \
2003-08-13 05:53:07 +04:00
printf ( " (%d) handle %s/%s incorrect - %s should be %s \n " , __LINE__ , # stype , # tfield , \
2004-04-11 00:18:22 +04:00
timestring ( mem_ctx , s1 - > stype . out . tfield ) , \
2004-05-25 17:57:39 +04:00
nt_time_string ( mem_ctx , correct_time ) ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} \
2007-05-15 04:10:18 +04:00
s1 = fname_find ( is_ipc , sname ) ; \
2004-05-25 17:57:39 +04:00
if ( s1 & & unx_nt_time_cmp ( s1 - > stype . out . tfield , correct_time ) ! = 0 ) { \
2003-08-13 05:53:07 +04:00
printf ( " (%d) path %s/%s incorrect - %s should be %s \n " , __LINE__ , # stype , # tfield , \
2004-04-11 00:18:22 +04:00
timestring ( mem_ctx , s1 - > stype . out . tfield ) , \
2004-05-25 17:57:39 +04:00
nt_time_string ( mem_ctx , correct_time ) ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} } while ( 0 )
2006-08-24 13:51:41 +04:00
# endif
2003-08-13 05:53:07 +04:00
/* now check that all the times that are supposed to be equal are correct */
s1 = fnum_find ( " BASIC_INFO " ) ;
correct_time = s1 - > basic_info . out . create_time ;
2007-09-02 06:35:11 +04:00
torture_comment ( torture , " create_time: %s \n " , nt_time_string ( mem_ctx , correct_time ) ) ;
2003-08-13 05:53:07 +04:00
TIME_CHECK_NT ( " BASIC_INFO " , basic_info , create_time ) ;
TIME_CHECK_NT ( " BASIC_INFORMATION " , basic_info , create_time ) ;
TIME_CHECK_DOS ( " GETATTRE " , getattre , create_time ) ;
TIME_CHECK_DOS ( " STANDARD " , standard , create_time ) ;
TIME_CHECK_DOS ( " EA_SIZE " , ea_size , create_time ) ;
TIME_CHECK_NT ( " ALL_INFO " , all_info , create_time ) ;
TIME_CHECK_NT ( " NETWORK_OPEN_INFORMATION " , network_open_information , create_time ) ;
s1 = fnum_find ( " BASIC_INFO " ) ;
correct_time = s1 - > basic_info . out . access_time ;
2007-09-02 06:35:11 +04:00
torture_comment ( torture , " access_time: %s \n " , nt_time_string ( mem_ctx , correct_time ) ) ;
2003-08-13 05:53:07 +04:00
TIME_CHECK_NT ( " BASIC_INFO " , basic_info , access_time ) ;
TIME_CHECK_NT ( " BASIC_INFORMATION " , basic_info , access_time ) ;
TIME_CHECK_DOS ( " GETATTRE " , getattre , access_time ) ;
TIME_CHECK_DOS ( " STANDARD " , standard , access_time ) ;
TIME_CHECK_DOS ( " EA_SIZE " , ea_size , access_time ) ;
TIME_CHECK_NT ( " ALL_INFO " , all_info , access_time ) ;
TIME_CHECK_NT ( " NETWORK_OPEN_INFORMATION " , network_open_information , access_time ) ;
s1 = fnum_find ( " BASIC_INFO " ) ;
correct_time = s1 - > basic_info . out . write_time ;
2007-09-02 06:35:11 +04:00
torture_comment ( torture , " write_time : %s \n " , nt_time_string ( mem_ctx , correct_time ) ) ;
2003-08-13 05:53:07 +04:00
TIME_CHECK_NT ( " BASIC_INFO " , basic_info , write_time ) ;
TIME_CHECK_NT ( " BASIC_INFORMATION " , basic_info , write_time ) ;
TIME_CHECK_DOS ( " GETATTR " , getattr , write_time ) ;
TIME_CHECK_DOS ( " GETATTRE " , getattre , write_time ) ;
TIME_CHECK_DOS ( " STANDARD " , standard , write_time ) ;
TIME_CHECK_DOS ( " EA_SIZE " , ea_size , write_time ) ;
TIME_CHECK_NT ( " ALL_INFO " , all_info , write_time ) ;
TIME_CHECK_NT ( " NETWORK_OPEN_INFORMATION " , network_open_information , write_time ) ;
s1 = fnum_find ( " BASIC_INFO " ) ;
correct_time = s1 - > basic_info . out . change_time ;
2007-09-02 06:35:11 +04:00
torture_comment ( torture , " change_time: %s \n " , nt_time_string ( mem_ctx , correct_time ) ) ;
2003-08-13 05:53:07 +04:00
TIME_CHECK_NT ( " BASIC_INFO " , basic_info , change_time ) ;
TIME_CHECK_NT ( " BASIC_INFORMATION " , basic_info , change_time ) ;
TIME_CHECK_NT ( " ALL_INFO " , all_info , change_time ) ;
TIME_CHECK_NT ( " NETWORK_OPEN_INFORMATION " , network_open_information , change_time ) ;
# define SIZE_CHECK(sname, stype, tfield) do { \
s1 = fnum_find ( sname ) ; \
if ( s1 & & s1 - > stype . out . tfield ! = correct_size ) { \
printf ( " (%d) handle %s/%s incorrect - %u should be %u \n " , __LINE__ , # stype , # tfield , \
2010-01-05 20:42:54 +03:00
( unsigned int ) s1 - > stype . out . tfield , \
( unsigned int ) correct_size ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} \
2007-05-15 04:10:18 +04:00
s1 = fname_find ( is_ipc , sname ) ; \
2003-08-13 05:53:07 +04:00
if ( s1 & & s1 - > stype . out . tfield ! = correct_size ) { \
printf ( " (%d) path %s/%s incorrect - %u should be %u \n " , __LINE__ , # stype , # tfield , \
2010-01-05 20:42:54 +03:00
( unsigned int ) s1 - > stype . out . tfield , \
( unsigned int ) correct_size ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} } while ( 0 )
s1 = fnum_find ( " STANDARD_INFO " ) ;
correct_size = s1 - > standard_info . out . size ;
2010-01-05 20:42:54 +03:00
torture_comment ( torture , " size: %u \n " , ( unsigned int ) correct_size ) ;
2003-08-13 05:53:07 +04:00
SIZE_CHECK ( " GETATTR " , getattr , size ) ;
SIZE_CHECK ( " GETATTRE " , getattre , size ) ;
SIZE_CHECK ( " STANDARD " , standard , size ) ;
SIZE_CHECK ( " EA_SIZE " , ea_size , size ) ;
SIZE_CHECK ( " STANDARD_INFO " , standard_info , size ) ;
SIZE_CHECK ( " STANDARD_INFORMATION " , standard_info , size ) ;
SIZE_CHECK ( " ALL_INFO " , all_info , size ) ;
SIZE_CHECK ( " ALL_INFORMATION " , all_info , size ) ;
SIZE_CHECK ( " COMPRESSION_INFO " , compression_info , compressed_size ) ;
SIZE_CHECK ( " COMPRESSION_INFORMATION " , compression_info , compressed_size ) ;
SIZE_CHECK ( " NETWORK_OPEN_INFORMATION " , network_open_information , size ) ;
if ( ! skip_streams ) {
SIZE_CHECK ( " STREAM_INFO " , stream_info , streams [ 0 ] . size ) ;
SIZE_CHECK ( " STREAM_INFORMATION " , stream_info , streams [ 0 ] . size ) ;
}
s1 = fnum_find ( " STANDARD_INFO " ) ;
correct_size = s1 - > standard_info . out . alloc_size ;
2010-01-05 20:42:54 +03:00
torture_comment ( torture , " alloc_size: %u \n " , ( unsigned int ) correct_size ) ;
2003-08-13 05:53:07 +04:00
SIZE_CHECK ( " GETATTRE " , getattre , alloc_size ) ;
SIZE_CHECK ( " STANDARD " , standard , alloc_size ) ;
SIZE_CHECK ( " EA_SIZE " , ea_size , alloc_size ) ;
SIZE_CHECK ( " STANDARD_INFO " , standard_info , alloc_size ) ;
SIZE_CHECK ( " STANDARD_INFORMATION " , standard_info , alloc_size ) ;
SIZE_CHECK ( " ALL_INFO " , all_info , alloc_size ) ;
SIZE_CHECK ( " ALL_INFORMATION " , all_info , alloc_size ) ;
SIZE_CHECK ( " NETWORK_OPEN_INFORMATION " , network_open_information , alloc_size ) ;
if ( ! skip_streams ) {
SIZE_CHECK ( " STREAM_INFO " , stream_info , streams [ 0 ] . alloc_size ) ;
SIZE_CHECK ( " STREAM_INFORMATION " , stream_info , streams [ 0 ] . alloc_size ) ;
}
# define ATTRIB_CHECK(sname, stype, tfield) do { \
s1 = fnum_find ( sname ) ; \
if ( s1 & & s1 - > stype . out . tfield ! = correct_attrib ) { \
printf ( " (%d) handle %s/%s incorrect - 0x%x should be 0x%x \n " , __LINE__ , # stype , # tfield , \
2010-01-05 20:42:54 +03:00
( unsigned int ) s1 - > stype . out . tfield , \
( unsigned int ) correct_attrib ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} \
2007-05-15 04:10:18 +04:00
s1 = fname_find ( is_ipc , sname ) ; \
2003-08-13 05:53:07 +04:00
if ( s1 & & s1 - > stype . out . tfield ! = correct_attrib ) { \
printf ( " (%d) path %s/%s incorrect - 0x%x should be 0x%x \n " , __LINE__ , # stype , # tfield , \
2010-01-05 20:42:54 +03:00
( unsigned int ) s1 - > stype . out . tfield , \
( unsigned int ) correct_attrib ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} } while ( 0 )
s1 = fnum_find ( " BASIC_INFO " ) ;
correct_attrib = s1 - > basic_info . out . attrib ;
2010-01-05 20:42:54 +03:00
torture_comment ( torture , " attrib: 0x%x \n " , ( unsigned int ) correct_attrib ) ;
2003-08-13 05:53:07 +04:00
ATTRIB_CHECK ( " GETATTR " , getattr , attrib ) ;
2007-05-15 04:10:18 +04:00
if ( ! is_ipc ) {
ATTRIB_CHECK ( " GETATTRE " , getattre , attrib ) ;
ATTRIB_CHECK ( " STANDARD " , standard , attrib ) ;
ATTRIB_CHECK ( " EA_SIZE " , ea_size , attrib ) ;
}
2003-08-13 05:53:07 +04:00
ATTRIB_CHECK ( " BASIC_INFO " , basic_info , attrib ) ;
ATTRIB_CHECK ( " BASIC_INFORMATION " , basic_info , attrib ) ;
ATTRIB_CHECK ( " ALL_INFO " , all_info , attrib ) ;
ATTRIB_CHECK ( " ALL_INFORMATION " , all_info , attrib ) ;
ATTRIB_CHECK ( " NETWORK_OPEN_INFORMATION " , network_open_information , attrib ) ;
ATTRIB_CHECK ( " ATTRIBUTE_TAG_INFORMATION " , attribute_tag_information , attrib ) ;
correct_name = fname ;
2007-09-02 06:35:11 +04:00
torture_comment ( torture , " name: %s \n " , correct_name ) ;
2003-08-13 05:53:07 +04:00
# define NAME_CHECK(sname, stype, tfield, flags) do { \
s1 = fnum_find ( sname ) ; \
2004-10-25 05:16:35 +04:00
if ( s1 & & ( strcmp_safe ( s1 - > stype . out . tfield . s , correct_name ) ! = 0 | | \
2007-05-14 09:53:26 +04:00
wire_bad_flags ( & s1 - > stype . out . tfield , flags , tree - > session - > transport ) ) ) { \
2003-08-13 05:53:07 +04:00
printf ( " (%d) handle %s/%s incorrect - '%s/%d' \n " , __LINE__ , # stype , # tfield , \
s1 - > stype . out . tfield . s , s1 - > stype . out . tfield . private_length ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} \
2007-05-15 04:10:18 +04:00
s1 = fname_find ( is_ipc , sname ) ; \
2004-10-25 05:16:35 +04:00
if ( s1 & & ( strcmp_safe ( s1 - > stype . out . tfield . s , correct_name ) ! = 0 | | \
2007-05-14 09:53:26 +04:00
wire_bad_flags ( & s1 - > stype . out . tfield , flags , tree - > session - > transport ) ) ) { \
2003-08-13 05:53:07 +04:00
printf ( " (%d) path %s/%s incorrect - '%s/%d' \n " , __LINE__ , # stype , # tfield , \
s1 - > stype . out . tfield . s , s1 - > stype . out . tfield . private_length ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} } while ( 0 )
NAME_CHECK ( " NAME_INFO " , name_info , fname , STR_UNICODE ) ;
NAME_CHECK ( " NAME_INFORMATION " , name_info , fname , STR_UNICODE ) ;
/* the ALL_INFO file name is the full path on the filesystem */
s1 = fnum_find ( " ALL_INFO " ) ;
if ( s1 & & ! s1 - > all_info . out . fname . s ) {
2007-09-02 06:35:11 +04:00
torture_fail ( torture , " ALL_INFO didn't give a filename " ) ;
2003-08-13 05:53:07 +04:00
}
if ( s1 & & s1 - > all_info . out . fname . s ) {
char * p = strrchr ( s1 - > all_info . out . fname . s , ' \\ ' ) ;
if ( ! p ) {
printf ( " Not a full path in all_info/fname? - '%s' \n " ,
s1 - > all_info . out . fname . s ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2003-08-13 05:53:07 +04:00
} else {
2004-10-25 05:16:35 +04:00
if ( strcmp_safe ( correct_name , p ) ! = 0 ) {
2003-08-13 05:53:07 +04:00
printf ( " incorrect basename in all_info/fname - '%s' \n " ,
s1 - > all_info . out . fname . s ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2003-08-13 05:53:07 +04:00
}
}
2007-05-14 09:53:26 +04:00
if ( wire_bad_flags ( & s1 - > all_info . out . fname , STR_UNICODE , tree - > session - > transport ) ) {
2003-08-13 05:53:07 +04:00
printf ( " Should not null terminate all_info/fname \n " ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2003-08-13 05:53:07 +04:00
}
}
s1 = fnum_find ( " ALT_NAME_INFO " ) ;
2007-05-14 09:53:26 +04:00
if ( s1 ) {
correct_name = s1 - > alt_name_info . out . fname . s ;
2010-08-07 02:21:31 +04:00
}
if ( ! correct_name ) {
torture_comment ( torture , " no alternate name information \n " ) ;
} else {
2007-09-02 06:35:11 +04:00
torture_comment ( torture , " alt_name: %s \n " , correct_name ) ;
2007-05-14 09:53:26 +04:00
NAME_CHECK ( " ALT_NAME_INFO " , alt_name_info , fname , STR_UNICODE ) ;
NAME_CHECK ( " ALT_NAME_INFORMATION " , alt_name_info , fname , STR_UNICODE ) ;
/* and make sure we can open by alternate name */
smbcli_close ( tree , fnum ) ;
fnum = smbcli_nt_create_full ( tree , correct_name , 0 ,
SEC_RIGHTS_FILE_ALL ,
FILE_ATTRIBUTE_NORMAL ,
NTCREATEX_SHARE_ACCESS_DELETE |
NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE ,
NTCREATEX_DISP_OVERWRITE_IF ,
0 , 0 ) ;
if ( fnum = = - 1 ) {
printf ( " Unable to open by alt_name - %s \n " , smbcli_errstr ( tree ) ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2007-05-14 09:53:26 +04:00
}
if ( ! skip_streams ) {
correct_name = " ::$DATA " ;
2007-09-02 06:35:11 +04:00
torture_comment ( torture , " stream_name: %s \n " , correct_name ) ;
2007-05-14 09:53:26 +04:00
NAME_CHECK ( " STREAM_INFO " , stream_info , streams [ 0 ] . stream_name , STR_UNICODE ) ;
NAME_CHECK ( " STREAM_INFORMATION " , stream_info , streams [ 0 ] . stream_name , STR_UNICODE ) ;
}
2003-08-13 05:53:07 +04:00
}
2007-05-14 09:53:26 +04:00
2003-08-13 05:53:07 +04:00
/* make sure the EAs look right */
s1 = fnum_find ( " ALL_EAS " ) ;
s2 = fnum_find ( " ALL_INFO " ) ;
if ( s1 ) {
for ( i = 0 ; i < s1 - > all_eas . out . num_eas ; i + + ) {
printf ( " flags=%d %s=%*.*s \n " ,
s1 - > all_eas . out . eas [ i ] . flags ,
s1 - > all_eas . out . eas [ i ] . name . s ,
2005-07-17 13:20:52 +04:00
( int ) s1 - > all_eas . out . eas [ i ] . value . length ,
( int ) s1 - > all_eas . out . eas [ i ] . value . length ,
2003-08-13 05:53:07 +04:00
s1 - > all_eas . out . eas [ i ] . value . data ) ;
}
}
if ( s1 & & s2 ) {
if ( s1 - > all_eas . out . num_eas = = 0 ) {
if ( s2 - > all_info . out . ea_size ! = 0 ) {
printf ( " ERROR: num_eas==0 but fnum all_info.out.ea_size == %d \n " ,
s2 - > all_info . out . ea_size ) ;
}
} else {
if ( s2 - > all_info . out . ea_size ! =
ea_list_size ( s1 - > all_eas . out . num_eas , s1 - > all_eas . out . eas ) ) {
printf ( " ERROR: ea_list_size=%d != fnum all_info.out.ea_size=%d \n " ,
2006-09-09 14:05:58 +04:00
( int ) ea_list_size ( s1 - > all_eas . out . num_eas , s1 - > all_eas . out . eas ) ,
( int ) s2 - > all_info . out . ea_size ) ;
2003-08-13 05:53:07 +04:00
}
}
}
2007-05-15 04:10:18 +04:00
s2 = fname_find ( is_ipc , " ALL_EAS " ) ;
2003-08-13 05:53:07 +04:00
if ( s2 ) {
VAL_EQUAL ( all_eas , num_eas , all_eas , num_eas ) ;
for ( i = 0 ; i < s1 - > all_eas . out . num_eas ; i + + ) {
VAL_EQUAL ( all_eas , eas [ i ] . flags , all_eas , eas [ i ] . flags ) ;
STR_EQUAL ( all_eas , eas [ i ] . name , all_eas , eas [ i ] . name ) ;
VAL_EQUAL ( all_eas , eas [ i ] . value . length , all_eas , eas [ i ] . value . length ) ;
}
}
# define VAL_CHECK(sname1, stype1, tfield1, sname2, stype2, tfield2) do { \
s1 = fnum_find ( sname1 ) ; s2 = fnum_find ( sname2 ) ; \
if ( s1 & & s2 & & s1 - > stype1 . out . tfield1 ! = s2 - > stype2 . out . tfield2 ) { \
printf ( " (%d) handle %s/%s != %s/%s - 0x%x vs 0x%x \n " , __LINE__ , \
# stype1, #tfield1, #stype2, #tfield2, \
s1 - > stype1 . out . tfield1 , s2 - > stype2 . out . tfield2 ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} \
2007-05-15 04:10:18 +04:00
s1 = fname_find ( is_ipc , sname1 ) ; s2 = fname_find ( is_ipc , sname2 ) ; \
2003-08-13 05:53:07 +04:00
if ( s1 & & s2 & & s1 - > stype1 . out . tfield1 ! = s2 - > stype2 . out . tfield2 ) { \
printf ( " (%d) path %s/%s != %s/%s - 0x%x vs 0x%x \n " , __LINE__ , \
# stype1, #tfield1, #stype2, #tfield2, \
s1 - > stype1 . out . tfield1 , s2 - > stype2 . out . tfield2 ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} \
2007-05-15 04:10:18 +04:00
s1 = fnum_find ( sname1 ) ; s2 = fname_find ( is_ipc , sname2 ) ; \
2003-08-13 05:53:07 +04:00
if ( s1 & & s2 & & s1 - > stype1 . out . tfield1 ! = s2 - > stype2 . out . tfield2 ) { \
printf ( " (%d) handle %s/%s != path %s/%s - 0x%x vs 0x%x \n " , __LINE__ , \
# stype1, #tfield1, #stype2, #tfield2, \
s1 - > stype1 . out . tfield1 , s2 - > stype2 . out . tfield2 ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} \
2007-05-15 04:10:18 +04:00
s1 = fname_find ( is_ipc , sname1 ) ; s2 = fnum_find ( sname2 ) ; \
2003-08-13 05:53:07 +04:00
if ( s1 & & s2 & & s1 - > stype1 . out . tfield1 ! = s2 - > stype2 . out . tfield2 ) { \
printf ( " (%d) path %s/%s != handle %s/%s - 0x%x vs 0x%x \n " , __LINE__ , \
# stype1, #tfield1, #stype2, #tfield2, \
s1 - > stype1 . out . tfield1 , s2 - > stype2 . out . tfield2 ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
} } while ( 0 )
VAL_CHECK ( " STANDARD_INFO " , standard_info , delete_pending ,
" ALL_INFO " , all_info , delete_pending ) ;
VAL_CHECK ( " STANDARD_INFO " , standard_info , directory ,
" ALL_INFO " , all_info , directory ) ;
VAL_CHECK ( " STANDARD_INFO " , standard_info , nlink ,
" ALL_INFO " , all_info , nlink ) ;
2007-05-15 05:21:20 +04:00
s1 = fnum_find ( " BASIC_INFO " ) ;
if ( s1 & & is_ipc ) {
if ( s1 - > basic_info . out . attrib ! = FILE_ATTRIBUTE_NORMAL ) {
printf ( " (%d) attrib basic_info/nlink incorrect - %d should be %d \n " , __LINE__ , s1 - > basic_info . out . attrib , FILE_ATTRIBUTE_NORMAL ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2007-05-15 05:21:20 +04:00
}
}
s1 = fnum_find ( " STANDARD_INFO " ) ;
if ( s1 & & is_ipc ) {
if ( s1 - > standard_info . out . nlink ! = 1 ) {
printf ( " (%d) nlinks standard_info/nlink incorrect - %d should be 1 \n " , __LINE__ , s1 - > standard_info . out . nlink ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2007-05-15 05:21:20 +04:00
}
if ( s1 - > standard_info . out . delete_pending ! = 1 ) {
printf ( " (%d) nlinks standard_info/delete_pending incorrect - %d should be 1 \n " , __LINE__ , s1 - > standard_info . out . delete_pending ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2007-05-15 05:21:20 +04:00
}
}
2003-08-13 05:53:07 +04:00
VAL_CHECK ( " EA_INFO " , ea_info , ea_size ,
" ALL_INFO " , all_info , ea_size ) ;
2007-05-15 04:10:18 +04:00
if ( ! is_ipc ) {
VAL_CHECK ( " EA_SIZE " , ea_size , ea_size ,
" ALL_INFO " , all_info , ea_size ) ;
}
2003-08-13 05:53:07 +04:00
# define NAME_PATH_CHECK(sname, stype, field) do { \
2007-05-15 04:10:18 +04:00
s1 = fname_find ( is_ipc , sname ) ; s2 = fnum_find ( sname ) ; \
2003-08-23 22:53:46 +04:00
if ( s1 & & s2 ) { \
VAL_EQUAL ( stype , field , stype , field ) ; \
} \
2003-08-13 05:53:07 +04:00
} while ( 0 )
2003-09-02 08:37:33 +04:00
s1 = fnum_find ( " INTERNAL_INFORMATION " ) ;
if ( s1 ) {
2007-09-02 06:35:11 +04:00
torture_comment ( torture , " file_id=%.0f \n " , ( double ) s1 - > internal_information . out . file_id ) ;
2003-09-02 08:37:33 +04:00
}
NAME_PATH_CHECK ( " INTERNAL_INFORMATION " , internal_information , file_id ) ;
2003-08-13 05:53:07 +04:00
NAME_PATH_CHECK ( " POSITION_INFORMATION " , position_information , position ) ;
2004-01-21 06:30:03 +03:00
if ( s1 & & s2 ) {
printf ( " fnum pos = %.0f, fname pos = %.0f \n " ,
( double ) s2 - > position_information . out . position ,
( double ) s1 - > position_information . out . position ) ;
}
2003-08-13 05:53:07 +04:00
NAME_PATH_CHECK ( " MODE_INFORMATION " , mode_information , mode ) ;
NAME_PATH_CHECK ( " ALIGNMENT_INFORMATION " , alignment_information , alignment_requirement ) ;
NAME_PATH_CHECK ( " ATTRIBUTE_TAG_INFORMATION " , attribute_tag_information , attrib ) ;
NAME_PATH_CHECK ( " ATTRIBUTE_TAG_INFORMATION " , attribute_tag_information , reparse_tag ) ;
#if 0
/* these are expected to differ */
NAME_PATH_CHECK ( " ACCESS_INFORMATION " , access_information , access_flags ) ;
# endif
2006-08-24 13:51:41 +04:00
#if 0 /* unused */
2003-08-13 05:53:07 +04:00
# define UNKNOWN_CHECK(sname, stype, tfield) do { \
s1 = fnum_find ( sname ) ; \
if ( s1 & & s1 - > stype . out . tfield ! = 0 ) { \
printf ( " (%d) handle %s/%s unknown != 0 (0x%x) \n " , __LINE__ , \
# stype, #tfield, \
2010-01-05 20:42:54 +03:00
( unsigned int ) s1 - > stype . out . tfield ) ; \
2003-08-13 05:53:07 +04:00
} \
2007-05-15 04:10:18 +04:00
s1 = fname_find ( is_ipc , sname ) ; \
2003-08-13 05:53:07 +04:00
if ( s1 & & s1 - > stype . out . tfield ! = 0 ) { \
printf ( " (%d) path %s/%s unknown != 0 (0x%x) \n " , __LINE__ , \
# stype, #tfield, \
2010-01-05 20:42:54 +03:00
( unsigned int ) s1 - > stype . out . tfield ) ; \
2003-08-13 05:53:07 +04:00
} } while ( 0 )
2006-08-24 13:51:41 +04:00
# endif
2003-08-13 05:53:07 +04:00
/* now get a bit fancier .... */
/* when we set the delete disposition then the link count should drop
to 0 and delete_pending should be 1 */
2007-05-14 09:53:26 +04:00
return ret ;
}
/* basic testing of all RAW_FILEINFO_* calls
for each call we test that it succeeds , and where possible test
for consistency between the calls .
*/
2007-08-28 16:54:27 +04:00
bool torture_raw_qfileinfo ( struct torture_context * torture ,
struct smbcli_state * cli )
2007-05-14 09:53:26 +04:00
{
int fnum ;
2007-08-28 16:54:27 +04:00
bool ret ;
2007-05-14 09:53:26 +04:00
const char * fname = " \\ torture_qfileinfo.txt " ;
2007-08-28 16:54:27 +04:00
fnum = create_complex_file ( cli , torture , fname ) ;
2007-05-14 09:53:26 +04:00
if ( fnum = = - 1 ) {
printf ( " ERROR: open of %s failed (%s) \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2007-08-28 16:54:27 +04:00
return false ;
2007-05-14 09:53:26 +04:00
}
2007-10-07 02:28:14 +04:00
ret = torture_raw_qfileinfo_internals ( torture , torture , cli - > tree , fnum , fname , false /* is_ipc */ ) ;
2007-05-14 09:53:26 +04:00
2004-08-04 17:23:35 +04:00
smbcli_close ( cli - > tree , fnum ) ;
smbcli_unlink ( cli - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
return ret ;
}
2007-05-14 09:53:26 +04:00
2007-08-28 16:54:27 +04:00
bool torture_raw_qfileinfo_pipe ( struct torture_context * torture ,
2007-09-02 06:35:11 +04:00
struct smbcli_state * cli )
2007-05-14 09:53:26 +04:00
{
2007-08-28 16:54:27 +04:00
bool ret = true ;
2007-05-14 09:53:26 +04:00
int fnum ;
const char * fname = " \\ lsass " ;
struct dcerpc_pipe * p ;
struct smbcli_tree * ipc_tree ;
NTSTATUS status ;
2010-05-09 19:20:01 +04:00
if ( ! ( p = dcerpc_pipe_init ( torture , cli - > tree - > session - > transport - > socket - > event . ctx ) ) ) {
2007-10-07 02:28:14 +04:00
return false ;
2007-05-14 09:53:26 +04:00
}
status = dcerpc_pipe_open_smb ( p , cli - > tree , fname ) ;
2007-09-02 06:35:11 +04:00
torture_assert_ntstatus_ok ( torture , status , " dcerpc_pipe_open_smb failed " ) ;
2007-05-14 09:53:26 +04:00
ipc_tree = dcerpc_smb_tree ( p - > conn ) ;
fnum = dcerpc_smb_fnum ( p - > conn ) ;
2007-09-02 06:35:11 +04:00
ret = torture_raw_qfileinfo_internals ( torture , torture , ipc_tree , fnum , fname , true /* is_ipc */ ) ;
2007-05-14 09:53:26 +04:00
talloc_free ( p ) ;
return ret ;
}