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 .
*/
/*
2006-08-31 00:48:06 +04:00
a composite function for domain handling on samr and lsa pipes
2005-06-04 03:10:26 +04:00
*/
# include "includes.h"
# include "libcli/composite/composite.h"
2006-05-16 01:49:27 +04:00
# include "libnet/libnet.h"
2006-03-15 02:35:30 +03:00
# include "librpc/gen_ndr/ndr_samr_c.h"
2006-08-22 00:52:14 +04:00
# include "librpc/gen_ndr/ndr_lsa_c.h"
2005-06-04 03:10:26 +04:00
static void domain_open_handler ( struct rpc_request * ) ;
2006-05-16 01:49:27 +04:00
enum domain_open_stage { DOMOPEN_CONNECT , DOMOPEN_LOOKUP , DOMOPEN_OPEN ,
DOMOPEN_CLOSE_EXISTING , DOMOPEN_RPC_CONNECT } ;
2005-06-04 03:10:26 +04:00
2006-08-22 00:52:14 +04:00
struct domain_open_samr_state {
2005-06-04 03:10:26 +04:00
enum domain_open_stage stage ;
2006-05-16 01:49:27 +04:00
struct libnet_context * ctx ;
2005-06-04 03:10:26 +04:00
struct dcerpc_pipe * pipe ;
struct rpc_request * req ;
2006-05-16 01:49:27 +04:00
struct composite_context * rpcconn_req ;
2005-06-04 03:10:26 +04:00
struct samr_Connect connect ;
struct samr_LookupDomain lookup ;
struct samr_OpenDomain open ;
2006-05-16 01:49:27 +04:00
struct samr_Close close ;
struct libnet_RpcConnect rpcconn ;
2005-07-08 12:09:02 +04:00
struct lsa_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 ;
2006-09-05 21:56:35 +04:00
/* information about the progress */
void ( * monitor_fn ) ( struct monitor_msg * ) ;
2005-06-04 03:10:26 +04:00
} ;
2006-05-16 01:49:27 +04:00
/**
* Stage 0.5 ( optional ) : Connect to samr rpc pipe
*/
static void domain_open_rpc_connect ( struct composite_context * ctx )
{
struct composite_context * c ;
2006-08-22 00:52:14 +04:00
struct domain_open_samr_state * s ;
2006-05-16 01:49:27 +04:00
c = talloc_get_type ( ctx - > async . private_data , struct composite_context ) ;
2006-08-22 00:52:14 +04:00
s = talloc_get_type ( c - > private_data , struct domain_open_samr_state ) ;
2006-05-16 01:49:27 +04:00
c - > status = libnet_RpcConnect_recv ( ctx , s - > ctx , c , & s - > rpcconn ) ;
if ( ! composite_is_ok ( c ) ) return ;
s - > pipe = s - > rpcconn . out . dcerpc_pipe ;
/* preparing parameters for samr_Connect rpc call */
s - > connect . in . system_name = 0 ;
s - > connect . in . access_mask = s - > access_mask ;
s - > connect . out . connect_handle = & s - > connect_handle ;
/* send request */
s - > req = dcerpc_samr_Connect_send ( s - > pipe , c , & s - > connect ) ;
if ( composite_nomem ( s - > req , c ) ) return ;
/* callback handler */
s - > req - > async . callback = domain_open_handler ;
s - > req - > async . private = c ;
s - > stage = DOMOPEN_CONNECT ;
}
/**
* Stage 0.5 ( optional ) : Close existing ( in libnet context ) domain
* handle
*/
static NTSTATUS domain_open_close ( struct composite_context * c ,
2006-08-22 00:52:14 +04:00
struct domain_open_samr_state * s )
2006-05-16 01:49:27 +04:00
{
/* receive samr_Close reply */
c - > status = dcerpc_ndr_request_recv ( s - > req ) ;
NT_STATUS_NOT_OK_RETURN ( c - > status ) ;
/* reset domain handle and associated data in libnet_context */
2006-08-22 00:52:14 +04:00
s - > ctx - > samr . name = NULL ;
s - > ctx - > samr . access_mask = 0 ;
ZERO_STRUCT ( s - > ctx - > samr . handle ) ;
2006-05-16 01:49:27 +04:00
/* preparing parameters for samr_Connect rpc call */
s - > connect . in . system_name = 0 ;
s - > connect . in . access_mask = s - > access_mask ;
s - > connect . out . connect_handle = & s - > connect_handle ;
/* send request */
s - > req = dcerpc_samr_Connect_send ( s - > pipe , c , & s - > connect ) ;
if ( s - > req = = NULL ) return NT_STATUS_NO_MEMORY ;
/* callback handler */
s - > req - > async . callback = domain_open_handler ;
s - > req - > async . private = c ;
s - > stage = DOMOPEN_CONNECT ;
return NT_STATUS_OK ;
}
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 ,
2006-08-22 00:52:14 +04:00
struct domain_open_samr_state * s )
2005-06-06 12:59:19 +04:00
{
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 ,
2006-08-22 00:52:14 +04:00
struct domain_open_samr_state * s )
2005-06-06 12:59:19 +04:00
{
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 ,
2006-08-22 00:52:14 +04:00
struct domain_open_samr_state * s )
2005-06-06 12:59:19 +04:00
{
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 ) ;
2005-09-26 15:47:55 +04:00
c - > state = COMPOSITE_STATE_DONE ;
2005-06-06 12:59:19 +04:00
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 ;
2006-08-22 00:52:14 +04:00
struct domain_open_samr_state * s = talloc_get_type ( c - > private_data ,
struct domain_open_samr_state ) ;
2005-06-04 03:10:26 +04:00
/* 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 ;
2006-05-16 01:49:27 +04:00
case DOMOPEN_CLOSE_EXISTING :
c - > status = domain_open_close ( c , s ) ;
break ;
case DOMOPEN_RPC_CONNECT :
/* this state shouldn't be handled here */
c - > status = NT_STATUS_UNSUCCESSFUL ;
break ;
2005-06-04 03:10:26 +04:00
}
if ( ! NT_STATUS_IS_OK ( c - > status ) ) {
2005-09-26 15:47:55 +04:00
c - > state = COMPOSITE_STATE_ERROR ;
2005-06-04 03:10:26 +04:00
}
2006-05-16 01:49:27 +04:00
if ( c - > state = = COMPOSITE_STATE_DONE ) {
composite_done ( c ) ;
}
2005-06-04 03:10:26 +04:00
}
2005-06-15 02:08:00 +04:00
/**
2006-08-31 00:48:06 +04:00
* Sends asynchronous DomainOpenSamr request
2005-06-15 02:08:00 +04:00
*
2006-05-16 01:49:27 +04:00
* @ param ctx initialised libnet context
2005-06-15 02:08:00 +04:00
* @ param io arguments and results of the call
2006-05-16 01:49:27 +04:00
* @ param monitor pointer to monitor function that is passed monitor message
2005-06-15 02:08:00 +04:00
*/
2006-05-16 01:49:27 +04:00
2006-08-22 00:52:14 +04:00
struct composite_context * libnet_DomainOpenSamr_send ( struct libnet_context * ctx ,
struct libnet_DomainOpen * io ,
void ( * monitor ) ( struct monitor_msg * ) )
2005-06-04 03:10:26 +04:00
{
struct composite_context * c ;
2006-08-22 00:52:14 +04:00
struct domain_open_samr_state * s ;
2005-06-04 03:10:26 +04:00
2006-09-05 21:56:35 +04:00
c = composite_create ( ctx , ctx - > event_ctx ) ;
2006-05-16 01:49:27 +04:00
if ( c = = NULL ) return NULL ;
2005-06-04 03:10:26 +04:00
2006-08-22 00:52:14 +04:00
s = talloc_zero ( c , struct domain_open_samr_state ) ;
2006-05-16 01:49:27 +04:00
if ( composite_nomem ( s , c ) ) return c ;
2005-06-04 03:10:26 +04:00
2006-05-16 01:49:27 +04:00
c - > private_data = s ;
2006-09-05 21:56:35 +04:00
s - > monitor_fn = monitor ;
2005-06-04 03:10:26 +04:00
2006-05-16 01:49:27 +04:00
s - > ctx = ctx ;
2006-08-22 00:52:14 +04:00
s - > pipe = ctx - > samr . pipe ;
2005-06-06 12:59:19 +04:00
s - > access_mask = io - > in . access_mask ;
s - > domain_name . string = io - > in . domain_name ;
2006-08-31 00:48:06 +04:00
/* check, if there's samr pipe opened already, before opening a domain */
2006-08-22 00:52:14 +04:00
if ( ctx - > samr . pipe = = NULL ) {
2006-08-31 00:48:06 +04:00
/* attempting to connect a domain controller */
2006-05-16 01:49:27 +04:00
s - > rpcconn . level = LIBNET_RPC_CONNECT_DC ;
s - > rpcconn . in . name = io - > in . domain_name ;
s - > rpcconn . in . dcerpc_iface = & dcerpc_table_samr ;
2006-08-31 00:48:06 +04:00
/* send rpc pipe connect request */
2006-05-16 01:49:27 +04:00
s - > rpcconn_req = libnet_RpcConnect_send ( ctx , c , & s - > rpcconn ) ;
if ( composite_nomem ( s - > rpcconn_req , c ) ) return c ;
s - > rpcconn_req - > async . fn = domain_open_rpc_connect ;
s - > rpcconn_req - > async . private_data = c ;
s - > stage = DOMOPEN_RPC_CONNECT ;
return c ;
}
/* libnet context's domain handle is not empty, so check out what
was opened first , before doing anything */
2006-08-22 00:52:14 +04:00
if ( ! policy_handle_empty ( & ctx - > samr . handle ) ) {
if ( strequal ( ctx - > samr . name , io - > in . domain_name ) & &
ctx - > samr . access_mask = = io - > in . access_mask ) {
2006-05-16 01:49:27 +04:00
/* this domain is already opened */
composite_done ( c ) ;
return c ;
} else {
/* another domain or access rights have been
requested - close the existing handle first */
2006-08-22 00:52:14 +04:00
s - > close . in . handle = & ctx - > samr . handle ;
2006-05-16 01:49:27 +04:00
/* send request to close domain handle */
s - > req = dcerpc_samr_Close_send ( s - > pipe , c , & s - > close ) ;
if ( composite_nomem ( s - > req , c ) ) return c ;
/* callback handler */
s - > req - > async . callback = domain_open_handler ;
s - > req - > async . private = c ;
s - > stage = DOMOPEN_CLOSE_EXISTING ;
return c ;
}
}
/* preparing parameters for samr_Connect rpc call */
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 */
2006-05-16 01:49:27 +04:00
s - > req = dcerpc_samr_Connect_send ( s - > pipe , c , & s - > connect ) ;
if ( composite_nomem ( s - > req , c ) ) return c ;
2005-06-04 03:10:26 +04:00
/* callback handler */
s - > req - > async . callback = domain_open_handler ;
s - > req - > async . private = c ;
s - > stage = DOMOPEN_CONNECT ;
return c ;
}
2005-06-06 12:59:19 +04:00
2005-06-15 02:08:00 +04:00
/**
2006-08-31 00:48:06 +04:00
* Waits for and receives result of asynchronous DomainOpenSamr call
2005-06-15 02:08:00 +04:00
*
2006-06-28 02:16:36 +04:00
* @ param c composite context returned by asynchronous DomainOpen call
2006-05-16 01:49:27 +04:00
* @ param ctx initialised libnet context
2005-06-15 02:08:00 +04:00
* @ param mem_ctx memory context of the call
* @ param io pointer to results ( and arguments ) of the call
* @ return nt status code of execution
*/
2006-05-16 01:49:27 +04:00
2006-08-22 00:52:14 +04:00
NTSTATUS libnet_DomainOpenSamr_recv ( struct composite_context * c , struct libnet_context * ctx ,
TALLOC_CTX * mem_ctx , struct libnet_DomainOpen * io )
2005-06-06 12:59:19 +04:00
{
NTSTATUS status ;
2006-08-22 00:52:14 +04:00
struct domain_open_samr_state * s ;
2005-06-06 12:59:19 +04:00
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 ) {
2006-08-22 00:52:14 +04:00
s = talloc_get_type ( c - > private_data , struct domain_open_samr_state ) ;
2005-06-06 12:59:19 +04:00
io - > out . domain_handle = s - > domain_handle ;
2006-05-16 01:49:27 +04:00
/* store the resulting handle and related data for use by other
libnet functions */
2006-08-22 00:52:14 +04:00
ctx - > samr . handle = s - > domain_handle ;
ctx - > samr . name = talloc_strdup ( ctx , s - > domain_name . string ) ;
ctx - > samr . access_mask = s - > access_mask ;
}
talloc_free ( c ) ;
return status ;
}
struct domain_open_lsa_state {
const char * name ;
uint32_t access_mask ;
struct libnet_context * ctx ;
struct libnet_RpcConnect rpcconn ;
struct lsa_OpenPolicy2 openpol ;
struct policy_handle handle ;
struct dcerpc_pipe * pipe ;
2006-09-05 21:56:35 +04:00
/* information about the progress */
void ( * monitor_fn ) ( struct monitor_msg * ) ;
2006-08-22 00:52:14 +04:00
} ;
static void continue_rpc_connect_lsa ( struct composite_context * ctx ) ;
static void continue_lsa_policy_open ( struct rpc_request * req ) ;
2006-08-31 00:48:06 +04:00
/**
* Sends asynchronous DomainOpenLsa request
*
* @ param ctx initialised libnet context
* @ param io arguments and results of the call
* @ param monitor pointer to monitor function that is passed monitor message
*/
2006-08-22 00:52:14 +04:00
struct composite_context * libnet_DomainOpenLsa_send ( struct libnet_context * ctx ,
struct libnet_DomainOpen * io ,
void ( * monitor ) ( struct monitor_msg * ) )
{
struct composite_context * c ;
struct domain_open_lsa_state * s ;
struct composite_context * rpcconn_req ;
struct rpc_request * openpol_req ;
struct lsa_QosInfo * qos ;
2006-08-31 00:48:06 +04:00
/* create composite context and state */
2006-08-22 00:52:14 +04:00
c = composite_create ( ctx , ctx - > event_ctx ) ;
if ( c = = NULL ) return c ;
s = talloc_zero ( c , struct domain_open_lsa_state ) ;
if ( composite_nomem ( s , c ) ) return c ;
c - > private_data = s ;
2006-08-31 00:48:06 +04:00
/* store arguments in the state structure */
s - > name = talloc_strdup ( c , io - > in . domain_name ) ;
s - > access_mask = io - > in . access_mask ;
s - > ctx = ctx ;
2006-08-22 00:52:14 +04:00
2006-08-31 00:48:06 +04:00
/* check, if there's lsa pipe opened already, before opening a handle */
2006-08-22 00:52:14 +04:00
if ( ctx - > lsa . pipe = = NULL ) {
2006-08-31 00:48:06 +04:00
/* attempting to connect a domain controller */
2006-08-22 00:52:14 +04:00
s - > rpcconn . level = LIBNET_RPC_CONNECT_DC ;
s - > rpcconn . in . name = talloc_strdup ( c , io - > in . domain_name ) ;
s - > rpcconn . in . dcerpc_iface = & dcerpc_table_lsarpc ;
2006-08-31 00:48:06 +04:00
/* send rpc pipe connect request */
2006-08-22 00:52:14 +04:00
rpcconn_req = libnet_RpcConnect_send ( ctx , c , & s - > rpcconn ) ;
if ( composite_nomem ( rpcconn_req , c ) ) return c ;
composite_continue ( c , rpcconn_req , continue_rpc_connect_lsa , c ) ;
return c ;
}
s - > pipe = ctx - > lsa . pipe ;
2006-08-31 00:48:06 +04:00
/* preparing parameters for lsa_OpenPolicy2 rpc call */
2006-08-22 00:52:14 +04:00
s - > openpol . in . system_name = s - > name ;
s - > openpol . in . access_mask = s - > access_mask ;
s - > openpol . in . attr = talloc_zero ( c , struct lsa_ObjectAttribute ) ;
qos = talloc_zero ( c , struct lsa_QosInfo ) ;
qos - > len = 0 ;
qos - > impersonation_level = 2 ;
qos - > context_mode = 1 ;
qos - > effective_only = 0 ;
s - > openpol . in . attr - > sec_qos = qos ;
s - > openpol . out . handle = & s - > handle ;
2006-08-31 00:48:06 +04:00
/* send rpc request */
2006-08-22 00:52:14 +04:00
openpol_req = dcerpc_lsa_OpenPolicy2_send ( s - > pipe , c , & s - > openpol ) ;
if ( composite_nomem ( openpol_req , c ) ) return c ;
composite_continue_rpc ( c , openpol_req , continue_lsa_policy_open , c ) ;
return c ;
}
2006-08-31 00:48:06 +04:00
/*
Stage 0.5 ( optional ) : Rpc pipe connected , send lsa open policy request
*/
2006-08-22 00:52:14 +04:00
static void continue_rpc_connect_lsa ( struct composite_context * ctx )
{
struct composite_context * c ;
struct domain_open_lsa_state * s ;
struct lsa_QosInfo * qos ;
struct rpc_request * openpol_req ;
c = talloc_get_type ( ctx - > async . private_data , struct composite_context ) ;
s = talloc_get_type ( c - > private_data , struct domain_open_lsa_state ) ;
2006-08-31 00:48:06 +04:00
/* receive rpc connection */
2006-08-22 00:52:14 +04:00
c - > status = libnet_RpcConnect_recv ( ctx , s - > ctx , c , & s - > rpcconn ) ;
if ( ! composite_is_ok ( c ) ) return ;
2006-08-31 00:48:06 +04:00
/* RpcConnect function leaves the pipe in libnet context,
so get it from there */
2006-08-22 00:52:14 +04:00
s - > pipe = s - > ctx - > lsa . pipe ;
2006-08-31 00:48:06 +04:00
/* prepare lsa_OpenPolicy2 call */
2006-08-22 00:52:14 +04:00
s - > openpol . in . system_name = s - > name ;
s - > openpol . in . access_mask = s - > access_mask ;
s - > openpol . in . attr = talloc_zero ( c , struct lsa_ObjectAttribute ) ;
qos = talloc_zero ( c , struct lsa_QosInfo ) ;
qos - > len = 0 ;
qos - > impersonation_level = 2 ;
qos - > context_mode = 1 ;
qos - > effective_only = 0 ;
s - > openpol . in . attr - > sec_qos = qos ;
s - > openpol . out . handle = & s - > handle ;
2006-08-31 00:48:06 +04:00
/* send rpc request */
2006-08-22 00:52:14 +04:00
openpol_req = dcerpc_lsa_OpenPolicy2_send ( s - > pipe , c , & s - > openpol ) ;
if ( composite_nomem ( openpol_req , c ) ) return ;
composite_continue_rpc ( c , openpol_req , continue_lsa_policy_open , c ) ;
}
2006-08-31 00:48:06 +04:00
/*
Stage 1 : Lsa policy opened - we ' re done , if successfully
*/
2006-08-22 00:52:14 +04:00
static void continue_lsa_policy_open ( struct rpc_request * req )
{
struct composite_context * c ;
struct domain_open_lsa_state * s ;
c = talloc_get_type ( req - > async . private , struct composite_context ) ;
s = talloc_get_type ( c - > private_data , struct domain_open_lsa_state ) ;
c - > status = dcerpc_ndr_request_recv ( req ) ;
if ( ! composite_is_ok ( c ) ) return ;
composite_done ( c ) ;
}
2006-08-31 00:48:06 +04:00
/**
* Receives result of asynchronous DomainOpenLsa call
*
* @ param c composite context returned by asynchronous DomainOpenLsa call
* @ param ctx initialised libnet context
* @ param mem_ctx memory context of the call
* @ param io pointer to results ( and arguments ) of the call
* @ return nt status code of execution
*/
2006-08-22 00:52:14 +04:00
NTSTATUS libnet_DomainOpenLsa_recv ( struct composite_context * c , struct libnet_context * ctx ,
TALLOC_CTX * mem_ctx , struct libnet_DomainOpen * io )
{
NTSTATUS status ;
struct domain_open_lsa_state * s ;
status = composite_wait ( c ) ;
if ( NT_STATUS_IS_OK ( status ) & & io ) {
2006-08-31 00:48:06 +04:00
/* everything went fine - get the results and
return the error string */
2006-08-22 00:52:14 +04:00
s = talloc_get_type ( c - > private_data , struct domain_open_lsa_state ) ;
io - > out . domain_handle = s - > handle ;
ctx - > lsa . handle = s - > handle ;
2006-08-31 00:48:06 +04:00
ctx - > lsa . name = talloc_steal ( ctx , s - > name ) ;
2006-08-22 00:52:14 +04:00
ctx - > lsa . access_mask = s - > access_mask ;
2006-08-31 00:48:06 +04:00
io - > out . error_string = talloc_strdup ( mem_ctx , " Success " ) ;
2006-08-22 00:52:14 +04:00
} else if ( ! NT_STATUS_IS_OK ( status ) ) {
2006-08-31 00:48:06 +04:00
/* there was an error, so provide nt status code description */
2006-08-22 00:52:14 +04:00
io - > out . error_string = talloc_asprintf ( mem_ctx ,
" Failed to open domain: %s " ,
nt_errstr ( status ) ) ;
2005-06-06 12:59:19 +04:00
}
talloc_free ( c ) ;
return status ;
}
2006-08-31 00:48:06 +04:00
/**
* Sends a request to open a domain in desired service
*
* @ param ctx initalised libnet context
* @ param io arguments and results of the call
* @ param monitor pointer to monitor function that is passed monitor message
*/
2006-08-22 00:52:14 +04:00
struct composite_context * libnet_DomainOpen_send ( struct libnet_context * ctx ,
struct libnet_DomainOpen * io ,
void ( * monitor ) ( struct monitor_msg * ) )
{
struct composite_context * c ;
switch ( io - > in . type ) {
case DOMAIN_LSA :
2006-08-31 00:48:06 +04:00
/* reques to open a policy handle on \pipe\lsarpc */
2006-08-22 00:52:14 +04:00
c = libnet_DomainOpenLsa_send ( ctx , io , monitor ) ;
break ;
case DOMAIN_SAMR :
default :
2006-08-31 00:48:06 +04:00
/* request to open a domain policy handle on \pipe\samr */
2006-08-22 00:52:14 +04:00
c = libnet_DomainOpenSamr_send ( ctx , io , monitor ) ;
break ;
}
return c ;
}
2006-08-31 00:48:06 +04:00
/**
* Receive result of domain open request
*
* @ param c composite context returned by DomainOpen_send function
* @ param ctx initialised libnet context
* @ param mem_ctx memory context of the call
* @ param io results and arguments of the call
*/
2006-08-22 00:52:14 +04:00
NTSTATUS libnet_DomainOpen_recv ( struct composite_context * c , struct libnet_context * ctx ,
TALLOC_CTX * mem_ctx , struct libnet_DomainOpen * io )
{
NTSTATUS status ;
switch ( io - > in . type ) {
case DOMAIN_LSA :
status = libnet_DomainOpenLsa_recv ( c , ctx , mem_ctx , io ) ;
break ;
case DOMAIN_SAMR :
default :
status = libnet_DomainOpenSamr_recv ( c , ctx , mem_ctx , io ) ;
break ;
}
return status ;
}
2005-06-15 02:08:00 +04:00
/**
2006-06-28 02:16:36 +04:00
* Synchronous version of DomainOpen call
2005-06-15 02:08:00 +04:00
*
2006-05-16 01:49:27 +04:00
* @ param ctx initialised libnet context
2005-06-15 02:08:00 +04:00
* @ param mem_ctx memory context for the call
* @ param io arguments and results of the call
* @ return nt status code of execution
*/
2006-05-16 01:49:27 +04:00
NTSTATUS libnet_DomainOpen ( struct libnet_context * ctx ,
TALLOC_CTX * mem_ctx ,
struct libnet_DomainOpen * io )
2005-06-06 12:59:19 +04:00
{
2006-05-16 01:49:27 +04:00
struct composite_context * c = libnet_DomainOpen_send ( ctx , io , NULL ) ;
return libnet_DomainOpen_recv ( c , ctx , mem_ctx , io ) ;
2005-06-06 12:59:19 +04:00
}
2006-08-22 00:52:14 +04:00
struct domain_close_lsa_state {
struct dcerpc_pipe * pipe ;
struct lsa_Close close ;
struct policy_handle handle ;
void ( * monitor_fn ) ( struct monitor_msg * ) ;
} ;
static void continue_lsa_close ( struct rpc_request * req ) ;
struct composite_context * libnet_DomainCloseLsa_send ( struct libnet_context * ctx ,
struct libnet_DomainClose * io ,
void ( * monitor ) ( struct monitor_msg * ) )
{
struct composite_context * c ;
struct domain_close_lsa_state * s ;
struct rpc_request * close_req ;
2006-08-31 00:48:06 +04:00
/* composite context and state structure allocation */
2006-08-22 00:52:14 +04:00
c = composite_create ( ctx , ctx - > event_ctx ) ;
if ( c = = NULL ) return c ;
s = talloc_zero ( c , struct domain_close_lsa_state ) ;
if ( composite_nomem ( s , c ) ) return c ;
c - > private_data = s ;
s - > monitor_fn = monitor ;
/* TODO: check if lsa pipe pointer is non-null */
if ( ! strequal ( ctx - > lsa . name , io - > in . domain_name ) ) {
composite_error ( c , NT_STATUS_INVALID_PARAMETER ) ;
return c ;
}
2006-08-31 00:48:06 +04:00
/* get opened lsarpc pipe pointer */
2006-08-22 00:52:14 +04:00
s - > pipe = ctx - > lsa . pipe ;
2006-08-31 00:48:06 +04:00
/* prepare close handle call arguments */
2006-08-22 00:52:14 +04:00
s - > close . in . handle = & ctx - > lsa . handle ;
s - > close . out . handle = & s - > handle ;
2006-08-31 00:48:06 +04:00
/* send the request */
2006-08-22 00:52:14 +04:00
close_req = dcerpc_lsa_Close_send ( s - > pipe , c , & s - > close ) ;
if ( composite_nomem ( close_req , c ) ) return c ;
composite_continue_rpc ( c , close_req , continue_lsa_close , c ) ;
return c ;
}
2006-08-31 00:48:06 +04:00
/*
Stage 1 : Receive result of lsa close call
*/
2006-08-22 00:52:14 +04:00
static void continue_lsa_close ( struct rpc_request * req )
{
struct composite_context * c ;
struct domain_close_lsa_state * s ;
c = talloc_get_type ( req - > async . private , struct composite_context ) ;
s = talloc_get_type ( c - > private_data , struct domain_close_lsa_state ) ;
c - > status = dcerpc_ndr_request_recv ( req ) ;
if ( ! composite_is_ok ( c ) ) return ;
composite_done ( c ) ;
}
NTSTATUS libnet_DomainCloseLsa_recv ( struct composite_context * c , struct libnet_context * ctx ,
TALLOC_CTX * mem_ctx , struct libnet_DomainClose * io )
{
NTSTATUS status ;
status = composite_wait ( c ) ;
if ( NT_STATUS_IS_OK ( status ) & & io ) {
2006-08-31 00:48:06 +04:00
/* policy handle closed successfully */
2006-08-22 00:52:14 +04:00
ctx - > lsa . name = NULL ;
ZERO_STRUCT ( ctx - > lsa . handle ) ;
2006-08-28 00:37:23 +04:00
2006-08-22 00:52:14 +04:00
io - > out . error_string = talloc_asprintf ( mem_ctx , " Success " ) ;
} else if ( ! NT_STATUS_IS_OK ( status ) ) {
2006-08-31 00:48:06 +04:00
/* there was an error, so return description of the status code */
2006-08-22 00:52:14 +04:00
io - > out . error_string = talloc_asprintf ( mem_ctx , " Error: %s " , nt_errstr ( status ) ) ;
}
talloc_free ( c ) ;
return status ;
}
struct domain_close_samr_state {
struct samr_Close close ;
void ( * monitor_fn ) ( struct monitor_msg * ) ;
} ;
static void continue_samr_close ( struct rpc_request * req ) ;
struct composite_context * libnet_DomainCloseSamr_send ( struct libnet_context * ctx ,
struct libnet_DomainClose * io ,
void ( * monitor ) ( struct monitor_msg * ) )
{
struct composite_context * c ;
struct domain_close_samr_state * s ;
struct rpc_request * close_req ;
2006-08-31 00:48:06 +04:00
/* composite context and state structure allocation */
2006-08-22 00:52:14 +04:00
c = composite_create ( ctx , ctx - > event_ctx ) ;
if ( c = = NULL ) return c ;
s = talloc_zero ( c , struct domain_close_samr_state ) ;
if ( composite_nomem ( s , c ) ) return c ;
c - > private_data = s ;
s - > monitor_fn = monitor ;
/* TODO: check if samr pipe pointer is non-null */
if ( ! strequal ( ctx - > samr . name , io - > in . domain_name ) ) {
composite_error ( c , NT_STATUS_INVALID_PARAMETER ) ;
return c ;
}
2006-08-31 00:48:06 +04:00
/* prepare close domain handle call arguments */
2006-08-22 00:52:14 +04:00
s - > close . in . handle = & ctx - > samr . handle ;
2006-08-31 00:48:06 +04:00
/* send the request */
2006-08-22 00:52:14 +04:00
close_req = dcerpc_samr_Close_send ( ctx - > samr . pipe , ctx , & s - > close ) ;
if ( composite_nomem ( close_req , c ) ) return c ;
composite_continue_rpc ( c , close_req , continue_samr_close , c ) ;
return c ;
}
2006-08-31 00:48:06 +04:00
/*
Stage 1 : Receive result of samr close call
*/
2006-08-22 00:52:14 +04:00
static void continue_samr_close ( struct rpc_request * req )
{
struct composite_context * c ;
struct domain_close_samr_state * s ;
c = talloc_get_type ( req - > async . private , struct composite_context ) ;
s = talloc_get_type ( c - > private_data , struct domain_close_samr_state ) ;
c - > status = dcerpc_ndr_request_recv ( req ) ;
if ( ! composite_is_ok ( c ) ) return ;
composite_done ( c ) ;
}
NTSTATUS libnet_DomainCloseSamr_recv ( struct composite_context * c , struct libnet_context * ctx ,
TALLOC_CTX * mem_ctx , struct libnet_DomainClose * io )
{
NTSTATUS status ;
status = composite_wait ( c ) ;
if ( NT_STATUS_IS_OK ( status ) & & io ) {
2006-08-31 00:48:06 +04:00
/* domain policy handle closed successfully */
2006-08-22 00:52:14 +04:00
ZERO_STRUCT ( ctx - > samr . handle ) ;
ctx - > samr . name = NULL ;
2006-08-31 00:48:06 +04:00
2006-08-22 00:52:14 +04:00
io - > out . error_string = talloc_asprintf ( mem_ctx , " Success " ) ;
} else if ( ! NT_STATUS_IS_OK ( status ) ) {
2006-08-31 00:48:06 +04:00
/* there was an error, so return description of the status code */
2006-08-22 00:52:14 +04:00
io - > out . error_string = talloc_asprintf ( mem_ctx , " Error: %s " , nt_errstr ( status ) ) ;
}
talloc_free ( c ) ;
return status ;
}
struct composite_context * libnet_DomainClose_send ( struct libnet_context * ctx ,
struct libnet_DomainClose * io ,
void ( * monitor ) ( struct monitor_msg * ) )
{
struct composite_context * c ;
switch ( io - > in . type ) {
case DOMAIN_LSA :
2006-08-31 00:48:06 +04:00
/* request to close policy handle on \pipe\lsarpc */
2006-08-22 00:52:14 +04:00
c = libnet_DomainCloseLsa_send ( ctx , io , monitor ) ;
break ;
case DOMAIN_SAMR :
default :
2006-08-31 00:48:06 +04:00
/* request to close domain policy handle on \pipe\samr */
2006-08-22 00:52:14 +04:00
c = libnet_DomainCloseSamr_send ( ctx , io , monitor ) ;
break ;
}
return c ;
}
NTSTATUS libnet_DomainClose_recv ( struct composite_context * c , struct libnet_context * ctx ,
TALLOC_CTX * mem_ctx , struct libnet_DomainClose * io )
{
NTSTATUS status ;
switch ( io - > in . type ) {
case DOMAIN_LSA :
2006-08-31 00:48:06 +04:00
/* receive result of closing lsa policy handle */
2006-08-22 00:52:14 +04:00
status = libnet_DomainCloseLsa_recv ( c , ctx , mem_ctx , io ) ;
break ;
case DOMAIN_SAMR :
default :
2006-08-31 00:48:06 +04:00
/* receive result of closing samr domain policy handle */
2006-08-22 00:52:14 +04:00
status = libnet_DomainCloseSamr_recv ( c , ctx , mem_ctx , io ) ;
break ;
}
return status ;
}
NTSTATUS libnet_DomainClose ( struct libnet_context * ctx , TALLOC_CTX * mem_ctx ,
struct libnet_DomainClose * io )
{
struct composite_context * c ;
c = libnet_DomainClose_send ( ctx , io , NULL ) ;
return libnet_DomainClose_recv ( c , ctx , mem_ctx , io ) ;
}