2008-06-02 17:29:55 +02:00
/*
* Unix SMB / CIFS implementation .
* NetApi Samr Support
* Copyright ( C ) Guenther Deschner 2008
*
* 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 3 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 , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
2008-07-17 19:43:34 +02:00
# include "lib/netapi/netapi.h"
# include "lib/netapi/netapi_private.h"
2011-04-13 14:32:16 +02:00
# include "rpc_client/rpc_client.h"
2011-01-14 16:16:31 +01:00
# include "../librpc/gen_ndr/ndr_samr_c.h"
2010-05-18 18:25:50 +02:00
# include "rpc_client/cli_samr.h"
2010-08-19 23:15:22 +02:00
# include "rpc_client/init_lsa.h"
2010-10-12 15:27:50 +11:00
# include "../libcli/security/security.h"
2008-06-02 17:29:55 +02:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-07-17 19:43:34 +02:00
WERROR libnetapi_samr_open_domain ( struct libnetapi_ctx * mem_ctx ,
2008-06-02 23:55:45 +02:00
struct rpc_pipe_client * pipe_cli ,
uint32_t connect_mask ,
uint32_t domain_mask ,
struct policy_handle * connect_handle ,
struct policy_handle * domain_handle ,
struct dom_sid2 * * domain_sid )
2008-06-02 17:29:55 +02:00
{
2011-01-14 16:16:31 +01:00
NTSTATUS status , result ;
2008-06-02 23:55:45 +02:00
WERROR werr ;
2008-07-17 19:43:34 +02:00
struct libnetapi_private_ctx * priv ;
2008-06-02 17:29:55 +02:00
uint32_t resume_handle = 0 ;
uint32_t num_entries = 0 ;
struct samr_SamArray * sam = NULL ;
const char * domain_name = NULL ;
struct lsa_String lsa_domain_name ;
2015-03-23 17:11:31 +05:30
bool domain_found = false ;
2008-06-02 17:29:55 +02:00
int i ;
2011-01-14 16:16:31 +01:00
struct dcerpc_binding_handle * b = pipe_cli - > binding_handle ;
2008-06-02 17:29:55 +02:00
2008-07-17 19:43:34 +02:00
priv = talloc_get_type_abort ( mem_ctx - > private_data ,
struct libnetapi_private_ctx ) ;
if ( is_valid_policy_hnd ( & priv - > samr . connect_handle ) ) {
if ( ( priv - > samr . connect_mask & connect_mask ) = = connect_mask ) {
* connect_handle = priv - > samr . connect_handle ;
} else {
libnetapi_samr_close_connect_handle ( mem_ctx ,
& priv - > samr . connect_handle ) ;
}
}
if ( is_valid_policy_hnd ( & priv - > samr . domain_handle ) ) {
if ( ( priv - > samr . domain_mask & domain_mask ) = = domain_mask ) {
* domain_handle = priv - > samr . domain_handle ;
} else {
libnetapi_samr_close_domain_handle ( mem_ctx ,
& priv - > samr . domain_handle ) ;
}
}
if ( priv - > samr . domain_sid ) {
* domain_sid = priv - > samr . domain_sid ;
}
if ( is_valid_policy_hnd ( & priv - > samr . connect_handle ) & &
( ( priv - > samr . connect_mask & connect_mask ) = = connect_mask ) & &
is_valid_policy_hnd ( & priv - > samr . domain_handle ) & &
( priv - > samr . domain_mask & domain_mask ) = = domain_mask ) {
return WERR_OK ;
}
2008-06-02 17:29:55 +02:00
if ( ! is_valid_policy_hnd ( connect_handle ) ) {
2011-04-06 14:40:50 +02:00
status = dcerpc_try_samr_connects ( pipe_cli - > binding_handle , mem_ctx ,
pipe_cli - > srv_name_slash ,
2008-06-02 17:29:55 +02:00
connect_mask ,
2011-04-06 14:40:50 +02:00
connect_handle ,
& result ) ;
2021-07-25 10:26:30 +02:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-06-02 23:55:45 +02:00
werr = ntstatus_to_werror ( status ) ;
2008-06-02 17:29:55 +02:00
goto done ;
}
}
2011-01-14 16:16:31 +01:00
status = dcerpc_samr_EnumDomains ( b , mem_ctx ,
2008-06-02 17:29:55 +02:00
connect_handle ,
& resume_handle ,
& sam ,
0xffffffff ,
2011-01-14 16:16:31 +01:00
& num_entries ,
& result ) ;
2021-07-25 10:26:30 +02:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-06-02 23:55:45 +02:00
werr = ntstatus_to_werror ( status ) ;
2008-06-02 17:29:55 +02:00
goto done ;
}
for ( i = 0 ; i < num_entries ; i + + ) {
domain_name = sam - > entries [ i ] . name . string ;
if ( strequal ( domain_name , builtin_domain_name ( ) ) ) {
continue ;
}
domain_found = true ;
break ;
}
if ( ! domain_found ) {
2008-06-02 23:55:45 +02:00
werr = WERR_NO_SUCH_DOMAIN ;
2008-06-02 17:29:55 +02:00
goto done ;
}
init_lsa_String ( & lsa_domain_name , domain_name ) ;
2011-01-14 16:16:31 +01:00
status = dcerpc_samr_LookupDomain ( b , mem_ctx ,
2008-06-02 17:29:55 +02:00
connect_handle ,
& lsa_domain_name ,
2011-01-14 16:16:31 +01:00
domain_sid ,
& result ) ;
2021-07-25 10:26:30 +02:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-06-02 23:55:45 +02:00
werr = ntstatus_to_werror ( status ) ;
2008-06-02 17:29:55 +02:00
goto done ;
}
2011-01-14 16:16:31 +01:00
status = dcerpc_samr_OpenDomain ( b , mem_ctx ,
2008-06-02 17:29:55 +02:00
connect_handle ,
domain_mask ,
* domain_sid ,
2011-01-14 16:16:31 +01:00
domain_handle ,
& result ) ;
2021-07-25 10:26:30 +02:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-06-02 23:55:45 +02:00
werr = ntstatus_to_werror ( status ) ;
2008-06-02 17:29:55 +02:00
goto done ;
}
2008-07-17 19:43:34 +02:00
priv - > samr . cli = pipe_cli ;
priv - > samr . domain_name = domain_name ;
priv - > samr . domain_sid = * domain_sid ;
priv - > samr . connect_mask = connect_mask ;
priv - > samr . connect_handle = * connect_handle ;
priv - > samr . domain_mask = domain_mask ;
priv - > samr . domain_handle = * domain_handle ;
2008-06-02 23:55:45 +02:00
werr = WERR_OK ;
2008-06-02 17:29:55 +02:00
done :
2008-06-02 23:55:45 +02:00
return werr ;
2008-06-02 17:29:55 +02:00
}
2008-06-03 00:13:39 +02:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-07-17 20:16:10 +02:00
WERROR libnetapi_samr_open_builtin_domain ( struct libnetapi_ctx * mem_ctx ,
2008-06-03 00:13:39 +02:00
struct rpc_pipe_client * pipe_cli ,
uint32_t connect_mask ,
uint32_t builtin_mask ,
struct policy_handle * connect_handle ,
struct policy_handle * builtin_handle )
{
2011-01-14 16:16:31 +01:00
NTSTATUS status , result ;
2008-06-03 00:13:39 +02:00
WERROR werr ;
2008-07-17 20:16:10 +02:00
struct libnetapi_private_ctx * priv ;
2011-01-14 16:16:31 +01:00
struct dcerpc_binding_handle * b = pipe_cli - > binding_handle ;
2008-07-17 20:16:10 +02:00
priv = talloc_get_type_abort ( mem_ctx - > private_data ,
struct libnetapi_private_ctx ) ;
if ( is_valid_policy_hnd ( & priv - > samr . connect_handle ) ) {
if ( ( priv - > samr . connect_mask & connect_mask ) = = connect_mask ) {
* connect_handle = priv - > samr . connect_handle ;
} else {
libnetapi_samr_close_connect_handle ( mem_ctx ,
& priv - > samr . connect_handle ) ;
}
}
if ( is_valid_policy_hnd ( & priv - > samr . builtin_handle ) ) {
if ( ( priv - > samr . builtin_mask & builtin_mask ) = = builtin_mask ) {
* builtin_handle = priv - > samr . builtin_handle ;
} else {
libnetapi_samr_close_builtin_handle ( mem_ctx ,
& priv - > samr . builtin_handle ) ;
}
}
if ( is_valid_policy_hnd ( & priv - > samr . connect_handle ) & &
( ( priv - > samr . connect_mask & connect_mask ) = = connect_mask ) & &
is_valid_policy_hnd ( & priv - > samr . builtin_handle ) & &
( priv - > samr . builtin_mask & builtin_mask ) = = builtin_mask ) {
return WERR_OK ;
}
2008-06-03 00:13:39 +02:00
if ( ! is_valid_policy_hnd ( connect_handle ) ) {
2011-04-06 14:40:50 +02:00
status = dcerpc_try_samr_connects ( pipe_cli - > binding_handle , mem_ctx ,
pipe_cli - > srv_name_slash ,
2008-06-03 00:13:39 +02:00
connect_mask ,
2011-04-06 14:40:50 +02:00
connect_handle ,
& result ) ;
2021-07-25 10:26:30 +02:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-06-03 00:13:39 +02:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
}
2011-01-14 16:16:31 +01:00
status = dcerpc_samr_OpenDomain ( b , mem_ctx ,
2008-06-03 00:13:39 +02:00
connect_handle ,
builtin_mask ,
2011-05-05 13:42:05 -07:00
discard_const_p ( struct dom_sid , & global_sid_Builtin ) ,
2011-01-14 16:16:31 +01:00
builtin_handle ,
& result ) ;
2021-07-25 10:26:30 +02:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-06-03 00:13:39 +02:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
2008-07-17 20:16:10 +02:00
priv - > samr . cli = pipe_cli ;
priv - > samr . connect_mask = connect_mask ;
priv - > samr . connect_handle = * connect_handle ;
priv - > samr . builtin_mask = builtin_mask ;
priv - > samr . builtin_handle = * builtin_handle ;
2008-06-03 00:13:39 +02:00
werr = WERR_OK ;
done :
return werr ;
}
2008-07-17 19:47:59 +02:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void libnetapi_samr_close_domain_handle ( struct libnetapi_ctx * ctx ,
struct policy_handle * handle )
{
struct libnetapi_private_ctx * priv ;
2011-01-14 16:16:31 +01:00
struct dcerpc_binding_handle * b ;
NTSTATUS result ;
2008-07-17 19:47:59 +02:00
if ( ! is_valid_policy_hnd ( handle ) ) {
return ;
}
priv = talloc_get_type_abort ( ctx - > private_data ,
struct libnetapi_private_ctx ) ;
2012-03-18 16:54:21 +01:00
if ( ! ndr_policy_handle_equal ( handle , & priv - > samr . domain_handle ) ) {
2008-07-17 19:47:59 +02:00
return ;
}
2011-01-14 16:16:31 +01:00
b = priv - > samr . cli - > binding_handle ;
dcerpc_samr_Close ( b , ctx , handle , & result ) ;
2008-07-17 19:47:59 +02:00
ZERO_STRUCT ( priv - > samr . domain_handle ) ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-07-17 19:56:25 +02:00
void libnetapi_samr_close_builtin_handle ( struct libnetapi_ctx * ctx ,
struct policy_handle * handle )
{
struct libnetapi_private_ctx * priv ;
2011-01-14 16:16:31 +01:00
struct dcerpc_binding_handle * b ;
NTSTATUS result ;
2008-07-17 19:56:25 +02:00
if ( ! is_valid_policy_hnd ( handle ) ) {
return ;
}
priv = talloc_get_type_abort ( ctx - > private_data ,
struct libnetapi_private_ctx ) ;
2012-03-18 16:54:21 +01:00
if ( ! ndr_policy_handle_equal ( handle , & priv - > samr . builtin_handle ) ) {
2008-07-17 19:56:25 +02:00
return ;
}
2011-01-14 16:16:31 +01:00
b = priv - > samr . cli - > binding_handle ;
dcerpc_samr_Close ( b , ctx , handle , & result ) ;
2008-07-17 19:56:25 +02:00
ZERO_STRUCT ( priv - > samr . builtin_handle ) ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-07-17 19:47:59 +02:00
void libnetapi_samr_close_connect_handle ( struct libnetapi_ctx * ctx ,
struct policy_handle * handle )
{
struct libnetapi_private_ctx * priv ;
2011-01-14 16:16:31 +01:00
struct dcerpc_binding_handle * b ;
NTSTATUS result ;
2008-07-17 19:47:59 +02:00
if ( ! is_valid_policy_hnd ( handle ) ) {
return ;
}
priv = talloc_get_type_abort ( ctx - > private_data ,
struct libnetapi_private_ctx ) ;
2012-03-18 16:54:21 +01:00
if ( ! ndr_policy_handle_equal ( handle , & priv - > samr . connect_handle ) ) {
2008-07-17 19:47:59 +02:00
return ;
}
2011-01-14 16:16:31 +01:00
b = priv - > samr . cli - > binding_handle ;
dcerpc_samr_Close ( b , ctx , handle , & result ) ;
2008-07-17 19:47:59 +02:00
ZERO_STRUCT ( priv - > samr . connect_handle ) ;
}
2008-07-17 19:06:02 +02:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void libnetapi_samr_free ( struct libnetapi_ctx * ctx )
{
struct libnetapi_private_ctx * priv ;
if ( ! ctx - > private_data ) {
return ;
}
priv = talloc_get_type_abort ( ctx - > private_data ,
struct libnetapi_private_ctx ) ;
libnetapi_samr_close_domain_handle ( ctx , & priv - > samr . domain_handle ) ;
libnetapi_samr_close_builtin_handle ( ctx , & priv - > samr . builtin_handle ) ;
libnetapi_samr_close_connect_handle ( ctx , & priv - > samr . connect_handle ) ;
}