2003-12-11 01:21:04 +03:00
/*
Unix SMB / CIFS implementation .
endpoint server for the echo pipe
Copyright ( C ) Andrew Tridgell 2003
2005-01-11 19:53:02 +03:00
Copyright ( C ) Stefan ( metze ) Metzmacher 2005
2003-12-11 01:21:04 +03: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-12-11 01:21:04 +03: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-12-11 01:21:04 +03:00
*/
# include "includes.h"
2005-02-10 08:09:35 +03:00
# include "system/filesys.h"
2004-11-02 10:42:47 +03:00
# include "rpc_server/dcerpc_server.h"
2004-11-01 13:30:34 +03:00
# include "librpc/gen_ndr/ndr_echo.h"
2005-02-03 14:56:03 +03:00
# include "lib/events/events.h"
2003-12-11 01:21:04 +03:00
2016-03-26 21:19:04 +03:00
# define DCESRV_INTERFACE_RPCECHO_BIND(call, iface) \
dcesrv_interface_rpcecho_bind ( call , iface )
static NTSTATUS dcesrv_interface_rpcecho_bind ( struct dcesrv_call_state * dce_call ,
const struct dcesrv_interface * iface )
{
return dcesrv_interface_bind_allow_connect ( dce_call , iface ) ;
}
2003-12-11 01:21:04 +03:00
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_echo_AddOne ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx , struct echo_AddOne * r )
2003-12-12 06:59:09 +03:00
{
2005-06-01 04:00:50 +04:00
* r - > out . out_data = r - > in . in_data + 1 ;
2003-12-12 06:59:09 +03:00
return NT_STATUS_OK ;
}
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_echo_EchoData ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx , struct echo_EchoData * r )
2003-12-12 06:59:09 +03:00
{
2003-12-15 04:06:01 +03:00
if ( ! r - > in . len ) {
return NT_STATUS_OK ;
}
2010-10-02 04:13:36 +04:00
r - > out . out_data = ( uint8_t * ) talloc_memdup ( mem_ctx , r - > in . in_data , r - > in . len ) ;
2003-12-12 08:01:41 +03:00
if ( ! r - > out . out_data ) {
return NT_STATUS_NO_MEMORY ;
}
2003-12-12 06:59:09 +03:00
return NT_STATUS_OK ;
}
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_echo_SinkData ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx , struct echo_SinkData * r )
2003-12-12 06:59:09 +03:00
{
return NT_STATUS_OK ;
}
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_echo_SourceData ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx , struct echo_SourceData * r )
2003-12-12 06:59:09 +03:00
{
2009-11-21 20:58:26 +03:00
unsigned int i ;
2005-06-02 17:21:11 +04:00
r - > out . data = talloc_array ( mem_ctx , uint8_t , r - > in . len ) ;
2007-03-05 13:28:24 +03:00
if ( ! r - > out . data ) {
return NT_STATUS_NO_MEMORY ;
}
2005-06-02 17:21:11 +04:00
2003-12-12 06:59:09 +03:00
for ( i = 0 ; i < r - > in . len ; i + + ) {
r - > out . data [ i ] = i ;
}
return NT_STATUS_OK ;
}
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_echo_TestCall ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx , struct echo_TestCall * r )
2003-12-12 06:59:09 +03:00
{
2006-10-16 17:06:41 +04:00
* r - > out . s2 = talloc_strdup ( mem_ctx , r - > in . s1 ) ;
2007-03-07 14:15:44 +03:00
if ( r - > in . s1 & & ! * r - > out . s2 ) {
return NT_STATUS_NO_MEMORY ;
}
2003-12-12 08:40:26 +03:00
return NT_STATUS_OK ;
2003-12-12 06:59:09 +03:00
}
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_echo_TestCall2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx , struct echo_TestCall2 * r )
2003-12-12 06:59:09 +03:00
{
2005-01-27 10:08:20 +03:00
r - > out . info = talloc ( mem_ctx , union echo_Info ) ;
2003-12-12 08:40:26 +03:00
if ( ! r - > out . info ) {
2004-05-04 10:07:52 +04:00
return NT_STATUS_NO_MEMORY ;
2003-12-12 08:40:26 +03:00
}
switch ( r - > in . level ) {
case 1 :
r - > out . info - > info1 . v = 10 ;
break ;
case 2 :
r - > out . info - > info2 . v = 20 ;
break ;
case 3 :
r - > out . info - > info3 . v = 30 ;
break ;
case 4 :
2004-05-25 17:57:39 +04:00
r - > out . info - > info4 . v = 40 ;
2003-12-12 08:40:26 +03:00
break ;
case 5 :
r - > out . info - > info5 . v1 = 50 ;
2004-05-25 17:57:39 +04:00
r - > out . info - > info5 . v2 = 60 ;
2003-12-12 08:40:26 +03:00
break ;
case 6 :
r - > out . info - > info6 . v1 = 70 ;
r - > out . info - > info6 . info1 . v = 80 ;
break ;
case 7 :
r - > out . info - > info7 . v1 = 80 ;
2004-05-25 17:57:39 +04:00
r - > out . info - > info7 . info4 . v = 90 ;
2003-12-12 08:40:26 +03:00
break ;
default :
2004-05-04 10:07:52 +04:00
return NT_STATUS_INVALID_LEVEL ;
2003-12-12 08:40:26 +03:00
}
return NT_STATUS_OK ;
2003-12-12 06:59:09 +03:00
}
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_echo_TestEnum ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx , struct echo_TestEnum * r )
2005-01-05 02:27:12 +03:00
{
r - > out . foo2 - > e1 = ECHO_ENUM2 ;
return NT_STATUS_OK ;
}
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_echo_TestSurrounding ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx , struct echo_TestSurrounding * r )
2005-02-19 02:30:26 +03:00
{
if ( ! r - > in . data ) {
r - > out . data = NULL ;
return NT_STATUS_OK ;
}
r - > out . data = talloc ( mem_ctx , struct echo_Surrounding ) ;
2007-03-05 13:28:24 +03:00
if ( ! r - > out . data ) {
return NT_STATUS_NO_MEMORY ;
}
2005-02-19 02:30:26 +03:00
r - > out . data - > x = 2 * r - > in . data - > x ;
r - > out . data - > surrounding = talloc_zero_array ( mem_ctx , uint16_t , r - > out . data - > x ) ;
2007-03-07 14:15:44 +03:00
if ( ! r - > out . data - > surrounding ) {
return NT_STATUS_NO_MEMORY ;
}
2005-02-19 02:30:26 +03:00
return NT_STATUS_OK ;
}
2007-01-17 17:49:36 +03:00
static uint16_t dcesrv_echo_TestDoublePointer ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx , struct echo_TestDoublePointer * r )
2005-02-20 05:57:38 +03:00
{
if ( ! * r - > in . data )
return 0 ;
if ( ! * * r - > in . data )
return 0 ;
return * * * r - > in . data ;
}
2005-06-16 15:52:15 +04:00
struct echo_TestSleep_private {
struct dcesrv_call_state * dce_call ;
struct echo_TestSleep * r ;
} ;
2008-12-29 22:24:57 +03:00
static void echo_TestSleep_handler ( struct tevent_context * ev , struct tevent_timer * te ,
2009-02-02 10:38:07 +03:00
struct timeval t , void * private_data )
2005-06-16 15:52:15 +04:00
{
2009-02-02 10:38:07 +03:00
struct echo_TestSleep_private * p = talloc_get_type ( private_data ,
2005-06-16 15:52:15 +04:00
struct echo_TestSleep_private ) ;
struct echo_TestSleep * r = p - > r ;
NTSTATUS status ;
r - > out . result = r - > in . seconds ;
status = dcesrv_reply ( p - > dce_call ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " echo_TestSleep_handler: dcesrv_reply() failed - %s \n " ,
nt_errstr ( status ) ) ) ;
}
}
2007-01-17 17:49:36 +03:00
static long dcesrv_echo_TestSleep ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx , struct echo_TestSleep * r )
2004-08-30 11:36:16 +04:00
{
2005-01-11 19:53:02 +03:00
struct echo_TestSleep_private * p ;
if ( ! ( dce_call - > state_flags & DCESRV_CALL_STATE_FLAG_MAY_ASYNC ) ) {
/* we're not allowed to reply async */
sleep ( r - > in . seconds ) ;
return r - > in . seconds ;
}
/* we're allowed to reply async */
p = talloc ( mem_ctx , struct echo_TestSleep_private ) ;
if ( ! p ) {
return 0 ;
}
p - > dce_call = dce_call ;
p - > r = r ;
2010-05-25 23:29:14 +04:00
tevent_add_timer ( dce_call - > event_ctx , p ,
2005-02-03 05:35:52 +03:00
timeval_add ( & dce_call - > time , r - > in . seconds , 0 ) ,
echo_TestSleep_handler , p ) ;
2005-01-11 19:53:02 +03:00
dce_call - > state_flags | = DCESRV_CALL_STATE_FLAG_ASYNC ;
return 0 ;
2004-08-30 11:36:16 +04:00
}
2003-12-12 06:59:09 +03:00
2003-12-14 16:22:12 +03:00
/* include the generated boilerplate */
# include "librpc/gen_ndr/ndr_echo_s.c"