2007-07-19 01:24:37 +04:00
/*
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
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2005-06-04 03:10:26 +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/>.
2005-06-04 03:10:26 +04:00
*/
/*
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
2006-08-22 00:52:14 +04:00
struct domain_open_samr_state {
2006-05-16 01:49:27 +04:00
struct libnet_context * ctx ;
2005-06-04 03:10:26 +04:00
struct dcerpc_pipe * pipe ;
2007-04-25 19:24:01 +04:00
struct libnet_RpcConnect rpcconn ;
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 ;
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 ;
2008-11-07 04:42:45 +03:00
struct dom_sid2 * domain_sid ;
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
} ;
2010-03-09 18:45:04 +03:00
static void continue_domain_open_close ( struct tevent_req * subreq ) ;
static void continue_domain_open_connect ( struct tevent_req * subreq ) ;
static void continue_domain_open_lookup ( struct tevent_req * subreq ) ;
static void continue_domain_open_open ( struct tevent_req * subreq ) ;
2007-04-25 19:24:01 +04:00
2006-05-16 01:49:27 +04:00
/**
* Stage 0.5 ( optional ) : Connect to samr rpc pipe
*/
2007-04-25 19:24:01 +04:00
static void continue_domain_open_rpc_connect ( struct composite_context * ctx )
2006-05-16 01:49:27 +04:00
{
struct composite_context * c ;
2006-08-22 00:52:14 +04:00
struct domain_open_samr_state * s ;
2010-03-09 18:45:04 +03:00
struct tevent_req * subreq ;
2006-05-16 01:49:27 +04:00
2012-03-01 14:02:24 +04:00
c = talloc_get_type_abort ( ctx - > async . private_data , struct composite_context ) ;
s = talloc_get_type_abort ( 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 */
2010-03-09 18:45:04 +03:00
subreq = dcerpc_samr_Connect_r_send ( s , c - > event_ctx ,
s - > pipe - > binding_handle ,
& s - > connect ) ;
if ( composite_nomem ( subreq , c ) ) return ;
2006-05-16 01:49:27 +04:00
/* callback handler */
2010-03-09 18:45:04 +03:00
tevent_req_set_callback ( subreq , continue_domain_open_connect , c ) ;
2006-05-16 01:49:27 +04:00
}
/**
* Stage 0.5 ( optional ) : Close existing ( in libnet context ) domain
* handle
*/
2010-03-09 18:45:04 +03:00
static void continue_domain_open_close ( struct tevent_req * subreq )
2006-05-16 01:49:27 +04:00
{
2007-04-25 19:24:01 +04:00
struct composite_context * c ;
struct domain_open_samr_state * s ;
2010-03-09 18:45:04 +03:00
c = tevent_req_callback_data ( subreq , struct composite_context ) ;
2012-03-01 14:02:24 +04:00
s = talloc_get_type_abort ( c - > private_data , struct domain_open_samr_state ) ;
2007-04-25 19:24:01 +04:00
2006-05-16 01:49:27 +04:00
/* receive samr_Close reply */
2010-03-09 18:45:04 +03:00
c - > status = dcerpc_samr_Close_r_recv ( subreq , s ) ;
TALLOC_FREE ( subreq ) ;
2007-04-25 19:24:01 +04:00
if ( ! composite_is_ok ( c ) ) return ;
2006-05-16 01:49:27 +04:00
2007-07-19 01:24:37 +04:00
if ( s - > monitor_fn ) {
struct monitor_msg msg ;
2007-07-26 03:17:02 +04:00
msg . type = mon_SamrClose ;
2007-07-19 01:24:37 +04:00
msg . data = NULL ;
msg . data_size = 0 ;
s - > monitor_fn ( & msg ) ;
}
2006-05-16 01:49:27 +04:00
/* 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 */
2010-03-09 18:45:04 +03:00
subreq = dcerpc_samr_Connect_r_send ( s , c - > event_ctx ,
s - > pipe - > binding_handle ,
& s - > connect ) ;
if ( composite_nomem ( subreq , c ) ) return ;
2006-05-16 01:49:27 +04:00
/* callback handler */
2010-03-09 18:45:04 +03:00
tevent_req_set_callback ( subreq , continue_domain_open_connect , c ) ;
2006-05-16 01:49:27 +04:00
}
2005-06-15 02:08:00 +04:00
/**
* Stage 1 : Connect to SAM server .
*/
2010-03-09 18:45:04 +03:00
static void continue_domain_open_connect ( struct tevent_req * subreq )
2005-06-06 12:59:19 +04:00
{
2007-04-25 19:24:01 +04:00
struct composite_context * c ;
struct domain_open_samr_state * s ;
struct samr_LookupDomain * r ;
2010-03-09 18:45:04 +03:00
c = tevent_req_callback_data ( subreq , struct composite_context ) ;
2012-03-01 14:02:24 +04:00
s = talloc_get_type_abort ( c - > private_data , struct domain_open_samr_state ) ;
2005-06-06 12:59:19 +04:00
/* receive samr_Connect reply */
2010-03-09 18:45:04 +03:00
c - > status = dcerpc_samr_Connect_r_recv ( subreq , s ) ;
TALLOC_FREE ( subreq ) ;
2007-04-25 19:24:01 +04:00
if ( ! composite_is_ok ( c ) ) return ;
2007-07-19 01:24:37 +04:00
if ( s - > monitor_fn ) {
struct monitor_msg msg ;
2007-07-26 03:17:02 +04:00
msg . type = mon_SamrConnect ;
2007-07-19 01:24:37 +04:00
msg . data = NULL ;
msg . data_size = 0 ;
s - > monitor_fn ( & msg ) ;
}
2007-04-25 19:24:01 +04:00
r = & s - > lookup ;
2005-06-06 12:59:19 +04:00
/* prepare for samr_LookupDomain call */
r - > in . connect_handle = & s - > connect_handle ;
r - > in . domain_name = & s - > domain_name ;
2008-11-07 04:42:45 +03:00
r - > out . sid = talloc ( s , struct dom_sid2 * ) ;
if ( composite_nomem ( r - > out . sid , c ) ) return ;
2005-06-06 12:59:19 +04:00
2010-03-09 18:45:04 +03:00
subreq = dcerpc_samr_LookupDomain_r_send ( s , c - > event_ctx ,
s - > pipe - > binding_handle ,
r ) ;
if ( composite_nomem ( subreq , c ) ) return ;
2005-06-06 12:59:19 +04:00
2010-03-09 18:45:04 +03:00
tevent_req_set_callback ( subreq , continue_domain_open_lookup , c ) ;
2005-06-06 12:59:19 +04:00
}
2005-06-15 02:08:00 +04:00
/**
* Stage 2 : Lookup domain by name .
*/
2010-03-09 18:45:04 +03:00
static void continue_domain_open_lookup ( struct tevent_req * subreq )
2005-06-06 12:59:19 +04:00
{
2007-04-25 19:24:01 +04:00
struct composite_context * c ;
struct domain_open_samr_state * s ;
struct samr_OpenDomain * r ;
2005-06-06 12:59:19 +04:00
2010-03-09 18:45:04 +03:00
c = tevent_req_callback_data ( subreq , struct composite_context ) ;
2012-03-01 14:02:24 +04:00
s = talloc_get_type_abort ( c - > private_data , struct domain_open_samr_state ) ;
2007-04-25 19:24:01 +04:00
2005-06-15 02:08:00 +04:00
/* receive samr_LookupDomain reply */
2010-03-09 18:45:04 +03:00
c - > status = dcerpc_samr_LookupDomain_r_recv ( subreq , s ) ;
TALLOC_FREE ( subreq ) ;
2007-04-25 19:24:01 +04:00
2007-07-19 01:24:37 +04:00
if ( s - > monitor_fn ) {
struct monitor_msg msg ;
struct msg_rpc_lookup_domain data ;
data . domain_name = s - > domain_name . string ;
2007-07-26 03:17:02 +04:00
msg . type = mon_SamrLookupDomain ;
2007-07-19 01:24:37 +04:00
msg . data = ( void * ) & data ;
msg . data_size = sizeof ( data ) ;
s - > monitor_fn ( & msg ) ;
}
2007-04-25 19:24:01 +04:00
r = & s - > open ;
/* check the rpc layer status */
2014-05-05 15:46:58 +04:00
if ( ! composite_is_ok ( c ) ) return ;
2007-04-25 19:24:01 +04:00
/* check the rpc call itself status */
if ( ! NT_STATUS_IS_OK ( s - > lookup . out . result ) ) {
composite_error ( c , s - > lookup . out . result ) ;
return ;
}
2005-06-06 12:59:19 +04:00
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 ;
2008-11-07 04:42:45 +03:00
r - > in . sid = * s - > lookup . out . sid ;
2005-06-06 12:59:19 +04:00
r - > out . domain_handle = & s - > domain_handle ;
2010-03-09 18:45:04 +03:00
subreq = dcerpc_samr_OpenDomain_r_send ( s , c - > event_ctx ,
s - > pipe - > binding_handle ,
r ) ;
if ( composite_nomem ( subreq , c ) ) return ;
2005-06-06 12:59:19 +04:00
2010-03-09 18:45:04 +03:00
tevent_req_set_callback ( subreq , continue_domain_open_open , c ) ;
2005-06-06 12:59:19 +04:00
}
2005-06-15 02:08:00 +04:00
/*
* Stage 3 : Open domain .
*/
2010-03-09 18:45:04 +03:00
static void continue_domain_open_open ( struct tevent_req * subreq )
2005-06-06 12:59:19 +04:00
{
2007-04-25 19:24:01 +04:00
struct composite_context * c ;
struct domain_open_samr_state * s ;
2005-06-06 12:59:19 +04:00
2010-03-09 18:45:04 +03:00
c = tevent_req_callback_data ( subreq , struct composite_context ) ;
2012-03-01 14:02:24 +04:00
s = talloc_get_type_abort ( c - > private_data , struct domain_open_samr_state ) ;
2005-06-04 03:10:26 +04:00
2007-04-25 19:24:01 +04:00
/* receive samr_OpenDomain reply */
2010-03-09 18:45:04 +03:00
c - > status = dcerpc_samr_OpenDomain_r_recv ( subreq , s ) ;
TALLOC_FREE ( subreq ) ;
2007-04-25 19:24:01 +04:00
if ( ! composite_is_ok ( c ) ) return ;
2006-05-16 01:49:27 +04:00
2007-07-19 01:24:37 +04:00
if ( s - > monitor_fn ) {
struct monitor_msg msg ;
2007-07-26 03:17:02 +04:00
msg . type = mon_SamrOpenDomain ;
2007-07-19 01:24:37 +04:00
msg . data = NULL ;
msg . data_size = 0 ;
s - > monitor_fn ( & msg ) ;
}
2007-04-25 19:24:01 +04:00
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 ,
2012-04-30 13:57:45 +04:00
TALLOC_CTX * mem_ctx ,
2006-08-22 00:52:14 +04:00
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 ;
2007-04-25 19:24:01 +04:00
struct composite_context * rpcconn_req ;
2010-03-09 18:45:04 +03:00
struct tevent_req * subreq ;
2005-06-04 03:10:26 +04:00
2012-04-30 13:57:45 +04:00
c = composite_create ( mem_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 ;
2006-09-05 22:45:03 +04:00
s - > domain_name . string = talloc_strdup ( c , io - > in . domain_name ) ;
2005-06-06 12:59:19 +04:00
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 ;
2007-08-20 01:23:03 +04:00
s - > rpcconn . in . dcerpc_iface = & ndr_table_samr ;
2006-08-31 00:48:06 +04:00
/* send rpc pipe connect request */
2007-07-19 01:24:37 +04:00
rpcconn_req = libnet_RpcConnect_send ( ctx , c , & s - > rpcconn , s - > monitor_fn ) ;
2007-04-25 19:24:01 +04:00
if ( composite_nomem ( rpcconn_req , c ) ) return c ;
2006-05-16 01:49:27 +04:00
2007-04-25 19:24:01 +04:00
composite_continue ( c , rpcconn_req , continue_domain_open_rpc_connect , c ) ;
2006-05-16 01:49:27 +04:00
return c ;
}
/* libnet context's domain handle is not empty, so check out what
was opened first , before doing anything */
2012-03-18 20:44:24 +04:00
if ( ! ndr_policy_handle_empty ( & ctx - > samr . handle ) ) {
2006-08-22 00:52:14 +04:00
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 */
2010-03-09 18:45:04 +03:00
subreq = dcerpc_samr_Close_r_send ( s , c - > event_ctx ,
s - > pipe - > binding_handle ,
& s - > close ) ;
if ( composite_nomem ( subreq , c ) ) return c ;
2006-05-16 01:49:27 +04:00
/* callback handler */
2010-03-09 18:45:04 +03:00
tevent_req_set_callback ( subreq , continue_domain_open_close , c ) ;
2006-05-16 01:49:27 +04:00
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 */
2010-03-09 18:45:04 +03:00
subreq = dcerpc_samr_Connect_r_send ( s , c - > event_ctx ,
s - > pipe - > binding_handle ,
& s - > connect ) ;
if ( composite_nomem ( subreq , c ) ) return c ;
2005-06-04 03:10:26 +04:00
/* callback handler */
2010-03-09 18:45:04 +03:00
tevent_req_set_callback ( subreq , continue_domain_open_connect , c ) ;
2005-06-04 03:10:26 +04:00
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 ) {
2012-03-01 14:02:24 +04:00
s = talloc_get_type_abort ( 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 */
2007-07-24 10:02:32 +04:00
ctx - > samr . connect_handle = s - > connect_handle ;
2006-08-22 00:52:14 +04:00
ctx - > samr . handle = s - > domain_handle ;
2008-11-07 04:42:45 +03:00
ctx - > samr . sid = talloc_steal ( ctx , * s - > lookup . out . sid ) ;
2006-09-05 22:45:03 +04:00
ctx - > samr . name = talloc_steal ( ctx , s - > domain_name . string ) ;
2006-08-22 00:52:14 +04:00
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 ) ;
2010-03-09 18:45:04 +03:00
static void continue_lsa_policy_open ( struct tevent_req * subreq ) ;
2006-08-22 00:52:14 +04:00
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 ,
2012-04-30 13:57:45 +04:00
TALLOC_CTX * mem_ctx ,
2006-08-22 00:52:14 +04:00
struct libnet_DomainOpen * io ,
void ( * monitor ) ( struct monitor_msg * ) )
{
struct composite_context * c ;
struct domain_open_lsa_state * s ;
struct composite_context * rpcconn_req ;
2010-03-09 18:45:04 +03:00
struct tevent_req * subreq ;
2006-08-22 00:52:14 +04:00
struct lsa_QosInfo * qos ;
2006-08-31 00:48:06 +04:00
/* create composite context and state */
2012-04-30 13:57:45 +04:00
c = composite_create ( mem_ctx , ctx - > event_ctx ) ;
2006-08-22 00:52:14 +04:00
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
2009-06-18 06:33:46 +04:00
ZERO_STRUCT ( s - > rpcconn ) ;
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 ) ;
2007-08-20 01:23:03 +04:00
s - > rpcconn . in . dcerpc_iface = & ndr_table_lsarpc ;
2006-08-22 00:52:14 +04:00
2006-08-31 00:48:06 +04:00
/* send rpc pipe connect request */
2007-07-19 01:24:37 +04:00
rpcconn_req = libnet_RpcConnect_send ( ctx , c , & s - > rpcconn , s - > monitor_fn ) ;
2006-08-22 00:52:14 +04:00
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 */
2010-03-09 18:45:04 +03:00
subreq = dcerpc_lsa_OpenPolicy2_r_send ( s , c - > event_ctx ,
s - > pipe - > binding_handle ,
& s - > openpol ) ;
if ( composite_nomem ( subreq , c ) ) return c ;
2006-08-22 00:52:14 +04:00
2010-03-09 18:45:04 +03:00
tevent_req_set_callback ( subreq , continue_lsa_policy_open , c ) ;
2006-08-22 00:52:14 +04:00
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 ;
2010-03-09 18:45:04 +03:00
struct tevent_req * subreq ;
2006-08-22 00:52:14 +04:00
2012-03-01 14:02:24 +04:00
c = talloc_get_type_abort ( ctx - > async . private_data , struct composite_context ) ;
s = talloc_get_type_abort ( c - > private_data , struct domain_open_lsa_state ) ;
2006-08-22 00:52:14 +04:00
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 */
2010-03-09 18:45:04 +03:00
subreq = dcerpc_lsa_OpenPolicy2_r_send ( s , c - > event_ctx ,
s - > pipe - > binding_handle ,
& s - > openpol ) ;
if ( composite_nomem ( subreq , c ) ) return ;
2006-08-22 00:52:14 +04:00
2010-03-09 18:45:04 +03:00
tevent_req_set_callback ( subreq , continue_lsa_policy_open , c ) ;
2006-08-22 00:52:14 +04:00
}
2006-08-31 00:48:06 +04:00
/*
Stage 1 : Lsa policy opened - we ' re done , if successfully
*/
2010-03-09 18:45:04 +03:00
static void continue_lsa_policy_open ( struct tevent_req * subreq )
2006-08-22 00:52:14 +04:00
{
struct composite_context * c ;
struct domain_open_lsa_state * s ;
2010-03-09 18:45:04 +03:00
c = tevent_req_callback_data ( subreq , struct composite_context ) ;
2012-03-01 14:02:24 +04:00
s = talloc_get_type_abort ( c - > private_data , struct domain_open_lsa_state ) ;
2006-08-22 00:52:14 +04:00
2010-03-09 18:45:04 +03:00
c - > status = dcerpc_lsa_OpenPolicy2_r_recv ( subreq , s ) ;
TALLOC_FREE ( subreq ) ;
2006-08-22 00:52:14 +04:00
if ( ! composite_is_ok ( c ) ) return ;
2007-07-26 03:17:02 +04:00
if ( s - > monitor_fn ) {
struct monitor_msg msg ;
msg . type = mon_LsaOpenPolicy ;
msg . data = NULL ;
msg . data_size = 0 ;
s - > monitor_fn ( & msg ) ;
}
2006-08-22 00:52:14 +04:00
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 */
2012-03-01 14:02:24 +04:00
s = talloc_get_type_abort ( c - > private_data , struct domain_open_lsa_state ) ;
2006-08-22 00:52:14 +04:00
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
*
2018-11-28 01:10:17 +03:00
* @ param ctx initialised libnet context
2006-08-31 00:48:06 +04:00
* @ 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 ,
2012-04-30 13:57:45 +04:00
TALLOC_CTX * mem_ctx ,
2006-08-22 00:52:14 +04:00
struct libnet_DomainOpen * io ,
void ( * monitor ) ( struct monitor_msg * ) )
{
struct composite_context * c ;
switch ( io - > in . type ) {
case DOMAIN_LSA :
2023-08-03 15:36:50 +03:00
/* request to open a policy handle on \pipe\lsarpc */
2012-04-30 13:57:45 +04:00
c = libnet_DomainOpenLsa_send ( ctx , mem_ctx , io , monitor ) ;
2006-08-22 00:52:14 +04:00
break ;
case DOMAIN_SAMR :
default :
2006-08-31 00:48:06 +04:00
/* request to open a domain policy handle on \pipe\samr */
2012-04-30 13:57:45 +04:00
c = libnet_DomainOpenSamr_send ( ctx , mem_ctx , io , monitor ) ;
2006-08-22 00:52:14 +04:00
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
{
2012-04-30 13:57:45 +04:00
struct composite_context * c = libnet_DomainOpen_send ( ctx , mem_ctx , io , NULL ) ;
2006-05-16 01:49:27 +04:00
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 * ) ;
} ;
2010-03-09 18:45:04 +03:00
static void continue_lsa_close ( struct tevent_req * subreq ) ;
2006-08-22 00:52:14 +04:00
struct composite_context * libnet_DomainCloseLsa_send ( struct libnet_context * ctx ,
2012-04-30 14:02:42 +04:00
TALLOC_CTX * mem_ctx ,
2006-08-22 00:52:14 +04:00
struct libnet_DomainClose * io ,
void ( * monitor ) ( struct monitor_msg * ) )
{
struct composite_context * c ;
struct domain_close_lsa_state * s ;
2010-03-09 18:45:04 +03:00
struct tevent_req * subreq ;
2006-08-22 00:52:14 +04:00
2006-08-31 00:48:06 +04:00
/* composite context and state structure allocation */
2012-04-30 14:02:42 +04:00
c = composite_create ( mem_ctx , ctx - > event_ctx ) ;
2006-08-22 00:52:14 +04:00
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 */
2010-03-09 18:45:04 +03:00
subreq = dcerpc_lsa_Close_r_send ( s , c - > event_ctx ,
s - > pipe - > binding_handle ,
& s - > close ) ;
if ( composite_nomem ( subreq , c ) ) return c ;
2006-08-22 00:52:14 +04:00
2010-03-09 18:45:04 +03:00
tevent_req_set_callback ( subreq , continue_lsa_close , c ) ;
2006-08-22 00:52:14 +04:00
return c ;
}
2006-08-31 00:48:06 +04:00
/*
Stage 1 : Receive result of lsa close call
*/
2010-03-09 18:45:04 +03:00
static void continue_lsa_close ( struct tevent_req * subreq )
2006-08-22 00:52:14 +04:00
{
struct composite_context * c ;
struct domain_close_lsa_state * s ;
2010-03-09 18:45:04 +03:00
c = tevent_req_callback_data ( subreq , struct composite_context ) ;
2012-03-01 14:02:24 +04:00
s = talloc_get_type_abort ( c - > private_data , struct domain_close_lsa_state ) ;
2006-08-22 00:52:14 +04:00
2010-03-09 18:45:04 +03:00
c - > status = dcerpc_lsa_Close_r_recv ( subreq , s ) ;
TALLOC_FREE ( subreq ) ;
2006-08-22 00:52:14 +04:00
if ( ! composite_is_ok ( c ) ) return ;
2007-07-26 03:17:02 +04:00
if ( s - > monitor_fn ) {
struct monitor_msg msg ;
msg . type = mon_LsaClose ;
msg . data = NULL ;
msg . data_size = 0 ;
s - > monitor_fn ( & msg ) ;
}
2006-08-22 00:52:14 +04:00
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 ;
2006-09-05 22:45:03 +04:00
struct policy_handle handle ;
2006-08-22 00:52:14 +04:00
void ( * monitor_fn ) ( struct monitor_msg * ) ;
} ;
2010-03-09 18:45:04 +03:00
static void continue_samr_close ( struct tevent_req * subreq ) ;
2006-08-22 00:52:14 +04:00
struct composite_context * libnet_DomainCloseSamr_send ( struct libnet_context * ctx ,
2012-04-30 14:02:42 +04:00
TALLOC_CTX * mem_ctx ,
2006-08-22 00:52:14 +04:00
struct libnet_DomainClose * io ,
void ( * monitor ) ( struct monitor_msg * ) )
{
struct composite_context * c ;
struct domain_close_samr_state * s ;
2010-03-09 18:45:04 +03:00
struct tevent_req * subreq ;
2006-08-22 00:52:14 +04:00
2006-08-31 00:48:06 +04:00
/* composite context and state structure allocation */
2012-04-30 14:02:42 +04:00
c = composite_create ( mem_ctx , ctx - > event_ctx ) ;
2006-08-22 00:52:14 +04:00
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-09-05 22:45:03 +04:00
ZERO_STRUCT ( s - > close ) ;
s - > close . in . handle = & ctx - > samr . handle ;
s - > close . out . handle = & s - > handle ;
2006-08-22 00:52:14 +04:00
2006-08-31 00:48:06 +04:00
/* send the request */
2010-03-09 18:45:04 +03:00
subreq = dcerpc_samr_Close_r_send ( s , c - > event_ctx ,
ctx - > samr . pipe - > binding_handle ,
& s - > close ) ;
if ( composite_nomem ( subreq , c ) ) return c ;
2006-08-22 00:52:14 +04:00
2010-03-09 18:45:04 +03:00
tevent_req_set_callback ( subreq , continue_samr_close , c ) ;
2006-08-22 00:52:14 +04:00
return c ;
}
2006-08-31 00:48:06 +04:00
/*
Stage 1 : Receive result of samr close call
*/
2010-03-09 18:45:04 +03:00
static void continue_samr_close ( struct tevent_req * subreq )
2006-08-22 00:52:14 +04:00
{
struct composite_context * c ;
struct domain_close_samr_state * s ;
2010-03-09 18:45:04 +03:00
c = tevent_req_callback_data ( subreq , struct composite_context ) ;
2012-03-01 14:02:24 +04:00
s = talloc_get_type_abort ( c - > private_data , struct domain_close_samr_state ) ;
2006-08-22 00:52:14 +04:00
2010-03-09 18:45:04 +03:00
c - > status = dcerpc_samr_Close_r_recv ( subreq , s ) ;
TALLOC_FREE ( subreq ) ;
2006-08-22 00:52:14 +04:00
if ( ! composite_is_ok ( c ) ) return ;
2007-07-26 03:17:02 +04:00
if ( s - > monitor_fn ) {
struct monitor_msg msg ;
msg . type = mon_SamrClose ;
msg . data = NULL ;
msg . data_size = 0 ;
s - > monitor_fn ( & msg ) ;
}
2006-08-22 00:52:14 +04:00
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 ) ;
2008-06-27 11:22:11 +04:00
talloc_free ( discard_const_p ( char , ctx - > samr . name ) ) ;
2007-08-02 17:08:39 +04:00
talloc_free ( ctx - > samr . sid ) ;
2006-08-22 00:52:14 +04:00
ctx - > samr . name = NULL ;
2007-08-02 17:08:39 +04:00
ctx - > samr . sid = 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 ,
2012-04-30 14:02:42 +04:00
TALLOC_CTX * mem_ctx ,
2006-08-22 00:52:14 +04:00
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 */
2012-04-30 14:02:42 +04:00
c = libnet_DomainCloseLsa_send ( ctx , mem_ctx , io , monitor ) ;
2006-08-22 00:52:14 +04:00
break ;
case DOMAIN_SAMR :
default :
2006-08-31 00:48:06 +04:00
/* request to close domain policy handle on \pipe\samr */
2012-04-30 14:02:42 +04:00
c = libnet_DomainCloseSamr_send ( ctx , mem_ctx , io , monitor ) ;
2006-08-22 00:52:14 +04:00
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 ;
2012-04-30 14:02:42 +04:00
c = libnet_DomainClose_send ( ctx , mem_ctx , io , NULL ) ;
2006-08-22 00:52:14 +04:00
return libnet_DomainClose_recv ( c , ctx , mem_ctx , io ) ;
}
2007-04-29 16:31:09 +04:00
struct domain_list_state {
struct libnet_context * ctx ;
struct libnet_RpcConnect rpcconn ;
struct samr_Connect samrconn ;
struct samr_EnumDomains enumdom ;
2007-05-07 09:42:26 +04:00
struct samr_Close samrclose ;
2007-04-29 16:31:09 +04:00
const char * hostname ;
struct policy_handle connect_handle ;
int buf_size ;
struct domainlist * domains ;
uint32_t resume_handle ;
uint32_t count ;
void ( * monitor_fn ) ( struct monitor_msg * ) ;
} ;
static void continue_rpc_connect ( struct composite_context * c ) ;
2010-03-09 18:45:04 +03:00
static void continue_samr_connect ( struct tevent_req * subreq ) ;
static void continue_samr_enum_domains ( struct tevent_req * subreq ) ;
static void continue_samr_close_handle ( struct tevent_req * subreq ) ;
2007-04-29 16:31:09 +04:00
static struct domainlist * get_domain_list ( TALLOC_CTX * mem_ctx , struct domain_list_state * s ) ;
/*
Stage 1 : Receive connected rpc pipe and send connection
request to SAMR service
*/
static void continue_rpc_connect ( struct composite_context * ctx )
{
struct composite_context * c ;
struct domain_list_state * s ;
2010-03-09 18:45:04 +03:00
struct tevent_req * subreq ;
2007-04-29 16:31:09 +04:00
2012-03-01 14:02:24 +04:00
c = talloc_get_type_abort ( ctx - > async . private_data , struct composite_context ) ;
s = talloc_get_type_abort ( c - > private_data , struct domain_list_state ) ;
2007-04-29 16:31:09 +04:00
c - > status = libnet_RpcConnect_recv ( ctx , s - > ctx , c , & s - > rpcconn ) ;
if ( ! composite_is_ok ( c ) ) return ;
s - > samrconn . in . system_name = 0 ;
s - > samrconn . in . access_mask = SEC_GENERIC_READ ; /* should be enough */
s - > samrconn . out . connect_handle = & s - > connect_handle ;
2010-03-09 18:45:04 +03:00
subreq = dcerpc_samr_Connect_r_send ( s , c - > event_ctx ,
s - > ctx - > samr . pipe - > binding_handle ,
& s - > samrconn ) ;
if ( composite_nomem ( subreq , c ) ) return ;
2007-04-29 16:31:09 +04:00
2010-03-09 18:45:04 +03:00
tevent_req_set_callback ( subreq , continue_samr_connect , c ) ;
2007-04-29 16:31:09 +04:00
}
/*
Stage 2 : Receive policy handle to the connected SAMR service and issue
a request to enumerate domain databases available
*/
2010-03-09 18:45:04 +03:00
static void continue_samr_connect ( struct tevent_req * subreq )
2007-04-29 16:31:09 +04:00
{
struct composite_context * c ;
struct domain_list_state * s ;
2010-03-09 18:45:04 +03:00
c = tevent_req_callback_data ( subreq , struct composite_context ) ;
2012-03-01 14:02:24 +04:00
s = talloc_get_type_abort ( c - > private_data , struct domain_list_state ) ;
2007-04-29 16:31:09 +04:00
2010-03-09 18:45:04 +03:00
c - > status = dcerpc_samr_Connect_r_recv ( subreq , s ) ;
TALLOC_FREE ( subreq ) ;
2007-04-29 16:31:09 +04:00
if ( ! composite_is_ok ( c ) ) return ;
2007-07-26 03:17:02 +04:00
if ( s - > monitor_fn ) {
struct monitor_msg msg ;
msg . type = mon_SamrConnect ;
msg . data = NULL ;
msg . data_size = 0 ;
s - > monitor_fn ( & msg ) ;
}
2007-04-29 16:31:09 +04:00
s - > enumdom . in . connect_handle = & s - > connect_handle ;
s - > enumdom . in . resume_handle = & s - > resume_handle ;
s - > enumdom . in . buf_size = s - > buf_size ;
s - > enumdom . out . resume_handle = & s - > resume_handle ;
2008-11-07 04:57:58 +03:00
s - > enumdom . out . num_entries = talloc ( s , uint32_t ) ;
if ( composite_nomem ( s - > enumdom . out . num_entries , c ) ) return ;
s - > enumdom . out . sam = talloc ( s , struct samr_SamArray * ) ;
if ( composite_nomem ( s - > enumdom . out . sam , c ) ) return ;
2007-04-29 16:31:09 +04:00
2010-03-09 18:45:04 +03:00
subreq = dcerpc_samr_EnumDomains_r_send ( s , c - > event_ctx ,
s - > ctx - > samr . pipe - > binding_handle ,
& s - > enumdom ) ;
if ( composite_nomem ( subreq , c ) ) return ;
2007-04-29 16:31:09 +04:00
2010-03-09 18:45:04 +03:00
tevent_req_set_callback ( subreq , continue_samr_enum_domains , c ) ;
2007-04-29 16:31:09 +04:00
}
/*
Stage 3 : Receive domain names available and repeat the request
2007-05-07 09:42:26 +04:00
enumeration is not complete yet . Close samr connection handle
upon completion .
2007-04-29 16:31:09 +04:00
*/
2010-03-09 18:45:04 +03:00
static void continue_samr_enum_domains ( struct tevent_req * subreq )
2007-04-29 16:31:09 +04:00
{
struct composite_context * c ;
struct domain_list_state * s ;
2010-03-09 18:45:04 +03:00
c = tevent_req_callback_data ( subreq , struct composite_context ) ;
2012-03-01 14:02:24 +04:00
s = talloc_get_type_abort ( c - > private_data , struct domain_list_state ) ;
2007-04-29 16:31:09 +04:00
2010-03-09 18:45:04 +03:00
c - > status = dcerpc_samr_EnumDomains_r_recv ( subreq , s ) ;
TALLOC_FREE ( subreq ) ;
2007-04-29 16:31:09 +04:00
if ( ! composite_is_ok ( c ) ) return ;
2007-07-26 03:17:02 +04:00
if ( s - > monitor_fn ) {
struct monitor_msg msg ;
msg . type = mon_SamrEnumDomains ;
msg . data = NULL ;
msg . data_size = 0 ;
s - > monitor_fn ( & msg ) ;
}
2007-04-29 16:31:09 +04:00
if ( NT_STATUS_IS_OK ( s - > enumdom . out . result ) ) {
s - > domains = get_domain_list ( c , s ) ;
} else if ( NT_STATUS_EQUAL ( s - > enumdom . out . result , STATUS_MORE_ENTRIES ) ) {
s - > domains = get_domain_list ( c , s ) ;
2007-05-07 09:42:26 +04:00
/* prepare next round of enumeration */
2007-04-29 16:31:09 +04:00
s - > enumdom . in . connect_handle = & s - > connect_handle ;
s - > enumdom . in . resume_handle = & s - > resume_handle ;
2007-05-12 01:45:03 +04:00
s - > enumdom . in . buf_size = s - > ctx - > samr . buf_size ;
2007-04-29 16:31:09 +04:00
s - > enumdom . out . resume_handle = & s - > resume_handle ;
2007-05-07 09:42:26 +04:00
/* send the request */
2010-03-09 18:45:04 +03:00
subreq = dcerpc_samr_EnumDomains_r_send ( s , c - > event_ctx ,
s - > ctx - > samr . pipe - > binding_handle ,
& s - > enumdom ) ;
if ( composite_nomem ( subreq , c ) ) return ;
2007-04-29 16:31:09 +04:00
2010-03-09 18:45:04 +03:00
tevent_req_set_callback ( subreq , continue_samr_enum_domains , c ) ;
2007-04-29 16:31:09 +04:00
} else {
composite_error ( c , s - > enumdom . out . result ) ;
2007-05-07 09:42:26 +04:00
return ;
}
/* close samr connection handle */
s - > samrclose . in . handle = & s - > connect_handle ;
s - > samrclose . out . handle = & s - > connect_handle ;
/* send the request */
2010-03-09 18:45:04 +03:00
subreq = dcerpc_samr_Close_r_send ( s , c - > event_ctx ,
s - > ctx - > samr . pipe - > binding_handle ,
& s - > samrclose ) ;
if ( composite_nomem ( subreq , c ) ) return ;
2007-05-07 09:42:26 +04:00
2010-03-09 18:45:04 +03:00
tevent_req_set_callback ( subreq , continue_samr_close_handle , c ) ;
2007-05-07 09:42:26 +04:00
}
/*
Stage 4 : Receive result of closing samr connection handle .
*/
2010-03-09 18:45:04 +03:00
static void continue_samr_close_handle ( struct tevent_req * subreq )
2007-05-07 09:42:26 +04:00
{
struct composite_context * c ;
struct domain_list_state * s ;
2010-03-09 18:45:04 +03:00
c = tevent_req_callback_data ( subreq , struct composite_context ) ;
2012-03-01 14:02:24 +04:00
s = talloc_get_type_abort ( c - > private_data , struct domain_list_state ) ;
2007-05-07 09:42:26 +04:00
2010-03-09 18:45:04 +03:00
c - > status = dcerpc_samr_Close_r_recv ( subreq , s ) ;
TALLOC_FREE ( subreq ) ;
2007-05-07 09:42:26 +04:00
if ( ! composite_is_ok ( c ) ) return ;
2007-07-26 03:17:02 +04:00
if ( s - > monitor_fn ) {
struct monitor_msg msg ;
msg . type = mon_SamrClose ;
msg . data = NULL ;
msg . data_size = 0 ;
s - > monitor_fn ( & msg ) ;
}
2007-05-07 09:42:26 +04:00
/* did everything go fine ? */
if ( ! NT_STATUS_IS_OK ( s - > samrclose . out . result ) ) {
composite_error ( c , s - > samrclose . out . result ) ;
2012-04-23 11:27:02 +04:00
return ;
2007-04-29 16:31:09 +04:00
}
2007-05-07 09:42:26 +04:00
composite_done ( c ) ;
2007-04-29 16:31:09 +04:00
}
/*
Utility function to copy domain names from result of samr_EnumDomains call
*/
static struct domainlist * get_domain_list ( TALLOC_CTX * mem_ctx , struct domain_list_state * s )
{
2010-03-10 22:23:43 +03:00
uint32_t i ;
2007-04-29 16:31:09 +04:00
if ( mem_ctx = = NULL | | s = = NULL ) return NULL ;
2007-05-07 09:55:40 +04:00
/* prepare domains array */
2007-05-07 09:42:26 +04:00
if ( s - > domains = = NULL ) {
s - > domains = talloc_array ( mem_ctx , struct domainlist ,
2008-11-07 04:57:58 +03:00
* s - > enumdom . out . num_entries ) ;
2007-05-07 09:42:26 +04:00
} else {
s - > domains = talloc_realloc ( mem_ctx , s - > domains , struct domainlist ,
2008-11-07 04:57:58 +03:00
s - > count + * s - > enumdom . out . num_entries ) ;
2007-05-07 09:42:26 +04:00
}
2007-05-07 09:55:40 +04:00
/* copy domain names returned from samr_EnumDomains call */
2008-11-07 04:57:58 +03:00
for ( i = s - > count ; i < s - > count + * s - > enumdom . out . num_entries ; i + + )
2007-04-29 16:31:09 +04:00
{
2008-11-07 04:57:58 +03:00
struct lsa_String * domain_name = & ( * s - > enumdom . out . sam ) - > entries [ i - s - > count ] . name ;
2007-05-07 09:42:26 +04:00
2007-04-29 16:31:09 +04:00
/* strdup name as a child of allocated array to make it follow the array
in case of talloc_steal or talloc_free */
2007-05-07 09:42:26 +04:00
s - > domains [ i ] . name = talloc_strdup ( s - > domains , domain_name - > string ) ;
2007-04-29 16:31:09 +04:00
s - > domains [ i ] . sid = NULL ; /* this is to be filled out later */
}
2007-05-07 09:42:26 +04:00
/* number of entries returned (domains enumerated) */
2008-11-07 04:57:58 +03:00
s - > count + = * s - > enumdom . out . num_entries ;
2007-05-07 09:42:26 +04:00
2007-04-29 16:31:09 +04:00
return s - > domains ;
}
/**
* Sends a request to list domains on given host
*
2018-11-28 01:10:17 +03:00
* @ param ctx initialised libnet context
2007-04-29 16:31:09 +04:00
* @ param mem_ctx memory context
* @ param io arguments and results of the call
* @ param monitor pointer to monitor function that is passed monitor messages
*/
struct composite_context * libnet_DomainList_send ( struct libnet_context * ctx ,
TALLOC_CTX * mem_ctx ,
struct libnet_DomainList * io ,
void ( * monitor ) ( struct monitor_msg * ) )
{
struct composite_context * c ;
struct domain_list_state * s ;
struct composite_context * rpcconn_req ;
2010-03-09 18:45:04 +03:00
struct tevent_req * subreq ;
2007-04-29 16:31:09 +04:00
/* composite context and state structure allocation */
c = composite_create ( ctx , ctx - > event_ctx ) ;
if ( c = = NULL ) return c ;
s = talloc_zero ( c , struct domain_list_state ) ;
if ( composite_nomem ( s , c ) ) return c ;
c - > private_data = s ;
s - > monitor_fn = monitor ;
s - > ctx = ctx ;
s - > hostname = talloc_strdup ( c , io - > in . hostname ) ;
if ( composite_nomem ( s - > hostname , c ) ) return c ;
2007-05-07 09:42:26 +04:00
/* check whether samr pipe has already been opened */
if ( ctx - > samr . pipe = = NULL ) {
2009-06-18 06:33:46 +04:00
ZERO_STRUCT ( s - > rpcconn ) ;
2007-05-07 09:42:26 +04:00
/* prepare rpc connect call */
s - > rpcconn . level = LIBNET_RPC_CONNECT_SERVER ;
s - > rpcconn . in . name = s - > hostname ;
2007-08-20 01:23:03 +04:00
s - > rpcconn . in . dcerpc_iface = & ndr_table_samr ;
2007-05-07 09:42:26 +04:00
2007-07-19 01:24:37 +04:00
rpcconn_req = libnet_RpcConnect_send ( ctx , c , & s - > rpcconn , s - > monitor_fn ) ;
2007-05-07 09:42:26 +04:00
if ( composite_nomem ( rpcconn_req , c ) ) return c ;
composite_continue ( c , rpcconn_req , continue_rpc_connect , c ) ;
2007-04-29 16:31:09 +04:00
2007-05-07 09:42:26 +04:00
} else {
/* prepare samr_Connect call */
s - > samrconn . in . system_name = 0 ;
s - > samrconn . in . access_mask = SEC_GENERIC_READ ;
s - > samrconn . out . connect_handle = & s - > connect_handle ;
2010-03-09 18:45:04 +03:00
subreq = dcerpc_samr_Connect_r_send ( s , c - > event_ctx ,
s - > ctx - > samr . pipe - > binding_handle ,
& s - > samrconn ) ;
if ( composite_nomem ( subreq , c ) ) return c ;
2007-05-07 09:42:26 +04:00
2010-03-09 18:45:04 +03:00
tevent_req_set_callback ( subreq , continue_samr_connect , c ) ;
2007-05-07 09:42:26 +04:00
}
2007-04-29 16:31:09 +04:00
return c ;
}
/**
* Receive result of domain list request
*
* @ param c composite context returned by DomainList_send function
* @ param ctx initialised libnet context
* @ param mem_ctx memory context of the call
* @ param io results and arguments of the call
*/
NTSTATUS libnet_DomainList_recv ( struct composite_context * c , struct libnet_context * ctx ,
TALLOC_CTX * mem_ctx , struct libnet_DomainList * io )
{
NTSTATUS status ;
struct domain_list_state * s ;
status = composite_wait ( c ) ;
2012-03-01 14:02:24 +04:00
s = talloc_get_type_abort ( c - > private_data , struct domain_list_state ) ;
2007-04-29 16:31:09 +04:00
if ( NT_STATUS_IS_OK ( status ) & & ctx & & mem_ctx & & io ) {
/* fetch the results to be returned by io structure */
io - > out . count = s - > count ;
io - > out . domains = talloc_steal ( mem_ctx , s - > domains ) ;
io - > out . error_string = talloc_asprintf ( mem_ctx , " Success " ) ;
} else if ( ! NT_STATUS_IS_OK ( status ) ) {
/* there was an error, so return description of the status code */
io - > out . error_string = talloc_asprintf ( mem_ctx , " Error: %s " , nt_errstr ( status ) ) ;
}
talloc_free ( c ) ;
return status ;
}
/**
* Synchronous version of DomainList call
*
* @ param ctx initialised libnet context
* @ param mem_ctx memory context for the call
* @ param io arguments and results of the call
* @ return nt status code of execution
*/
NTSTATUS libnet_DomainList ( struct libnet_context * ctx , TALLOC_CTX * mem_ctx ,
struct libnet_DomainList * io )
{
struct composite_context * c ;
c = libnet_DomainList_send ( ctx , mem_ctx , io , NULL ) ;
return libnet_DomainList_recv ( c , ctx , mem_ctx , io ) ;
}