2010-06-07 12:18:01 +04:00
/*
* Unix SMB / CIFS implementation .
*
* Winbind rpc backend functions
*
* Copyright ( c ) 2000 - 2003 Tim Potter
* Copyright ( c ) 2001 Andrew Tridgell
* Copyright ( c ) 2005 Volker Lendecke
* Copyright ( c ) 2008 Guenther Deschner ( pidl conversion )
* Copyright ( c ) 2010 Andreas Schneider < asn @ samba . org >
*
* 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"
# include "winbindd.h"
2010-06-17 15:57:12 +04:00
# include "winbindd_rpc.h"
2016-12-27 15:52:00 +03:00
# include "lib/util_unixsids.h"
2011-04-13 16:32:16 +04:00
# include "rpc_client/rpc_client.h"
2011-01-18 14:43:02 +03:00
# include "../librpc/gen_ndr/ndr_samr_c.h"
2010-06-07 12:18:01 +04:00
# include "rpc_client/cli_samr.h"
2011-01-18 20:02:27 +03:00
# include "../librpc/gen_ndr/ndr_lsa_c.h"
2010-06-07 12:18:01 +04:00
# include "rpc_client/cli_lsarpc.h"
2010-07-06 23:29:32 +04:00
# include "rpc_server/rpc_ncacn_np.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2011-03-22 18:50:02 +03:00
# include "passdb/machine_sid.h"
2011-03-25 04:28:05 +03:00
# include "auth.h"
2010-06-07 12:18:01 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_WINBIND
2010-07-06 19:02:33 +04:00
NTSTATUS open_internal_samr_conn ( TALLOC_CTX * mem_ctx ,
struct winbindd_domain * domain ,
struct rpc_pipe_client * * samr_pipe ,
struct policy_handle * samr_domain_hnd )
2010-06-07 12:18:01 +04:00
{
2011-01-18 14:43:02 +03:00
NTSTATUS status , result ;
2010-06-07 12:18:01 +04:00
struct policy_handle samr_connect_hnd ;
2011-01-18 14:43:02 +03:00
struct dcerpc_binding_handle * b ;
2010-06-07 12:18:01 +04:00
2014-05-16 10:10:23 +04:00
status = wb_open_internal_pipe ( mem_ctx , & ndr_table_samr , samr_pipe ) ;
2010-06-07 12:18:01 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2011-01-18 14:43:02 +03:00
b = ( * samr_pipe ) - > binding_handle ;
status = dcerpc_samr_Connect2 ( b , mem_ctx ,
2010-06-07 12:18:01 +04:00
( * samr_pipe ) - > desthost ,
SEC_FLAG_MAXIMUM_ALLOWED ,
2011-01-18 14:43:02 +03:00
& samr_connect_hnd ,
& result ) ;
2010-06-07 12:18:01 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2011-01-18 14:43:02 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
return result ;
}
2010-06-07 12:18:01 +04:00
2011-01-18 14:43:02 +03:00
status = dcerpc_samr_OpenDomain ( b , mem_ctx ,
2010-06-07 12:18:01 +04:00
& samr_connect_hnd ,
SEC_FLAG_MAXIMUM_ALLOWED ,
& domain - > sid ,
2011-01-18 14:43:02 +03:00
samr_domain_hnd ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2010-06-07 12:18:01 +04:00
2011-01-18 14:43:02 +03:00
return result ;
2010-06-07 12:18:01 +04:00
}
2015-02-03 18:22:25 +03:00
NTSTATUS open_internal_lsa_conn ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * * lsa_pipe ,
struct policy_handle * lsa_hnd )
2010-06-07 12:18:01 +04:00
{
NTSTATUS status ;
2014-05-16 10:10:23 +04:00
status = wb_open_internal_pipe ( mem_ctx , & ndr_table_lsarpc , lsa_pipe ) ;
2010-06-07 12:18:01 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
status = rpccli_lsa_open_policy ( ( * lsa_pipe ) ,
mem_ctx ,
true ,
SEC_FLAG_MAXIMUM_ALLOWED ,
lsa_hnd ) ;
return status ;
}
/*********************************************************************
SAM specific functions .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* List all domain groups */
static NTSTATUS sam_enum_dom_groups ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2010-06-07 18:39:44 +04:00
uint32_t * pnum_info ,
2011-03-22 19:43:39 +03:00
struct wb_acct_info * * pinfo )
2010-06-07 12:18:01 +04:00
{
2010-06-07 18:39:44 +04:00
struct rpc_pipe_client * samr_pipe ;
2017-01-03 12:54:33 +03:00
struct policy_handle dom_pol = { 0 } ;
2011-03-22 19:43:39 +03:00
struct wb_acct_info * info = NULL ;
2010-06-07 18:39:44 +04:00
uint32_t num_info = 0 ;
2010-06-17 15:57:12 +04:00
TALLOC_CTX * tmp_ctx ;
2011-01-18 14:43:02 +03:00
NTSTATUS status , result ;
struct dcerpc_binding_handle * b = NULL ;
2010-06-07 18:39:44 +04:00
2010-06-17 15:57:12 +04:00
DEBUG ( 3 , ( " sam_enum_dom_groups \n " ) ) ;
2010-06-07 18:39:44 +04:00
if ( pnum_info ) {
* pnum_info = 0 ;
}
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
status = open_internal_samr_conn ( tmp_ctx , domain , & samr_pipe , & dom_pol ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto error ;
}
2011-01-18 14:43:02 +03:00
b = samr_pipe - > binding_handle ;
2010-06-17 15:57:12 +04:00
status = rpc_enum_dom_groups ( tmp_ctx ,
samr_pipe ,
& dom_pol ,
& num_info ,
& info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto error ;
}
2010-06-07 18:39:44 +04:00
if ( pnum_info ) {
* pnum_info = num_info ;
}
if ( pinfo ) {
* pinfo = talloc_move ( mem_ctx , & info ) ;
}
error :
2011-01-18 14:43:02 +03:00
if ( b & & is_valid_policy_hnd ( & dom_pol ) ) {
dcerpc_samr_Close ( b , mem_ctx , & dom_pol , & result ) ;
2010-07-06 03:05:39 +04:00
}
2010-06-07 18:39:44 +04:00
TALLOC_FREE ( tmp_ctx ) ;
return status ;
2010-06-07 12:18:01 +04:00
}
/* Query display info for a domain */
static NTSTATUS sam_query_user_list ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2017-01-03 15:11:30 +03:00
uint32_t * * prids )
2010-06-07 12:18:01 +04:00
{
2010-06-07 18:18:12 +04:00
struct rpc_pipe_client * samr_pipe = NULL ;
2017-01-03 12:54:33 +03:00
struct policy_handle dom_pol = { 0 } ;
2017-01-03 15:11:30 +03:00
uint32_t * rids ;
2010-06-07 18:18:12 +04:00
TALLOC_CTX * tmp_ctx ;
2011-01-18 14:43:02 +03:00
NTSTATUS status , result ;
struct dcerpc_binding_handle * b = NULL ;
2010-06-07 18:18:12 +04:00
2010-06-17 16:55:19 +04:00
DEBUG ( 3 , ( " samr_query_user_list \n " ) ) ;
2010-06-07 18:18:12 +04:00
2017-01-03 15:11:30 +03:00
* prids = NULL ;
2010-06-07 18:18:12 +04:00
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
status = open_internal_samr_conn ( tmp_ctx , domain , & samr_pipe , & dom_pol ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-06-17 16:55:19 +04:00
goto done ;
2010-06-07 18:18:12 +04:00
}
2011-01-18 14:43:02 +03:00
b = samr_pipe - > binding_handle ;
2010-06-17 16:55:19 +04:00
status = rpc_query_user_list ( tmp_ctx ,
samr_pipe ,
& dom_pol ,
& domain - > sid ,
2017-01-03 15:11:30 +03:00
& rids ) ;
2010-06-17 16:55:19 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
2010-06-07 18:18:12 +04:00
2017-01-03 15:11:30 +03:00
if ( prids ) {
* prids = talloc_move ( mem_ctx , & rids ) ;
2010-06-07 18:18:12 +04:00
}
2010-06-17 16:55:19 +04:00
done :
2011-01-18 14:43:02 +03:00
if ( b & & is_valid_policy_hnd ( & dom_pol ) ) {
dcerpc_samr_Close ( b , mem_ctx , & dom_pol , & result ) ;
2010-07-06 03:05:39 +04:00
}
2010-06-07 18:18:12 +04:00
TALLOC_FREE ( tmp_ctx ) ;
return status ;
2010-06-07 12:18:01 +04:00
}
/* get a list of trusted domains - builtin domain */
static NTSTATUS sam_trusted_domains ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2010-06-21 13:13:50 +04:00
struct netr_DomainTrustList * ptrust_list )
2010-06-07 12:18:01 +04:00
{
2010-06-07 23:46:02 +04:00
struct rpc_pipe_client * lsa_pipe ;
2017-01-03 12:54:33 +03:00
struct policy_handle lsa_policy = { 0 } ;
2010-06-21 13:13:50 +04:00
struct netr_DomainTrust * trusts = NULL ;
uint32_t num_trusts = 0 ;
2010-06-07 23:46:02 +04:00
TALLOC_CTX * tmp_ctx ;
2011-01-18 20:02:27 +03:00
NTSTATUS status , result ;
struct dcerpc_binding_handle * b = NULL ;
2010-06-07 23:46:02 +04:00
DEBUG ( 3 , ( " samr: trusted domains \n " ) ) ;
2010-06-21 13:13:50 +04:00
if ( ptrust_list ) {
ZERO_STRUCTP ( ptrust_list ) ;
}
2010-06-07 23:46:02 +04:00
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
status = open_internal_lsa_conn ( tmp_ctx , & lsa_pipe , & lsa_policy ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-06-21 13:13:50 +04:00
goto done ;
2010-06-07 23:46:02 +04:00
}
2011-01-18 20:02:27 +03:00
b = lsa_pipe - > binding_handle ;
2010-06-21 13:13:50 +04:00
status = rpc_trusted_domains ( tmp_ctx ,
lsa_pipe ,
& lsa_policy ,
& num_trusts ,
& trusts ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
2010-06-07 23:46:02 +04:00
2010-06-21 13:13:50 +04:00
if ( ptrust_list ) {
ptrust_list - > count = num_trusts ;
ptrust_list - > array = talloc_move ( mem_ctx , & trusts ) ;
2010-06-07 23:46:02 +04:00
}
2010-06-21 13:13:50 +04:00
done :
2011-01-18 20:02:27 +03:00
if ( b & & is_valid_policy_hnd ( & lsa_policy ) ) {
dcerpc_lsa_Close ( b , mem_ctx , & lsa_policy , & result ) ;
2010-07-06 03:05:39 +04:00
}
2010-06-07 23:46:02 +04:00
TALLOC_FREE ( tmp_ctx ) ;
return status ;
2010-06-07 12:18:01 +04:00
}
/* Lookup group membership given a rid. */
static NTSTATUS sam_lookup_groupmem ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
const struct dom_sid * group_sid ,
enum lsa_SidType type ,
2010-06-08 00:15:37 +04:00
uint32_t * pnum_names ,
struct dom_sid * * psid_mem ,
char * * * pnames ,
uint32_t * * pname_types )
2010-06-07 12:18:01 +04:00
{
2010-06-08 00:15:37 +04:00
struct rpc_pipe_client * samr_pipe ;
2017-01-03 12:54:33 +03:00
struct policy_handle dom_pol = { 0 } ;
2010-06-08 00:15:37 +04:00
uint32_t num_names = 0 ;
struct dom_sid * sid_mem = NULL ;
char * * names = NULL ;
uint32_t * name_types = NULL ;
TALLOC_CTX * tmp_ctx ;
2011-01-18 14:43:02 +03:00
NTSTATUS status , result ;
struct dcerpc_binding_handle * b = NULL ;
2010-06-08 00:15:37 +04:00
2010-06-21 12:28:47 +04:00
DEBUG ( 3 , ( " sam_lookup_groupmem \n " ) ) ;
2010-06-08 00:15:37 +04:00
2010-06-21 12:28:47 +04:00
/* Paranoia check */
if ( sid_check_is_in_builtin ( group_sid ) & & ( type ! = SID_NAME_ALIAS ) ) {
/* There's no groups, only aliases in BUILTIN */
return NT_STATUS_NO_SUCH_GROUP ;
2010-06-08 00:15:37 +04:00
}
2010-06-21 12:28:47 +04:00
if ( pnum_names ) {
2011-03-16 23:29:02 +03:00
* pnum_names = 0 ;
2010-06-08 00:15:37 +04:00
}
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
status = open_internal_samr_conn ( tmp_ctx , domain , & samr_pipe , & dom_pol ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-06-21 12:28:47 +04:00
goto done ;
2010-06-08 00:15:37 +04:00
}
2011-01-18 14:43:02 +03:00
b = samr_pipe - > binding_handle ;
2010-06-21 12:28:47 +04:00
status = rpc_lookup_groupmem ( tmp_ctx ,
samr_pipe ,
& dom_pol ,
domain - > name ,
& domain - > sid ,
group_sid ,
type ,
& num_names ,
& sid_mem ,
& names ,
& name_types ) ;
2010-06-08 00:15:37 +04:00
if ( pnum_names ) {
2010-06-21 12:28:47 +04:00
* pnum_names = num_names ;
2010-06-08 00:15:37 +04:00
}
if ( pnames ) {
* pnames = talloc_move ( mem_ctx , & names ) ;
}
if ( pname_types ) {
* pname_types = talloc_move ( mem_ctx , & name_types ) ;
}
if ( psid_mem ) {
* psid_mem = talloc_move ( mem_ctx , & sid_mem ) ;
}
2010-06-21 12:28:47 +04:00
done :
2011-01-18 14:43:02 +03:00
if ( b & & is_valid_policy_hnd ( & dom_pol ) ) {
dcerpc_samr_Close ( b , mem_ctx , & dom_pol , & result ) ;
2010-07-06 03:05:39 +04:00
}
2010-06-08 00:15:37 +04:00
TALLOC_FREE ( tmp_ctx ) ;
return status ;
2010-06-07 12:18:01 +04:00
}
/*********************************************************************
BUILTIN specific functions .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* List all domain groups */
static NTSTATUS builtin_enum_dom_groups ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2015-04-24 05:04:23 +03:00
uint32_t * num_entries ,
2011-03-22 19:43:39 +03:00
struct wb_acct_info * * info )
2010-06-07 12:18:01 +04:00
{
/* BUILTIN doesn't have domain groups */
* num_entries = 0 ;
* info = NULL ;
return NT_STATUS_OK ;
}
/* Query display info for a domain */
static NTSTATUS builtin_query_user_list ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2017-01-03 15:11:30 +03:00
uint32_t * * rids )
2010-06-07 12:18:01 +04:00
{
/* We don't have users */
2017-01-03 15:11:30 +03:00
* rids = NULL ;
2010-06-07 12:18:01 +04:00
return NT_STATUS_OK ;
}
/* get a list of trusted domains - builtin domain */
static NTSTATUS builtin_trusted_domains ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
struct netr_DomainTrustList * trusts )
{
ZERO_STRUCTP ( trusts ) ;
return NT_STATUS_OK ;
}
/*********************************************************************
COMMON functions .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* List all local groups (aliases) */
2010-06-17 17:53:06 +04:00
static NTSTATUS sam_enum_local_groups ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
uint32_t * pnum_info ,
2011-03-22 19:43:39 +03:00
struct wb_acct_info * * pinfo )
2010-06-07 12:18:01 +04:00
{
2010-06-08 10:47:13 +04:00
struct rpc_pipe_client * samr_pipe ;
2017-01-03 12:54:33 +03:00
struct policy_handle dom_pol = { 0 } ;
2011-03-22 19:43:39 +03:00
struct wb_acct_info * info = NULL ;
2010-06-08 10:47:13 +04:00
uint32_t num_info = 0 ;
TALLOC_CTX * tmp_ctx ;
2011-01-18 14:43:02 +03:00
NTSTATUS status , result ;
struct dcerpc_binding_handle * b = NULL ;
2010-06-08 10:47:13 +04:00
DEBUG ( 3 , ( " samr: enum local groups \n " ) ) ;
if ( pnum_info ) {
* pnum_info = 0 ;
}
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
status = open_internal_samr_conn ( tmp_ctx , domain , & samr_pipe , & dom_pol ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-06-17 17:53:06 +04:00
goto done ;
2010-06-08 10:47:13 +04:00
}
2011-01-18 14:43:02 +03:00
b = samr_pipe - > binding_handle ;
2010-06-17 17:53:06 +04:00
status = rpc_enum_local_groups ( mem_ctx ,
samr_pipe ,
& dom_pol ,
& num_info ,
& info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
2010-06-08 10:47:13 +04:00
if ( pnum_info ) {
* pnum_info = num_info ;
}
if ( pinfo ) {
* pinfo = talloc_move ( mem_ctx , & info ) ;
}
2010-06-17 17:53:06 +04:00
done :
2011-01-18 14:43:02 +03:00
if ( b & & is_valid_policy_hnd ( & dom_pol ) ) {
dcerpc_samr_Close ( b , mem_ctx , & dom_pol , & result ) ;
2010-07-06 03:05:39 +04:00
}
2010-06-08 10:47:13 +04:00
TALLOC_FREE ( tmp_ctx ) ;
return status ;
2010-06-07 12:18:01 +04:00
}
/* convert a single name to a sid in a domain */
2010-06-17 18:07:02 +04:00
static NTSTATUS sam_name_to_sid ( struct winbindd_domain * domain ,
2010-06-07 12:18:01 +04:00
TALLOC_CTX * mem_ctx ,
const char * domain_name ,
const char * name ,
uint32_t flags ,
2010-06-17 18:07:02 +04:00
struct dom_sid * psid ,
enum lsa_SidType * ptype )
2010-06-07 12:18:01 +04:00
{
2010-06-08 16:42:59 +04:00
struct rpc_pipe_client * lsa_pipe ;
2017-01-03 12:54:33 +03:00
struct policy_handle lsa_policy = { 0 } ;
2010-06-17 18:07:02 +04:00
struct dom_sid sid ;
enum lsa_SidType type ;
2010-06-08 16:42:59 +04:00
TALLOC_CTX * tmp_ctx ;
2011-01-18 20:02:27 +03:00
NTSTATUS status , result ;
struct dcerpc_binding_handle * b = NULL ;
2010-06-08 16:42:59 +04:00
2010-06-17 18:07:02 +04:00
DEBUG ( 3 , ( " sam_name_to_sid \n " ) ) ;
2010-06-08 16:42:59 +04:00
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
status = open_internal_lsa_conn ( tmp_ctx , & lsa_pipe , & lsa_policy ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-06-17 18:07:02 +04:00
goto done ;
2010-06-08 16:42:59 +04:00
}
2011-01-18 20:02:27 +03:00
b = lsa_pipe - > binding_handle ;
2010-06-17 18:07:02 +04:00
status = rpc_name_to_sid ( tmp_ctx ,
lsa_pipe ,
& lsa_policy ,
domain_name ,
name ,
flags ,
& sid ,
& type ) ;
2010-06-08 16:42:59 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-06-17 18:07:02 +04:00
goto done ;
2010-06-08 16:42:59 +04:00
}
2010-06-17 18:07:02 +04:00
if ( psid ) {
sid_copy ( psid , & sid ) ;
2010-06-08 16:42:59 +04:00
}
2010-06-17 18:07:02 +04:00
if ( ptype ) {
* ptype = type ;
2010-06-08 16:42:59 +04:00
}
2010-06-17 18:07:02 +04:00
done :
2011-01-18 20:02:27 +03:00
if ( b & & is_valid_policy_hnd ( & lsa_policy ) ) {
dcerpc_lsa_Close ( b , mem_ctx , & lsa_policy , & result ) ;
2010-07-06 03:05:39 +04:00
}
2010-06-08 16:42:59 +04:00
TALLOC_FREE ( tmp_ctx ) ;
return status ;
2010-06-07 12:18:01 +04:00
}
/* convert a domain SID to a user or group name */
2010-06-17 18:25:33 +04:00
static NTSTATUS sam_sid_to_name ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
const struct dom_sid * sid ,
char * * pdomain_name ,
char * * pname ,
enum lsa_SidType * ptype )
2010-06-07 12:18:01 +04:00
{
2010-06-09 13:52:26 +04:00
struct rpc_pipe_client * lsa_pipe ;
2017-01-03 12:54:33 +03:00
struct policy_handle lsa_policy = { 0 } ;
2010-06-17 18:25:33 +04:00
char * domain_name = NULL ;
char * name = NULL ;
enum lsa_SidType type ;
2010-06-09 13:52:26 +04:00
TALLOC_CTX * tmp_ctx ;
2011-01-18 20:02:27 +03:00
NTSTATUS status , result ;
struct dcerpc_binding_handle * b = NULL ;
2010-06-09 13:52:26 +04:00
2010-06-17 18:25:33 +04:00
DEBUG ( 3 , ( " sam_sid_to_name \n " ) ) ;
/* Paranoia check */
if ( ! sid_check_is_in_builtin ( sid ) & &
2014-02-20 19:50:32 +04:00
! sid_check_is_builtin ( sid ) & &
2012-07-12 18:00:59 +04:00
! sid_check_is_in_our_sam ( sid ) & &
2014-02-20 19:50:32 +04:00
! sid_check_is_our_sam ( sid ) & &
2010-06-17 18:25:33 +04:00
! sid_check_is_in_unix_users ( sid ) & &
! sid_check_is_unix_users ( sid ) & &
! sid_check_is_in_unix_groups ( sid ) & &
! sid_check_is_unix_groups ( sid ) & &
! sid_check_is_in_wellknown_domain ( sid ) ) {
DEBUG ( 0 , ( " sam_sid_to_name: possible deadlock - trying to "
" lookup SID %s \n " , sid_string_dbg ( sid ) ) ) ;
return NT_STATUS_NONE_MAPPED ;
}
2010-06-09 13:52:26 +04:00
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
status = open_internal_lsa_conn ( tmp_ctx , & lsa_pipe , & lsa_policy ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-06-17 18:25:33 +04:00
goto done ;
2010-06-09 13:52:26 +04:00
}
2011-01-18 20:02:27 +03:00
b = lsa_pipe - > binding_handle ;
2010-06-17 18:25:33 +04:00
status = rpc_sid_to_name ( tmp_ctx ,
lsa_pipe ,
& lsa_policy ,
domain ,
sid ,
& domain_name ,
& name ,
& type ) ;
2010-06-09 13:52:26 +04:00
2010-06-17 18:25:33 +04:00
if ( ptype ) {
* ptype = type ;
2010-06-09 13:52:26 +04:00
}
2010-06-17 18:25:33 +04:00
if ( pname ) {
* pname = talloc_move ( mem_ctx , & name ) ;
2010-06-09 13:52:26 +04:00
}
2010-06-17 18:25:33 +04:00
if ( pdomain_name ) {
* pdomain_name = talloc_move ( mem_ctx , & domain_name ) ;
2010-06-09 13:52:26 +04:00
}
2010-06-17 18:25:33 +04:00
done :
2011-01-18 20:02:27 +03:00
if ( b & & is_valid_policy_hnd ( & lsa_policy ) ) {
dcerpc_lsa_Close ( b , mem_ctx , & lsa_policy , & result ) ;
2010-07-06 03:05:39 +04:00
}
2010-06-09 13:52:26 +04:00
TALLOC_FREE ( tmp_ctx ) ;
return status ;
2010-06-07 12:18:01 +04:00
}
2010-06-17 21:32:18 +04:00
static NTSTATUS sam_rids_to_names ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2011-03-10 18:23:20 +03:00
const struct dom_sid * domain_sid ,
2015-04-24 05:04:23 +03:00
uint32_t * rids ,
2010-06-17 21:32:18 +04:00
size_t num_rids ,
char * * pdomain_name ,
char * * * pnames ,
enum lsa_SidType * * ptypes )
2010-06-07 12:18:01 +04:00
{
2010-06-09 16:33:02 +04:00
struct rpc_pipe_client * lsa_pipe ;
2017-01-03 12:54:33 +03:00
struct policy_handle lsa_policy = { 0 } ;
2010-06-09 16:33:02 +04:00
enum lsa_SidType * types = NULL ;
char * domain_name = NULL ;
char * * names = NULL ;
TALLOC_CTX * tmp_ctx ;
2011-01-18 20:02:27 +03:00
NTSTATUS status , result ;
struct dcerpc_binding_handle * b = NULL ;
2010-06-09 16:33:02 +04:00
2010-06-17 21:32:18 +04:00
DEBUG ( 3 , ( " sam_rids_to_names for %s \n " , domain - > name ) ) ;
/* Paranoia check */
2011-06-16 20:40:04 +04:00
if ( ! sid_check_is_builtin ( domain_sid ) & &
2012-07-12 17:55:21 +04:00
! sid_check_is_our_sam ( domain_sid ) & &
2011-03-10 18:23:20 +03:00
! sid_check_is_unix_users ( domain_sid ) & &
! sid_check_is_unix_groups ( domain_sid ) & &
! sid_check_is_in_wellknown_domain ( domain_sid ) ) {
2010-06-17 21:32:18 +04:00
DEBUG ( 0 , ( " sam_rids_to_names: possible deadlock - trying to "
2011-03-10 18:23:20 +03:00
" lookup SID %s \n " , sid_string_dbg ( domain_sid ) ) ) ;
2010-06-17 21:32:18 +04:00
return NT_STATUS_NONE_MAPPED ;
}
2010-06-09 16:33:02 +04:00
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
status = open_internal_lsa_conn ( tmp_ctx , & lsa_pipe , & lsa_policy ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-06-17 21:32:18 +04:00
goto done ;
2010-06-09 16:33:02 +04:00
}
2011-01-18 20:02:27 +03:00
b = lsa_pipe - > binding_handle ;
2010-06-17 21:32:18 +04:00
status = rpc_rids_to_names ( tmp_ctx ,
lsa_pipe ,
& lsa_policy ,
domain ,
2011-03-10 18:23:20 +03:00
domain_sid ,
2010-06-17 21:32:18 +04:00
rids ,
num_rids ,
& domain_name ,
& names ,
& types ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
2010-06-09 16:33:02 +04:00
}
if ( pdomain_name ) {
2010-06-17 21:32:18 +04:00
* pdomain_name = talloc_move ( mem_ctx , & domain_name ) ;
2010-06-09 16:33:02 +04:00
}
if ( ptypes ) {
* ptypes = talloc_move ( mem_ctx , & types ) ;
}
if ( pnames ) {
* pnames = talloc_move ( mem_ctx , & names ) ;
}
2010-06-17 21:32:18 +04:00
done :
2011-01-18 20:02:27 +03:00
if ( b & & is_valid_policy_hnd ( & lsa_policy ) ) {
dcerpc_lsa_Close ( b , mem_ctx , & lsa_policy , & result ) ;
2010-07-06 03:05:39 +04:00
}
2010-06-09 16:33:02 +04:00
TALLOC_FREE ( tmp_ctx ) ;
return status ;
2010-06-07 12:18:01 +04:00
}
2010-06-21 12:53:15 +04:00
static NTSTATUS sam_lockout_policy ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
struct samr_DomInfo12 * lockout_policy )
2010-06-07 12:18:01 +04:00
{
2010-06-09 16:39:55 +04:00
struct rpc_pipe_client * samr_pipe ;
2017-01-03 12:54:33 +03:00
struct policy_handle dom_pol = { 0 } ;
2010-06-09 16:39:55 +04:00
union samr_DomainInfo * info = NULL ;
TALLOC_CTX * tmp_ctx ;
2011-01-18 14:43:02 +03:00
NTSTATUS status , result ;
struct dcerpc_binding_handle * b = NULL ;
2010-06-09 16:39:55 +04:00
2010-06-21 12:53:15 +04:00
DEBUG ( 3 , ( " sam_lockout_policy \n " ) ) ;
2010-06-09 16:39:55 +04:00
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
status = open_internal_samr_conn ( tmp_ctx , domain , & samr_pipe , & dom_pol ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto error ;
}
2011-01-18 14:43:02 +03:00
b = samr_pipe - > binding_handle ;
status = dcerpc_samr_QueryDomainInfo ( b ,
2010-06-09 16:39:55 +04:00
mem_ctx ,
& dom_pol ,
2011-08-26 18:35:29 +04:00
DomainLockoutInformation ,
2011-01-18 14:43:02 +03:00
& info ,
& result ) ;
2010-06-09 16:39:55 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto error ;
}
2011-01-18 14:43:02 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
status = result ;
goto error ;
}
2010-06-09 16:39:55 +04:00
* lockout_policy = info - > info12 ;
error :
2011-01-18 14:43:02 +03:00
if ( b & & is_valid_policy_hnd ( & dom_pol ) ) {
dcerpc_samr_Close ( b , mem_ctx , & dom_pol , & result ) ;
2010-07-06 03:05:39 +04:00
}
2010-06-09 16:39:55 +04:00
TALLOC_FREE ( tmp_ctx ) ;
return status ;
2010-06-07 12:18:01 +04:00
}
2010-06-21 12:54:53 +04:00
static NTSTATUS sam_password_policy ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
struct samr_DomInfo1 * passwd_policy )
2010-06-07 12:18:01 +04:00
{
2010-06-09 16:41:54 +04:00
struct rpc_pipe_client * samr_pipe ;
2017-01-03 12:54:33 +03:00
struct policy_handle dom_pol = { 0 } ;
2010-06-09 16:41:54 +04:00
union samr_DomainInfo * info = NULL ;
TALLOC_CTX * tmp_ctx ;
2011-01-18 14:43:02 +03:00
NTSTATUS status , result ;
struct dcerpc_binding_handle * b = NULL ;
2010-06-09 16:41:54 +04:00
2010-06-21 12:54:53 +04:00
DEBUG ( 3 , ( " sam_password_policy \n " ) ) ;
2010-06-09 16:41:54 +04:00
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
status = open_internal_samr_conn ( tmp_ctx , domain , & samr_pipe , & dom_pol ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto error ;
}
2011-01-18 14:43:02 +03:00
b = samr_pipe - > binding_handle ;
status = dcerpc_samr_QueryDomainInfo ( b ,
2010-06-09 16:41:54 +04:00
mem_ctx ,
& dom_pol ,
2011-08-26 18:35:29 +04:00
DomainPasswordInformation ,
2011-01-18 14:43:02 +03:00
& info ,
& result ) ;
2010-06-09 16:41:54 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto error ;
}
2011-01-18 14:43:02 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
status = result ;
goto error ;
}
2010-06-09 16:41:54 +04:00
* passwd_policy = info - > info1 ;
error :
2011-01-18 14:43:02 +03:00
if ( b & & is_valid_policy_hnd ( & dom_pol ) ) {
dcerpc_samr_Close ( b , mem_ctx , & dom_pol , & result ) ;
2010-07-06 03:05:39 +04:00
}
2010-06-09 16:41:54 +04:00
TALLOC_FREE ( tmp_ctx ) ;
return status ;
2010-06-07 12:18:01 +04:00
}
2010-06-18 21:08:28 +04:00
static NTSTATUS sam_lookup_useraliases ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
uint32_t num_sids ,
const struct dom_sid * sids ,
uint32_t * pnum_aliases ,
uint32_t * * palias_rids )
2010-06-07 12:18:01 +04:00
{
2010-06-09 17:12:37 +04:00
struct rpc_pipe_client * samr_pipe ;
2017-01-03 12:54:33 +03:00
struct policy_handle dom_pol = { 0 } ;
2010-06-09 17:12:37 +04:00
uint32_t num_aliases = 0 ;
2010-06-18 21:08:28 +04:00
uint32_t * alias_rids = NULL ;
2010-06-09 17:12:37 +04:00
TALLOC_CTX * tmp_ctx ;
2011-01-18 14:43:02 +03:00
NTSTATUS status , result ;
struct dcerpc_binding_handle * b = NULL ;
2010-06-09 17:12:37 +04:00
2010-06-18 21:08:28 +04:00
DEBUG ( 3 , ( " sam_lookup_useraliases \n " ) ) ;
2010-06-09 17:12:37 +04:00
if ( pnum_aliases ) {
* pnum_aliases = 0 ;
}
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
status = open_internal_samr_conn ( tmp_ctx , domain , & samr_pipe , & dom_pol ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-06-18 21:08:28 +04:00
goto done ;
2010-06-09 17:12:37 +04:00
}
2011-01-18 14:43:02 +03:00
b = samr_pipe - > binding_handle ;
2010-06-18 21:08:28 +04:00
status = rpc_lookup_useraliases ( tmp_ctx ,
samr_pipe ,
& dom_pol ,
num_sids ,
sids ,
& num_aliases ,
& alias_rids ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
2010-06-09 17:12:37 +04:00
if ( pnum_aliases ) {
* pnum_aliases = num_aliases ;
}
2010-06-18 21:08:28 +04:00
if ( palias_rids ) {
* palias_rids = talloc_move ( mem_ctx , & alias_rids ) ;
}
done :
2011-01-18 14:43:02 +03:00
if ( b & & is_valid_policy_hnd ( & dom_pol ) ) {
dcerpc_samr_Close ( b , mem_ctx , & dom_pol , & result ) ;
2010-07-06 03:05:39 +04:00
}
2010-06-09 17:12:37 +04:00
TALLOC_FREE ( tmp_ctx ) ;
return status ;
2010-06-07 12:18:01 +04:00
}
/* find the sequence number for a domain */
2010-06-21 12:47:54 +04:00
static NTSTATUS sam_sequence_number ( struct winbindd_domain * domain ,
uint32_t * pseq )
2010-06-07 12:18:01 +04:00
{
2010-06-09 17:20:13 +04:00
struct rpc_pipe_client * samr_pipe ;
2017-01-03 12:54:33 +03:00
struct policy_handle dom_pol = { 0 } ;
2015-05-03 12:20:42 +03:00
uint32_t seq = DOM_SEQUENCE_NONE ;
2010-06-21 12:47:54 +04:00
TALLOC_CTX * tmp_ctx ;
2011-01-18 14:43:02 +03:00
NTSTATUS status , result ;
struct dcerpc_binding_handle * b = NULL ;
2010-06-09 17:20:13 +04:00
DEBUG ( 3 , ( " samr: sequence number \n " ) ) ;
2010-06-21 12:47:54 +04:00
if ( pseq ) {
* pseq = DOM_SEQUENCE_NONE ;
2010-06-09 17:20:13 +04:00
}
2010-06-21 12:47:54 +04:00
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
2010-06-09 17:20:13 +04:00
}
2010-06-21 12:47:54 +04:00
status = open_internal_samr_conn ( tmp_ctx , domain , & samr_pipe , & dom_pol ) ;
2010-06-09 17:20:13 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-06-21 12:47:54 +04:00
goto done ;
2010-06-09 17:20:13 +04:00
}
2011-01-18 14:43:02 +03:00
b = samr_pipe - > binding_handle ;
2010-06-21 12:47:54 +04:00
status = rpc_sequence_number ( tmp_ctx ,
samr_pipe ,
& dom_pol ,
domain - > name ,
& seq ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
2010-06-09 17:20:13 +04:00
}
2010-06-21 12:47:54 +04:00
if ( pseq ) {
* pseq = seq ;
2010-06-09 17:20:13 +04:00
}
2010-06-21 12:47:54 +04:00
done :
2011-01-18 14:43:02 +03:00
if ( b & & is_valid_policy_hnd ( & dom_pol ) ) {
dcerpc_samr_Close ( b , tmp_ctx , & dom_pol , & result ) ;
2010-07-06 03:05:39 +04:00
}
2010-06-21 12:47:54 +04:00
TALLOC_FREE ( tmp_ctx ) ;
2010-06-09 17:20:13 +04:00
return status ;
2010-06-07 12:18:01 +04:00
}
/* the rpc backend methods are exposed via this structure */
struct winbindd_methods builtin_passdb_methods = {
. consistent = false ,
. query_user_list = builtin_query_user_list ,
. enum_dom_groups = builtin_enum_dom_groups ,
2010-06-17 17:53:06 +04:00
. enum_local_groups = sam_enum_local_groups ,
2010-06-17 18:07:02 +04:00
. name_to_sid = sam_name_to_sid ,
2010-06-17 18:25:33 +04:00
. sid_to_name = sam_sid_to_name ,
2010-06-17 21:32:18 +04:00
. rids_to_names = sam_rids_to_names ,
2010-06-18 21:08:28 +04:00
. lookup_useraliases = sam_lookup_useraliases ,
2010-06-07 12:18:01 +04:00
. lookup_groupmem = sam_lookup_groupmem ,
2010-06-21 12:47:54 +04:00
. sequence_number = sam_sequence_number ,
2010-06-21 12:53:15 +04:00
. lockout_policy = sam_lockout_policy ,
2010-06-21 12:54:53 +04:00
. password_policy = sam_password_policy ,
2010-06-07 12:18:01 +04:00
. trusted_domains = builtin_trusted_domains
} ;
/* the rpc backend methods are exposed via this structure */
struct winbindd_methods sam_passdb_methods = {
. consistent = false ,
. query_user_list = sam_query_user_list ,
. enum_dom_groups = sam_enum_dom_groups ,
2010-06-17 17:53:06 +04:00
. enum_local_groups = sam_enum_local_groups ,
2010-06-17 18:07:02 +04:00
. name_to_sid = sam_name_to_sid ,
2010-06-17 18:25:33 +04:00
. sid_to_name = sam_sid_to_name ,
2010-06-17 21:32:18 +04:00
. rids_to_names = sam_rids_to_names ,
2010-06-18 21:08:28 +04:00
. lookup_useraliases = sam_lookup_useraliases ,
2010-06-07 12:18:01 +04:00
. lookup_groupmem = sam_lookup_groupmem ,
2010-06-21 12:47:54 +04:00
. sequence_number = sam_sequence_number ,
2010-06-21 12:53:15 +04:00
. lockout_policy = sam_lockout_policy ,
2010-06-21 12:54:53 +04:00
. password_policy = sam_password_policy ,
2010-06-07 12:18:01 +04:00
. trusted_domains = sam_trusted_domains
} ;