2004-10-08 05:15:25 +04:00
/*
Unix SMB / CIFS implementation .
count number of calls on an interface
Copyright ( C ) Andrew Tridgell 2003
2007-03-05 06:02:43 +03:00
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2007
2004-10-08 05:15:25 +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
2004-10-08 05:15:25 +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/>.
2004-10-08 05:15:25 +04:00
*/
# include "includes.h"
2007-08-21 23:35:43 +04:00
# include "librpc/ndr/libndr.h"
# include "librpc/ndr/ndr_table.h"
2010-04-14 00:06:51 +04:00
# include "torture/rpc/torture_rpc.h"
2007-09-08 16:42:09 +04:00
# include "param/param.h"
2004-10-08 05:15:25 +04:00
2007-03-05 06:02:43 +03:00
2007-12-03 04:58:12 +03:00
bool count_calls ( struct torture_context * tctx ,
TALLOC_CTX * mem_ctx ,
2007-08-20 00:46:45 +04:00
const struct ndr_interface_table * iface ,
2007-10-07 02:28:14 +04:00
bool all )
2004-10-08 05:15:25 +04:00
{
struct dcerpc_pipe * p ;
DATA_BLOB stub_in , stub_out ;
2007-03-05 06:02:43 +03:00
int i ;
2007-12-03 04:58:12 +03:00
NTSTATUS status = torture_rpc_connection ( tctx , & p , iface ) ;
2007-03-05 06:02:43 +03:00
if ( NT_STATUS_EQUAL ( NT_STATUS_OBJECT_NAME_NOT_FOUND , status )
2010-04-15 19:22:41 +04:00
| | NT_STATUS_IS_RPC ( status )
2007-03-05 06:02:43 +03:00
| | NT_STATUS_EQUAL ( NT_STATUS_PORT_UNREACHABLE , status )
| | NT_STATUS_EQUAL ( NT_STATUS_ACCESS_DENIED , status ) ) {
if ( all ) {
/* Not fatal if looking for all pipes */
2007-10-07 02:28:14 +04:00
return true ;
2007-03-05 06:02:43 +03:00
} else {
printf ( " Failed to open '%s' to count calls - %s \n " , iface - > name , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-03-05 06:02:43 +03:00
}
} else if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Failed to open '%s' to count calls - %s \n " , iface - > name , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2004-10-08 05:15:25 +04:00
}
2011-03-13 18:15:35 +03:00
stub_in = data_blob_null ;
2004-10-08 05:15:25 +04:00
printf ( " \n Scanning pipe '%s' \n " , iface - > name ) ;
2007-03-05 06:02:43 +03:00
for ( i = 0 ; i < 500 ; i + + ) {
2011-03-13 18:15:35 +03:00
uint32_t out_flags = 0 ;
status = dcerpc_binding_handle_raw_call ( p - > binding_handle ,
NULL , i ,
0 , /* in_flags */
stub_in . data ,
stub_in . length ,
mem_ctx ,
& stub_out . data ,
& stub_out . length ,
& out_flags ) ;
2010-04-12 16:12:10 +04:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE ) ) {
2007-03-05 06:02:43 +03:00
i - - ;
break ;
}
2004-11-24 14:24:33 +03:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS_CONNECTION_DISCONNECTED ) ) {
2007-03-05 06:02:43 +03:00
i - - ;
break ;
}
if ( NT_STATUS_EQUAL ( status , NT_STATUS_PIPE_DISCONNECTED ) ) {
i - - ;
break ;
}
if ( NT_STATUS_EQUAL ( status , NT_STATUS_ACCESS_DENIED ) ) {
i - - ;
break ;
}
if ( NT_STATUS_EQUAL ( status , NT_STATUS_LOGON_FAILURE ) ) {
i - - ;
2004-11-24 14:24:33 +03:00
break ;
}
2004-10-08 05:15:25 +04:00
}
2007-03-05 06:02:43 +03:00
if ( i = = 500 ) {
2005-03-22 11:00:45 +03:00
talloc_free ( p ) ;
2007-03-05 06:02:43 +03:00
printf ( " no limit on calls: %s!? \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2004-10-08 05:15:25 +04:00
}
printf ( " Found %d calls \n " , i ) ;
2005-03-22 11:00:45 +03:00
talloc_free ( p ) ;
2007-03-05 06:02:43 +03:00
2007-10-07 02:28:14 +04:00
return true ;
2007-03-05 06:02:43 +03:00
}
2007-10-07 02:28:14 +04:00
bool torture_rpc_countcalls ( struct torture_context * torture )
2007-03-05 06:02:43 +03:00
{
2007-08-20 00:46:45 +04:00
const struct ndr_interface_table * iface ;
2007-03-05 06:02:43 +03:00
const char * iface_name ;
2007-10-07 02:28:14 +04:00
bool ret = true ;
2007-08-20 00:46:45 +04:00
const struct ndr_interface_list * l ;
2010-07-16 08:32:42 +04:00
iface_name = lpcfg_parm_string ( torture - > lp_ctx , NULL , " countcalls " , " interface " ) ;
2007-03-05 06:02:43 +03:00
if ( iface_name ! = NULL ) {
2007-08-21 23:35:43 +04:00
iface = ndr_table_by_name ( iface_name ) ;
2007-03-05 06:02:43 +03:00
if ( ! iface ) {
printf ( " Unknown interface '%s' \n " , iface_name ) ;
2007-10-07 02:28:14 +04:00
return false ;
2007-03-05 06:02:43 +03:00
}
2007-12-03 04:58:12 +03:00
return count_calls ( torture , torture , iface , false ) ;
2007-03-05 06:02:43 +03:00
}
2007-08-21 23:35:43 +04:00
for ( l = ndr_table_list ( ) ; l ; l = l - > next ) {
2007-03-05 06:02:43 +03:00
TALLOC_CTX * loop_ctx ;
2007-12-03 04:58:12 +03:00
loop_ctx = talloc_named ( torture , 0 , " torture_rpc_councalls loop context " ) ;
ret & = count_calls ( torture , loop_ctx , l - > table , true ) ;
2007-03-05 06:02:43 +03:00
talloc_free ( loop_ctx ) ;
}
return ret ;
2004-10-08 05:15:25 +04:00
}