2001-12-03 04:23:42 +03:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2001-12-03 04:23:42 +03:00
Winbind rpc backend functions
2003-04-23 15:54:56 +04:00
Copyright ( C ) Tim Potter 2000 - 2001 , 2003
2001-12-03 04:23:42 +03:00
Copyright ( C ) Andrew Tridgell 2001
2005-01-15 22:00:18 +03:00
Copyright ( C ) Volker Lendecke 2005
2008-02-27 21:38:48 +03:00
Copyright ( C ) Guenther Deschner 2008 ( pidl conversion )
2009-08-03 00:28:49 +04:00
2001-12-03 04:23:42 +03:00
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-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2001-12-03 04:23:42 +03:00
( at your option ) any later version .
2009-08-03 00:28:49 +04:00
2001-12-03 04:23:42 +03:00
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 .
2009-08-03 00:28:49 +04:00
2001-12-03 04:23:42 +03:00
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2001-12-03 04:23:42 +03:00
*/
2003-11-12 04:51:10 +03:00
# include "includes.h"
2001-12-03 04:23:42 +03:00
# include "winbindd.h"
2010-06-17 15:56:54 +04:00
# include "winbindd_rpc.h"
2011-01-18 16:06:48 +03:00
# include "../librpc/gen_ndr/ndr_samr_c.h"
2011-02-28 12:19:44 +03:00
# include "rpc_client/cli_pipe.h"
2010-05-18 20:25:50 +04:00
# include "rpc_client/cli_samr.h"
2010-05-18 20:26:16 +04:00
# include "rpc_client/cli_lsarpc.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2016-11-29 18:41:27 +03:00
# include "libsmb/samlogon_cache.h"
2001-12-03 04:23:42 +03:00
2002-07-15 14:35:28 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_WINBIND
2011-09-06 20:33:35 +04:00
static NTSTATUS winbindd_lookup_names ( TALLOC_CTX * mem_ctx ,
struct winbindd_domain * domain ,
uint32_t num_names ,
const char * * names ,
const char * * * domains ,
struct dom_sid * * sids ,
enum lsa_SidType * * types ) ;
2003-04-23 15:54:56 +04:00
2001-12-03 04:23:42 +03:00
/* Query display info for a domain. This returns enough information plus a
bit extra to give an overview of domain users for the User Manager
application . */
2010-06-17 16:54:55 +04:00
static NTSTATUS msrpc_query_user_list ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2017-01-03 15:11:30 +03:00
uint32_t * * prids )
2001-12-03 04:23:42 +03:00
{
2010-06-17 16:54:55 +04:00
struct rpc_pipe_client * samr_pipe = NULL ;
2009-03-19 00:49:41 +03:00
struct policy_handle dom_pol ;
2017-01-17 16:39:03 +03:00
uint32_t * rids = NULL ;
2010-06-17 16:54:55 +04:00
TALLOC_CTX * tmp_ctx ;
NTSTATUS status ;
2001-12-03 04:23:42 +03:00
2010-07-06 12:58:46 +04:00
DEBUG ( 3 , ( " msrpc_query_user_list \n " ) ) ;
2002-07-15 14:35:28 +04:00
2010-06-17 16:54:55 +04:00
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2001-12-11 01:10:16 +03:00
2007-05-07 00:16:12 +04:00
if ( ! winbindd_can_contact_domain ( domain ) ) {
DEBUG ( 10 , ( " query_user_list: No incoming trust for domain %s \n " ,
domain - > name ) ) ;
2010-06-17 16:54:55 +04:00
status = NT_STATUS_OK ;
goto done ;
2007-05-07 00:16:12 +04:00
}
2014-05-26 03:58:38 +04:00
status = cm_connect_sam ( domain , tmp_ctx , false , & samr_pipe , & dom_pol ) ;
2010-06-17 16:54:55 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
2001-12-11 03:03:58 +03:00
2010-06-17 16:54:55 +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:54:55 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
2001-12-11 03:03:58 +03:00
2017-01-03 15:11:30 +03:00
if ( prids ) {
* prids = talloc_move ( mem_ctx , & rids ) ;
2010-06-17 16:54:55 +04:00
}
2001-12-03 04:23:42 +03:00
2010-06-17 16:54:55 +04:00
done :
2017-01-10 16:24:22 +03:00
TALLOC_FREE ( rids ) ;
2010-06-17 16:54:55 +04:00
TALLOC_FREE ( tmp_ctx ) ;
return status ;
2001-12-03 04:23:42 +03:00
}
/* list all domain groups */
2010-06-17 15:56:54 +04:00
static NTSTATUS msrpc_enum_dom_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 )
2001-12-03 04:23:42 +03:00
{
2010-06-17 15:56:54 +04:00
struct rpc_pipe_client * samr_pipe ;
2009-03-19 00:49:41 +03:00
struct policy_handle dom_pol ;
2011-03-22 19:43:39 +03:00
struct wb_acct_info * info = NULL ;
2010-06-17 15:56:54 +04:00
uint32_t num_info = 0 ;
TALLOC_CTX * tmp_ctx ;
2001-12-03 04:23:42 +03:00
NTSTATUS status ;
2010-06-17 15:56:54 +04:00
DEBUG ( 3 , ( " msrpc_enum_dom_groups \n " ) ) ;
if ( pnum_info ) {
* pnum_info = 0 ;
}
2001-12-03 04:23:42 +03:00
2010-06-17 15:56:54 +04:00
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2002-07-15 14:35:28 +04:00
2007-05-07 00:16:12 +04:00
if ( ! winbindd_can_contact_domain ( domain ) ) {
DEBUG ( 10 , ( " enum_domain_groups: No incoming trust for domain %s \n " ,
domain - > name ) ) ;
2010-06-17 15:56:54 +04:00
status = NT_STATUS_OK ;
goto done ;
2007-05-07 00:16:12 +04:00
}
2014-05-26 03:58:38 +04:00
status = cm_connect_sam ( domain , tmp_ctx , false , & samr_pipe , & dom_pol ) ;
2010-06-17 15:56:54 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
2001-12-11 04:04:13 +03:00
2010-06-17 15:56:54 +04:00
status = rpc_enum_dom_groups ( tmp_ctx ,
samr_pipe ,
& dom_pol ,
& num_info ,
& info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
2008-02-13 13:08:49 +03:00
2010-06-17 15:56:54 +04:00
if ( pnum_info ) {
* pnum_info = num_info ;
}
2008-02-13 13:08:49 +03:00
2010-06-17 15:56:54 +04:00
if ( pinfo ) {
* pinfo = talloc_move ( mem_ctx , & info ) ;
}
2001-12-03 04:23:42 +03:00
2010-06-17 15:56:54 +04:00
done :
TALLOC_FREE ( tmp_ctx ) ;
2010-01-06 10:05:20 +03:00
return status ;
2001-12-03 04:23:42 +03:00
}
2002-10-08 22:32:42 +04:00
/* List all domain groups */
2010-06-17 17:52:44 +04:00
static NTSTATUS msrpc_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 )
2002-10-08 22:32:42 +04:00
{
2010-06-17 17:52:44 +04:00
struct rpc_pipe_client * samr_pipe ;
2009-03-19 00:49:41 +03:00
struct policy_handle dom_pol ;
2011-03-22 19:43:39 +03:00
struct wb_acct_info * info = NULL ;
2010-06-17 17:52:44 +04:00
uint32_t num_info = 0 ;
TALLOC_CTX * tmp_ctx ;
NTSTATUS status ;
2002-10-08 22:32:42 +04:00
2010-06-17 17:52:44 +04:00
DEBUG ( 3 , ( " msrpc_enum_local_groups \n " ) ) ;
2002-10-08 22:32:42 +04:00
2010-06-17 17:52:44 +04:00
if ( pnum_info ) {
* pnum_info = 0 ;
}
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2002-10-08 22:32:42 +04:00
2007-05-07 00:16:12 +04:00
if ( ! winbindd_can_contact_domain ( domain ) ) {
DEBUG ( 10 , ( " enum_local_groups: No incoming trust for domain %s \n " ,
domain - > name ) ) ;
2010-06-17 17:52:44 +04:00
status = NT_STATUS_OK ;
goto done ;
2007-05-07 00:16:12 +04:00
}
2014-05-26 03:58:38 +04:00
status = cm_connect_sam ( domain , tmp_ctx , false , & samr_pipe , & dom_pol ) ;
2010-06-17 17:52:44 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
2008-02-13 13:15:40 +03:00
2010-06-17 17:52:44 +04:00
status = rpc_enum_local_groups ( mem_ctx ,
samr_pipe ,
& dom_pol ,
& num_info ,
& info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
2008-02-13 13:15:40 +03:00
2010-06-17 17:52:44 +04:00
if ( pnum_info ) {
* pnum_info = num_info ;
}
2002-10-08 22:32:42 +04:00
2010-06-17 17:52:44 +04:00
if ( pinfo ) {
* pinfo = talloc_move ( mem_ctx , & info ) ;
}
2002-10-08 22:32:42 +04:00
2010-06-17 17:52:44 +04:00
done :
TALLOC_FREE ( tmp_ctx ) ;
return status ;
2002-10-08 22:32:42 +04:00
}
2001-12-03 11:17:46 +03:00
/* convert a single name to a sid in a domain */
2008-11-22 01:17:05 +03:00
static NTSTATUS msrpc_name_to_sid ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
const char * domain_name ,
const char * name ,
2009-08-02 12:43:05 +04:00
uint32_t flags ,
2019-03-12 02:11:01 +03:00
const char * * pdom_name ,
2010-05-21 05:25:01 +04:00
struct dom_sid * sid ,
2008-11-22 01:17:05 +03:00
enum lsa_SidType * type )
2001-12-03 11:17:46 +03:00
{
2003-06-21 08:05:01 +04:00
NTSTATUS result ;
2010-05-21 05:25:01 +04:00
struct dom_sid * sids = NULL ;
2006-09-08 18:28:06 +04:00
enum lsa_SidType * types = NULL ;
2007-02-01 18:22:08 +03:00
char * full_name = NULL ;
2014-02-26 23:16:26 +04:00
const char * names [ 1 ] ;
2019-03-12 01:53:51 +03:00
const char * * domains ;
2008-09-16 00:50:15 +04:00
NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL ;
char * mapped_name = NULL ;
2001-12-03 11:17:46 +03:00
2007-07-02 13:46:18 +04:00
if ( name = = NULL | | * name = = ' \0 ' ) {
full_name = talloc_asprintf ( mem_ctx , " %s " , domain_name ) ;
} else if ( domain_name = = NULL | | * domain_name = = ' \0 ' ) {
full_name = talloc_asprintf ( mem_ctx , " %s " , name ) ;
} else {
full_name = talloc_asprintf ( mem_ctx , " %s \\ %s " , domain_name , name ) ;
}
2002-01-26 14:48:42 +03:00
if ( ! full_name ) {
DEBUG ( 0 , ( " talloc_asprintf failed! \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
2010-07-06 12:58:46 +04:00
DEBUG ( 3 , ( " msrpc_name_to_sid: name=%s \n " , full_name ) ) ;
2007-07-02 13:46:18 +04:00
2008-09-16 00:50:15 +04:00
name_map_status = normalize_name_unmap ( mem_ctx , full_name ,
& mapped_name ) ;
2007-01-31 08:38:36 +03:00
2011-09-08 14:01:42 +04:00
/* Reset the full_name pointer if we mapped anything */
2008-09-16 00:50:15 +04:00
if ( NT_STATUS_IS_OK ( name_map_status ) | |
NT_STATUS_EQUAL ( name_map_status , NT_STATUS_FILE_RENAMED ) )
{
full_name = mapped_name ;
}
DEBUG ( 3 , ( " name_to_sid [rpc] %s for domain %s \n " ,
full_name ? full_name : " " , domain_name ) ) ;
2003-06-21 08:05:01 +04:00
2014-02-26 23:16:26 +04:00
names [ 0 ] = full_name ;
2009-09-17 10:06:34 +04:00
result = winbindd_lookup_names ( mem_ctx , domain , 1 ,
2019-03-12 01:53:51 +03:00
names , & domains ,
2009-09-17 10:06:34 +04:00
& sids , & types ) ;
2005-06-09 02:10:34 +04:00
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
2002-07-15 14:35:28 +04:00
/* Return rid and type if lookup successful */
2019-03-12 02:11:01 +03:00
if ( pdom_name ! = NULL ) {
const char * dom_name ;
dom_name = talloc_strdup ( mem_ctx , domains [ 0 ] ) ;
if ( dom_name = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
* pdom_name = dom_name ;
}
2005-06-09 02:10:34 +04:00
sid_copy ( sid , & sids [ 0 ] ) ;
2006-06-29 01:30:21 +04:00
* type = types [ 0 ] ;
2001-12-03 11:17:46 +03:00
2005-06-09 02:10:34 +04:00
return NT_STATUS_OK ;
2001-12-03 11:17:46 +03:00
}
2001-12-03 14:11:14 +03:00
/*
convert a domain SID to a user or group name
*/
2008-11-22 01:17:05 +03:00
static NTSTATUS msrpc_sid_to_name ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * sid ,
2008-11-22 01:17:05 +03:00
char * * domain_name ,
char * * name ,
enum lsa_SidType * type )
2001-12-03 14:11:14 +03:00
{
2002-01-20 04:24:59 +03:00
char * * domains ;
2001-12-03 14:11:14 +03:00
char * * names ;
2008-01-12 09:44:33 +03:00
enum lsa_SidType * types = NULL ;
2003-06-21 08:05:01 +04:00
NTSTATUS result ;
2008-09-16 00:50:15 +04:00
NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL ;
char * mapped_name = NULL ;
2018-12-14 23:09:51 +03:00
struct dom_sid_buf buf ;
2001-12-03 14:11:14 +03:00
2018-12-14 23:09:51 +03:00
DEBUG ( 3 , ( " msrpc_sid_to_name: %s for domain %s \n " ,
dom_sid_str_buf ( sid , & buf ) ,
domain - > name ) ) ;
2002-07-15 14:35:28 +04:00
2009-09-17 09:59:25 +04:00
result = winbindd_lookup_sids ( mem_ctx ,
domain ,
1 ,
sid ,
& domains ,
& names ,
& types ) ;
2007-05-07 00:16:12 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2009-09-17 09:59:25 +04:00
DEBUG ( 2 , ( " msrpc_sid_to_name: failed to lookup sids: %s \n " ,
nt_errstr ( result ) ) ) ;
2005-06-09 02:10:34 +04:00
return result ;
2007-05-07 00:16:12 +04:00
}
2009-08-03 00:28:49 +04:00
2001-12-03 14:11:14 +03:00
2006-09-08 18:28:06 +04:00
* type = ( enum lsa_SidType ) types [ 0 ] ;
2005-06-09 02:10:34 +04:00
* domain_name = domains [ 0 ] ;
* name = names [ 0 ] ;
2007-01-31 08:38:36 +03:00
2005-06-09 02:10:34 +04:00
DEBUG ( 5 , ( " Mapped sid to [%s] \\ [%s] \n " , domains [ 0 ] , * name ) ) ;
2008-09-16 00:50:15 +04:00
2017-11-27 14:42:44 +03:00
name_map_status = normalize_name_map ( mem_ctx , domain - > name , * name ,
2008-09-16 00:50:15 +04:00
& mapped_name ) ;
if ( NT_STATUS_IS_OK ( name_map_status ) | |
NT_STATUS_EQUAL ( name_map_status , NT_STATUS_FILE_RENAMED ) )
{
* name = mapped_name ;
DEBUG ( 5 , ( " returning mapped name -- %s \n " , * name ) ) ;
}
2005-06-09 02:10:34 +04:00
return NT_STATUS_OK ;
2001-12-03 14:11:14 +03:00
}
2008-11-22 01:17:05 +03:00
static NTSTATUS msrpc_rids_to_names ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * sid ,
2015-04-24 05:04:23 +03:00
uint32_t * rids ,
2008-11-22 01:17:05 +03:00
size_t num_rids ,
char * * domain_name ,
char * * * names ,
enum lsa_SidType * * types )
2006-07-11 22:01:26 +04:00
{
char * * domains ;
NTSTATUS result ;
2010-05-21 05:25:01 +04:00
struct dom_sid * sids ;
2006-07-11 22:01:26 +04:00
size_t i ;
2007-01-31 08:38:36 +03:00
char * * ret_names ;
2006-07-11 22:01:26 +04:00
2010-07-06 12:58:46 +04:00
DEBUG ( 3 , ( " msrpc_rids_to_names: domain %s \n " , domain - > name ) ) ;
2006-07-11 22:01:26 +04:00
2007-04-30 06:39:34 +04:00
if ( num_rids ) {
2011-06-07 05:30:12 +04:00
sids = talloc_array ( mem_ctx , struct dom_sid , num_rids ) ;
2007-04-30 06:39:34 +04:00
if ( sids = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
} else {
sids = NULL ;
2006-07-11 22:01:26 +04:00
}
for ( i = 0 ; i < num_rids ; i + + ) {
if ( ! sid_compose ( & sids [ i ] , sid , rids [ i ] ) ) {
return NT_STATUS_INTERNAL_ERROR ;
}
}
2009-09-17 09:59:25 +04:00
result = winbindd_lookup_sids ( mem_ctx ,
domain ,
num_rids ,
sids ,
& domains ,
names ,
types ) ;
2009-08-11 15:50:16 +04:00
2006-07-11 22:01:26 +04:00
if ( ! NT_STATUS_IS_OK ( result ) & &
! NT_STATUS_EQUAL ( result , STATUS_SOME_UNMAPPED ) ) {
return result ;
}
2007-01-31 08:38:36 +03:00
ret_names = * names ;
2006-07-11 22:01:26 +04:00
for ( i = 0 ; i < num_rids ; i + + ) {
2008-09-16 00:50:15 +04:00
NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL ;
char * mapped_name = NULL ;
2006-07-11 22:01:26 +04:00
if ( ( * types ) [ i ] ! = SID_NAME_UNKNOWN ) {
2008-09-16 00:50:15 +04:00
name_map_status = normalize_name_map ( mem_ctx ,
2017-11-27 14:42:44 +03:00
domain - > name ,
2008-09-16 00:50:15 +04:00
ret_names [ i ] ,
& mapped_name ) ;
if ( NT_STATUS_IS_OK ( name_map_status ) | |
NT_STATUS_EQUAL ( name_map_status , NT_STATUS_FILE_RENAMED ) )
{
ret_names [ i ] = mapped_name ;
}
2006-07-11 22:01:26 +04:00
* domain_name = domains [ i ] ;
}
}
return result ;
}
2017-03-02 16:53:47 +03:00
/* Lookup groups a user is a member of. I wish Unix had a call like this! */
static NTSTATUS msrpc_lookup_usergroups ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
const struct dom_sid * user_sid ,
uint32_t * pnum_groups ,
struct dom_sid * * puser_grpsids )
{
struct rpc_pipe_client * samr_pipe ;
struct policy_handle dom_pol ;
struct dom_sid * user_grpsids = NULL ;
2018-12-14 23:09:51 +03:00
struct dom_sid_buf buf ;
2017-03-02 16:53:47 +03:00
uint32_t num_groups = 0 ;
TALLOC_CTX * tmp_ctx ;
NTSTATUS status ;
2018-12-14 23:09:51 +03:00
DEBUG ( 3 , ( " msrpc_lookup_usergroups sid=%s \n " ,
dom_sid_str_buf ( user_sid , & buf ) ) ) ;
2017-03-02 16:53:47 +03:00
* pnum_groups = 0 ;
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
/* Check if we have a cached user_info_3 */
status = lookup_usergroups_cached ( tmp_ctx ,
user_sid ,
& num_groups ,
& user_grpsids ) ;
if ( NT_STATUS_IS_OK ( status ) ) {
goto cached ;
}
if ( ! winbindd_can_contact_domain ( domain ) ) {
DEBUG ( 10 , ( " lookup_usergroups: No incoming trust for domain %s \n " ,
domain - > name ) ) ;
/* Tell the cache manager not to remember this one */
status = NT_STATUS_SYNCHRONIZATION_REQUIRED ;
goto done ;
}
/* no cache; hit the wire */
status = cm_connect_sam ( domain , tmp_ctx , false , & samr_pipe , & dom_pol ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
status = rpc_lookup_usergroups ( tmp_ctx ,
samr_pipe ,
& dom_pol ,
& domain - > sid ,
user_sid ,
& num_groups ,
& user_grpsids ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
cached :
* pnum_groups = num_groups ;
if ( puser_grpsids ) {
* puser_grpsids = talloc_move ( mem_ctx , & user_grpsids ) ;
}
done :
TALLOC_FREE ( tmp_ctx ) ;
return status ;
return NT_STATUS_OK ;
}
2008-11-05 15:39:25 +03:00
# define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
2008-11-22 01:17:05 +03:00
static NTSTATUS msrpc_lookup_useraliases ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2015-04-24 05:04:23 +03:00
uint32_t num_sids , const struct dom_sid * sids ,
uint32_t * pnum_aliases ,
uint32_t * * palias_rids )
2005-01-15 22:00:18 +03:00
{
2010-06-18 21:08:41 +04:00
struct rpc_pipe_client * samr_pipe ;
2009-03-19 00:49:41 +03:00
struct policy_handle dom_pol ;
2010-06-18 21:08:41 +04:00
uint32_t num_aliases = 0 ;
uint32_t * alias_rids = NULL ;
TALLOC_CTX * tmp_ctx ;
NTSTATUS status ;
2005-01-15 22:00:18 +03:00
2010-06-18 21:08:41 +04:00
DEBUG ( 3 , ( " msrpc_lookup_useraliases \n " ) ) ;
2005-01-15 22:00:18 +03:00
2010-06-18 21:08:41 +04:00
if ( pnum_aliases ) {
* pnum_aliases = 0 ;
}
2005-01-15 22:00:18 +03:00
2010-06-18 21:08:41 +04:00
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
if ( ! winbindd_can_contact_domain ( domain ) ) {
2007-05-07 00:16:12 +04:00
DEBUG ( 10 , ( " msrpc_lookup_useraliases: No incoming trust for domain %s \n " ,
domain - > name ) ) ;
2010-07-07 16:27:04 +04:00
/* Tell the cache manager not to remember this one */
status = NT_STATUS_SYNCHRONIZATION_REQUIRED ;
2010-06-18 21:08:41 +04:00
goto done ;
2007-05-07 00:16:12 +04:00
}
2014-05-26 03:58:38 +04:00
status = cm_connect_sam ( domain , tmp_ctx , false , & samr_pipe , & dom_pol ) ;
2010-06-18 21:08:41 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
2006-06-19 20:00:32 +04:00
2010-06-18 21:08:41 +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 ;
}
2006-06-19 20:00:32 +04:00
2010-06-18 21:08:41 +04:00
if ( pnum_aliases ) {
* pnum_aliases = num_aliases ;
}
2005-01-15 22:00:18 +03:00
2010-06-18 21:08:41 +04:00
if ( palias_rids ) {
* palias_rids = talloc_move ( mem_ctx , & alias_rids ) ;
}
2005-01-15 22:00:18 +03:00
2010-06-18 21:08:41 +04:00
done :
TALLOC_FREE ( tmp_ctx ) ;
return status ;
2005-01-15 22:00:18 +03:00
}
2001-12-03 04:23:42 +03:00
2001-12-05 07:48:51 +03:00
/* Lookup group membership given a rid. */
2010-06-21 13:15:18 +04:00
static NTSTATUS msrpc_lookup_groupmem ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
const struct dom_sid * group_sid ,
enum lsa_SidType type ,
uint32_t * num_names ,
struct dom_sid * * sid_mem ,
char * * * names ,
uint32_t * * name_types )
2001-12-05 07:48:51 +03:00
{
2011-01-18 16:06:48 +03:00
NTSTATUS status , result ;
2015-04-24 05:04:23 +03:00
uint32_t i , total_names = 0 ;
2009-03-19 00:49:41 +03:00
struct policy_handle dom_pol , group_pol ;
2015-04-24 05:04:23 +03:00
uint32_t des_access = SEC_FLAG_MAXIMUM_ALLOWED ;
uint32_t * rid_mem = NULL ;
uint32_t group_rid ;
2008-02-13 12:49:55 +03:00
unsigned int j , r ;
2005-06-09 02:10:34 +04:00
struct rpc_pipe_client * cli ;
2006-10-16 18:29:14 +04:00
unsigned int orig_timeout ;
2010-10-07 15:01:29 +04:00
struct samr_RidAttrArray * rids = NULL ;
2011-01-18 16:06:48 +03:00
struct dcerpc_binding_handle * b ;
2018-12-14 23:09:51 +03:00
struct dom_sid_buf buf ;
2001-12-05 07:48:51 +03:00
2010-07-06 12:58:46 +04:00
DEBUG ( 3 , ( " msrpc_lookup_groupmem: %s sid=%s \n " , domain - > name ,
2018-12-14 23:09:51 +03:00
dom_sid_str_buf ( group_sid , & buf ) ) ) ;
2003-04-23 15:54:56 +04:00
2007-05-07 00:16:12 +04:00
if ( ! winbindd_can_contact_domain ( domain ) ) {
DEBUG ( 10 , ( " lookup_groupmem: No incoming trust for domain %s \n " ,
domain - > name ) ) ;
return NT_STATUS_OK ;
}
2005-06-09 02:10:34 +04:00
if ( ! sid_peek_check_rid ( & domain - > sid , group_sid , & group_rid ) )
return NT_STATUS_UNSUCCESSFUL ;
2002-07-15 14:35:28 +04:00
2001-12-11 01:10:16 +03:00
* num_names = 0 ;
2014-05-26 03:58:38 +04:00
result = cm_connect_sam ( domain , mem_ctx , false , & cli , & dom_pol ) ;
2005-06-09 02:10:34 +04:00
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
2001-12-05 07:48:51 +03:00
2011-01-18 16:06:48 +03:00
b = cli - > binding_handle ;
status = dcerpc_samr_OpenGroup ( b , mem_ctx ,
2008-02-01 13:24:01 +03:00
& dom_pol ,
des_access ,
group_rid ,
2011-01-18 16:06:48 +03:00
& group_pol ,
& result ) ;
2017-03-09 20:57:14 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2011-01-18 16:06:48 +03:00
return status ;
}
2001-12-05 07:48:51 +03:00
/* Step #1: Get a list of user rids that are the members of the
group . */
2006-10-16 18:29:14 +04:00
/* This call can take a long time - allow the server to time out.
35 seconds should do it . */
2008-04-20 01:27:35 +04:00
orig_timeout = rpccli_set_timeout ( cli , 35000 ) ;
2006-10-16 18:29:14 +04:00
2011-01-18 16:06:48 +03:00
status = dcerpc_samr_QueryGroupMember ( b , mem_ctx ,
2008-02-05 12:58:37 +03:00
& group_pol ,
2011-01-18 16:06:48 +03:00
& rids ,
& result ) ;
2005-06-09 02:10:34 +04:00
2006-10-16 18:29:14 +04:00
/* And restore our original timeout. */
2008-04-20 01:27:35 +04:00
rpccli_set_timeout ( cli , orig_timeout ) ;
2006-10-16 18:29:14 +04:00
2011-01-18 16:06:48 +03:00
{
NTSTATUS _result ;
dcerpc_samr_Close ( b , mem_ctx , & group_pol , & _result ) ;
}
2017-03-09 20:57:14 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2011-01-18 16:06:48 +03:00
return status ;
}
2001-12-05 07:48:51 +03:00
2009-12-30 23:04:55 +03:00
if ( ! rids | | ! rids - > count ) {
2004-01-02 08:33:14 +03:00
names = NULL ;
name_types = NULL ;
sid_mem = NULL ;
2005-06-09 02:10:34 +04:00
return NT_STATUS_OK ;
2004-01-02 08:33:14 +03:00
}
2009-12-30 23:04:55 +03:00
* num_names = rids - > count ;
rid_mem = rids - > rids ;
2001-12-05 07:48:51 +03:00
/* Step #2: Convert list of rids into list of usernames. Do this
in bunches of ~ 1000 to avoid crashing NT4 . It looks like there
is a buffer overflow or something like that lurking around
somewhere . */
# define MAX_LOOKUP_RIDS 900
2011-06-07 05:58:39 +04:00
* names = talloc_zero_array ( mem_ctx , char * , * num_names ) ;
2015-04-24 05:04:23 +03:00
* name_types = talloc_zero_array ( mem_ctx , uint32_t , * num_names ) ;
2011-06-07 05:58:39 +04:00
* sid_mem = talloc_zero_array ( mem_ctx , struct dom_sid , * num_names ) ;
2003-04-23 15:54:56 +04:00
2005-06-09 02:10:34 +04:00
for ( j = 0 ; j < ( * num_names ) ; j + + )
sid_compose ( & ( * sid_mem ) [ j ] , & domain - > sid , rid_mem [ j ] ) ;
2009-08-03 00:28:49 +04:00
2005-06-09 02:10:34 +04:00
if ( * num_names > 0 & & ( ! * names | | ! * name_types ) )
return NT_STATUS_NO_MEMORY ;
2001-12-05 07:48:51 +03:00
2008-02-13 12:49:55 +03:00
for ( i = 0 ; i < * num_names ; i + = MAX_LOOKUP_RIDS ) {
int num_lookup_rids = MIN ( * num_names - i , MAX_LOOKUP_RIDS ) ;
struct lsa_Strings tmp_names ;
struct samr_Ids tmp_types ;
2001-12-05 07:48:51 +03:00
2008-02-13 12:49:55 +03:00
/* Lookup a chunk of rids */
2001-12-05 07:48:51 +03:00
2011-01-18 16:06:48 +03:00
status = dcerpc_samr_LookupRids ( b , mem_ctx ,
2008-02-13 12:49:55 +03:00
& dom_pol ,
num_lookup_rids ,
& rid_mem [ i ] ,
& tmp_names ,
2011-01-18 16:06:48 +03:00
& tmp_types ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2001-12-05 07:48:51 +03:00
2005-06-09 02:10:34 +04:00
/* see if we have a real error (and yes the
STATUS_SOME_UNMAPPED is the one returned from 2 k ) */
2008-02-13 12:49:55 +03:00
2005-06-09 02:10:34 +04:00
if ( ! NT_STATUS_IS_OK ( result ) & &
! NT_STATUS_EQUAL ( result , STATUS_SOME_UNMAPPED ) )
return result ;
2001-12-05 07:48:51 +03:00
2008-02-13 12:49:55 +03:00
/* Copy result into array. The talloc system will take
care of freeing the temporary arrays later on . */
2001-12-05 07:48:51 +03:00
2013-11-08 10:41:22 +04:00
if ( tmp_names . count ! = num_lookup_rids ) {
return NT_STATUS_INVALID_NETWORK_RESPONSE ;
}
if ( tmp_types . count ! = num_lookup_rids ) {
return NT_STATUS_INVALID_NETWORK_RESPONSE ;
2008-02-13 12:49:55 +03:00
}
for ( r = 0 ; r < tmp_names . count ; r + + ) {
2009-03-16 15:17:04 +03:00
if ( tmp_types . ids [ r ] = = SID_NAME_UNKNOWN ) {
continue ;
}
2013-11-08 10:41:22 +04:00
if ( total_names > = * num_names ) {
break ;
}
2009-03-16 15:17:04 +03:00
( * names ) [ total_names ] = fill_domain_username_talloc (
mem_ctx , domain - > name ,
tmp_names . names [ r ] . string , true ) ;
( * name_types ) [ total_names ] = tmp_types . ids [ r ] ;
total_names + = 1 ;
2008-02-13 12:49:55 +03:00
}
2001-12-05 07:48:51 +03:00
}
* num_names = total_names ;
2005-06-09 02:10:34 +04:00
return NT_STATUS_OK ;
2001-12-05 07:48:51 +03:00
}
2001-12-10 05:25:19 +03:00
/* get a list of trusted domains */
2010-06-21 13:14:12 +04:00
static NTSTATUS msrpc_trusted_domains ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
struct netr_DomainTrustList * ptrust_list )
2001-12-10 05:25:19 +03:00
{
2010-06-21 13:14:12 +04:00
struct rpc_pipe_client * lsa_pipe ;
2009-03-19 00:49:41 +03:00
struct policy_handle lsa_policy ;
2010-06-21 13:14:12 +04:00
struct netr_DomainTrust * trusts = NULL ;
uint32_t num_trusts = 0 ;
TALLOC_CTX * tmp_ctx ;
NTSTATUS status ;
2002-07-15 14:35:28 +04:00
2010-07-06 12:58:46 +04:00
DEBUG ( 3 , ( " msrpc_trusted_domains \n " ) ) ;
2009-12-28 17:51:36 +03:00
2010-06-21 13:14:12 +04:00
if ( ptrust_list ) {
ZERO_STRUCTP ( ptrust_list ) ;
}
2005-06-09 02:10:34 +04:00
2010-06-21 13:14:12 +04:00
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2009-12-28 17:51:36 +03:00
2010-06-21 13:14:12 +04:00
status = cm_connect_lsa ( domain , tmp_ctx , & lsa_pipe , & lsa_policy ) ;
2013-10-09 02:01:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
2009-12-28 17:51:36 +03:00
2010-06-21 13:14:12 +04:00
status = rpc_trusted_domains ( tmp_ctx ,
lsa_pipe ,
& lsa_policy ,
& num_trusts ,
& trusts ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
2009-12-28 17:51:36 +03:00
2010-06-21 13:14:12 +04:00
if ( ptrust_list ) {
ptrust_list - > count = num_trusts ;
ptrust_list - > array = talloc_move ( mem_ctx , & trusts ) ;
2005-06-09 02:10:34 +04:00
}
2010-06-21 13:14:12 +04:00
done :
TALLOC_FREE ( tmp_ctx ) ;
return status ;
2001-12-10 05:25:19 +03:00
}
2006-02-04 01:19:41 +03:00
/* find the lockout policy for a domain */
2008-11-22 01:17:05 +03:00
static NTSTATUS msrpc_lockout_policy ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
struct samr_DomInfo12 * lockout_policy )
2006-02-04 01:19:41 +03:00
{
2011-01-18 16:06:48 +03:00
NTSTATUS status , result ;
2006-02-04 01:19:41 +03:00
struct rpc_pipe_client * cli ;
2009-03-19 00:49:41 +03:00
struct policy_handle dom_pol ;
2008-02-05 19:25:07 +03:00
union samr_DomainInfo * info = NULL ;
2011-01-18 16:06:48 +03:00
struct dcerpc_binding_handle * b ;
2006-02-04 01:19:41 +03:00
2010-07-06 12:58:46 +04:00
DEBUG ( 3 , ( " msrpc_lockout_policy: fetch lockout policy for %s \n " , domain - > name ) ) ;
2006-02-04 01:19:41 +03:00
2007-05-07 00:16:12 +04:00
if ( ! winbindd_can_contact_domain ( domain ) ) {
DEBUG ( 10 , ( " msrpc_lockout_policy: No incoming trust for domain %s \n " ,
domain - > name ) ) ;
return NT_STATUS_NOT_SUPPORTED ;
}
2014-05-26 03:58:38 +04:00
status = cm_connect_sam ( domain , mem_ctx , false , & cli , & dom_pol ) ;
2011-01-18 16:06:48 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2006-02-04 01:19:41 +03:00
goto done ;
}
2011-01-18 16:06:48 +03:00
b = cli - > binding_handle ;
status = dcerpc_samr_QueryDomainInfo ( b , mem_ctx ,
2008-02-05 19:25:07 +03:00
& dom_pol ,
2011-03-30 13:08:31 +04:00
DomainLockoutInformation ,
2011-01-18 16:06:48 +03:00
& info ,
& result ) ;
2017-03-09 20:57:14 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
return status ;
2006-02-04 01:19:41 +03:00
}
2008-02-05 19:25:07 +03:00
* lockout_policy = info - > info12 ;
2006-02-04 01:19:41 +03:00
2008-02-05 19:25:07 +03:00
DEBUG ( 10 , ( " msrpc_lockout_policy: lockout_threshold %d \n " ,
info - > info12 . lockout_threshold ) ) ;
2006-02-04 01:19:41 +03:00
done :
2011-01-18 16:06:48 +03:00
return status ;
2006-02-04 01:19:41 +03:00
}
/* find the password policy for a domain */
2008-11-22 01:17:05 +03:00
static NTSTATUS msrpc_password_policy ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
struct samr_DomInfo1 * password_policy )
2006-02-04 01:19:41 +03:00
{
2011-01-18 16:06:48 +03:00
NTSTATUS status , result ;
2006-02-04 01:19:41 +03:00
struct rpc_pipe_client * cli ;
2009-03-19 00:49:41 +03:00
struct policy_handle dom_pol ;
2008-02-05 19:25:07 +03:00
union samr_DomainInfo * info = NULL ;
2011-01-18 16:06:48 +03:00
struct dcerpc_binding_handle * b ;
2006-02-04 01:19:41 +03:00
2010-07-06 12:58:46 +04:00
DEBUG ( 3 , ( " msrpc_password_policy: fetch password policy for %s \n " ,
domain - > name ) ) ;
2006-02-04 01:19:41 +03:00
2007-05-07 00:16:12 +04:00
if ( ! winbindd_can_contact_domain ( domain ) ) {
DEBUG ( 10 , ( " msrpc_password_policy: No incoming trust for domain %s \n " ,
domain - > name ) ) ;
return NT_STATUS_NOT_SUPPORTED ;
}
2014-05-26 03:58:38 +04:00
status = cm_connect_sam ( domain , mem_ctx , false , & cli , & dom_pol ) ;
2011-01-18 16:06:48 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2006-02-04 01:19:41 +03:00
goto done ;
}
2011-01-18 16:06:48 +03:00
b = cli - > binding_handle ;
status = dcerpc_samr_QueryDomainInfo ( b , mem_ctx ,
2008-02-05 19:25:07 +03:00
& dom_pol ,
2011-03-30 13:08:31 +04:00
DomainPasswordInformation ,
2011-01-18 16:06:48 +03:00
& info ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
2006-02-04 01:19:41 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2008-02-05 19:25:07 +03:00
* password_policy = info - > info1 ;
2006-02-04 01:19:41 +03:00
2008-02-05 19:25:07 +03:00
DEBUG ( 10 , ( " msrpc_password_policy: min_length_password %d \n " ,
info - > info1 . min_password_length ) ) ;
2006-02-04 01:19:41 +03:00
done :
2011-01-18 16:06:48 +03:00
return status ;
2006-02-04 01:19:41 +03:00
}
2018-01-15 15:02:04 +03:00
static enum lsa_LookupNamesLevel winbindd_lookup_level (
struct winbindd_domain * domain )
{
enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_DOMAINS_ONLY ;
if ( domain - > internal ) {
level = LSA_LOOKUP_NAMES_ALL ;
} else if ( domain - > secure_channel_type = = SEC_CHAN_DNS_DOMAIN ) {
if ( domain - > domain_flags & NETR_TRUST_FLAG_IN_FOREST ) {
/*
* TODO :
*
* Depending on what we want to resolve . We need to use :
* 1. LsapLookupXForestReferral ( 5 ) / LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY
* if we want to pass the request into the direction of the forest
* root domain . The forest root domain uses
* LsapLookupXForestResolve ( 6 ) / LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2
* when passing the request to trusted forests .
* 2. LsapLookupGC ( 4 ) / LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY
* if we ' re not a GC and want to resolve a name within our own forest .
*
* As we don ' t support more than one domain in our own forest
* and always try to be a GC for now , we just set
* LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY .
*/
level = LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY ;
} else if ( domain - > domain_trust_attribs & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE ) {
/*
* This is LsapLookupXForestResolve ( 6 ) / LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2
*/
level = LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2 ;
} else {
/*
* This is LsapLookupTDL ( 3 ) / LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY
*/
level = LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY ;
}
} else if ( domain - > secure_channel_type = = SEC_CHAN_DOMAIN ) {
/*
* This is LsapLookupTDL ( 3 ) / LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY
*/
level = LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY ;
} else if ( domain - > rodc ) {
level = LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC ;
} else {
/*
* This is LsapLookupPDC ( 2 ) / LSA_LOOKUP_NAMES_DOMAINS_ONLY
*/
level = LSA_LOOKUP_NAMES_DOMAINS_ONLY ;
}
return level ;
}
2009-09-17 09:59:25 +04:00
NTSTATUS winbindd_lookup_sids ( TALLOC_CTX * mem_ctx ,
struct winbindd_domain * domain ,
uint32_t num_sids ,
const struct dom_sid * sids ,
char * * * domains ,
char * * * names ,
enum lsa_SidType * * types )
{
NTSTATUS status ;
2011-04-24 01:56:27 +04:00
NTSTATUS result ;
2009-09-17 09:59:25 +04:00
struct rpc_pipe_client * cli = NULL ;
2011-04-24 01:56:27 +04:00
struct dcerpc_binding_handle * b = NULL ;
2009-09-17 09:59:25 +04:00
struct policy_handle lsa_policy ;
unsigned int orig_timeout ;
2012-11-28 23:41:21 +04:00
bool use_lookupsids3 = false ;
2012-11-29 15:03:16 +04:00
bool retried = false ;
2018-01-15 14:57:11 +03:00
enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL ;
2009-09-17 09:59:25 +04:00
2012-11-29 15:03:16 +04:00
connect :
status = cm_connect_lsat ( domain , mem_ctx , & cli , & lsa_policy ) ;
2009-09-17 09:59:25 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2011-04-24 01:56:27 +04:00
b = cli - > binding_handle ;
2012-11-29 15:03:16 +04:00
if ( cli - > transport - > transport = = NCACN_IP_TCP ) {
use_lookupsids3 = true ;
}
2018-01-15 15:02:04 +03:00
level = winbindd_lookup_level ( domain ) ;
2009-09-17 09:59:25 +04:00
/*
* This call can take a long time
* allow the server to time out .
* 35 seconds should do it .
*/
2011-04-24 01:56:27 +04:00
orig_timeout = dcerpc_binding_handle_set_timeout ( b , 35000 ) ;
2009-09-17 09:59:25 +04:00
2012-11-28 23:41:21 +04:00
status = dcerpc_lsa_lookup_sids_generic ( b ,
mem_ctx ,
& lsa_policy ,
num_sids ,
sids ,
2018-01-15 14:57:11 +03:00
level ,
2012-11-28 23:41:21 +04:00
domains ,
names ,
types ,
use_lookupsids3 ,
& result ) ;
2009-09-17 09:59:25 +04:00
/* And restore our original timeout. */
2011-04-24 01:56:27 +04:00
dcerpc_binding_handle_set_timeout ( b , orig_timeout ) ;
2009-09-17 09:59:25 +04:00
2011-04-24 02:00:40 +04:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS_ACCESS_DENIED ) | |
2012-11-29 15:03:16 +04:00
NT_STATUS_EQUAL ( status , NT_STATUS_RPC_SEC_PKG_ERROR ) | |
NT_STATUS_EQUAL ( status , NT_STATUS_NETWORK_ACCESS_DENIED ) ) {
2011-02-01 20:46:57 +03:00
/*
* This can happen if the schannel key is not
* valid anymore , we need to invalidate the
* all connections to the dc and reestablish
* a netlogon connection first .
*/
2014-09-23 21:35:21 +04:00
invalidate_cm_connection ( domain ) ;
2012-11-29 15:03:16 +04:00
domain - > can_do_ncacn_ip_tcp = domain - > active_directory ;
if ( ! retried ) {
retried = true ;
goto connect ;
}
2011-02-01 20:46:57 +03:00
status = NT_STATUS_ACCESS_DENIED ;
}
2017-03-09 20:57:14 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2011-02-01 20:46:57 +03:00
return status ;
}
2011-04-24 01:56:27 +04:00
return NT_STATUS_OK ;
2009-09-17 09:59:25 +04:00
}
2011-09-06 20:33:35 +04:00
static NTSTATUS winbindd_lookup_names ( TALLOC_CTX * mem_ctx ,
struct winbindd_domain * domain ,
uint32_t num_names ,
const char * * names ,
const char * * * domains ,
struct dom_sid * * sids ,
enum lsa_SidType * * types )
2009-09-17 10:06:34 +04:00
{
NTSTATUS status ;
2011-04-24 01:57:19 +04:00
NTSTATUS result ;
2009-09-17 10:06:34 +04:00
struct rpc_pipe_client * cli = NULL ;
2011-04-24 01:57:19 +04:00
struct dcerpc_binding_handle * b = NULL ;
2009-09-17 10:06:34 +04:00
struct policy_handle lsa_policy ;
2009-12-24 14:56:09 +03:00
unsigned int orig_timeout = 0 ;
2012-11-28 20:03:40 +04:00
bool use_lookupnames4 = false ;
2012-11-29 15:03:53 +04:00
bool retried = false ;
2018-01-15 15:02:04 +03:00
enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL ;
2009-09-17 10:06:34 +04:00
2012-11-29 15:03:53 +04:00
connect :
status = cm_connect_lsat ( domain , mem_ctx , & cli , & lsa_policy ) ;
2009-09-17 10:06:34 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2011-04-24 01:57:19 +04:00
b = cli - > binding_handle ;
2009-09-17 11:43:36 +04:00
2012-11-29 15:03:53 +04:00
if ( cli - > transport - > transport = = NCACN_IP_TCP ) {
use_lookupnames4 = true ;
}
2018-01-15 15:02:04 +03:00
level = winbindd_lookup_level ( domain ) ;
2009-09-17 10:06:34 +04:00
/*
* This call can take a long time
* allow the server to time out .
* 35 seconds should do it .
*/
2011-04-24 01:57:19 +04:00
orig_timeout = dcerpc_binding_handle_set_timeout ( b , 35000 ) ;
2009-09-17 10:06:34 +04:00
2012-11-28 20:03:40 +04:00
status = dcerpc_lsa_lookup_names_generic ( b ,
mem_ctx ,
& lsa_policy ,
num_names ,
( const char * * ) names ,
domains ,
2018-01-15 15:02:04 +03:00
level ,
2012-11-28 20:03:40 +04:00
sids ,
types ,
use_lookupnames4 ,
& result ) ;
2009-09-17 10:06:34 +04:00
/* And restore our original timeout. */
2011-04-24 01:57:19 +04:00
dcerpc_binding_handle_set_timeout ( b , orig_timeout ) ;
2009-09-17 10:06:34 +04:00
2011-04-24 02:00:40 +04:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS_ACCESS_DENIED ) | |
2012-11-29 15:03:53 +04:00
NT_STATUS_EQUAL ( status , NT_STATUS_RPC_SEC_PKG_ERROR ) | |
NT_STATUS_EQUAL ( status , NT_STATUS_NETWORK_ACCESS_DENIED ) ) {
2011-02-01 20:46:57 +03:00
/*
* This can happen if the schannel key is not
* valid anymore , we need to invalidate the
* all connections to the dc and reestablish
* a netlogon connection first .
*/
2014-09-23 21:35:21 +04:00
invalidate_cm_connection ( domain ) ;
2012-11-29 15:03:53 +04:00
if ( ! retried ) {
retried = true ;
goto connect ;
}
2011-02-01 20:46:57 +03:00
status = NT_STATUS_ACCESS_DENIED ;
}
2017-03-09 20:57:14 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2009-09-17 10:06:34 +04:00
return status ;
}
2011-04-24 01:57:19 +04:00
return NT_STATUS_OK ;
2009-09-17 10:06:34 +04:00
}
2006-02-04 01:19:41 +03:00
2001-12-03 04:23:42 +03:00
/* the rpc backend methods are exposed via this structure */
struct winbindd_methods msrpc_methods = {
2001-12-10 09:05:21 +03:00
False ,
2010-06-17 16:54:55 +04:00
msrpc_query_user_list ,
2010-06-17 15:56:54 +04:00
msrpc_enum_dom_groups ,
2010-06-17 17:52:44 +04:00
msrpc_enum_local_groups ,
2004-04-20 06:37:49 +04:00
msrpc_name_to_sid ,
msrpc_sid_to_name ,
2006-07-11 22:01:26 +04:00
msrpc_rids_to_names ,
2017-03-02 16:53:47 +03:00
msrpc_lookup_usergroups ,
2005-01-15 22:00:18 +03:00
msrpc_lookup_useraliases ,
2010-06-21 13:15:18 +04:00
msrpc_lookup_groupmem ,
2006-02-04 01:19:41 +03:00
msrpc_lockout_policy ,
msrpc_password_policy ,
2010-06-21 13:14:12 +04:00
msrpc_trusted_domains ,
2001-12-03 04:23:42 +03:00
} ;