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
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
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
2003-11-12 04:51:10 +03:00
# include "includes.h"
2001-12-03 04:23:42 +03:00
# include "winbindd.h"
2002-07-15 14:35:28 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_WINBIND
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 . */
2001-12-03 14:32:55 +03:00
static NTSTATUS query_user_list ( struct winbindd_domain * domain ,
2001-12-03 09:04:18 +03:00
TALLOC_CTX * mem_ctx ,
2001-12-11 03:03:58 +03:00
uint32 * num_entries ,
2001-12-03 14:32:55 +03:00
WINBIND_USERINFO * * info )
2001-12-03 04:23:42 +03:00
{
2005-06-09 02:10:34 +04:00
NTSTATUS result ;
2001-12-03 04:23:42 +03:00
POLICY_HND dom_pol ;
2005-06-09 02:10:34 +04:00
unsigned int i , start_idx ;
2003-11-27 07:39:53 +03:00
uint32 loop_count ;
2005-06-09 02:10:34 +04:00
struct rpc_pipe_client * cli ;
2001-12-03 04:23:42 +03:00
2002-07-15 14:35:28 +04:00
DEBUG ( 3 , ( " rpc: query_user_list \n " ) ) ;
2001-12-11 01:10:16 +03:00
* num_entries = 0 ;
2001-12-11 03:03:58 +03:00
* info = NULL ;
2001-12-11 01:10:16 +03:00
2005-06-09 02:10:34 +04:00
result = cm_connect_sam ( domain , mem_ctx , & cli , & dom_pol ) ;
2001-12-03 04:23:42 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
2005-06-09 02:10:34 +04:00
return result ;
2001-12-03 04:23:42 +03:00
2003-04-23 15:54:56 +04:00
i = start_idx = 0 ;
2003-11-27 07:39:53 +03:00
loop_count = 0 ;
2001-12-11 03:03:58 +03:00
do {
2002-01-31 15:47:42 +03:00
TALLOC_CTX * ctx2 ;
2003-11-27 07:39:53 +03:00
uint32 num_dom_users , j ;
uint32 max_entries , max_size ;
SAM_DISPINFO_CTR ctr ;
SAM_DISPINFO_1 info1 ;
ZERO_STRUCT ( ctr ) ;
ZERO_STRUCT ( info1 ) ;
ctr . sam . info1 = & info1 ;
2005-06-09 02:10:34 +04:00
if ( ! ( ctx2 = talloc_init ( " winbindd enum_users " ) ) )
return NT_STATUS_NO_MEMORY ;
2003-01-29 23:15:35 +03:00
2003-11-27 07:39:53 +03:00
/* this next bit is copied from net_user_list_internal() */
2005-06-09 02:10:34 +04:00
get_query_dispinfo_params ( loop_count , & max_entries ,
& max_size ) ;
2003-11-27 07:39:53 +03:00
2005-06-09 02:10:34 +04:00
result = rpccli_samr_query_dispinfo ( cli , mem_ctx , & dom_pol ,
& start_idx , 1 ,
& num_dom_users ,
max_entries , max_size ,
& ctr ) ;
2003-11-27 07:39:53 +03:00
loop_count + + ;
2003-01-29 23:15:35 +03:00
2003-04-23 15:54:56 +04:00
* num_entries + = num_dom_users ;
2001-12-11 03:03:58 +03:00
2005-06-09 02:10:34 +04:00
* info = TALLOC_REALLOC_ARRAY ( mem_ctx , * info , WINBIND_USERINFO ,
* num_entries ) ;
2001-12-11 03:03:58 +03:00
if ( ! ( * info ) ) {
2002-04-04 06:39:57 +04:00
talloc_destroy ( ctx2 ) ;
2005-06-09 02:10:34 +04:00
return NT_STATUS_NO_MEMORY ;
2001-12-11 03:03:58 +03:00
}
2003-04-23 15:54:56 +04:00
for ( j = 0 ; j < num_dom_users ; i + + , j + + ) {
2003-11-27 07:39:53 +03:00
fstring username , fullname ;
uint32 rid = ctr . sam . info1 - > sam [ j ] . rid_user ;
unistr2_to_ascii ( username , & ( & ctr . sam . info1 - > str [ j ] ) - > uni_acct_name , sizeof ( username ) - 1 ) ;
unistr2_to_ascii ( fullname , & ( & ctr . sam . info1 - > str [ j ] ) - > uni_full_name , sizeof ( fullname ) - 1 ) ;
( * info ) [ i ] . acct_name = talloc_strdup ( mem_ctx , username ) ;
( * info ) [ i ] . full_name = talloc_strdup ( mem_ctx , fullname ) ;
2005-06-29 18:03:53 +04:00
( * info ) [ i ] . homedir = NULL ;
( * info ) [ i ] . shell = NULL ;
2005-06-09 02:10:34 +04:00
sid_compose ( & ( * info ) [ i ] . user_sid , & domain - > sid , rid ) ;
2003-11-27 07:39:53 +03:00
2001-12-11 03:03:58 +03:00
/* For the moment we set the primary group for
every user to be the Domain Users group .
There are serious problems with determining
the actual primary group for large domains .
This should really be made into a ' winbind
force group ' smb . conf parameter or
something like that . */
2003-11-27 07:39:53 +03:00
2005-06-09 02:10:34 +04:00
sid_compose ( & ( * info ) [ i ] . group_sid , & domain - > sid ,
DOMAIN_GROUP_RID_USERS ) ;
2001-12-11 03:03:58 +03:00
}
2002-01-31 15:47:42 +03:00
talloc_destroy ( ctx2 ) ;
2003-04-23 15:54:56 +04:00
2001-12-11 03:03:58 +03:00
} while ( NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) ) ;
2001-12-03 04:23:42 +03:00
return result ;
}
/* list all domain groups */
2001-12-03 09:04:18 +03:00
static NTSTATUS enum_dom_groups ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2001-12-11 04:04:13 +03:00
uint32 * num_entries ,
2001-12-03 09:04:18 +03:00
struct acct_info * * info )
2001-12-03 04:23:42 +03:00
{
POLICY_HND dom_pol ;
NTSTATUS status ;
2003-01-06 10:29:38 +03:00
uint32 start = 0 ;
2005-06-09 02:10:34 +04:00
struct rpc_pipe_client * cli ;
2001-12-03 04:23:42 +03:00
* num_entries = 0 ;
2001-12-11 04:04:13 +03:00
* info = NULL ;
2001-12-03 04:23:42 +03:00
2002-07-15 14:35:28 +04:00
DEBUG ( 3 , ( " rpc: enum_dom_groups \n " ) ) ;
2005-06-09 02:10:34 +04:00
status = cm_connect_sam ( domain , mem_ctx , & cli , & dom_pol ) ;
2003-02-15 04:34:37 +03:00
if ( ! NT_STATUS_IS_OK ( status ) )
2001-12-03 04:23:42 +03:00
return status ;
2001-12-11 04:04:13 +03:00
do {
struct acct_info * info2 = NULL ;
2003-01-06 10:29:38 +03:00
uint32 count = 0 ;
2001-12-11 04:04:13 +03:00
TALLOC_CTX * mem_ctx2 ;
2002-12-20 23:21:31 +03:00
mem_ctx2 = talloc_init ( " enum_dom_groups[rpc] " ) ;
2001-12-11 04:04:13 +03:00
2003-01-06 10:29:38 +03:00
/* start is updated by this call. */
2005-06-09 02:10:34 +04:00
status = rpccli_samr_enum_dom_groups ( cli , mem_ctx2 , & dom_pol ,
& start ,
0xFFFF , /* buffer size? */
& info2 , & count ) ;
2001-12-11 04:04:13 +03:00
if ( ! NT_STATUS_IS_OK ( status ) & &
! NT_STATUS_EQUAL ( status , STATUS_MORE_ENTRIES ) ) {
talloc_destroy ( mem_ctx2 ) ;
break ;
}
2005-06-09 02:10:34 +04:00
( * info ) = TALLOC_REALLOC_ARRAY ( mem_ctx , * info ,
struct acct_info ,
( * num_entries ) + count ) ;
2001-12-11 04:04:13 +03:00
if ( ! * info ) {
talloc_destroy ( mem_ctx2 ) ;
2005-06-09 02:10:34 +04:00
status = NT_STATUS_NO_MEMORY ;
break ;
2001-12-11 04:04:13 +03:00
}
memcpy ( & ( * info ) [ * num_entries ] , info2 , count * sizeof ( * info2 ) ) ;
( * num_entries ) + = count ;
talloc_destroy ( mem_ctx2 ) ;
} while ( NT_STATUS_EQUAL ( status , STATUS_MORE_ENTRIES ) ) ;
2001-12-03 04:23:42 +03:00
2005-06-09 02:10:34 +04:00
return NT_STATUS_OK ;
2001-12-03 04:23:42 +03:00
}
2002-10-08 22:32:42 +04:00
/* List all domain groups */
static NTSTATUS enum_local_groups ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
uint32 * num_entries ,
struct acct_info * * info )
{
POLICY_HND dom_pol ;
NTSTATUS result ;
2005-06-09 02:10:34 +04:00
struct rpc_pipe_client * cli ;
2002-10-08 22:32:42 +04:00
* num_entries = 0 ;
* info = NULL ;
2005-06-09 02:10:34 +04:00
DEBUG ( 3 , ( " rpc: enum_local_groups \n " ) ) ;
2002-10-08 22:32:42 +04:00
2005-06-09 02:10:34 +04:00
result = cm_connect_sam ( domain , mem_ctx , & cli , & dom_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
2002-10-08 22:32:42 +04:00
return result ;
do {
struct acct_info * info2 = NULL ;
uint32 count = 0 , start = * num_entries ;
TALLOC_CTX * mem_ctx2 ;
2002-12-20 23:21:31 +03:00
mem_ctx2 = talloc_init ( " enum_dom_local_groups[rpc] " ) ;
2002-10-08 22:32:42 +04:00
2005-06-09 02:10:34 +04:00
result = rpccli_samr_enum_als_groups ( cli , mem_ctx2 , & dom_pol ,
& start , 0xFFFF , & info2 ,
& count ) ;
2002-10-08 22:32:42 +04:00
2005-06-09 02:10:34 +04:00
if ( ! NT_STATUS_IS_OK ( result ) & &
! NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) )
2002-10-08 22:32:42 +04:00
{
talloc_destroy ( mem_ctx2 ) ;
2005-06-09 02:10:34 +04:00
return result ;
2002-10-08 22:32:42 +04:00
}
2005-06-09 02:10:34 +04:00
( * info ) = TALLOC_REALLOC_ARRAY ( mem_ctx , * info ,
struct acct_info ,
( * num_entries ) + count ) ;
2002-10-08 22:32:42 +04:00
if ( ! * info ) {
talloc_destroy ( mem_ctx2 ) ;
return NT_STATUS_NO_MEMORY ;
}
memcpy ( & ( * info ) [ * num_entries ] , info2 , count * sizeof ( * info2 ) ) ;
( * num_entries ) + = count ;
talloc_destroy ( mem_ctx2 ) ;
2005-06-09 02:10:34 +04:00
} while ( NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) ) ;
2002-10-08 22:32:42 +04:00
2005-06-09 02:10:34 +04:00
return NT_STATUS_OK ;
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 */
2004-04-20 06:37:49 +04:00
NTSTATUS msrpc_name_to_sid ( struct winbindd_domain * domain ,
2003-04-23 15:54:56 +04:00
TALLOC_CTX * mem_ctx ,
2004-04-20 06:37:49 +04:00
const char * domain_name ,
2001-12-03 11:17:46 +03:00
const char * name ,
DOM_SID * sid ,
2006-09-08 18:28:06 +04:00
enum lsa_SidType * type )
2001-12-03 11:17:46 +03:00
{
2003-06-21 08:05:01 +04:00
NTSTATUS result ;
2001-12-03 11:17:46 +03:00
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 ;
2005-06-09 02:10:34 +04:00
struct rpc_pipe_client * cli ;
POLICY_HND lsa_policy ;
2001-12-03 11:17:46 +03:00
2005-05-09 20:02:57 +04:00
if ( name = = NULL | | * name = = ' \0 ' ) {
DEBUG ( 3 , ( " rpc: name_to_sid name=%s \n " , domain_name ) ) ;
full_name = talloc_asprintf ( mem_ctx , " %s " , domain_name ) ;
} else {
DEBUG ( 3 , ( " rpc: name_to_sid name=%s \\ %s \n " , domain_name , name ) ) ;
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 ;
}
2007-03-16 20:54:10 +03:00
ws_name_return ( full_name , WB_REPLACE_CHAR ) ;
2007-01-31 08:38:36 +03:00
2006-06-14 18:43:15 +04:00
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
2005-06-09 02:10:34 +04:00
result = cm_connect_lsa ( domain , mem_ctx , & cli , & lsa_policy ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
result = rpccli_lsa_lookup_names ( cli , mem_ctx , & lsa_policy , 1 ,
2007-02-01 18:22:08 +03:00
( const char * * ) & full_name , NULL , & sids , & types ) ;
2001-12-03 11:17:46 +03:00
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 */
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
*/
2004-04-20 06:37:49 +04:00
NTSTATUS msrpc_sid_to_name ( struct winbindd_domain * domain ,
2001-12-05 07:48:51 +03:00
TALLOC_CTX * mem_ctx ,
2004-01-05 05:04:37 +03:00
const DOM_SID * sid ,
2004-04-20 06:37:49 +04:00
char * * domain_name ,
2001-12-05 07:48:51 +03:00
char * * name ,
2006-09-08 18:28:06 +04:00
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 ;
2006-09-08 18:28:06 +04:00
enum lsa_SidType * types ;
2003-06-21 08:05:01 +04:00
NTSTATUS result ;
2005-06-09 02:10:34 +04:00
struct rpc_pipe_client * cli ;
POLICY_HND lsa_policy ;
2001-12-03 14:11:14 +03:00
2003-06-21 08:05:01 +04:00
DEBUG ( 3 , ( " sid_to_name [rpc] %s for domain %s \n " , sid_string_static ( sid ) ,
domain - > name ) ) ;
2002-07-15 14:35:28 +04:00
2005-06-09 02:10:34 +04:00
result = cm_connect_lsa ( domain , mem_ctx , & cli , & lsa_policy ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
2001-12-03 14:11:14 +03:00
2005-06-09 02:10:34 +04:00
result = rpccli_lsa_lookup_sids ( cli , mem_ctx , & lsa_policy ,
1 , sid , & domains , & names , & types ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
2003-06-21 08:05:01 +04: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
2007-03-16 20:54:10 +03:00
ws_name_replace ( * name , WB_REPLACE_CHAR ) ;
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 ) ) ;
return NT_STATUS_OK ;
2001-12-03 14:11:14 +03:00
}
2006-07-11 22:01:26 +04:00
NTSTATUS msrpc_rids_to_names ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
const DOM_SID * sid ,
uint32 * rids ,
size_t num_rids ,
char * * domain_name ,
char * * * names ,
2006-09-08 18:28:06 +04:00
enum lsa_SidType * * types )
2006-07-11 22:01:26 +04:00
{
char * * domains ;
NTSTATUS result ;
struct rpc_pipe_client * cli ;
POLICY_HND lsa_policy ;
DOM_SID * sids ;
size_t i ;
2007-01-31 08:38:36 +03:00
char * * ret_names ;
2006-07-11 22:01:26 +04:00
DEBUG ( 3 , ( " rids_to_names [rpc] for domain %s \n " , domain - > name ) ) ;
2007-04-30 06:39:34 +04:00
if ( num_rids ) {
sids = TALLOC_ARRAY ( mem_ctx , DOM_SID , num_rids ) ;
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 ;
}
}
result = cm_connect_lsa ( domain , mem_ctx , & cli , & lsa_policy ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
return result ;
}
result = rpccli_lsa_lookup_sids ( cli , mem_ctx , & lsa_policy ,
num_rids , sids , & domains ,
names , types ) ;
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 + + ) {
if ( ( * types ) [ i ] ! = SID_NAME_UNKNOWN ) {
2007-03-16 20:54:10 +03:00
ws_name_replace ( ret_names [ i ] , WB_REPLACE_CHAR ) ;
2006-07-11 22:01:26 +04:00
* domain_name = domains [ i ] ;
}
}
return result ;
}
2001-12-04 09:17:39 +03:00
/* Lookup user information from a rid or username. */
static NTSTATUS query_user ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2004-03-30 12:03:32 +04:00
const DOM_SID * user_sid ,
2001-12-04 09:17:39 +03:00
WINBIND_USERINFO * user_info )
{
2003-04-23 15:54:56 +04:00
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
2001-12-04 09:17:39 +03:00
POLICY_HND dom_pol , user_pol ;
SAM_USERINFO_CTR * ctr ;
2003-04-23 15:54:56 +04:00
fstring sid_string ;
uint32 user_rid ;
2005-11-10 23:28:23 +03:00
NET_USER_INFO_3 * user ;
2005-06-09 02:10:34 +04:00
struct rpc_pipe_client * cli ;
2001-12-04 09:17:39 +03:00
2007-02-05 17:57:31 +03:00
DEBUG ( 3 , ( " rpc: query_user sid=%s \n " ,
2005-06-09 02:10:34 +04:00
sid_to_string ( sid_string , user_sid ) ) ) ;
if ( ! sid_peek_check_rid ( & domain - > sid , user_sid , & user_rid ) )
return NT_STATUS_UNSUCCESSFUL ;
2003-06-21 08:05:01 +04:00
2005-11-10 23:28:23 +03:00
/* try netsamlogon cache first */
if ( ( user = netsamlogon_cache_get ( mem_ctx , user_sid ) ) ! = NULL )
{
DEBUG ( 5 , ( " query_user: Cache lookup succeeded for %s \n " ,
sid_string_static ( user_sid ) ) ) ;
sid_compose ( & user_info - > user_sid , & domain - > sid , user_rid ) ;
sid_compose ( & user_info - > group_sid , & domain - > sid ,
user - > group_rid ) ;
user_info - > acct_name = unistr2_tdup ( mem_ctx ,
& user - > uni_user_name ) ;
user_info - > full_name = unistr2_tdup ( mem_ctx ,
& user - > uni_full_name ) ;
user_info - > homedir = NULL ;
user_info - > shell = NULL ;
2007-02-16 18:13:57 +03:00
user_info - > primary_gid = ( gid_t ) - 1 ;
2005-11-10 23:28:23 +03:00
2007-05-03 16:29:32 +04:00
TALLOC_FREE ( user ) ;
2005-11-10 23:28:23 +03:00
return NT_STATUS_OK ;
}
/* no cache; hit the wire */
2005-06-09 02:10:34 +04:00
result = cm_connect_sam ( domain , mem_ctx , & cli , & dom_pol ) ;
2001-12-04 09:17:39 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
2005-06-09 02:10:34 +04:00
return result ;
2001-12-04 09:17:39 +03:00
/* Get user handle */
2005-06-09 02:10:34 +04:00
result = rpccli_samr_open_user ( cli , mem_ctx , & dom_pol ,
SEC_RIGHTS_MAXIMUM_ALLOWED , user_rid ,
& user_pol ) ;
2001-12-04 09:17:39 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
2005-06-09 02:10:34 +04:00
return result ;
2002-04-04 06:39:57 +04:00
2001-12-04 09:17:39 +03:00
/* Get user info */
2005-06-09 02:10:34 +04:00
result = rpccli_samr_query_userinfo ( cli , mem_ctx , & user_pol ,
0x15 , & ctr ) ;
2001-12-04 09:17:39 +03:00
2005-06-09 02:10:34 +04:00
rpccli_samr_close ( cli , mem_ctx , & user_pol ) ;
2002-07-15 14:35:28 +04:00
2005-06-09 02:10:34 +04:00
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
2001-12-04 09:17:39 +03:00
2005-06-09 02:10:34 +04:00
sid_compose ( & user_info - > user_sid , & domain - > sid , user_rid ) ;
sid_compose ( & user_info - > group_sid , & domain - > sid ,
ctr - > info . id21 - > group_rid ) ;
2001-12-05 07:48:51 +03:00
user_info - > acct_name = unistr2_tdup ( mem_ctx ,
& ctr - > info . id21 - > uni_user_name ) ;
2001-12-04 09:17:39 +03:00
user_info - > full_name = unistr2_tdup ( mem_ctx ,
& ctr - > info . id21 - > uni_full_name ) ;
2005-06-29 18:03:53 +04:00
user_info - > homedir = NULL ;
user_info - > shell = NULL ;
2007-02-16 18:13:57 +03:00
user_info - > primary_gid = ( gid_t ) - 1 ;
2001-12-04 09:17:39 +03:00
2005-06-09 02:10:34 +04:00
return NT_STATUS_OK ;
2001-12-04 09:17:39 +03:00
}
2001-12-04 09:46:53 +03:00
/* Lookup groups a user is a member of. I wish Unix had a call like this! */
static NTSTATUS lookup_usergroups ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2004-03-30 12:03:32 +04:00
const DOM_SID * user_sid ,
2005-06-09 02:10:34 +04:00
uint32 * num_groups , DOM_SID * * user_grpsids )
2001-12-04 09:46:53 +03:00
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
POLICY_HND dom_pol , user_pol ;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED ;
DOM_GID * user_groups ;
2003-04-23 15:54:56 +04:00
unsigned int i ;
fstring sid_string ;
uint32 user_rid ;
2005-06-09 02:10:34 +04:00
struct rpc_pipe_client * cli ;
DEBUG ( 3 , ( " rpc: lookup_usergroups sid=%s \n " ,
sid_to_string ( sid_string , user_sid ) ) ) ;
2001-12-04 09:46:53 +03:00
2005-06-09 02:10:34 +04:00
if ( ! sid_peek_check_rid ( & domain - > sid , user_sid , & user_rid ) )
return NT_STATUS_UNSUCCESSFUL ;
2002-07-15 14:35:28 +04:00
2001-12-11 01:10:16 +03:00
* num_groups = 0 ;
2003-06-21 08:05:01 +04:00
* user_grpsids = NULL ;
2005-11-10 23:28:23 +03:00
/* so lets see if we have a cached user_info_3 */
2006-04-28 18:48:22 +04:00
result = lookup_usergroups_cached ( domain , mem_ctx , user_sid ,
num_groups , user_grpsids ) ;
if ( NT_STATUS_IS_OK ( result ) ) {
2005-11-10 23:28:23 +03:00
return NT_STATUS_OK ;
}
/* no cache; hit the wire */
2003-06-21 08:05:01 +04:00
2005-06-09 02:10:34 +04:00
result = cm_connect_sam ( domain , mem_ctx , & cli , & dom_pol ) ;
2001-12-04 09:46:53 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
2005-06-09 02:10:34 +04:00
return result ;
2003-04-23 15:54:56 +04:00
2001-12-04 09:46:53 +03:00
/* Get user handle */
2005-06-09 02:10:34 +04:00
result = rpccli_samr_open_user ( cli , mem_ctx , & dom_pol ,
2001-12-04 09:46:53 +03:00
des_access , user_rid , & user_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
2005-06-09 02:10:34 +04:00
return result ;
2001-12-04 09:46:53 +03:00
/* Query user rids */
2005-06-09 02:10:34 +04:00
result = rpccli_samr_query_usergroups ( cli , mem_ctx , & user_pol ,
2001-12-04 09:46:53 +03:00
num_groups , & user_groups ) ;
2005-06-09 02:10:34 +04:00
rpccli_samr_close ( cli , mem_ctx , & user_pol ) ;
2001-12-04 09:46:53 +03:00
if ( ! NT_STATUS_IS_OK ( result ) | | ( * num_groups ) = = 0 )
2005-06-09 02:10:34 +04:00
return result ;
2001-12-04 09:46:53 +03:00
2005-06-09 02:10:34 +04:00
( * user_grpsids ) = TALLOC_ARRAY ( mem_ctx , DOM_SID , * num_groups ) ;
if ( ! ( * user_grpsids ) )
return NT_STATUS_NO_MEMORY ;
2003-04-23 15:54:56 +04:00
2001-12-04 09:46:53 +03:00
for ( i = 0 ; i < ( * num_groups ) ; i + + ) {
2005-06-09 02:10:34 +04:00
sid_copy ( & ( ( * user_grpsids ) [ i ] ) , & domain - > sid ) ;
sid_append_rid ( & ( ( * user_grpsids ) [ i ] ) ,
user_groups [ i ] . g_rid ) ;
2001-12-04 09:46:53 +03:00
}
2005-06-09 02:10:34 +04:00
return NT_STATUS_OK ;
2001-12-04 09:46:53 +03:00
}
2005-01-15 22:00:18 +03:00
NTSTATUS msrpc_lookup_useraliases ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2005-06-09 02:10:34 +04:00
uint32 num_sids , const DOM_SID * sids ,
2005-01-15 22:00:18 +03:00
uint32 * num_aliases , uint32 * * alias_rids )
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
POLICY_HND dom_pol ;
2006-06-19 20:00:32 +04:00
DOM_SID2 * query_sids ;
uint32 num_query_sids = 0 ;
2005-06-09 02:10:34 +04:00
int i ;
struct rpc_pipe_client * cli ;
2006-06-19 20:00:32 +04:00
uint32 * alias_rids_query , num_aliases_query ;
int rangesize = MAX_SAM_ENTRIES_W2K ;
uint32 total_sids = 0 ;
int num_queries = 1 ;
2005-01-15 22:00:18 +03:00
* num_aliases = 0 ;
* alias_rids = NULL ;
2005-06-09 02:10:34 +04:00
DEBUG ( 3 , ( " rpc: lookup_useraliases \n " ) ) ;
2005-01-15 22:00:18 +03:00
2005-06-09 02:10:34 +04:00
result = cm_connect_sam ( domain , mem_ctx , & cli , & dom_pol ) ;
2005-01-15 22:00:18 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
2005-06-09 02:10:34 +04:00
return result ;
2005-01-15 22:00:18 +03:00
2006-06-19 20:00:32 +04:00
do {
/* prepare query */
2005-01-15 22:00:18 +03:00
2006-06-19 20:00:32 +04:00
num_query_sids = MIN ( num_sids - total_sids , rangesize ) ;
2005-01-15 22:00:18 +03:00
2006-06-19 20:00:32 +04:00
DEBUG ( 10 , ( " rpc: lookup_useraliases: entering query %d for %d sids \n " ,
num_queries , num_query_sids ) ) ;
2007-04-30 06:39:34 +04:00
if ( num_query_sids ) {
query_sids = TALLOC_ARRAY ( mem_ctx , DOM_SID2 , num_query_sids ) ;
if ( query_sids = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
} else {
query_sids = NULL ;
2006-06-19 20:00:32 +04:00
}
for ( i = 0 ; i < num_query_sids ; i + + ) {
sid_copy ( & query_sids [ i ] . sid , & sids [ total_sids + + ] ) ;
query_sids [ i ] . num_auths = query_sids [ i ] . sid . num_auths ;
}
/* do request */
result = rpccli_samr_query_useraliases ( cli , mem_ctx , & dom_pol ,
num_query_sids , query_sids ,
& num_aliases_query ,
& alias_rids_query ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
* num_aliases = 0 ;
* alias_rids = NULL ;
TALLOC_FREE ( query_sids ) ;
goto done ;
}
/* process output */
for ( i = 0 ; i < num_aliases_query ; i + + ) {
2006-06-19 22:49:51 +04:00
size_t na = * num_aliases ;
2006-12-09 05:58:18 +03:00
if ( ! add_rid_to_array_unique ( mem_ctx , alias_rids_query [ i ] ,
alias_rids , & na ) ) {
return NT_STATUS_NO_MEMORY ;
}
2006-06-19 22:49:51 +04:00
* num_aliases = na ;
2006-06-19 20:00:32 +04:00
}
TALLOC_FREE ( query_sids ) ;
num_queries + + ;
} while ( total_sids < num_sids ) ;
2005-01-15 22:00:18 +03:00
2006-06-19 20:00:32 +04:00
done :
DEBUG ( 10 , ( " rpc: lookup_useraliases: got %d aliases in %d queries "
" (rangesize: %d) \n " , * num_aliases , num_queries , rangesize ) ) ;
2005-01-15 22:00:18 +03:00
return result ;
}
2001-12-03 04:23:42 +03:00
2001-12-05 07:48:51 +03:00
/* Lookup group membership given a rid. */
static NTSTATUS lookup_groupmem ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2004-03-30 12:03:32 +04:00
const DOM_SID * group_sid , uint32 * num_names ,
2005-06-09 02:10:34 +04:00
DOM_SID * * sid_mem , char * * * names ,
2001-12-05 07:48:51 +03:00
uint32 * * name_types )
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
uint32 i , total_names = 0 ;
POLICY_HND dom_pol , group_pol ;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED ;
2003-04-23 15:54:56 +04:00
uint32 * rid_mem = NULL ;
uint32 group_rid ;
unsigned int j ;
fstring sid_string ;
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 ;
2001-12-05 07:48:51 +03:00
2005-06-09 02:10:34 +04:00
DEBUG ( 10 , ( " rpc: lookup_groupmem %s sid=%s \n " , domain - > name ,
sid_to_string ( sid_string , group_sid ) ) ) ;
2003-04-23 15:54:56 +04:00
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 ;
2005-06-09 02:10:34 +04:00
result = cm_connect_sam ( domain , mem_ctx , & cli , & dom_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
2001-12-05 07:48:51 +03:00
2005-06-09 02:10:34 +04:00
result = rpccli_samr_open_group ( cli , mem_ctx , & dom_pol ,
des_access , group_rid , & group_pol ) ;
2001-12-05 07:48:51 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
2005-06-09 02:10:34 +04:00
return result ;
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 . */
orig_timeout = cli_set_timeout ( cli - > cli , 35000 ) ;
2005-06-09 02:10:34 +04:00
result = rpccli_samr_query_groupmem ( cli , mem_ctx ,
& group_pol , num_names , & rid_mem ,
name_types ) ;
2006-10-16 18:29:14 +04:00
/* And restore our original timeout. */
cli_set_timeout ( cli - > cli , orig_timeout ) ;
2005-06-09 02:10:34 +04:00
rpccli_samr_close ( cli , mem_ctx , & group_pol ) ;
2001-12-05 07:48:51 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
2005-06-09 02:10:34 +04:00
return result ;
2001-12-05 07:48:51 +03:00
2004-01-02 08:33:14 +03:00
if ( ! * num_names ) {
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
}
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
2004-12-07 21:25:53 +03:00
* names = TALLOC_ZERO_ARRAY ( mem_ctx , char * , * num_names ) ;
* name_types = TALLOC_ZERO_ARRAY ( mem_ctx , uint32 , * num_names ) ;
2005-06-09 02:10:34 +04:00
* sid_mem = TALLOC_ZERO_ARRAY ( mem_ctx , 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 ] ) ;
2003-04-23 15:54:56 +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
for ( i = 0 ; i < * num_names ; i + = MAX_LOOKUP_RIDS ) {
int num_lookup_rids = MIN ( * num_names - i , MAX_LOOKUP_RIDS ) ;
uint32 tmp_num_names = 0 ;
char * * tmp_names = NULL ;
uint32 * tmp_types = NULL ;
/* Lookup a chunk of rids */
2005-06-09 02:10:34 +04:00
result = rpccli_samr_lookup_rids ( cli , mem_ctx ,
& dom_pol ,
num_lookup_rids ,
& rid_mem [ i ] ,
& tmp_num_names ,
& tmp_names , & tmp_types ) ;
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 ) */
2003-06-21 08:05:01 +04:00
2005-06-09 02:10:34 +04:00
if ( ! NT_STATUS_IS_OK ( result ) & &
! NT_STATUS_EQUAL ( result , STATUS_SOME_UNMAPPED ) )
return result ;
2003-06-21 08:05:01 +04:00
2001-12-05 07:48:51 +03:00
/* Copy result into array. The talloc system will take
care of freeing the temporary arrays later on . */
memcpy ( & ( * names ) [ i ] , tmp_names , sizeof ( char * ) *
tmp_num_names ) ;
memcpy ( & ( * name_types ) [ i ] , tmp_types , sizeof ( uint32 ) *
tmp_num_names ) ;
2003-04-23 15:54:56 +04:00
2001-12-05 07:48:51 +03:00
total_names + = tmp_num_names ;
}
* num_names = total_names ;
2005-06-09 02:10:34 +04:00
return NT_STATUS_OK ;
2001-12-05 07:48:51 +03:00
}
2003-06-23 09:10:07 +04:00
# ifdef HAVE_LDAP
# include <ldap.h>
2003-06-25 21:41:05 +04:00
static int get_ldap_seq ( const char * server , int port , uint32 * seq )
2003-06-23 09:10:07 +04:00
{
int ret = - 1 ;
struct timeval to ;
2005-02-17 17:27:34 +03:00
const char * attrs [ ] = { " highestCommittedUSN " , NULL } ;
2003-06-23 09:10:07 +04:00
LDAPMessage * res = NULL ;
char * * values = NULL ;
LDAP * ldp = NULL ;
* seq = DOM_SEQUENCE_NONE ;
/*
2005-06-09 02:10:34 +04:00
* Parameterised ( 5 ) second timeout on open . This is needed as the
* search timeout doesn ' t seem to apply to doing an open as well . JRA .
2003-06-23 09:10:07 +04:00
*/
2005-06-09 02:10:34 +04:00
ldp = ldap_open_with_timeout ( server , port , lp_ldap_timeout ( ) ) ;
if ( ldp = = NULL )
2003-06-23 09:10:07 +04:00
return - 1 ;
/* Timeout if no response within 20 seconds. */
to . tv_sec = 10 ;
to . tv_usec = 0 ;
2005-03-30 08:40:24 +04:00
if ( ldap_search_st ( ldp , " " , LDAP_SCOPE_BASE , " (objectclass=*) " ,
2005-06-09 02:10:34 +04:00
CONST_DISCARD ( char * * , attrs ) , 0 , & to , & res ) )
2003-06-23 09:10:07 +04:00
goto done ;
if ( ldap_count_entries ( ldp , res ) ! = 1 )
goto done ;
values = ldap_get_values ( ldp , res , " highestCommittedUSN " ) ;
if ( ! values | | ! values [ 0 ] )
goto done ;
* seq = atoi ( values [ 0 ] ) ;
ret = 0 ;
done :
if ( values )
ldap_value_free ( values ) ;
if ( res )
ldap_msgfree ( res ) ;
if ( ldp )
ldap_unbind ( ldp ) ;
return ret ;
}
/**********************************************************************
Get the sequence number for a Windows AD native mode domain using
2006-09-07 01:43:31 +04:00
LDAP queries .
2003-06-23 09:10:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-07 01:43:31 +04:00
static int get_ldap_sequence_number ( struct winbindd_domain * domain , uint32 * seq )
2003-06-23 09:10:07 +04:00
{
int ret = - 1 ;
2006-10-06 06:04:57 +04:00
fstring ipstr ;
2003-06-23 09:10:07 +04:00
2006-10-06 06:04:57 +04:00
fstrcpy ( ipstr , inet_ntoa ( domain - > dcaddr . sin_addr ) ) ;
if ( ( ret = get_ldap_seq ( ipstr , LDAP_PORT , seq ) ) = = 0 ) {
2005-06-09 02:10:34 +04:00
DEBUG ( 3 , ( " get_ldap_sequence_number: Retrieved sequence "
2006-10-06 06:04:57 +04:00
" number for Domain (%s) from DC (%s) \n " ,
domain - > name , ipstr ) ) ;
}
2003-06-23 09:10:07 +04:00
return ret ;
}
# endif /* HAVE_LDAP */
2001-12-05 10:52:44 +03:00
/* find the sequence number for a domain */
2001-12-10 02:59:42 +03:00
static NTSTATUS sequence_number ( struct winbindd_domain * domain , uint32 * seq )
2001-12-05 10:52:44 +03:00
{
TALLOC_CTX * mem_ctx ;
SAM_UNK_CTR ctr ;
NTSTATUS result ;
POLICY_HND dom_pol ;
2004-12-22 19:58:43 +03:00
BOOL got_seq_num = False ;
2005-06-09 02:10:34 +04:00
struct rpc_pipe_client * cli ;
2001-12-05 10:52:44 +03:00
2002-09-25 19:19:00 +04:00
DEBUG ( 10 , ( " rpc: fetch sequence_number for %s \n " , domain - > name ) ) ;
2002-07-15 14:35:28 +04:00
2001-12-10 02:59:42 +03:00
* seq = DOM_SEQUENCE_NONE ;
2002-12-20 23:21:31 +03:00
if ( ! ( mem_ctx = talloc_init ( " sequence_number[rpc] " ) ) )
2001-12-10 02:59:42 +03:00
return NT_STATUS_NO_MEMORY ;
2001-12-05 10:52:44 +03:00
2005-06-09 02:10:34 +04:00
# ifdef HAVE_LDAP
2007-05-06 23:37:13 +04:00
if ( domain - > active_directory )
2005-06-09 02:10:34 +04:00
{
int res ;
DEBUG ( 8 , ( " using get_ldap_seq() to retrieve the "
" sequence number \n " ) ) ;
2006-09-07 01:52:06 +04:00
res = get_ldap_sequence_number ( domain , seq ) ;
2005-06-09 02:10:34 +04:00
if ( res = = 0 )
{
result = NT_STATUS_OK ;
DEBUG ( 10 , ( " domain_sequence_number: LDAP for "
" domain %s is %u \n " ,
domain - > name , * seq ) ) ;
2003-02-15 04:34:37 +03:00
goto done ;
2005-06-09 02:10:34 +04:00
}
2001-12-05 10:52:44 +03:00
2005-06-09 02:10:34 +04:00
DEBUG ( 10 , ( " domain_sequence_number: failed to get LDAP "
" sequence number for domain %s \n " ,
domain - > name ) ) ;
}
# endif /* HAVE_LDAP */
2001-12-05 10:52:44 +03:00
2005-06-09 02:10:34 +04:00
result = cm_connect_sam ( domain , mem_ctx , & cli , & dom_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
2001-12-05 10:52:44 +03:00
goto done ;
2005-06-09 02:10:34 +04:00
}
2001-12-05 10:52:44 +03:00
/* Query domain info */
2005-06-09 02:10:34 +04:00
result = rpccli_samr_query_dom_info ( cli , mem_ctx , & dom_pol , 8 , & ctr ) ;
2001-12-05 10:52:44 +03:00
if ( NT_STATUS_IS_OK ( result ) ) {
2006-09-06 22:32:20 +04:00
* seq = ctr . info . inf8 . seq_num ;
2004-12-22 19:58:43 +03:00
got_seq_num = True ;
goto seq_num ;
}
/* retry with info-level 2 in case the dc does not support info-level 8
* ( like all older samba2 and samba3 dc ' s - Guenther */
2005-06-09 02:10:34 +04:00
result = rpccli_samr_query_dom_info ( cli , mem_ctx , & dom_pol , 2 , & ctr ) ;
2004-12-22 19:58:43 +03:00
if ( NT_STATUS_IS_OK ( result ) ) {
2006-09-06 22:32:20 +04:00
* seq = ctr . info . inf2 . seq_num ;
2004-12-22 19:58:43 +03:00
got_seq_num = True ;
}
seq_num :
if ( got_seq_num ) {
2005-06-09 02:10:34 +04:00
DEBUG ( 10 , ( " domain_sequence_number: for domain %s is %u \n " ,
domain - > name , ( unsigned ) * seq ) ) ;
2001-12-05 10:52:44 +03:00
} else {
2005-06-09 02:10:34 +04:00
DEBUG ( 10 , ( " domain_sequence_number: failed to get sequence "
" number (%u) for domain %s \n " ,
( unsigned ) * seq , domain - > name ) ) ;
2001-12-05 10:52:44 +03:00
}
done :
talloc_destroy ( mem_ctx ) ;
2001-12-10 02:59:42 +03:00
return result ;
2001-12-05 10:52:44 +03:00
}
2001-12-10 05:25:19 +03:00
/* get a list of trusted domains */
static NTSTATUS trusted_domains ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
uint32 * num_domains ,
char * * * names ,
2002-08-17 21:00:51 +04:00
char * * * alt_names ,
2001-12-10 05:25:19 +03:00
DOM_SID * * dom_sids )
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
uint32 enum_ctx = 0 ;
2005-06-09 02:10:34 +04:00
struct rpc_pipe_client * cli ;
POLICY_HND lsa_policy ;
2002-07-15 14:35:28 +04:00
DEBUG ( 3 , ( " rpc: trusted_domains \n " ) ) ;
2001-12-10 05:25:19 +03:00
2001-12-11 01:10:16 +03:00
* num_domains = 0 ;
2005-03-04 22:29:18 +03:00
* names = NULL ;
2002-08-17 21:00:51 +04:00
* alt_names = NULL ;
2005-03-04 22:29:18 +03:00
* dom_sids = NULL ;
2001-12-11 01:10:16 +03:00
2005-06-09 02:10:34 +04:00
result = cm_connect_lsa ( domain , mem_ctx , & cli , & lsa_policy ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
2003-02-15 04:34:37 +03:00
2005-06-09 02:10:34 +04:00
result = STATUS_MORE_ENTRIES ;
2001-12-10 05:25:19 +03:00
2005-06-09 02:10:34 +04:00
while ( NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) ) {
uint32 start_idx , num ;
char * * tmp_names ;
DOM_SID * tmp_sids ;
int i ;
result = rpccli_lsa_enum_trust_dom ( cli , mem_ctx ,
& lsa_policy , & enum_ctx ,
& num , & tmp_names ,
& tmp_sids ) ;
if ( ! NT_STATUS_IS_OK ( result ) & &
! NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) )
break ;
start_idx = * num_domains ;
* num_domains + = num ;
* names = TALLOC_REALLOC_ARRAY ( mem_ctx , * names ,
char * , * num_domains ) ;
* dom_sids = TALLOC_REALLOC_ARRAY ( mem_ctx , * dom_sids ,
DOM_SID , * num_domains ) ;
* alt_names = TALLOC_REALLOC_ARRAY ( mem_ctx , * alt_names ,
char * , * num_domains ) ;
if ( ( * names = = NULL ) | | ( * dom_sids = = NULL ) | |
( * alt_names = = NULL ) )
return NT_STATUS_NO_MEMORY ;
for ( i = 0 ; i < num ; i + + ) {
( * names ) [ start_idx + i ] = tmp_names [ i ] ;
( * dom_sids ) [ start_idx + i ] = tmp_sids [ i ] ;
( * alt_names ) [ start_idx + i ] = talloc_strdup ( mem_ctx , " " ) ;
}
}
2001-12-10 05:25:19 +03:00
return result ;
}
2006-02-04 01:19:41 +03:00
/* find the lockout policy for a domain */
NTSTATUS msrpc_lockout_policy ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
SAM_UNK_INFO_12 * lockout_policy )
{
NTSTATUS result ;
struct rpc_pipe_client * cli ;
POLICY_HND dom_pol ;
SAM_UNK_CTR ctr ;
DEBUG ( 10 , ( " rpc: fetch lockout policy for %s \n " , domain - > name ) ) ;
result = cm_connect_sam ( domain , mem_ctx , & cli , & dom_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
result = rpccli_samr_query_dom_info ( cli , mem_ctx , & dom_pol , 12 , & ctr ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
* lockout_policy = ctr . info . inf12 ;
DEBUG ( 10 , ( " msrpc_lockout_policy: bad_attempt_lockout %d \n " ,
ctr . info . inf12 . bad_attempt_lockout ) ) ;
done :
return result ;
}
/* find the password policy for a domain */
NTSTATUS msrpc_password_policy ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
SAM_UNK_INFO_1 * password_policy )
{
NTSTATUS result ;
struct rpc_pipe_client * cli ;
POLICY_HND dom_pol ;
SAM_UNK_CTR ctr ;
DEBUG ( 10 , ( " rpc: fetch password policy for %s \n " , domain - > name ) ) ;
result = cm_connect_sam ( domain , mem_ctx , & cli , & dom_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
result = rpccli_samr_query_dom_info ( cli , mem_ctx , & dom_pol , 1 , & ctr ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
* password_policy = ctr . info . inf1 ;
DEBUG ( 10 , ( " msrpc_password_policy: min_length_password %d \n " ,
ctr . info . inf1 . min_length_password ) ) ;
done :
return result ;
}
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 ,
2001-12-03 14:32:55 +03:00
query_user_list ,
2001-12-03 11:17:46 +03:00
enum_dom_groups ,
2002-10-08 22:32:42 +04:00
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 ,
2001-12-04 09:46:53 +03:00
query_user ,
2001-12-05 07:48:51 +03:00
lookup_usergroups ,
2005-01-15 22:00:18 +03:00
msrpc_lookup_useraliases ,
2001-12-05 10:52:44 +03:00
lookup_groupmem ,
2001-12-10 05:25:19 +03:00
sequence_number ,
2006-02-04 01:19:41 +03:00
msrpc_lockout_policy ,
msrpc_password_policy ,
2001-12-10 05:25:19 +03:00
trusted_domains ,
2001-12-03 04:23:42 +03:00
} ;