2003-08-13 05:53:07 +04:00
/*
Unix SMB / CIFS implementation .
SMB trans2 alias scanner
Copyright ( C ) Andrew Tridgell 2003
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"
2008-10-11 23:31:42 +04:00
# include "../lib/util/dlinklist.h"
2005-12-28 18:38:36 +03:00
# include "libcli/raw/libcliraw.h"
2008-04-02 06:53:27 +04:00
# include "libcli/raw/raw_proto.h"
2006-03-17 20:59:58 +03:00
# include "libcli/libcli.h"
# include "torture/util.h"
2011-03-19 02:42:52 +03:00
# include "torture/basic/proto.h"
2003-08-13 05:53:07 +04:00
2004-08-04 17:23:35 +04:00
int create_complex_file ( struct smbcli_state * cli , TALLOC_CTX * mem_ctx , const char * fname ) ;
2003-08-13 05:53:07 +04:00
struct trans2_blobs {
struct trans2_blobs * next , * prev ;
2004-05-25 21:24:24 +04:00
uint16_t level ;
2003-08-13 05:53:07 +04:00
DATA_BLOB params , data ;
} ;
/* look for aliases for a query */
2006-10-16 17:06:41 +04:00
static bool gen_aliases ( struct torture_context * tctx ,
struct smbcli_state * cli , struct smb_trans2 * t2 ,
int level_offset )
2003-08-13 05:53:07 +04:00
{
2004-05-25 21:24:24 +04:00
uint16_t level ;
2003-08-13 05:53:07 +04:00
struct trans2_blobs * alias_blobs = NULL ;
struct trans2_blobs * t2b , * t2b2 ;
int count = 0 , alias_count = 0 ;
for ( level = 0 ; level < 2000 ; level + + ) {
NTSTATUS status ;
SSVAL ( t2 - > in . params . data , level_offset , level ) ;
2006-10-16 17:06:41 +04:00
status = smb_raw_trans2 ( cli - > tree , tctx , t2 ) ;
2003-08-13 05:53:07 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) continue ;
2006-10-16 17:06:41 +04:00
t2b = talloc ( tctx , struct trans2_blobs ) ;
2003-08-13 05:53:07 +04:00
t2b - > level = level ;
t2b - > params = t2 - > out . params ;
t2b - > data = t2 - > out . data ;
DLIST_ADD ( alias_blobs , t2b ) ;
2006-10-16 17:06:41 +04:00
torture_comment ( tctx ,
" \t Found level %4u (0x%03x) of size %3d (0x%02x) \n " ,
2003-08-13 05:53:07 +04:00
level , level ,
2005-07-17 14:38:59 +04:00
( int ) t2b - > data . length , ( int ) t2b - > data . length ) ;
2003-08-13 05:53:07 +04:00
count + + ;
}
2006-10-16 17:06:41 +04:00
torture_comment ( tctx , " Found %d levels with success status \n " , count ) ;
2003-08-13 05:53:07 +04:00
for ( t2b = alias_blobs ; t2b ; t2b = t2b - > next ) {
for ( t2b2 = alias_blobs ; t2b2 ; t2b2 = t2b2 - > next ) {
if ( t2b - > level > = t2b2 - > level ) continue ;
2007-06-20 08:15:39 +04:00
if ( data_blob_cmp ( & t2b - > params , & t2b2 - > params ) = = 0 & &
data_blob_cmp ( & t2b - > data , & t2b2 - > data ) = = 0 ) {
2006-10-16 17:06:41 +04:00
torture_comment ( tctx ,
" \t Level %u (0x%x) and level %u (0x%x) are possible aliases \n " ,
2003-08-13 05:53:07 +04:00
t2b - > level , t2b - > level , t2b2 - > level , t2b2 - > level ) ;
alias_count + + ;
}
}
}
2006-10-16 17:06:41 +04:00
torture_comment ( tctx , " Found %d aliased levels \n " , alias_count ) ;
return true ;
2003-08-13 05:53:07 +04:00
}
/* look for qfsinfo aliases */
2007-02-26 15:02:10 +03:00
static bool qfsinfo_aliases ( struct torture_context * tctx , struct smbcli_state * cli )
2003-08-13 05:53:07 +04:00
{
struct smb_trans2 t2 ;
2004-05-25 21:24:24 +04:00
uint16_t setup = TRANSACT2_QFSINFO ;
2003-08-13 05:53:07 +04:00
t2 . in . max_param = 0 ;
2008-07-07 20:07:47 +04:00
t2 . in . max_data = UINT16_MAX ;
2003-08-13 05:53:07 +04:00
t2 . in . max_setup = 0 ;
t2 . in . flags = 0 ;
t2 . in . timeout = 0 ;
t2 . in . setup_count = 1 ;
t2 . in . setup = & setup ;
2007-02-26 15:02:10 +03:00
t2 . in . params = data_blob_talloc_zero ( tctx , 2 ) ;
2003-08-13 05:53:07 +04:00
t2 . in . data = data_blob ( NULL , 0 ) ;
2007-02-26 15:02:10 +03:00
ZERO_STRUCT ( t2 . out ) ;
2003-08-13 05:53:07 +04:00
2006-10-16 17:06:41 +04:00
return gen_aliases ( tctx , cli , & t2 , 0 ) ;
2003-08-13 05:53:07 +04:00
}
/* look for qfileinfo aliases */
2007-02-26 15:02:10 +03:00
static bool qfileinfo_aliases ( struct torture_context * tctx , struct smbcli_state * cli )
2003-08-13 05:53:07 +04:00
{
struct smb_trans2 t2 ;
2004-05-25 21:24:24 +04:00
uint16_t setup = TRANSACT2_QFILEINFO ;
2003-08-13 05:53:07 +04:00
const char * fname = " \\ qfileinfo_aliases.txt " ;
int fnum ;
t2 . in . max_param = 2 ;
2008-07-07 20:07:47 +04:00
t2 . in . max_data = UINT16_MAX ;
2003-08-13 05:53:07 +04:00
t2 . in . max_setup = 0 ;
t2 . in . flags = 0 ;
t2 . in . timeout = 0 ;
t2 . in . setup_count = 1 ;
t2 . in . setup = & setup ;
2007-02-26 15:02:10 +03:00
t2 . in . params = data_blob_talloc_zero ( tctx , 4 ) ;
2003-08-13 05:53:07 +04:00
t2 . in . data = data_blob ( NULL , 0 ) ;
2007-02-26 15:02:10 +03:00
ZERO_STRUCT ( t2 . out ) ;
2003-08-13 05:53:07 +04:00
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli - > tree , fname ) ;
2004-08-21 11:43:29 +04:00
fnum = create_complex_file ( cli , cli , fname ) ;
2006-10-16 17:06:41 +04:00
torture_assert ( tctx , fnum ! = - 1 , talloc_asprintf ( tctx ,
" open of %s failed (%s) " , fname ,
smbcli_errstr ( cli - > tree ) ) ) ;
2003-08-13 05:53:07 +04:00
2004-12-04 16:56:25 +03:00
smbcli_write ( cli - > tree , fnum , 0 , & t2 , 0 , sizeof ( t2 ) ) ;
2003-08-13 05:53:07 +04:00
SSVAL ( t2 . in . params . data , 0 , fnum ) ;
2006-10-16 17:06:41 +04:00
if ( ! gen_aliases ( tctx , cli , & t2 , 2 ) )
return false ;
2003-08-13 05:53:07 +04:00
2004-08-04 17:23:35 +04:00
smbcli_close ( cli - > tree , fnum ) ;
smbcli_unlink ( cli - > tree , fname ) ;
2006-10-16 17:06:41 +04:00
return true ;
2003-08-13 05:53:07 +04:00
}
/* look for qpathinfo aliases */
2007-02-26 15:02:10 +03:00
static bool qpathinfo_aliases ( struct torture_context * tctx , struct smbcli_state * cli )
2003-08-13 05:53:07 +04:00
{
struct smb_trans2 t2 ;
2004-05-25 21:24:24 +04:00
uint16_t setup = TRANSACT2_QPATHINFO ;
2003-08-13 05:53:07 +04:00
const char * fname = " \\ qpathinfo_aliases.txt " ;
int fnum ;
2016-04-18 13:50:08 +03:00
ZERO_STRUCT ( t2 ) ;
2003-08-13 05:53:07 +04:00
t2 . in . max_param = 2 ;
2008-07-07 20:07:47 +04:00
t2 . in . max_data = UINT16_MAX ;
2003-08-13 05:53:07 +04:00
t2 . in . max_setup = 0 ;
t2 . in . flags = 0 ;
t2 . in . timeout = 0 ;
t2 . in . setup_count = 1 ;
t2 . in . setup = & setup ;
2007-02-26 15:02:10 +03:00
t2 . in . params = data_blob_talloc_zero ( tctx , 6 ) ;
2003-08-13 05:53:07 +04:00
t2 . in . data = data_blob ( NULL , 0 ) ;
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli - > tree , fname ) ;
2004-08-21 11:43:29 +04:00
fnum = create_complex_file ( cli , cli , fname ) ;
2006-10-16 17:06:41 +04:00
torture_assert ( tctx , fnum ! = - 1 , talloc_asprintf ( tctx ,
" open of %s failed (%s) " , fname ,
smbcli_errstr ( cli - > tree ) ) ) ;
2003-08-13 05:53:07 +04:00
2004-12-04 16:56:25 +03:00
smbcli_write ( cli - > tree , fnum , 0 , & t2 , 0 , sizeof ( t2 ) ) ;
2004-08-04 17:23:35 +04:00
smbcli_close ( cli - > tree , fnum ) ;
2003-08-13 05:53:07 +04:00
SIVAL ( t2 . in . params . data , 2 , 0 ) ;
2006-10-16 17:06:41 +04:00
smbcli_blob_append_string ( cli - > session , tctx , & t2 . in . params ,
2003-08-13 05:53:07 +04:00
fname , STR_TERMINATE ) ;
2006-10-16 17:06:41 +04:00
if ( ! gen_aliases ( tctx , cli , & t2 , 0 ) )
return false ;
2003-08-13 05:53:07 +04:00
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli - > tree , fname ) ;
2006-10-16 17:06:41 +04:00
return true ;
2003-08-13 05:53:07 +04:00
}
/* look for trans2 findfirst aliases */
2007-02-26 15:02:10 +03:00
static bool findfirst_aliases ( struct torture_context * tctx , struct smbcli_state * cli )
2003-08-13 05:53:07 +04:00
{
struct smb_trans2 t2 ;
2004-05-25 21:24:24 +04:00
uint16_t setup = TRANSACT2_FINDFIRST ;
2003-08-13 05:53:07 +04:00
const char * fname = " \\ findfirst_aliases.txt " ;
int fnum ;
2016-04-18 13:57:58 +03:00
ZERO_STRUCT ( t2 ) ;
2003-08-13 05:53:07 +04:00
t2 . in . max_param = 16 ;
2008-07-07 20:07:47 +04:00
t2 . in . max_data = UINT16_MAX ;
2003-08-13 05:53:07 +04:00
t2 . in . max_setup = 0 ;
t2 . in . flags = 0 ;
t2 . in . timeout = 0 ;
t2 . in . setup_count = 1 ;
t2 . in . setup = & setup ;
2007-02-26 15:02:10 +03:00
t2 . in . params = data_blob_talloc_zero ( tctx , 12 ) ;
2003-08-13 05:53:07 +04:00
t2 . in . data = data_blob ( NULL , 0 ) ;
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli - > tree , fname ) ;
2004-08-21 11:43:29 +04:00
fnum = create_complex_file ( cli , cli , fname ) ;
2006-10-16 17:06:41 +04:00
torture_assert ( tctx , fnum ! = - 1 , talloc_asprintf ( tctx ,
" open of %s failed (%s) " , fname ,
smbcli_errstr ( cli - > tree ) ) ) ;
2003-08-13 05:53:07 +04:00
2004-12-04 16:56:25 +03:00
smbcli_write ( cli - > tree , fnum , 0 , & t2 , 0 , sizeof ( t2 ) ) ;
2004-08-04 17:23:35 +04:00
smbcli_close ( cli - > tree , fnum ) ;
2003-08-13 05:53:07 +04:00
SSVAL ( t2 . in . params . data , 0 , 0 ) ;
SSVAL ( t2 . in . params . data , 2 , 1 ) ;
SSVAL ( t2 . in . params . data , 4 , FLAG_TRANS2_FIND_CLOSE ) ;
SSVAL ( t2 . in . params . data , 6 , 0 ) ;
SIVAL ( t2 . in . params . data , 8 , 0 ) ;
2006-10-16 17:06:41 +04:00
smbcli_blob_append_string ( cli - > session , tctx , & t2 . in . params ,
2003-08-13 05:53:07 +04:00
fname , STR_TERMINATE ) ;
2006-10-16 17:06:41 +04:00
if ( ! gen_aliases ( tctx , cli , & t2 , 6 ) )
return false ;
2003-08-13 05:53:07 +04:00
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli - > tree , fname ) ;
2006-10-16 17:06:41 +04:00
return true ;
2003-08-13 05:53:07 +04:00
}
/* look for aliases for a set function */
2006-10-16 17:06:41 +04:00
static bool gen_set_aliases ( struct torture_context * tctx ,
struct smbcli_state * cli ,
struct smb_trans2 * t2 , int level_offset )
2003-08-13 05:53:07 +04:00
{
2004-05-25 21:24:24 +04:00
uint16_t level ;
2003-08-13 05:53:07 +04:00
struct trans2_blobs * alias_blobs = NULL ;
struct trans2_blobs * t2b ;
int count = 0 , dsize ;
for ( level = 1 ; level < 1100 ; level + + ) {
NTSTATUS status , status1 ;
SSVAL ( t2 - > in . params . data , level_offset , level ) ;
status1 = NT_STATUS_OK ;
for ( dsize = 2 ; dsize < 1024 ; dsize + = 2 ) {
data_blob_free ( & t2 - > in . data ) ;
t2 - > in . data = data_blob ( NULL , dsize ) ;
data_blob_clear ( & t2 - > in . data ) ;
2006-10-16 17:06:41 +04:00
status = smb_raw_trans2 ( cli - > tree , tctx , t2 ) ;
2003-08-13 05:53:07 +04:00
/* some error codes mean that this whole level doesn't exist */
if ( NT_STATUS_EQUAL ( NT_STATUS_INVALID_LEVEL , status ) | |
NT_STATUS_EQUAL ( NT_STATUS_INVALID_INFO_CLASS , status ) | |
NT_STATUS_EQUAL ( NT_STATUS_NOT_SUPPORTED , status ) ) {
break ;
}
if ( NT_STATUS_IS_OK ( status ) ) break ;
/* invalid parameter means that the level exists at this
size , but the contents are wrong ( not surprising with
all zeros ! ) */
if ( NT_STATUS_EQUAL ( status , NT_STATUS_INVALID_PARAMETER ) ) break ;
/* this is the usual code for 'wrong size' */
if ( NT_STATUS_EQUAL ( status , NT_STATUS_INFO_LENGTH_MISMATCH ) ) {
continue ;
}
if ( ! NT_STATUS_EQUAL ( status , status1 ) ) {
2006-10-16 17:06:41 +04:00
torture_comment ( tctx , " level=%d size=%d %s \n " , level , dsize , nt_errstr ( status ) ) ;
2003-08-13 05:53:07 +04:00
}
status1 = status ;
}
if ( ! NT_STATUS_IS_OK ( status ) & &
! NT_STATUS_EQUAL ( status , NT_STATUS_INVALID_PARAMETER ) ) continue ;
2006-10-16 17:06:41 +04:00
t2b = talloc ( tctx , struct trans2_blobs ) ;
2003-08-13 05:53:07 +04:00
t2b - > level = level ;
t2b - > params = t2 - > out . params ;
t2b - > data = t2 - > out . data ;
DLIST_ADD ( alias_blobs , t2b ) ;
2006-10-16 17:06:41 +04:00
torture_comment ( tctx ,
" \t Found level %4u (0x%03x) of size %3d (0x%02x) \n " ,
2003-08-13 05:53:07 +04:00
level , level ,
2005-07-17 14:38:59 +04:00
( int ) t2 - > in . data . length , ( int ) t2 - > in . data . length ) ;
2003-08-13 05:53:07 +04:00
count + + ;
}
2006-10-16 17:06:41 +04:00
torture_comment ( tctx , " Found %d valid levels \n " , count ) ;
return true ;
2003-08-13 05:53:07 +04:00
}
/* look for setfileinfo aliases */
2007-02-26 15:02:10 +03:00
static bool setfileinfo_aliases ( struct torture_context * tctx , struct smbcli_state * cli )
2003-08-13 05:53:07 +04:00
{
struct smb_trans2 t2 ;
2004-05-25 21:24:24 +04:00
uint16_t setup = TRANSACT2_SETFILEINFO ;
2003-08-13 05:53:07 +04:00
const char * fname = " \\ setfileinfo_aliases.txt " ;
int fnum ;
2016-04-18 14:20:35 +03:00
ZERO_STRUCT ( t2 ) ;
2003-08-13 05:53:07 +04:00
t2 . in . max_param = 2 ;
t2 . in . max_data = 0 ;
t2 . in . max_setup = 0 ;
t2 . in . flags = 0 ;
t2 . in . timeout = 0 ;
t2 . in . setup_count = 1 ;
t2 . in . setup = & setup ;
2007-02-26 15:02:10 +03:00
t2 . in . params = data_blob_talloc_zero ( tctx , 6 ) ;
2003-08-13 05:53:07 +04:00
t2 . in . data = data_blob ( NULL , 0 ) ;
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli - > tree , fname ) ;
2004-08-21 11:43:29 +04:00
fnum = create_complex_file ( cli , cli , fname ) ;
2006-10-16 17:06:41 +04:00
torture_assert ( tctx , fnum ! = - 1 , talloc_asprintf ( tctx ,
" open of %s failed (%s) " , fname ,
smbcli_errstr ( cli - > tree ) ) ) ;
2003-08-13 05:53:07 +04:00
2004-12-04 16:56:25 +03:00
smbcli_write ( cli - > tree , fnum , 0 , & t2 , 0 , sizeof ( t2 ) ) ;
2003-08-13 05:53:07 +04:00
SSVAL ( t2 . in . params . data , 0 , fnum ) ;
SSVAL ( t2 . in . params . data , 4 , 0 ) ;
2006-10-16 17:06:41 +04:00
gen_set_aliases ( tctx , cli , & t2 , 2 ) ;
2003-08-13 05:53:07 +04:00
2004-08-04 17:23:35 +04:00
smbcli_close ( cli - > tree , fnum ) ;
smbcli_unlink ( cli - > tree , fname ) ;
2006-10-16 17:06:41 +04:00
return true ;
2003-08-13 05:53:07 +04:00
}
/* look for setpathinfo aliases */
2006-10-16 17:06:41 +04:00
static bool setpathinfo_aliases ( struct torture_context * tctx ,
struct smbcli_state * cli )
2003-08-13 05:53:07 +04:00
{
struct smb_trans2 t2 ;
2004-05-25 21:24:24 +04:00
uint16_t setup = TRANSACT2_SETPATHINFO ;
2003-08-13 05:53:07 +04:00
const char * fname = " \\ setpathinfo_aliases.txt " ;
int fnum ;
2016-04-18 14:37:03 +03:00
ZERO_STRUCT ( t2 ) ;
2003-08-13 05:53:07 +04:00
t2 . in . max_param = 32 ;
2008-07-07 20:07:47 +04:00
t2 . in . max_data = UINT16_MAX ;
2003-08-13 05:53:07 +04:00
t2 . in . max_setup = 0 ;
t2 . in . flags = 0 ;
t2 . in . timeout = 0 ;
t2 . in . setup_count = 1 ;
t2 . in . setup = & setup ;
2007-02-26 15:02:10 +03:00
t2 . in . params = data_blob_talloc_zero ( tctx , 4 ) ;
2003-08-13 05:53:07 +04:00
t2 . in . data = data_blob ( NULL , 0 ) ;
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
2004-08-21 11:43:29 +04:00
fnum = create_complex_file ( cli , cli , fname ) ;
2006-10-16 17:06:41 +04:00
torture_assert ( tctx , fnum ! = - 1 , talloc_asprintf ( tctx ,
" open of %s failed (%s) " , fname ,
smbcli_errstr ( cli - > tree ) ) ) ;
2003-08-13 05:53:07 +04:00
2004-12-04 16:56:25 +03:00
smbcli_write ( cli - > tree , fnum , 0 , & t2 , 0 , sizeof ( t2 ) ) ;
2004-08-04 17:23:35 +04:00
smbcli_close ( cli - > tree , fnum ) ;
2003-08-13 05:53:07 +04:00
SSVAL ( t2 . in . params . data , 2 , 0 ) ;
2006-10-16 17:06:41 +04:00
smbcli_blob_append_string ( cli - > session , tctx , & t2 . in . params ,
2003-08-13 05:53:07 +04:00
fname , STR_TERMINATE ) ;
2006-10-16 17:06:41 +04:00
if ( ! gen_set_aliases ( tctx , cli , & t2 , 0 ) )
return false ;
2003-08-13 05:53:07 +04:00
2006-10-16 17:06:41 +04:00
torture_assert_ntstatus_ok ( tctx , smbcli_unlink ( cli - > tree , fname ) ,
talloc_asprintf ( tctx , " unlink: %s " , smbcli_errstr ( cli - > tree ) ) ) ;
return true ;
2003-08-13 05:53:07 +04:00
}
/* look for aliased info levels in trans2 calls */
2007-09-07 19:08:14 +04:00
struct torture_suite * torture_trans2_aliases ( TALLOC_CTX * mem_ctx )
2003-08-13 05:53:07 +04:00
{
2010-12-11 05:26:31 +03:00
struct torture_suite * suite = torture_suite_create ( mem_ctx , " aliases " ) ;
2006-10-16 17:06:41 +04:00
2015-12-01 15:11:35 +03:00
torture_suite_add_1smb_test ( suite , " QFSINFO aliases " , qfsinfo_aliases ) ;
torture_suite_add_1smb_test ( suite , " QFILEINFO aliases " , qfileinfo_aliases ) ;
2006-10-16 17:06:41 +04:00
torture_suite_add_1smb_test ( suite , " QPATHINFO aliases " , qpathinfo_aliases ) ;
torture_suite_add_1smb_test ( suite , " FINDFIRST aliases " , findfirst_aliases ) ;
2007-02-26 15:02:10 +03:00
torture_suite_add_1smb_test ( suite , " setfileinfo_aliases " , setfileinfo_aliases ) ;
torture_suite_add_1smb_test ( suite , " setpathinfo_aliases " , setpathinfo_aliases ) ;
2006-10-16 17:06:41 +04:00
return suite ;
2003-08-13 05:53:07 +04:00
}