2005-04-15 18:45:00 +04:00
/*
a composite API for quering file system information
*/
# include "includes.h"
# include "libcli/raw/libcliraw.h"
# include "libcli/composite/composite.h"
2005-09-26 15:47:55 +04:00
# include "libcli/smb_composite/smb_composite.h"
2005-04-15 18:45:00 +04:00
# include "librpc/gen_ndr/ndr_security.h"
/* the stages of this call */
enum fsinfo_stage { FSINFO_CONNECT , FSINFO_QUERY } ;
static void fsinfo_raw_handler ( struct smbcli_request * req ) ;
static void fsinfo_composite_handler ( struct composite_context * c ) ;
static void fsinfo_state_handler ( struct composite_context * c ) ;
struct fsinfo_state {
enum fsinfo_stage stage ;
struct composite_context * creq ;
struct smb_composite_fsinfo * io ;
struct smb_composite_connect * connect ;
union smb_fsinfo * fsinfo ;
struct smbcli_tree * tree ;
struct smbcli_request * req ;
} ;
static NTSTATUS fsinfo_connect ( struct composite_context * c ,
struct smb_composite_fsinfo * io )
{
NTSTATUS status ;
struct fsinfo_state * state ;
2005-09-26 15:47:55 +04:00
state = talloc_get_type ( c - > private_data , struct fsinfo_state ) ;
2005-04-15 18:45:00 +04:00
status = smb_composite_connect_recv ( state - > creq , c ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
state - > fsinfo = talloc ( state , union smb_fsinfo ) ;
NT_STATUS_HAVE_NO_MEMORY ( state - > fsinfo ) ;
state - > fsinfo - > generic . level = io - > in . level ;
state - > req = smb_raw_fsinfo_send ( state - > connect - > out . tree ,
state ,
state - > fsinfo ) ;
NT_STATUS_HAVE_NO_MEMORY ( state - > req ) ;
state - > req - > async . private = c ;
state - > req - > async . fn = fsinfo_raw_handler ;
state - > stage = FSINFO_QUERY ;
c - > event_ctx = talloc_reference ( c , state - > req - > session - > transport - > socket - > event . ctx ) ;
return NT_STATUS_OK ;
}
static NTSTATUS fsinfo_query ( struct composite_context * c ,
struct smb_composite_fsinfo * io )
{
NTSTATUS status ;
struct fsinfo_state * state ;
2005-09-26 15:47:55 +04:00
state = talloc_get_type ( c - > private_data , struct fsinfo_state ) ;
2005-04-15 18:45:00 +04:00
status = smb_raw_fsinfo_recv ( state - > req , state , state - > fsinfo ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
state - > io - > out . fsinfo = state - > fsinfo ;
2005-09-26 15:47:55 +04:00
c - > state = COMPOSITE_STATE_DONE ;
2005-04-15 18:45:00 +04:00
if ( c - > async . fn )
c - > async . fn ( c ) ;
return NT_STATUS_OK ;
}
/*
handler for completion of a sub - request in fsinfo
*/
2005-09-26 15:47:55 +04:00
static void fsinfo_state_handler ( struct composite_context * creq )
2005-04-15 18:45:00 +04:00
{
2005-09-26 15:47:55 +04:00
struct fsinfo_state * state = talloc_get_type ( creq - > private_data , struct fsinfo_state ) ;
2005-04-15 18:45:00 +04:00
/* when this handler is called, the stage indicates what
call has just finished */
switch ( state - > stage ) {
case FSINFO_CONNECT :
2005-09-26 15:47:55 +04:00
creq - > status = fsinfo_connect ( creq , state - > io ) ;
2005-04-15 18:45:00 +04:00
break ;
case FSINFO_QUERY :
2005-09-26 15:47:55 +04:00
creq - > status = fsinfo_query ( creq , state - > io ) ;
2005-04-15 18:45:00 +04:00
break ;
}
2005-09-26 15:47:55 +04:00
if ( ! NT_STATUS_IS_OK ( creq - > status ) ) {
creq - > state = COMPOSITE_STATE_ERROR ;
2005-04-15 18:45:00 +04:00
}
2005-09-26 15:47:55 +04:00
if ( creq - > state > = COMPOSITE_STATE_DONE & & creq - > async . fn ) {
creq - > async . fn ( creq ) ;
2005-04-15 18:45:00 +04:00
}
}
/*
As raw and composite handlers take different requests , we need to handlers
to adapt both for the same state machine in fsinfo_state_handler ( )
*/
static void fsinfo_raw_handler ( struct smbcli_request * req )
{
struct composite_context * c = talloc_get_type ( req - > async . private ,
struct composite_context ) ;
2005-06-09 14:33:20 +04:00
fsinfo_state_handler ( c ) ;
2005-04-15 18:45:00 +04:00
}
2005-09-26 15:47:55 +04:00
static void fsinfo_composite_handler ( struct composite_context * creq )
2005-04-15 18:45:00 +04:00
{
2005-09-26 15:47:55 +04:00
struct composite_context * c = talloc_get_type ( creq - > async . private_data ,
2005-04-15 18:45:00 +04:00
struct composite_context ) ;
2005-06-09 14:33:20 +04:00
fsinfo_state_handler ( c ) ;
2005-04-15 18:45:00 +04:00
}
/*
composite fsinfo call - connects to a tree and queries a file system information
*/
struct composite_context * smb_composite_fsinfo_send ( struct smbcli_tree * tree ,
struct smb_composite_fsinfo * io )
{
struct composite_context * c ;
struct fsinfo_state * state ;
c = talloc_zero ( tree , struct composite_context ) ;
if ( c = = NULL ) goto failed ;
state = talloc ( c , struct fsinfo_state ) ;
if ( state = = NULL ) goto failed ;
state - > io = io ;
state - > connect = talloc ( state , struct smb_composite_connect ) ;
if ( state - > connect = = NULL ) goto failed ;
state - > connect - > in . dest_host = io - > in . dest_host ;
state - > connect - > in . port = io - > in . port ;
state - > connect - > in . called_name = io - > in . called_name ;
state - > connect - > in . service = io - > in . service ;
state - > connect - > in . service_type = io - > in . service_type ;
state - > connect - > in . credentials = io - > in . credentials ;
state - > connect - > in . workgroup = io - > in . workgroup ;
2005-09-26 15:47:55 +04:00
c - > state = COMPOSITE_STATE_IN_PROGRESS ;
2005-04-15 18:45:00 +04:00
state - > stage = FSINFO_CONNECT ;
c - > event_ctx = talloc_reference ( c , tree - > session - > transport - > socket - > event . ctx ) ;
2005-09-26 15:47:55 +04:00
c - > private_data = state ;
2005-04-15 18:45:00 +04:00
2005-10-02 14:02:35 +04:00
state - > creq = smb_composite_connect_send ( state - > connect , state ,
c - > event_ctx ) ;
2005-04-15 18:45:00 +04:00
if ( state - > creq = = NULL ) goto failed ;
2005-09-26 15:47:55 +04:00
state - > creq - > async . private_data = c ;
2005-04-15 18:45:00 +04:00
state - > creq - > async . fn = fsinfo_composite_handler ;
return c ;
failed :
talloc_free ( c ) ;
return NULL ;
}
/*
composite fsinfo call - recv side
*/
NTSTATUS smb_composite_fsinfo_recv ( struct composite_context * c , TALLOC_CTX * mem_ctx )
{
NTSTATUS status ;
status = composite_wait ( c ) ;
if ( NT_STATUS_IS_OK ( status ) ) {
2005-09-26 15:47:55 +04:00
struct fsinfo_state * state = talloc_get_type ( c - > private_data , struct fsinfo_state ) ;
2005-04-15 18:45:00 +04:00
talloc_steal ( mem_ctx , state - > io - > out . fsinfo ) ;
}
talloc_free ( c ) ;
return status ;
}
/*
composite fsinfo call - sync interface
*/
NTSTATUS smb_composite_fsinfo ( struct smbcli_tree * tree ,
TALLOC_CTX * mem_ctx ,
struct smb_composite_fsinfo * io )
{
struct composite_context * c = smb_composite_fsinfo_send ( tree , io ) ;
return smb_composite_fsinfo_recv ( c , mem_ctx ) ;
}