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"
2010-06-07 12:18:01 +04:00
# include "../librpc/gen_ndr/cli_samr.h"
# include "rpc_client/cli_samr.h"
# include "../librpc/gen_ndr/srv_samr.h"
# include "../librpc/gen_ndr/cli_lsa.h"
# include "rpc_client/cli_lsarpc.h"
# include "../librpc/gen_ndr/srv_lsa.h"
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_WINBIND
static NTSTATUS open_internal_samr_pipe ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * * samr_pipe )
{
static struct rpc_pipe_client * cli = NULL ;
struct auth_serversupplied_info * server_info = NULL ;
NTSTATUS status ;
if ( cli ! = NULL ) {
goto done ;
}
if ( server_info = = NULL ) {
status = make_server_info_system ( mem_ctx , & server_info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " open_samr_pipe: Could not create auth_serversupplied_info: %s \n " ,
nt_errstr ( status ) ) ) ;
return status ;
}
}
/* create a samr connection */
status = rpc_pipe_open_internal ( talloc_autofree_context ( ) ,
& ndr_table_samr . syntax_id ,
rpc_samr_dispatch ,
server_info ,
& cli ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " open_samr_pipe: Could not connect to samr_pipe: %s \n " ,
nt_errstr ( status ) ) ) ;
return status ;
}
done :
if ( samr_pipe ) {
* samr_pipe = cli ;
}
return NT_STATUS_OK ;
}
static 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 )
{
NTSTATUS status ;
struct policy_handle samr_connect_hnd ;
status = open_internal_samr_pipe ( mem_ctx , samr_pipe ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
status = rpccli_samr_Connect2 ( ( * samr_pipe ) ,
mem_ctx ,
( * samr_pipe ) - > desthost ,
SEC_FLAG_MAXIMUM_ALLOWED ,
& samr_connect_hnd ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
status = rpccli_samr_OpenDomain ( ( * samr_pipe ) ,
mem_ctx ,
& samr_connect_hnd ,
SEC_FLAG_MAXIMUM_ALLOWED ,
& domain - > sid ,
samr_domain_hnd ) ;
return status ;
}
static NTSTATUS open_internal_lsa_pipe ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * * lsa_pipe )
{
static struct rpc_pipe_client * cli = NULL ;
struct auth_serversupplied_info * server_info = NULL ;
NTSTATUS status ;
if ( cli ! = NULL ) {
goto done ;
}
if ( server_info = = NULL ) {
status = make_server_info_system ( mem_ctx , & server_info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " open_samr_pipe: Could not create auth_serversupplied_info: %s \n " ,
nt_errstr ( status ) ) ) ;
return status ;
}
}
/* create a samr connection */
status = rpc_pipe_open_internal ( talloc_autofree_context ( ) ,
& ndr_table_lsarpc . syntax_id ,
rpc_lsarpc_dispatch ,
server_info ,
& cli ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " open_samr_pipe: Could not connect to samr_pipe: %s \n " ,
nt_errstr ( status ) ) ) ;
return status ;
}
done :
if ( lsa_pipe ) {
* lsa_pipe = cli ;
}
return NT_STATUS_OK ;
}
static NTSTATUS open_internal_lsa_conn ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * * lsa_pipe ,
struct policy_handle * lsa_hnd )
{
NTSTATUS status ;
status = open_internal_lsa_pipe ( mem_ctx , lsa_pipe ) ;
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 ,
struct 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 ;
struct policy_handle dom_pol ;
struct acct_info * info = NULL ;
uint32_t num_info = 0 ;
2010-06-17 15:57:12 +04:00
TALLOC_CTX * tmp_ctx ;
2010-06-07 18:39:44 +04:00
NTSTATUS status ;
2010-06-17 15:57:12 +04:00
DEBUG ( 3 , ( " sam_enum_dom_groups \n " ) ) ;
2010-06-07 18:39:44 +04:00
2010-07-06 03:05:39 +04:00
ZERO_STRUCT ( dom_pol ) ;
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 ;
}
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 :
2010-07-06 03:05:39 +04:00
if ( is_valid_policy_hnd ( & dom_pol ) ) {
rpccli_samr_Close ( samr_pipe , mem_ctx , & dom_pol ) ;
}
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 ,
2010-06-07 18:18:12 +04:00
uint32_t * pnum_info ,
struct wbint_userinfo * * pinfo )
2010-06-07 12:18:01 +04:00
{
2010-06-07 18:18:12 +04:00
struct rpc_pipe_client * samr_pipe = NULL ;
struct policy_handle dom_pol ;
2010-06-17 16:55:19 +04:00
struct wbint_userinfo * info = NULL ;
2010-06-07 18:18:12 +04:00
uint32_t num_info = 0 ;
TALLOC_CTX * tmp_ctx ;
NTSTATUS status ;
2010-06-17 16:55:19 +04:00
DEBUG ( 3 , ( " samr_query_user_list \n " ) ) ;
2010-06-07 18:18:12 +04:00
2010-07-06 03:05:39 +04:00
ZERO_STRUCT ( dom_pol ) ;
2010-06-07 18:18:12 +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 ) ) {
2010-06-17 16:55:19 +04:00
goto done ;
2010-06-07 18:18:12 +04:00
}
2010-06-17 16:55:19 +04:00
status = rpc_query_user_list ( tmp_ctx ,
samr_pipe ,
& dom_pol ,
& domain - > sid ,
& num_info ,
& info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
2010-06-07 18:18:12 +04:00
if ( pnum_info ) {
* pnum_info = num_info ;
}
if ( pinfo ) {
* pinfo = talloc_move ( mem_ctx , & info ) ;
}
2010-06-17 16:55:19 +04:00
done :
2010-07-06 03:05:39 +04:00
if ( is_valid_policy_hnd ( & dom_pol ) ) {
rpccli_samr_Close ( samr_pipe , mem_ctx , & dom_pol ) ;
}
2010-06-07 18:18:12 +04:00
TALLOC_FREE ( tmp_ctx ) ;
return status ;
2010-06-07 12:18:01 +04:00
}
/* Lookup user information from a rid or username. */
static NTSTATUS sam_query_user ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
const struct dom_sid * user_sid ,
struct wbint_userinfo * user_info )
{
2010-06-07 23:20:15 +04:00
struct rpc_pipe_client * samr_pipe ;
2010-06-18 19:48:17 +04:00
struct policy_handle dom_pol ;
2010-06-07 23:20:15 +04:00
TALLOC_CTX * tmp_ctx ;
NTSTATUS status ;
2010-06-18 19:48:17 +04:00
DEBUG ( 3 , ( " sam_query_user \n " ) ) ;
2010-06-07 23:20:15 +04:00
2010-07-06 03:05:39 +04:00
ZERO_STRUCT ( dom_pol ) ;
2010-06-18 19:48:17 +04:00
/* Paranoia check */
if ( ! sid_check_is_in_our_domain ( user_sid ) ) {
return NT_STATUS_NO_SUCH_USER ;
2010-06-07 23:20:15 +04:00
}
if ( user_info ) {
user_info - > homedir = NULL ;
user_info - > shell = NULL ;
user_info - > primary_gid = ( gid_t ) - 1 ;
}
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 19:48:17 +04:00
goto done ;
2010-06-07 23:20:15 +04:00
}
2010-06-18 19:48:17 +04:00
status = rpc_query_user ( tmp_ctx ,
samr_pipe ,
& dom_pol ,
& domain - > sid ,
user_sid ,
user_info ) ;
2010-06-07 23:20:15 +04:00
2010-06-18 19:48:17 +04:00
done :
2010-07-06 03:05:39 +04:00
if ( is_valid_policy_hnd ( & dom_pol ) ) {
rpccli_samr_Close ( samr_pipe , mem_ctx , & dom_pol ) ;
}
2010-06-07 23:20:15 +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 ;
struct policy_handle lsa_policy ;
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 ;
NTSTATUS status ;
DEBUG ( 3 , ( " samr: trusted domains \n " ) ) ;
2010-07-06 03:05:39 +04:00
ZERO_STRUCT ( lsa_policy ) ;
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
}
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 :
2010-07-06 03:05:39 +04:00
if ( is_valid_policy_hnd ( & lsa_policy ) ) {
rpccli_lsa_Close ( lsa_pipe , mem_ctx , & lsa_policy ) ;
}
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 ;
2010-06-21 12:28:47 +04:00
struct policy_handle dom_pol ;
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 ;
NTSTATUS status ;
2010-06-21 12:28:47 +04:00
DEBUG ( 3 , ( " sam_lookup_groupmem \n " ) ) ;
2010-06-08 00:15:37 +04:00
2010-07-06 03:05:39 +04:00
ZERO_STRUCT ( dom_pol ) ;
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 ) {
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
}
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 :
2010-07-06 03:05:39 +04:00
if ( is_valid_policy_hnd ( & dom_pol ) ) {
rpccli_samr_Close ( samr_pipe , mem_ctx , & dom_pol ) ;
}
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 ,
uint32 * num_entries ,
struct acct_info * * info )
{
/* 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 ,
uint32 * num_entries ,
struct wbint_userinfo * * info )
{
/* We don't have users */
* num_entries = 0 ;
* info = NULL ;
return NT_STATUS_OK ;
}
/* Lookup user information from a rid or username. */
static NTSTATUS builtin_query_user ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
const struct dom_sid * user_sid ,
struct wbint_userinfo * user_info )
{
return NT_STATUS_NO_SUCH_USER ;
}
/* 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 ,
struct 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 ;
struct policy_handle dom_pol ;
struct acct_info * info = NULL ;
uint32_t num_info = 0 ;
TALLOC_CTX * tmp_ctx ;
NTSTATUS status ;
DEBUG ( 3 , ( " samr: enum local groups \n " ) ) ;
2010-07-06 03:05:39 +04:00
ZERO_STRUCT ( dom_pol ) ;
2010-06-08 10:47:13 +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 ) ) {
2010-06-17 17:53:06 +04:00
goto done ;
2010-06-08 10:47:13 +04:00
}
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 :
2010-07-06 03:05:39 +04:00
if ( is_valid_policy_hnd ( & dom_pol ) ) {
rpccli_samr_Close ( samr_pipe , mem_ctx , & dom_pol ) ;
}
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 ;
struct policy_handle lsa_policy ;
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 ;
NTSTATUS status ;
2010-06-17 18:07:02 +04:00
DEBUG ( 3 , ( " sam_name_to_sid \n " ) ) ;
2010-06-08 16:42:59 +04:00
2010-07-06 03:05:39 +04:00
ZERO_STRUCT ( lsa_policy ) ;
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
}
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 :
2010-07-06 03:05:39 +04:00
if ( is_valid_policy_hnd ( & lsa_policy ) ) {
rpccli_lsa_Close ( lsa_pipe , mem_ctx , & lsa_policy ) ;
}
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 ;
struct policy_handle lsa_policy ;
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 ;
NTSTATUS status ;
2010-06-17 18:25:33 +04:00
DEBUG ( 3 , ( " sam_sid_to_name \n " ) ) ;
2010-07-06 03:05:39 +04:00
ZERO_STRUCT ( lsa_policy ) ;
2010-06-17 18:25:33 +04:00
/* Paranoia check */
if ( ! sid_check_is_in_builtin ( sid ) & &
! sid_check_is_in_our_domain ( sid ) & &
! 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
}
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 :
2010-07-06 03:05:39 +04:00
if ( is_valid_policy_hnd ( & lsa_policy ) ) {
rpccli_lsa_Close ( lsa_pipe , mem_ctx , & lsa_policy ) ;
}
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 ,
const struct dom_sid * sid ,
uint32 * rids ,
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 ;
struct policy_handle lsa_policy ;
enum lsa_SidType * types = NULL ;
char * domain_name = NULL ;
char * * names = NULL ;
TALLOC_CTX * tmp_ctx ;
NTSTATUS status ;
2010-06-17 21:32:18 +04:00
DEBUG ( 3 , ( " sam_rids_to_names for %s \n " , domain - > name ) ) ;
2010-07-06 03:05:39 +04:00
ZERO_STRUCT ( lsa_policy ) ;
2010-06-17 21:32:18 +04:00
/* Paranoia check */
if ( ! sid_check_is_in_builtin ( sid ) & &
! sid_check_is_in_our_domain ( sid ) & &
! 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_rids_to_names: possible deadlock - trying to "
" lookup SID %s \n " , sid_string_dbg ( sid ) ) ) ;
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
}
2010-06-17 21:32:18 +04:00
status = rpc_rids_to_names ( tmp_ctx ,
lsa_pipe ,
& lsa_policy ,
domain ,
sid ,
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 :
2010-07-06 03:05:39 +04:00
if ( is_valid_policy_hnd ( & lsa_policy ) ) {
rpccli_lsa_Close ( lsa_pipe , mem_ctx , & lsa_policy ) ;
}
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 ;
struct policy_handle dom_pol ;
union samr_DomainInfo * info = NULL ;
TALLOC_CTX * tmp_ctx ;
NTSTATUS status ;
2010-06-21 12:53:15 +04:00
DEBUG ( 3 , ( " sam_lockout_policy \n " ) ) ;
2010-06-09 16:39:55 +04:00
2010-07-06 03:05:39 +04:00
ZERO_STRUCT ( dom_pol ) ;
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 ;
}
status = rpccli_samr_QueryDomainInfo ( samr_pipe ,
mem_ctx ,
& dom_pol ,
12 ,
& info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto error ;
}
* lockout_policy = info - > info12 ;
error :
2010-07-06 03:05:39 +04:00
if ( is_valid_policy_hnd ( & dom_pol ) ) {
rpccli_samr_Close ( samr_pipe , mem_ctx , & dom_pol ) ;
}
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 ;
struct policy_handle dom_pol ;
union samr_DomainInfo * info = NULL ;
TALLOC_CTX * tmp_ctx ;
NTSTATUS status ;
2010-06-21 12:54:53 +04:00
DEBUG ( 3 , ( " sam_password_policy \n " ) ) ;
2010-06-09 16:41:54 +04:00
2010-07-06 03:05:39 +04:00
ZERO_STRUCT ( dom_pol ) ;
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 ;
}
status = rpccli_samr_QueryDomainInfo ( samr_pipe ,
mem_ctx ,
& dom_pol ,
1 ,
& info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto error ;
}
* passwd_policy = info - > info1 ;
error :
2010-07-06 03:05:39 +04:00
if ( is_valid_policy_hnd ( & dom_pol ) ) {
rpccli_samr_Close ( samr_pipe , mem_ctx , & dom_pol ) ;
}
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 20:19:50 +04:00
/* Lookup groups a user is a member of. */
static NTSTATUS sam_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 )
2010-06-07 12:18:01 +04:00
{
2010-06-09 16:57:15 +04:00
struct rpc_pipe_client * samr_pipe ;
2010-06-18 20:19:50 +04:00
struct policy_handle dom_pol ;
2010-06-09 16:57:15 +04:00
struct dom_sid * user_grpsids = NULL ;
2010-06-18 20:19:50 +04:00
uint32_t num_groups = 0 ;
2010-06-09 16:57:15 +04:00
TALLOC_CTX * tmp_ctx ;
NTSTATUS status ;
2010-06-18 20:19:50 +04:00
DEBUG ( 3 , ( " sam_lookup_usergroups \n " ) ) ;
2010-06-09 16:57:15 +04:00
2010-07-06 03:05:39 +04:00
ZERO_STRUCT ( dom_pol ) ;
2010-06-09 16:57:15 +04:00
if ( pnum_groups ) {
* pnum_groups = 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 20:19:50 +04:00
goto done ;
2010-06-09 16:57:15 +04:00
}
2010-06-18 20:19:50 +04:00
status = rpc_lookup_usergroups ( tmp_ctx ,
samr_pipe ,
& dom_pol ,
& domain - > sid ,
user_sid ,
& num_groups ,
& user_grpsids ) ;
2010-06-09 16:57:15 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-06-18 20:19:50 +04:00
goto done ;
2010-06-09 16:57:15 +04:00
}
if ( pnum_groups ) {
* pnum_groups = num_groups ;
}
if ( puser_grpsids ) {
* puser_grpsids = talloc_move ( mem_ctx , & user_grpsids ) ;
}
2010-06-18 20:19:50 +04:00
done :
2010-07-06 03:05:39 +04:00
if ( is_valid_policy_hnd ( & dom_pol ) ) {
rpccli_samr_Close ( samr_pipe , mem_ctx , & dom_pol ) ;
}
2010-06-09 16:57:15 +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 ;
struct policy_handle dom_pol ;
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 ;
NTSTATUS status ;
2010-06-18 21:08:28 +04:00
DEBUG ( 3 , ( " sam_lookup_useraliases \n " ) ) ;
2010-06-09 17:12:37 +04:00
2010-07-06 03:05:39 +04:00
ZERO_STRUCT ( dom_pol ) ;
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
}
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 :
2010-07-06 03:05:39 +04:00
if ( is_valid_policy_hnd ( & dom_pol ) ) {
rpccli_samr_Close ( samr_pipe , mem_ctx , & dom_pol ) ;
}
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 ;
struct policy_handle dom_pol ;
2010-06-21 12:47:54 +04:00
uint32_t seq ;
TALLOC_CTX * tmp_ctx ;
2010-06-09 17:20:13 +04:00
NTSTATUS status ;
DEBUG ( 3 , ( " samr: sequence number \n " ) ) ;
2010-07-06 03:05:39 +04:00
ZERO_STRUCT ( dom_pol ) ;
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
}
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 :
2010-07-06 03:05:39 +04:00
if ( is_valid_policy_hnd ( & dom_pol ) ) {
rpccli_samr_Close ( samr_pipe , tmp_ctx , & dom_pol ) ;
}
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-07 12:18:01 +04:00
. query_user = builtin_query_user ,
2010-06-18 20:19:50 +04:00
. lookup_usergroups = sam_lookup_usergroups ,
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-07 12:18:01 +04:00
. query_user = sam_query_user ,
2010-06-18 20:19:50 +04:00
. lookup_usergroups = sam_lookup_usergroups ,
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
} ;