2005-06-04 03:10:26 +04:00
/*
Unix SMB / CIFS implementation .
Copyright ( C ) Rafal Szczesniak 2005
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
the Free Software Foundation ; either version 2 of the License , or
( 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
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
/*
2005-06-11 14:31:33 +04:00
a composite function for domain handling
2005-06-04 03:10:26 +04:00
*/
# include "includes.h"
# include "libcli/raw/libcliraw.h"
# include "libcli/composite/composite.h"
# include "libcli/composite/monitor.h"
# include "librpc/gen_ndr/ndr_samr.h"
# include "libnet/composite.h"
static void domain_open_handler ( struct rpc_request * ) ;
enum domain_open_stage { DOMOPEN_CONNECT , DOMOPEN_LOOKUP , DOMOPEN_OPEN } ;
struct domain_open_state {
enum domain_open_stage stage ;
struct dcerpc_pipe * pipe ;
struct rpc_request * req ;
struct samr_Connect connect ;
struct samr_LookupDomain lookup ;
struct samr_OpenDomain open ;
2005-06-06 12:59:19 +04:00
struct samr_String domain_name ;
2005-06-04 03:10:26 +04:00
uint32_t access_mask ;
2005-06-06 12:59:19 +04:00
struct policy_handle connect_handle ;
2005-06-04 03:10:26 +04:00
struct policy_handle domain_handle ;
} ;
2005-06-15 02:08:00 +04:00
/**
* Stage 1 : Connect to SAM server .
*/
2005-06-06 12:59:19 +04:00
static NTSTATUS domain_open_connect ( struct composite_context * c ,
struct domain_open_state * s )
{
struct samr_LookupDomain * r = & s - > lookup ;
/* receive samr_Connect reply */
c - > status = dcerpc_ndr_request_recv ( s - > req ) ;
NT_STATUS_NOT_OK_RETURN ( c - > status ) ;
/* prepare for samr_LookupDomain call */
r - > in . connect_handle = & s - > connect_handle ;
r - > in . domain_name = & s - > domain_name ;
s - > req = dcerpc_samr_LookupDomain_send ( s - > pipe , c , r ) ;
if ( s - > req = = NULL ) goto failure ;
s - > req - > async . callback = domain_open_handler ;
s - > req - > async . private = c ;
s - > stage = DOMOPEN_LOOKUP ;
return NT_STATUS_OK ;
failure :
return NT_STATUS_UNSUCCESSFUL ;
}
2005-06-15 02:08:00 +04:00
/**
* Stage 2 : Lookup domain by name .
*/
2005-06-06 12:59:19 +04:00
static NTSTATUS domain_open_lookup ( struct composite_context * c ,
struct domain_open_state * s )
{
struct samr_OpenDomain * r = & s - > open ;
2005-06-15 02:08:00 +04:00
/* receive samr_LookupDomain reply */
2005-06-06 12:59:19 +04:00
c - > status = dcerpc_ndr_request_recv ( s - > req ) ;
NT_STATUS_NOT_OK_RETURN ( c - > status ) ;
2005-06-15 02:08:00 +04:00
/* prepare for samr_OpenDomain call */
2005-06-06 12:59:19 +04:00
r - > in . connect_handle = & s - > connect_handle ;
r - > in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
r - > in . sid = s - > lookup . out . sid ;
r - > out . domain_handle = & s - > domain_handle ;
s - > req = dcerpc_samr_OpenDomain_send ( s - > pipe , c , r ) ;
if ( s - > req = = NULL ) goto failure ;
s - > req - > async . callback = domain_open_handler ;
s - > req - > async . private = c ;
s - > stage = DOMOPEN_OPEN ;
return NT_STATUS_OK ;
failure :
return NT_STATUS_UNSUCCESSFUL ;
}
2005-06-15 02:08:00 +04:00
/*
* Stage 3 : Open domain .
*/
2005-06-06 12:59:19 +04:00
static NTSTATUS domain_open_open ( struct composite_context * c ,
struct domain_open_state * s )
{
2005-06-15 02:08:00 +04:00
/* receive samr_OpenDomain reply */
2005-06-06 12:59:19 +04:00
c - > status = dcerpc_ndr_request_recv ( s - > req ) ;
NT_STATUS_NOT_OK_RETURN ( c - > status ) ;
c - > state = SMBCLI_REQUEST_DONE ;
return NT_STATUS_OK ;
}
2005-06-15 02:08:00 +04:00
/**
* Event handler for asynchronous request . Handles transition through
* intermediate stages of the call .
*
* @ param req rpc call context
*/
2005-06-04 03:10:26 +04:00
static void domain_open_handler ( struct rpc_request * req )
{
struct composite_context * c = req - > async . private ;
struct domain_open_state * s = talloc_get_type ( c - > private , struct domain_open_state ) ;
struct monitor_msg msg ;
/* Stages of the call */
switch ( s - > stage ) {
case DOMOPEN_CONNECT :
2005-06-06 12:59:19 +04:00
c - > status = domain_open_connect ( c , s ) ;
2005-06-04 03:10:26 +04:00
break ;
case DOMOPEN_LOOKUP :
2005-06-06 12:59:19 +04:00
c - > status = domain_open_lookup ( c , s ) ;
2005-06-04 03:10:26 +04:00
break ;
case DOMOPEN_OPEN :
2005-06-06 12:59:19 +04:00
c - > status = domain_open_open ( c , s ) ;
2005-06-04 03:10:26 +04:00
break ;
}
if ( ! NT_STATUS_IS_OK ( c - > status ) ) {
c - > state = SMBCLI_REQUEST_ERROR ;
}
if ( c - > monitor_fn ) {
c - > monitor_fn ( & msg ) ;
}
}
2005-06-15 02:08:00 +04:00
/**
* Sends asynchronous domain_open request
*
* @ param p dce / rpc call pipe
* @ param io arguments and results of the call
*/
2005-06-11 14:31:33 +04:00
struct composite_context * libnet_rpc_domain_open_send ( struct dcerpc_pipe * p ,
struct libnet_rpc_domain_open * io ,
void ( * monitor ) ( struct monitor_msg * ) )
2005-06-04 03:10:26 +04:00
{
struct composite_context * c ;
struct domain_open_state * s ;
c = talloc_zero ( p , struct composite_context ) ;
if ( c = = NULL ) goto failure ;
s = talloc_zero ( c , struct domain_open_state ) ;
if ( c = = NULL ) goto failure ;
c - > state = SMBCLI_REQUEST_SEND ;
c - > private = s ;
c - > event_ctx = dcerpc_event_context ( p ) ;
c - > monitor_fn = monitor ;
2005-06-06 12:59:19 +04:00
s - > pipe = p ;
s - > access_mask = io - > in . access_mask ;
s - > domain_name . string = io - > in . domain_name ;
2005-06-04 03:10:26 +04:00
/* preparing parameters to send rpc request */
2005-06-06 12:59:19 +04:00
s - > connect . in . system_name = 0 ;
s - > connect . in . access_mask = s - > access_mask ;
s - > connect . out . connect_handle = & s - > connect_handle ;
2005-06-04 03:10:26 +04:00
/* send request */
s - > req = dcerpc_samr_Connect_send ( p , c , & s - > connect ) ;
/* callback handler */
s - > req - > async . callback = domain_open_handler ;
s - > req - > async . private = c ;
s - > stage = DOMOPEN_CONNECT ;
return c ;
failure :
talloc_free ( c ) ;
return NULL ;
}
2005-06-06 12:59:19 +04:00
2005-06-15 02:08:00 +04:00
/**
* Waits for and receives result of asynchronous domain_open call
*
* @ param c composite context returned by asynchronous domain_open call
* @ param mem_ctx memory context of the call
* @ param io pointer to results ( and arguments ) of the call
* @ return nt status code of execution
*/
2005-06-11 14:31:33 +04:00
NTSTATUS libnet_rpc_domain_open_recv ( struct composite_context * c , TALLOC_CTX * mem_ctx ,
struct libnet_rpc_domain_open * io )
2005-06-06 12:59:19 +04:00
{
NTSTATUS status ;
struct domain_open_state * s ;
2005-06-15 02:08:00 +04:00
/* wait for results of sending request */
2005-06-06 12:59:19 +04:00
status = composite_wait ( c ) ;
if ( NT_STATUS_IS_OK ( status ) & & io ) {
s = talloc_get_type ( c - > private , struct domain_open_state ) ;
io - > out . domain_handle = s - > domain_handle ;
}
talloc_free ( c ) ;
return status ;
}
2005-06-15 02:08:00 +04:00
/**
* Synchronous version of domain_open call
*
* @ param pipe dce / rpc call pipe
* @ param mem_ctx memory context for the call
* @ param io arguments and results of the call
* @ return nt status code of execution
*/
2005-06-11 14:31:33 +04:00
NTSTATUS libnet_rpc_domain_open ( struct dcerpc_pipe * p ,
TALLOC_CTX * mem_ctx ,
struct libnet_rpc_domain_open * io )
2005-06-06 12:59:19 +04:00
{
2005-06-11 14:31:33 +04:00
struct composite_context * c = libnet_rpc_domain_open_send ( p , io , NULL ) ;
return libnet_rpc_domain_open_recv ( c , mem_ctx , io ) ;
2005-06-06 12:59:19 +04:00
}