2005-06-09 02:10:34 +04:00
/*
Unix SMB / CIFS implementation .
Async helpers for blocking functions
Copyright ( C ) Volker Lendecke 2005
2006-07-13 22:10:29 +04:00
Copyright ( C ) Gerald Carter 2006
2005-06-09 02:10:34 +04:00
The helpers always consist of three functions :
* A request setup function that takes the necessary parameters together
with a continuation function that is to be called upon completion
* A private continuation function that is internal only . This is to be
called by the lower - level functions in do_async ( ) . Its only task is to
properly call the continuation function named above .
* A worker function that is called inside the appropriate child process .
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 .
*/
# include "includes.h"
# include "winbindd.h"
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_WINBIND
struct do_async_state {
TALLOC_CTX * mem_ctx ;
struct winbindd_request request ;
struct winbindd_response response ;
void ( * cont ) ( TALLOC_CTX * mem_ctx ,
BOOL success ,
struct winbindd_response * response ,
2005-06-25 00:25:18 +04:00
void * c , void * private_data ) ;
void * c , * private_data ;
2005-06-09 02:10:34 +04:00
} ;
2005-06-25 00:25:18 +04:00
static void do_async_recv ( void * private_data , BOOL success )
2005-06-09 02:10:34 +04:00
{
struct do_async_state * state =
2005-06-25 00:25:18 +04:00
talloc_get_type_abort ( private_data , struct do_async_state ) ;
2005-06-09 02:10:34 +04:00
state - > cont ( state - > mem_ctx , success , & state - > response ,
2005-06-25 00:25:18 +04:00
state - > c , state - > private_data ) ;
2005-06-09 02:10:34 +04:00
}
static void do_async ( TALLOC_CTX * mem_ctx , struct winbindd_child * child ,
const struct winbindd_request * request ,
void ( * cont ) ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
2005-06-25 00:25:18 +04:00
void * c , void * private_data ) ,
void * c , void * private_data )
2005-06-09 02:10:34 +04:00
{
struct do_async_state * state ;
2006-10-16 04:12:00 +04:00
state = TALLOC_ZERO_P ( mem_ctx , struct do_async_state ) ;
2005-06-09 02:10:34 +04:00
if ( state = = NULL ) {
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( mem_ctx , False , NULL , c , private_data ) ;
2005-06-09 02:10:34 +04:00
return ;
}
state - > mem_ctx = mem_ctx ;
state - > request = * request ;
state - > request . length = sizeof ( state - > request ) ;
state - > cont = cont ;
state - > c = c ;
2005-06-25 00:25:18 +04:00
state - > private_data = private_data ;
2005-06-09 02:10:34 +04:00
async_request ( mem_ctx , child , & state - > request ,
& state - > response , do_async_recv , state ) ;
}
2005-09-30 21:13:37 +04:00
void do_async_domain ( TALLOC_CTX * mem_ctx , struct winbindd_domain * domain ,
const struct winbindd_request * request ,
void ( * cont ) ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
void * c , void * private_data ) ,
void * c , void * private_data )
2005-06-09 02:10:34 +04:00
{
struct do_async_state * state ;
2006-10-16 04:12:00 +04:00
state = TALLOC_ZERO_P ( mem_ctx , struct do_async_state ) ;
2005-06-09 02:10:34 +04:00
if ( state = = NULL ) {
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( mem_ctx , False , NULL , c , private_data ) ;
2005-06-09 02:10:34 +04:00
return ;
}
state - > mem_ctx = mem_ctx ;
state - > request = * request ;
state - > request . length = sizeof ( state - > request ) ;
state - > cont = cont ;
state - > c = c ;
2005-06-25 00:25:18 +04:00
state - > private_data = private_data ;
2005-06-09 02:10:34 +04:00
async_domain_request ( mem_ctx , domain , & state - > request ,
& state - > response , do_async_recv , state ) ;
}
2006-12-12 17:52:13 +03:00
static void winbindd_set_mapping_recv ( TALLOC_CTX * mem_ctx , BOOL success ,
2005-06-09 02:10:34 +04:00
struct winbindd_response * response ,
2005-06-25 00:25:18 +04:00
void * c , void * private_data )
2005-06-09 02:10:34 +04:00
{
2006-07-11 22:01:26 +04:00
void ( * cont ) ( void * priv , BOOL succ ) = ( void ( * ) ( void * , BOOL ) ) c ;
2005-06-09 02:10:34 +04:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger idmap_set_mapping \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False ) ;
2005-06-09 02:10:34 +04:00
return ;
}
if ( response - > result ! = WINBINDD_OK ) {
DEBUG ( 5 , ( " idmap_set_mapping returned an error \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2005-06-25 00:25:18 +04:00
cont ( private_data , True ) ;
2005-06-09 02:10:34 +04:00
}
2006-12-12 17:52:13 +03:00
void winbindd_set_mapping_async ( TALLOC_CTX * mem_ctx , const struct id_map * map ,
2005-06-25 00:25:18 +04:00
void ( * cont ) ( void * private_data , BOOL success ) ,
void * private_data )
2005-06-09 02:10:34 +04:00
{
struct winbindd_request request ;
ZERO_STRUCT ( request ) ;
2006-12-12 17:52:13 +03:00
request . cmd = WINBINDD_DUAL_SET_MAPPING ;
request . data . dual_idmapset . id = map - > xid . id ;
request . data . dual_idmapset . type = map - > xid . type ;
sid_to_string ( request . data . dual_idmapset . sid , map - > sid ) ;
do_async ( mem_ctx , idmap_child ( ) , & request , winbindd_set_mapping_recv ,
2006-07-11 22:01:26 +04:00
( void * ) cont , private_data ) ;
2005-06-09 02:10:34 +04:00
}
2006-12-12 17:52:13 +03:00
enum winbindd_result winbindd_dual_set_mapping ( struct winbindd_domain * domain ,
2005-06-09 02:10:34 +04:00
struct winbindd_cli_state * state )
{
2006-12-12 17:52:13 +03:00
struct id_map map ;
2005-06-09 02:10:34 +04:00
DOM_SID sid ;
NTSTATUS result ;
DEBUG ( 3 , ( " [%5lu]: dual_idmapset \n " , ( unsigned long ) state - > pid ) ) ;
if ( ! string_to_sid ( & sid , state - > request . data . dual_idmapset . sid ) )
return WINBINDD_ERROR ;
2006-12-12 17:52:13 +03:00
map . sid = & sid ;
map . xid . id = state - > request . data . dual_idmapset . id ;
map . xid . type = state - > request . data . dual_idmapset . type ;
2007-05-05 02:41:35 +04:00
map . status = ID_MAPPED ;
2005-06-09 02:10:34 +04:00
2006-12-12 17:52:13 +03:00
result = idmap_set_mapping ( & map ) ;
2005-06-09 02:10:34 +04:00
return NT_STATUS_IS_OK ( result ) ? WINBINDD_OK : WINBINDD_ERROR ;
}
2006-12-12 17:52:13 +03:00
static void winbindd_set_hwm_recv ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
void * c , void * private_data )
{
void ( * cont ) ( void * priv , BOOL succ ) = ( void ( * ) ( void * , BOOL ) ) c ;
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger idmap_set_hwm \n " ) ) ;
cont ( private_data , False ) ;
return ;
}
if ( response - > result ! = WINBINDD_OK ) {
DEBUG ( 5 , ( " idmap_set_hwm returned an error \n " ) ) ;
cont ( private_data , False ) ;
return ;
}
cont ( private_data , True ) ;
}
void winbindd_set_hwm_async ( TALLOC_CTX * mem_ctx , const struct unixid * xid ,
void ( * cont ) ( void * private_data , BOOL success ) ,
void * private_data )
{
struct winbindd_request request ;
ZERO_STRUCT ( request ) ;
request . cmd = WINBINDD_DUAL_SET_HWM ;
request . data . dual_idmapset . id = xid - > id ;
request . data . dual_idmapset . type = xid - > type ;
do_async ( mem_ctx , idmap_child ( ) , & request , winbindd_set_hwm_recv ,
( void * ) cont , private_data ) ;
}
enum winbindd_result winbindd_dual_set_hwm ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
struct unixid xid ;
NTSTATUS result ;
DEBUG ( 3 , ( " [%5lu]: dual_set_hwm \n " , ( unsigned long ) state - > pid ) ) ;
xid . id = state - > request . data . dual_idmapset . id ;
xid . type = state - > request . data . dual_idmapset . type ;
switch ( xid . type ) {
case ID_TYPE_UID :
result = idmap_set_uid_hwm ( & xid ) ;
break ;
case ID_TYPE_GID :
result = idmap_set_gid_hwm ( & xid ) ;
break ;
default :
return WINBINDD_ERROR ;
}
return NT_STATUS_IS_OK ( result ) ? WINBINDD_OK : WINBINDD_ERROR ;
}
static void winbindd_sids2xids_recv ( TALLOC_CTX * mem_ctx , BOOL success ,
2005-06-09 02:10:34 +04:00
struct winbindd_response * response ,
2006-12-12 17:52:13 +03:00
void * c , void * private_data )
{
void ( * cont ) ( void * priv , BOOL succ , void * , int ) =
( void ( * ) ( void * , BOOL , void * , int ) ) c ;
2005-06-09 02:10:34 +04:00
2006-12-12 17:52:13 +03:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger sids2xids \n " ) ) ;
cont ( private_data , False , NULL , 0 ) ;
return ;
}
if ( response - > result ! = WINBINDD_OK ) {
DEBUG ( 5 , ( " sids2xids returned an error \n " ) ) ;
cont ( private_data , False , NULL , 0 ) ;
return ;
}
cont ( private_data , True , response - > extra_data . data , response - > length - sizeof ( response ) ) ;
}
void winbindd_sids2xids_async ( TALLOC_CTX * mem_ctx , void * sids , int size ,
void ( * cont ) ( void * private_data , BOOL success , void * data , int len ) ,
2005-06-25 00:25:18 +04:00
void * private_data )
2005-06-09 02:10:34 +04:00
{
struct winbindd_request request ;
ZERO_STRUCT ( request ) ;
2006-12-12 17:52:13 +03:00
request . cmd = WINBINDD_DUAL_SIDS2XIDS ;
2006-12-27 13:26:32 +03:00
request . extra_data . data = ( char * ) sids ;
2006-12-12 17:52:13 +03:00
request . extra_len = size ;
do_async ( mem_ctx , idmap_child ( ) , & request , winbindd_sids2xids_recv ,
2006-07-11 22:01:26 +04:00
( void * ) cont , private_data ) ;
2005-06-09 02:10:34 +04:00
}
2006-12-12 17:52:13 +03:00
enum winbindd_result winbindd_dual_sids2xids ( struct winbindd_domain * domain ,
2005-06-09 02:10:34 +04:00
struct winbindd_cli_state * state )
{
2006-12-12 17:52:13 +03:00
DOM_SID * sids ;
struct unixid * xids ;
struct id_map * * ids ;
2005-06-09 02:10:34 +04:00
NTSTATUS result ;
2006-12-12 17:52:13 +03:00
int num , i ;
2005-06-09 02:10:34 +04:00
2006-12-12 17:52:13 +03:00
DEBUG ( 3 , ( " [%5lu]: sids to unix ids \n " , ( unsigned long ) state - > pid ) ) ;
2005-06-09 02:10:34 +04:00
2007-05-05 02:01:26 +04:00
if ( state - > request . extra_len = = 0 ) {
DEBUG ( 0 , ( " Invalid buffer size! \n " ) ) ;
return WINBINDD_ERROR ;
}
2006-12-12 17:52:13 +03:00
sids = ( DOM_SID * ) state - > request . extra_data . data ;
num = state - > request . extra_len / sizeof ( DOM_SID ) ;
2007-04-28 03:18:41 +04:00
ids = TALLOC_ZERO_ARRAY ( state - > mem_ctx , struct id_map * , num + 1 ) ;
2006-12-12 17:52:13 +03:00
if ( ! ids ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
2005-06-09 02:10:34 +04:00
return WINBINDD_ERROR ;
}
2006-12-12 17:52:13 +03:00
for ( i = 0 ; i < num ; i + + ) {
2007-04-28 03:18:41 +04:00
ids [ i ] = TALLOC_P ( ids , struct id_map ) ;
2006-12-12 17:52:13 +03:00
if ( ! ids [ i ] ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
talloc_free ( ids ) ;
return WINBINDD_ERROR ;
}
ids [ i ] - > sid = & sids [ i ] ;
}
2005-06-09 02:10:34 +04:00
2006-12-12 17:52:13 +03:00
result = idmap_sids_to_unixids ( ids ) ;
2005-06-09 02:10:34 +04:00
2006-12-12 17:52:13 +03:00
if ( NT_STATUS_IS_OK ( result ) ) {
2005-06-09 02:10:34 +04:00
2006-12-12 17:52:13 +03:00
xids = SMB_MALLOC_ARRAY ( struct unixid , num ) ;
if ( ! xids ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
talloc_free ( ids ) ;
return WINBINDD_ERROR ;
}
for ( i = 0 ; i < num ; i + + ) {
2007-01-14 20:58:24 +03:00
if ( ids [ i ] - > status = = ID_MAPPED ) {
2006-12-12 17:52:13 +03:00
xids [ i ] . type = ids [ i ] - > xid . type ;
xids [ i ] . id = ids [ i ] - > xid . id ;
} else {
xids [ i ] . type = - 1 ;
}
}
state - > response . length = sizeof ( state - > response ) + ( sizeof ( struct unixid ) * num ) ;
state - > response . extra_data . data = xids ;
} else {
DEBUG ( 2 , ( " idmap_sids_to_unixids returned an error: 0x%08x \n " , NT_STATUS_V ( result ) ) ) ;
talloc_free ( ids ) ;
return WINBINDD_ERROR ;
}
talloc_free ( ids ) ;
return WINBINDD_OK ;
2005-06-09 02:10:34 +04:00
}
2006-12-12 17:52:13 +03:00
static void winbindd_sid2uid_recv ( TALLOC_CTX * mem_ctx , BOOL success ,
2005-06-09 02:10:34 +04:00
struct winbindd_response * response ,
2005-06-25 00:25:18 +04:00
void * c , void * private_data )
2005-06-09 02:10:34 +04:00
{
2006-07-11 22:01:26 +04:00
void ( * cont ) ( void * priv , BOOL succ , uid_t uid ) =
( void ( * ) ( void * , BOOL , uid_t ) ) c ;
2005-06-09 02:10:34 +04:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger sid2uid \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
if ( response - > result ! = WINBINDD_OK ) {
DEBUG ( 5 , ( " sid2uid returned an error \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2005-06-25 00:25:18 +04:00
cont ( private_data , True , response - > data . uid ) ;
2005-06-09 02:10:34 +04:00
}
2006-12-12 17:52:13 +03:00
void winbindd_sid2uid_async ( TALLOC_CTX * mem_ctx , const DOM_SID * sid ,
void ( * cont ) ( void * private_data , BOOL success , uid_t uid ) ,
void * private_data )
{
struct winbindd_request request ;
ZERO_STRUCT ( request ) ;
request . cmd = WINBINDD_DUAL_SID2UID ;
sid_to_string ( request . data . dual_sid2id . sid , sid ) ;
do_async ( mem_ctx , idmap_child ( ) , & request , winbindd_sid2uid_recv ,
( void * ) cont , private_data ) ;
}
enum winbindd_result winbindd_dual_sid2uid ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
DOM_SID sid ;
NTSTATUS result ;
DEBUG ( 3 , ( " [%5lu]: sid to uid %s \n " , ( unsigned long ) state - > pid ,
state - > request . data . dual_sid2id . sid ) ) ;
if ( ! string_to_sid ( & sid , state - > request . data . dual_sid2id . sid ) ) {
DEBUG ( 1 , ( " Could not get convert sid %s from string \n " ,
state - > request . data . dual_sid2id . sid ) ) ;
return WINBINDD_ERROR ;
}
/* Find uid for this sid and return it, possibly ask the slow remote idmap */
result = idmap_sid_to_uid ( & sid , & ( state - > response . data . uid ) ) ;
return NT_STATUS_IS_OK ( result ) ? WINBINDD_OK : WINBINDD_ERROR ;
}
#if 0 /* not used */
2005-06-09 02:10:34 +04:00
static void uid2name_recv ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
2005-06-25 00:25:18 +04:00
void * c , void * private_data ) ;
2005-06-09 02:10:34 +04:00
void winbindd_uid2name_async ( TALLOC_CTX * mem_ctx , uid_t uid ,
2005-06-25 00:25:18 +04:00
void ( * cont ) ( void * private_data , BOOL success ,
2005-06-09 02:10:34 +04:00
const char * name ) ,
2005-06-25 00:25:18 +04:00
void * private_data )
2005-06-09 02:10:34 +04:00
{
struct winbindd_request request ;
ZERO_STRUCT ( request ) ;
request . cmd = WINBINDD_DUAL_UID2NAME ;
request . data . uid = uid ;
do_async ( mem_ctx , idmap_child ( ) , & request , uid2name_recv ,
2006-07-11 22:01:26 +04:00
( void * ) cont , private_data ) ;
2005-06-09 02:10:34 +04:00
}
2006-12-12 17:52:13 +03:00
# endif /* not used */
2005-06-09 02:10:34 +04:00
enum winbindd_result winbindd_dual_uid2name ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
struct passwd * pw ;
DEBUG ( 3 , ( " [%5lu]: uid2name %lu \n " , ( unsigned long ) state - > pid ,
( unsigned long ) state - > request . data . uid ) ) ;
pw = getpwuid ( state - > request . data . uid ) ;
if ( pw = = NULL ) {
DEBUG ( 5 , ( " User %lu not found \n " ,
( unsigned long ) state - > request . data . uid ) ) ;
return WINBINDD_ERROR ;
}
fstrcpy ( state - > response . data . name . name , pw - > pw_name ) ;
return WINBINDD_OK ;
}
2006-12-12 17:52:13 +03:00
#if 0 /* not used */
2005-06-09 02:10:34 +04:00
static void uid2name_recv ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
2005-06-25 00:25:18 +04:00
void * c , void * private_data )
2005-06-09 02:10:34 +04:00
{
2006-07-11 22:01:26 +04:00
void ( * cont ) ( void * priv , BOOL succ , const char * name ) =
( void ( * ) ( void * , BOOL , const char * ) ) c ;
2005-06-09 02:10:34 +04:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger uid2name \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , NULL ) ;
2005-06-09 02:10:34 +04:00
return ;
}
if ( response - > result ! = WINBINDD_OK ) {
DEBUG ( 5 , ( " uid2name returned an error \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , NULL ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2005-06-25 00:25:18 +04:00
cont ( private_data , True , response - > data . name . name ) ;
2005-06-09 02:10:34 +04:00
}
static void name2uid_recv ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
2005-06-25 00:25:18 +04:00
void * c , void * private_data ) ;
2005-06-09 02:10:34 +04:00
static void winbindd_name2uid_async ( TALLOC_CTX * mem_ctx , const char * name ,
2005-06-25 00:25:18 +04:00
void ( * cont ) ( void * private_data , BOOL success ,
2005-06-09 02:10:34 +04:00
uid_t uid ) ,
2005-06-25 00:25:18 +04:00
void * private_data )
2005-06-09 02:10:34 +04:00
{
struct winbindd_request request ;
ZERO_STRUCT ( request ) ;
request . cmd = WINBINDD_DUAL_NAME2UID ;
fstrcpy ( request . data . username , name ) ;
do_async ( mem_ctx , idmap_child ( ) , & request , name2uid_recv ,
2006-07-11 22:01:26 +04:00
( void * ) cont , private_data ) ;
2005-06-09 02:10:34 +04:00
}
2006-12-12 17:52:13 +03:00
# endif /* not used */
2005-06-09 02:10:34 +04:00
enum winbindd_result winbindd_dual_name2uid ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
struct passwd * pw ;
/* Ensure null termination */
state - > request . data . username
[ sizeof ( state - > request . data . username ) - 1 ] = ' \0 ' ;
DEBUG ( 3 , ( " [%5lu]: name2uid %s \n " , ( unsigned long ) state - > pid ,
state - > request . data . username ) ) ;
pw = getpwnam ( state - > request . data . username ) ;
if ( pw = = NULL ) {
return WINBINDD_ERROR ;
}
state - > response . data . uid = pw - > pw_uid ;
return WINBINDD_OK ;
}
2006-12-12 17:52:13 +03:00
#if 0 /* not used */
2005-06-09 02:10:34 +04:00
static void name2uid_recv ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
2005-06-25 00:25:18 +04:00
void * c , void * private_data )
2005-06-09 02:10:34 +04:00
{
2006-07-11 22:01:26 +04:00
void ( * cont ) ( void * priv , BOOL succ , uid_t uid ) =
( void ( * ) ( void * , BOOL , uid_t ) ) c ;
2005-06-09 02:10:34 +04:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger name2uid \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
if ( response - > result ! = WINBINDD_OK ) {
DEBUG ( 5 , ( " name2uid returned an error \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2005-06-25 00:25:18 +04:00
cont ( private_data , True , response - > data . uid ) ;
2005-06-09 02:10:34 +04:00
}
2006-12-12 17:52:13 +03:00
# endif /* not used */
2005-06-09 02:10:34 +04:00
2006-12-12 17:52:13 +03:00
static void winbindd_sid2gid_recv ( TALLOC_CTX * mem_ctx , BOOL success ,
2005-06-09 02:10:34 +04:00
struct winbindd_response * response ,
2006-12-12 17:52:13 +03:00
void * c , void * private_data )
{
void ( * cont ) ( void * priv , BOOL succ , gid_t gid ) =
( void ( * ) ( void * , BOOL , gid_t ) ) c ;
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger sid2gid \n " ) ) ;
cont ( private_data , False , 0 ) ;
return ;
}
if ( response - > result ! = WINBINDD_OK ) {
DEBUG ( 5 , ( " sid2gid returned an error \n " ) ) ;
cont ( private_data , False , 0 ) ;
return ;
}
2005-06-09 02:10:34 +04:00
2006-12-12 17:52:13 +03:00
cont ( private_data , True , response - > data . gid ) ;
}
void winbindd_sid2gid_async ( TALLOC_CTX * mem_ctx , const DOM_SID * sid ,
2005-06-25 00:25:18 +04:00
void ( * cont ) ( void * private_data , BOOL success , gid_t gid ) ,
void * private_data )
2005-06-09 02:10:34 +04:00
{
struct winbindd_request request ;
ZERO_STRUCT ( request ) ;
request . cmd = WINBINDD_DUAL_SID2GID ;
sid_to_string ( request . data . dual_sid2id . sid , sid ) ;
2006-03-15 06:46:20 +03:00
2007-03-01 06:16:38 +03:00
DEBUG ( 7 , ( " winbindd_sid2gid_async: Resolving %s to a gid \n " ,
2006-03-15 06:46:20 +03:00
request . data . dual_sid2id . sid ) ) ;
2006-12-12 17:52:13 +03:00
do_async ( mem_ctx , idmap_child ( ) , & request , winbindd_sid2gid_recv ,
2006-07-11 22:01:26 +04:00
( void * ) cont , private_data ) ;
2005-06-09 02:10:34 +04:00
}
enum winbindd_result winbindd_dual_sid2gid ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
DOM_SID sid ;
NTSTATUS result ;
DEBUG ( 3 , ( " [%5lu]: sid to gid %s \n " , ( unsigned long ) state - > pid ,
state - > request . data . dual_sid2id . sid ) ) ;
if ( ! string_to_sid ( & sid , state - > request . data . dual_sid2id . sid ) ) {
DEBUG ( 1 , ( " Could not get convert sid %s from string \n " ,
state - > request . data . dual_sid2id . sid ) ) ;
return WINBINDD_ERROR ;
}
2006-12-12 17:52:13 +03:00
/* Find gid for this sid and return it, possibly ask the slow remote idmap */
2006-03-15 06:46:20 +03:00
2006-12-12 17:52:13 +03:00
result = idmap_sid_to_gid ( & sid , & state - > response . data . gid ) ;
DEBUG ( 10 , ( " winbindd_dual_sid2gid: 0x%08x - %s - %u \n " , NT_STATUS_V ( result ) , sid_string_static ( & sid ) , state - > response . data . gid ) ) ;
2006-03-15 06:46:20 +03:00
2005-06-09 02:10:34 +04:00
return NT_STATUS_IS_OK ( result ) ? WINBINDD_OK : WINBINDD_ERROR ;
}
static void gid2name_recv ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
2005-06-25 00:25:18 +04:00
void * c , void * private_data )
2005-06-09 02:10:34 +04:00
{
2006-07-11 22:01:26 +04:00
void ( * cont ) ( void * priv , BOOL succ , const char * name ) =
( void ( * ) ( void * , BOOL , const char * ) ) c ;
2005-06-09 02:10:34 +04:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger gid2name \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , NULL ) ;
2005-06-09 02:10:34 +04:00
return ;
}
if ( response - > result ! = WINBINDD_OK ) {
DEBUG ( 5 , ( " gid2name returned an error \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , NULL ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2005-06-25 00:25:18 +04:00
cont ( private_data , True , response - > data . name . name ) ;
2005-06-09 02:10:34 +04:00
}
void winbindd_gid2name_async ( TALLOC_CTX * mem_ctx , gid_t gid ,
2005-06-25 00:25:18 +04:00
void ( * cont ) ( void * private_data , BOOL success ,
2005-06-09 02:10:34 +04:00
const char * name ) ,
2005-06-25 00:25:18 +04:00
void * private_data )
2005-06-09 02:10:34 +04:00
{
struct winbindd_request request ;
ZERO_STRUCT ( request ) ;
request . cmd = WINBINDD_DUAL_GID2NAME ;
request . data . gid = gid ;
do_async ( mem_ctx , idmap_child ( ) , & request , gid2name_recv ,
2006-07-11 22:01:26 +04:00
( void * ) cont , private_data ) ;
2005-06-09 02:10:34 +04:00
}
enum winbindd_result winbindd_dual_gid2name ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
struct group * gr ;
DEBUG ( 3 , ( " [%5lu]: gid2name %lu \n " , ( unsigned long ) state - > pid ,
( unsigned long ) state - > request . data . gid ) ) ;
gr = getgrgid ( state - > request . data . gid ) ;
if ( gr = = NULL )
return WINBINDD_ERROR ;
fstrcpy ( state - > response . data . name . name , gr - > gr_name ) ;
return WINBINDD_OK ;
}
2006-12-12 17:52:13 +03:00
#if 0 /* not used */
2005-06-09 02:10:34 +04:00
static void name2gid_recv ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
2005-06-25 00:25:18 +04:00
void * c , void * private_data ) ;
2005-06-09 02:10:34 +04:00
static void winbindd_name2gid_async ( TALLOC_CTX * mem_ctx , const char * name ,
2005-06-25 00:25:18 +04:00
void ( * cont ) ( void * private_data , BOOL success ,
2005-06-09 02:10:34 +04:00
gid_t gid ) ,
2005-06-25 00:25:18 +04:00
void * private_data )
2005-06-09 02:10:34 +04:00
{
struct winbindd_request request ;
ZERO_STRUCT ( request ) ;
request . cmd = WINBINDD_DUAL_NAME2GID ;
fstrcpy ( request . data . groupname , name ) ;
do_async ( mem_ctx , idmap_child ( ) , & request , name2gid_recv ,
2006-07-11 22:01:26 +04:00
( void * ) cont , private_data ) ;
2005-06-09 02:10:34 +04:00
}
2006-12-12 17:52:13 +03:00
# endif /* not used */
2005-06-09 02:10:34 +04:00
enum winbindd_result winbindd_dual_name2gid ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
struct group * gr ;
/* Ensure null termination */
state - > request . data . groupname
[ sizeof ( state - > request . data . groupname ) - 1 ] = ' \0 ' ;
DEBUG ( 3 , ( " [%5lu]: name2gid %s \n " , ( unsigned long ) state - > pid ,
state - > request . data . groupname ) ) ;
gr = getgrnam ( state - > request . data . groupname ) ;
if ( gr = = NULL ) {
return WINBINDD_ERROR ;
}
state - > response . data . gid = gr - > gr_gid ;
return WINBINDD_OK ;
}
2006-12-12 17:52:13 +03:00
#if 0 /* not used */
2005-06-09 02:10:34 +04:00
static void name2gid_recv ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
2005-06-25 00:25:18 +04:00
void * c , void * private_data )
2005-06-09 02:10:34 +04:00
{
2006-07-11 22:01:26 +04:00
void ( * cont ) ( void * priv , BOOL succ , gid_t gid ) =
( void ( * ) ( void * , BOOL , gid_t ) ) c ;
2005-06-09 02:10:34 +04:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger name2gid \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
if ( response - > result ! = WINBINDD_OK ) {
DEBUG ( 5 , ( " name2gid returned an error \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2005-06-25 00:25:18 +04:00
cont ( private_data , True , response - > data . gid ) ;
2005-06-09 02:10:34 +04:00
}
2006-12-12 17:52:13 +03:00
# endif /* not used */
2005-06-09 02:10:34 +04:00
2007-05-06 23:01:54 +04:00
struct lookupsid_state {
DOM_SID sid ;
void * caller_private_data ;
} ;
static void lookupsid_recv2 ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
void * c , void * private_data )
{
void ( * cont ) ( void * priv , BOOL succ , const char * dom_name ,
const char * name , enum lsa_SidType type ) =
( void ( * ) ( void * , BOOL , const char * , const char * ,
enum lsa_SidType ) ) c ;
struct lookupsid_state * s = talloc_get_type_abort ( private_data ,
struct lookupsid_state ) ;
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger lookupsid \n " ) ) ;
cont ( s - > caller_private_data , False , NULL , NULL , SID_NAME_UNKNOWN ) ;
return ;
}
if ( response - > result ! = WINBINDD_OK ) {
DEBUG ( 5 , ( " lookupsid (forest root) returned an error \n " ) ) ;
cont ( s - > caller_private_data , False , NULL , NULL , SID_NAME_UNKNOWN ) ;
return ;
}
cont ( s - > caller_private_data , True , response - > data . name . dom_name ,
response - > data . name . name ,
( enum lsa_SidType ) response - > data . name . type ) ;
}
2005-06-09 02:10:34 +04:00
static void lookupsid_recv ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
2005-06-25 00:25:18 +04:00
void * c , void * private_data )
2005-06-09 02:10:34 +04:00
{
void ( * cont ) ( void * priv , BOOL succ , const char * dom_name ,
2006-09-08 18:28:06 +04:00
const char * name , enum lsa_SidType type ) =
2006-07-11 22:01:26 +04:00
( void ( * ) ( void * , BOOL , const char * , const char * ,
2006-09-08 18:28:06 +04:00
enum lsa_SidType ) ) c ;
2007-05-06 23:01:54 +04:00
struct lookupsid_state * s = talloc_get_type_abort ( private_data ,
struct lookupsid_state ) ;
2005-06-09 02:10:34 +04:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger lookupsid \n " ) ) ;
2007-05-06 23:01:54 +04:00
cont ( s - > caller_private_data , False , NULL , NULL , SID_NAME_UNKNOWN ) ;
2005-06-09 02:10:34 +04:00
return ;
}
if ( response - > result ! = WINBINDD_OK ) {
2007-05-06 23:01:54 +04:00
/* Try again using the forest root */
struct winbindd_domain * root_domain = find_root_domain ( ) ;
struct winbindd_request request ;
if ( ! root_domain ) {
DEBUG ( 5 , ( " lookupsid_recv: unable to determine forest root \n " ) ) ;
cont ( s - > caller_private_data , False , NULL , NULL , SID_NAME_UNKNOWN ) ;
return ;
}
ZERO_STRUCT ( request ) ;
request . cmd = WINBINDD_LOOKUPSID ;
fstrcpy ( request . data . sid , sid_string_static ( & s - > sid ) ) ;
do_async_domain ( mem_ctx , root_domain , & request , lookupsid_recv2 ,
( void * ) cont , s ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2007-05-06 23:01:54 +04:00
cont ( s - > caller_private_data , True , response - > data . name . dom_name ,
2006-07-11 22:01:26 +04:00
response - > data . name . name ,
2006-09-08 18:28:06 +04:00
( enum lsa_SidType ) response - > data . name . type ) ;
2005-06-09 02:10:34 +04:00
}
void winbindd_lookupsid_async ( TALLOC_CTX * mem_ctx , const DOM_SID * sid ,
2005-06-25 00:25:18 +04:00
void ( * cont ) ( void * private_data , BOOL success ,
2005-06-09 02:10:34 +04:00
const char * dom_name ,
const char * name ,
2006-09-08 18:28:06 +04:00
enum lsa_SidType type ) ,
2005-06-25 00:25:18 +04:00
void * private_data )
2005-06-09 02:10:34 +04:00
{
struct winbindd_domain * domain ;
struct winbindd_request request ;
2007-05-06 23:01:54 +04:00
struct lookupsid_state * s ;
2005-06-09 02:10:34 +04:00
domain = find_lookup_domain_from_sid ( sid ) ;
if ( domain = = NULL ) {
DEBUG ( 5 , ( " Could not find domain for sid %s \n " ,
sid_string_static ( sid ) ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , NULL , NULL , SID_NAME_UNKNOWN ) ;
2005-06-09 02:10:34 +04:00
return ;
}
ZERO_STRUCT ( request ) ;
request . cmd = WINBINDD_LOOKUPSID ;
fstrcpy ( request . data . sid , sid_string_static ( sid ) ) ;
2007-05-06 23:01:54 +04:00
if ( ( s = TALLOC_ZERO_P ( mem_ctx , struct lookupsid_state ) ) = = NULL ) {
DEBUG ( 0 , ( " winbindd_lookupsid_async: talloc failed \n " ) ) ;
cont ( private_data , False , NULL , NULL , SID_NAME_UNKNOWN ) ;
return ;
}
sid_copy ( & s - > sid , sid ) ;
s - > caller_private_data = private_data ;
2005-06-09 02:10:34 +04:00
do_async_domain ( mem_ctx , domain , & request , lookupsid_recv ,
2007-05-06 23:42:25 +04:00
( void * ) cont , s ) ;
2005-06-09 02:10:34 +04:00
}
enum winbindd_result winbindd_dual_lookupsid ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
2006-09-08 18:28:06 +04:00
enum lsa_SidType type ;
2005-06-09 02:10:34 +04:00
DOM_SID sid ;
2006-12-13 19:39:50 +03:00
char * name ;
char * dom_name ;
2005-06-09 02:10:34 +04:00
/* Ensure null termination */
state - > request . data . sid [ sizeof ( state - > request . data . sid ) - 1 ] = ' \0 ' ;
DEBUG ( 3 , ( " [%5lu]: lookupsid %s \n " , ( unsigned long ) state - > pid ,
state - > request . data . sid ) ) ;
/* Lookup sid from PDC using lsa_lookup_sids() */
if ( ! string_to_sid ( & sid , state - > request . data . sid ) ) {
DEBUG ( 5 , ( " %s not a SID \n " , state - > request . data . sid ) ) ;
return WINBINDD_ERROR ;
}
/* Lookup the sid */
2007-05-06 23:01:54 +04:00
if ( ! winbindd_lookup_name_by_sid ( state - > mem_ctx , domain , & sid ,
& dom_name , & name , & type ) )
{
2006-12-12 17:52:13 +03:00
TALLOC_FREE ( dom_name ) ;
TALLOC_FREE ( name ) ;
2005-06-09 02:10:34 +04:00
return WINBINDD_ERROR ;
}
fstrcpy ( state - > response . data . name . dom_name , dom_name ) ;
fstrcpy ( state - > response . data . name . name , name ) ;
state - > response . data . name . type = type ;
2006-12-12 17:52:13 +03:00
TALLOC_FREE ( dom_name ) ;
TALLOC_FREE ( name ) ;
2005-06-09 02:10:34 +04:00
return WINBINDD_OK ;
}
2007-01-03 00:48:47 +03:00
/********************************************************************
This is the second callback after contacting the forest root
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-05-06 23:01:54 +04:00
struct lookupname_state {
char * dom_name ;
char * name ;
void * caller_private_data ;
} ;
2007-01-03 00:48:47 +03:00
static void lookupname_recv2 ( TALLOC_CTX * mem_ctx , BOOL success ,
2005-06-09 02:10:34 +04:00
struct winbindd_response * response ,
2005-06-25 00:25:18 +04:00
void * c , void * private_data )
2005-06-09 02:10:34 +04:00
{
void ( * cont ) ( void * priv , BOOL succ , const DOM_SID * sid ,
2006-09-08 18:28:06 +04:00
enum lsa_SidType type ) =
( void ( * ) ( void * , BOOL , const DOM_SID * , enum lsa_SidType ) ) c ;
2005-06-09 02:10:34 +04:00
DOM_SID sid ;
2007-05-06 23:01:54 +04:00
struct lookupname_state * s = talloc_get_type_abort ( private_data ,
struct lookupname_state ) ;
2005-06-09 02:10:34 +04:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger lookup_name \n " ) ) ;
2007-05-06 23:01:54 +04:00
cont ( s - > caller_private_data , False , NULL , SID_NAME_UNKNOWN ) ;
2005-06-09 02:10:34 +04:00
return ;
}
if ( response - > result ! = WINBINDD_OK ) {
DEBUG ( 5 , ( " lookup_name returned an error \n " ) ) ;
2007-05-06 23:01:54 +04:00
cont ( s - > caller_private_data , False , NULL , SID_NAME_UNKNOWN ) ;
2005-06-09 02:10:34 +04:00
return ;
}
if ( ! string_to_sid ( & sid , response - > data . sid . sid ) ) {
DEBUG ( 0 , ( " Could not convert string %s to sid \n " ,
response - > data . sid . sid ) ) ;
2007-05-06 23:01:54 +04:00
cont ( s - > caller_private_data , False , NULL , SID_NAME_UNKNOWN ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2007-05-06 23:01:54 +04:00
cont ( s - > caller_private_data , True , & sid ,
2006-09-08 18:28:06 +04:00
( enum lsa_SidType ) response - > data . sid . type ) ;
2005-06-09 02:10:34 +04:00
}
2007-01-03 00:48:47 +03:00
/********************************************************************
This is the first callback after contacting our own domain
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void lookupname_recv ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
void * c , void * private_data )
{
void ( * cont ) ( void * priv , BOOL succ , const DOM_SID * sid ,
enum lsa_SidType type ) =
( void ( * ) ( void * , BOOL , const DOM_SID * , enum lsa_SidType ) ) c ;
DOM_SID sid ;
2007-05-06 23:01:54 +04:00
struct lookupname_state * s = talloc_get_type_abort ( private_data ,
struct lookupname_state ) ;
2007-01-03 00:48:47 +03:00
if ( ! success ) {
DEBUG ( 5 , ( " lookupname_recv: lookup_name() failed! \n " ) ) ;
2007-05-06 23:01:54 +04:00
cont ( s - > caller_private_data , False , NULL , SID_NAME_UNKNOWN ) ;
2007-01-03 00:48:47 +03:00
return ;
}
if ( response - > result ! = WINBINDD_OK ) {
/* Try again using the forest root */
struct winbindd_domain * root_domain = find_root_domain ( ) ;
struct winbindd_request request ;
if ( ! root_domain ) {
2007-02-13 13:42:53 +03:00
DEBUG ( 5 , ( " lookupname_recv: unable to determine forest root \n " ) ) ;
2007-05-06 23:01:54 +04:00
cont ( s - > caller_private_data , False , NULL , SID_NAME_UNKNOWN ) ;
2007-01-03 00:48:47 +03:00
return ;
}
ZERO_STRUCT ( request ) ;
request . cmd = WINBINDD_LOOKUPNAME ;
2007-05-06 23:01:54 +04:00
fstrcpy ( request . data . name . dom_name , s - > dom_name ) ;
fstrcpy ( request . data . name . name , s - > name ) ;
2007-01-03 00:48:47 +03:00
do_async_domain ( mem_ctx , root_domain , & request , lookupname_recv2 ,
2007-05-06 23:01:54 +04:00
( void * ) cont , s ) ;
2007-01-03 00:48:47 +03:00
return ;
}
if ( ! string_to_sid ( & sid , response - > data . sid . sid ) ) {
DEBUG ( 0 , ( " Could not convert string %s to sid \n " ,
response - > data . sid . sid ) ) ;
2007-05-06 23:01:54 +04:00
cont ( s - > caller_private_data , False , NULL , SID_NAME_UNKNOWN ) ;
2007-01-03 00:48:47 +03:00
return ;
}
2007-05-06 23:01:54 +04:00
cont ( s - > caller_private_data , True , & sid ,
2007-01-03 00:48:47 +03:00
( enum lsa_SidType ) response - > data . sid . type ) ;
}
/********************************************************************
The lookup name call first contacts a DC in its own domain
and fallbacks to contact a DC in the forest in our domain doesn ' t
know the name .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void winbindd_lookupname_async ( TALLOC_CTX * mem_ctx ,
const char * dom_name , const char * name ,
2005-06-25 00:25:18 +04:00
void ( * cont ) ( void * private_data , BOOL success ,
2005-06-09 02:10:34 +04:00
const DOM_SID * sid ,
2006-09-08 18:28:06 +04:00
enum lsa_SidType type ) ,
2005-06-25 00:25:18 +04:00
void * private_data )
2005-06-09 02:10:34 +04:00
{
struct winbindd_request request ;
struct winbindd_domain * domain ;
2007-05-06 23:01:54 +04:00
struct lookupname_state * s ;
2005-06-09 02:10:34 +04:00
2007-01-03 00:48:47 +03:00
if ( ( domain = find_lookup_domain_from_name ( dom_name ) ) = = NULL ) {
2005-06-09 02:10:34 +04:00
DEBUG ( 5 , ( " Could not find domain for name %s \n " , dom_name ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , NULL , SID_NAME_UNKNOWN ) ;
2005-06-09 02:10:34 +04:00
return ;
}
ZERO_STRUCT ( request ) ;
request . cmd = WINBINDD_LOOKUPNAME ;
fstrcpy ( request . data . name . dom_name , dom_name ) ;
fstrcpy ( request . data . name . name , name ) ;
2007-05-06 23:01:54 +04:00
if ( ( s = TALLOC_ZERO_P ( mem_ctx , struct lookupname_state ) ) = = NULL ) {
DEBUG ( 0 , ( " winbindd_lookupname_async: talloc failed \n " ) ) ;
cont ( private_data , False , NULL , SID_NAME_UNKNOWN ) ;
return ;
}
s - > dom_name = talloc_strdup ( s , dom_name ) ;
s - > name = talloc_strdup ( s , name ) ;
s - > caller_private_data = private_data ;
2005-06-09 02:10:34 +04:00
do_async_domain ( mem_ctx , domain , & request , lookupname_recv ,
2007-05-06 23:01:54 +04:00
( void * ) cont , s ) ;
2005-06-09 02:10:34 +04:00
}
enum winbindd_result winbindd_dual_lookupname ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
2006-09-08 18:28:06 +04:00
enum lsa_SidType type ;
2005-06-09 02:10:34 +04:00
char * name_domain , * name_user ;
DOM_SID sid ;
char * p ;
/* Ensure null termination */
2007-02-13 13:42:53 +03:00
state - > request . data . name . dom_name [ sizeof ( state - > request . data . name . dom_name ) - 1 ] = ' \0 ' ;
2005-06-09 02:10:34 +04:00
/* Ensure null termination */
2007-02-13 13:42:53 +03:00
state - > request . data . name . name [ sizeof ( state - > request . data . name . name ) - 1 ] = ' \0 ' ;
2005-06-09 02:10:34 +04:00
/* cope with the name being a fully qualified name */
p = strstr ( state - > request . data . name . name , lp_winbind_separator ( ) ) ;
if ( p ) {
* p = 0 ;
name_domain = state - > request . data . name . name ;
name_user = p + 1 ;
} else {
name_domain = state - > request . data . name . dom_name ;
name_user = state - > request . data . name . name ;
}
DEBUG ( 3 , ( " [%5lu]: lookupname %s%s%s \n " , ( unsigned long ) state - > pid ,
name_domain , lp_winbind_separator ( ) , name_user ) ) ;
2007-02-13 13:42:53 +03:00
/* Lookup name from DC using lsa_lookup_names() */
2005-06-09 02:10:34 +04:00
if ( ! winbindd_lookup_sid_by_name ( state - > mem_ctx , domain , name_domain ,
name_user , & sid , & type ) ) {
return WINBINDD_ERROR ;
}
sid_to_string ( state - > response . data . sid . sid , & sid ) ;
state - > response . data . sid . type = type ;
return WINBINDD_OK ;
}
2005-09-30 21:13:37 +04:00
BOOL print_sidlist ( TALLOC_CTX * mem_ctx , const DOM_SID * sids ,
2005-10-18 07:24:00 +04:00
size_t num_sids , char * * result , ssize_t * len )
2005-06-09 02:10:34 +04:00
{
2005-10-18 07:24:00 +04:00
size_t i ;
2005-06-09 02:10:34 +04:00
size_t buflen = 0 ;
2005-09-30 21:13:37 +04:00
* len = 0 ;
2005-06-09 02:10:34 +04:00
* result = NULL ;
for ( i = 0 ; i < num_sids ; i + + ) {
2005-09-30 21:13:37 +04:00
sprintf_append ( mem_ctx , result , len , & buflen ,
2005-06-09 02:10:34 +04:00
" %s \n " , sid_string_static ( & sids [ i ] ) ) ;
}
if ( ( num_sids ! = 0 ) & & ( * result = = NULL ) ) {
return False ;
}
return True ;
}
2006-07-11 22:01:26 +04:00
static BOOL parse_sidlist ( TALLOC_CTX * mem_ctx , char * sidstr ,
DOM_SID * * sids , size_t * num_sids )
2005-06-09 02:10:34 +04:00
{
char * p , * q ;
p = sidstr ;
if ( p = = NULL )
2005-09-30 21:13:37 +04:00
return False ;
2005-06-09 02:10:34 +04:00
while ( p [ 0 ] ! = ' \0 ' ) {
DOM_SID sid ;
q = strchr ( p , ' \n ' ) ;
if ( q = = NULL ) {
DEBUG ( 0 , ( " Got invalid sidstr: %s \n " , p ) ) ;
return False ;
}
* q = ' \0 ' ;
q + = 1 ;
if ( ! string_to_sid ( & sid , p ) ) {
DEBUG ( 0 , ( " Could not parse sid %s \n " , p ) ) ;
return False ;
}
2006-12-09 05:58:18 +03:00
if ( ! add_sid_to_array ( mem_ctx , & sid , sids , num_sids ) ) {
return False ;
}
2005-06-09 02:10:34 +04:00
p = q ;
}
return True ;
}
2006-07-11 22:01:26 +04:00
static BOOL parse_ridlist ( TALLOC_CTX * mem_ctx , char * ridstr ,
uint32 * * rids , size_t * num_rids )
2005-09-30 21:13:37 +04:00
{
char * p ;
p = ridstr ;
if ( p = = NULL )
return False ;
while ( p [ 0 ] ! = ' \0 ' ) {
uint32 rid ;
char * q ;
rid = strtoul ( p , & q , 10 ) ;
if ( * q ! = ' \n ' ) {
DEBUG ( 0 , ( " Got invalid ridstr: %s \n " , p ) ) ;
return False ;
}
p = q + 1 ;
2006-07-11 22:01:26 +04:00
ADD_TO_ARRAY ( mem_ctx , uint32 , rid , rids , num_rids ) ;
2005-09-30 21:13:37 +04:00
}
return True ;
}
2006-07-11 22:01:26 +04:00
enum winbindd_result winbindd_dual_lookuprids ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
uint32 * rids = NULL ;
size_t i , buflen , num_rids = 0 ;
ssize_t len ;
DOM_SID domain_sid ;
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
NTSTATUS status ;
char * result ;
DEBUG ( 10 , ( " Looking up RIDs for domain %s (%s) \n " ,
state - > request . domain_name ,
state - > request . data . sid ) ) ;
if ( ! parse_ridlist ( state - > mem_ctx , state - > request . extra_data . data ,
& rids , & num_rids ) ) {
DEBUG ( 5 , ( " Could not parse ridlist \n " ) ) ;
return WINBINDD_ERROR ;
}
if ( ! string_to_sid ( & domain_sid , state - > request . data . sid ) ) {
DEBUG ( 5 , ( " Could not parse domain sid %s \n " ,
state - > request . data . sid ) ) ;
return WINBINDD_ERROR ;
}
status = domain - > methods - > rids_to_names ( domain , state - > mem_ctx ,
& domain_sid , rids , num_rids ,
& domain_name ,
& names , & types ) ;
if ( ! NT_STATUS_IS_OK ( status ) & &
! NT_STATUS_EQUAL ( status , STATUS_SOME_UNMAPPED ) ) {
return WINBINDD_ERROR ;
}
len = 0 ;
buflen = 0 ;
result = NULL ;
for ( i = 0 ; i < num_rids ; i + + ) {
sprintf_append ( state - > mem_ctx , & result , & len , & buflen ,
" %d %s \n " , types [ i ] , names [ i ] ) ;
}
fstrcpy ( state - > response . data . domain_name , domain_name ) ;
if ( result ! = NULL ) {
state - > response . extra_data . data = SMB_STRDUP ( result ) ;
2006-12-16 04:32:57 +03:00
if ( ! state - > response . extra_data . data ) {
return WINBINDD_ERROR ;
}
2006-07-11 22:01:26 +04:00
state - > response . length + = len + 1 ;
}
return WINBINDD_OK ;
}
2005-06-09 02:10:34 +04:00
static void getsidaliases_recv ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
2005-06-25 00:25:18 +04:00
void * c , void * private_data )
2005-06-09 02:10:34 +04:00
{
void ( * cont ) ( void * priv , BOOL succ ,
2006-07-11 22:01:26 +04:00
DOM_SID * aliases , size_t num_aliases ) =
( void ( * ) ( void * , BOOL , DOM_SID * , size_t ) ) c ;
2005-06-09 02:10:34 +04:00
char * aliases_str ;
DOM_SID * sids = NULL ;
2005-10-18 07:24:00 +04:00
size_t num_sids = 0 ;
2005-06-09 02:10:34 +04:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger getsidaliases \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , success , NULL , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
if ( response - > result ! = WINBINDD_OK ) {
DEBUG ( 5 , ( " getsidaliases returned an error \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , NULL , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2006-07-11 22:01:26 +04:00
aliases_str = ( char * ) response - > extra_data . data ;
2005-06-09 02:10:34 +04:00
if ( aliases_str = = NULL ) {
DEBUG ( 10 , ( " getsidaliases return 0 SIDs \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , True , NULL , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
if ( ! parse_sidlist ( mem_ctx , aliases_str , & sids , & num_sids ) ) {
DEBUG ( 0 , ( " Could not parse sids \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , NULL , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2006-04-12 18:10:39 +04:00
SAFE_FREE ( response - > extra_data . data ) ;
2005-06-09 02:10:34 +04:00
2005-06-25 00:25:18 +04:00
cont ( private_data , True , sids , num_sids ) ;
2005-06-09 02:10:34 +04:00
}
void winbindd_getsidaliases_async ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2005-10-18 07:24:00 +04:00
const DOM_SID * sids , size_t num_sids ,
2005-06-25 00:25:18 +04:00
void ( * cont ) ( void * private_data ,
2005-06-09 02:10:34 +04:00
BOOL success ,
const DOM_SID * aliases ,
2005-10-18 07:24:00 +04:00
size_t num_aliases ) ,
2005-06-25 00:25:18 +04:00
void * private_data )
2005-06-09 02:10:34 +04:00
{
struct winbindd_request request ;
char * sidstr = NULL ;
2005-09-30 21:13:37 +04:00
ssize_t len ;
2005-06-09 02:10:34 +04:00
if ( num_sids = = 0 ) {
2005-06-25 00:25:18 +04:00
cont ( private_data , True , NULL , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2005-09-30 21:13:37 +04:00
if ( ! print_sidlist ( mem_ctx , sids , num_sids , & sidstr , & len ) ) {
2005-06-25 00:25:18 +04:00
cont ( private_data , False , NULL , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
ZERO_STRUCT ( request ) ;
request . cmd = WINBINDD_DUAL_GETSIDALIASES ;
2005-09-30 21:13:37 +04:00
request . extra_len = len ;
2006-04-12 18:10:39 +04:00
request . extra_data . data = sidstr ;
2005-06-09 02:10:34 +04:00
do_async_domain ( mem_ctx , domain , & request , getsidaliases_recv ,
2006-07-11 22:01:26 +04:00
( void * ) cont , private_data ) ;
2005-06-09 02:10:34 +04:00
}
enum winbindd_result winbindd_dual_getsidaliases ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
DOM_SID * sids = NULL ;
2005-10-18 07:24:00 +04:00
size_t num_sids = 0 ;
2006-12-20 17:23:41 +03:00
char * sidstr = NULL ;
2005-10-18 07:24:00 +04:00
ssize_t len ;
size_t i ;
uint32 num_aliases ;
2005-06-09 02:10:34 +04:00
uint32 * alias_rids ;
NTSTATUS result ;
DEBUG ( 3 , ( " [%5lu]: getsidaliases \n " , ( unsigned long ) state - > pid ) ) ;
2006-04-12 18:10:39 +04:00
sidstr = state - > request . extra_data . data ;
2006-12-20 17:23:41 +03:00
if ( sidstr = = NULL ) {
2005-06-09 02:10:34 +04:00
sidstr = talloc_strdup ( state - > mem_ctx , " \n " ) ; /* No SID */
2006-12-20 17:23:41 +03:00
if ( ! sidstr ) {
DEBUG ( 0 , ( " Out of memory \n " ) ) ;
return WINBINDD_ERROR ;
}
}
2005-06-09 02:10:34 +04:00
DEBUG ( 10 , ( " Sidlist: %s \n " , sidstr ) ) ;
if ( ! parse_sidlist ( state - > mem_ctx , sidstr , & sids , & num_sids ) ) {
DEBUG ( 0 , ( " Could not parse SID list: %s \n " , sidstr ) ) ;
return WINBINDD_ERROR ;
}
num_aliases = 0 ;
alias_rids = NULL ;
result = domain - > methods - > lookup_useraliases ( domain ,
state - > mem_ctx ,
num_sids , sids ,
& num_aliases ,
& alias_rids ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
DEBUG ( 3 , ( " Could not lookup_useraliases: %s \n " ,
nt_errstr ( result ) ) ) ;
return WINBINDD_ERROR ;
}
num_sids = 0 ;
sids = NULL ;
2006-12-20 17:23:41 +03:00
sidstr = NULL ;
2005-06-09 02:10:34 +04:00
DEBUG ( 10 , ( " Got %d aliases \n " , num_aliases ) ) ;
for ( i = 0 ; i < num_aliases ; i + + ) {
DOM_SID sid ;
DEBUGADD ( 10 , ( " rid %d \n " , alias_rids [ i ] ) ) ;
sid_copy ( & sid , & domain - > sid ) ;
sid_append_rid ( & sid , alias_rids [ i ] ) ;
2006-12-09 05:58:18 +03:00
if ( ! add_sid_to_array ( state - > mem_ctx , & sid , & sids , & num_sids ) ) {
return WINBINDD_ERROR ;
}
2005-06-09 02:10:34 +04:00
}
2006-07-11 22:01:26 +04:00
2006-12-16 04:52:06 +03:00
if ( ! print_sidlist ( state - > mem_ctx , sids , num_sids , & sidstr , & len ) ) {
2005-06-09 02:10:34 +04:00
DEBUG ( 0 , ( " Could not print_sidlist \n " ) ) ;
2006-07-11 22:01:26 +04:00
state - > response . extra_data . data = NULL ;
2005-06-09 02:10:34 +04:00
return WINBINDD_ERROR ;
}
2006-12-20 17:23:41 +03:00
state - > response . extra_data . data = NULL ;
2006-07-11 22:01:26 +04:00
2006-12-20 17:23:41 +03:00
if ( sidstr ) {
state - > response . extra_data . data = SMB_STRDUP ( sidstr ) ;
if ( ! state - > response . extra_data . data ) {
DEBUG ( 0 , ( " Out of memory \n " ) ) ;
return WINBINDD_ERROR ;
}
2005-06-09 02:10:34 +04:00
DEBUG ( 10 , ( " aliases_list: %s \n " ,
2006-04-12 18:10:39 +04:00
( char * ) state - > response . extra_data . data ) ) ;
2005-09-30 21:13:37 +04:00
state - > response . length + = len + 1 ;
2005-06-09 02:10:34 +04:00
}
return WINBINDD_OK ;
}
struct gettoken_state {
TALLOC_CTX * mem_ctx ;
DOM_SID user_sid ;
struct winbindd_domain * alias_domain ;
2006-03-25 01:04:16 +03:00
struct winbindd_domain * local_alias_domain ;
2005-06-09 02:10:34 +04:00
struct winbindd_domain * builtin_domain ;
DOM_SID * sids ;
2005-10-18 07:24:00 +04:00
size_t num_sids ;
void ( * cont ) ( void * private_data , BOOL success , DOM_SID * sids , size_t num_sids ) ;
2005-06-25 00:25:18 +04:00
void * private_data ;
2005-06-09 02:10:34 +04:00
} ;
static void gettoken_recvdomgroups ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
2005-06-25 00:25:18 +04:00
void * c , void * private_data ) ;
static void gettoken_recvaliases ( void * private_data , BOOL success ,
2005-06-09 02:10:34 +04:00
const DOM_SID * aliases ,
2005-10-18 07:24:00 +04:00
size_t num_aliases ) ;
2005-06-09 02:10:34 +04:00
void winbindd_gettoken_async ( TALLOC_CTX * mem_ctx , const DOM_SID * user_sid ,
2005-06-25 00:25:18 +04:00
void ( * cont ) ( void * private_data , BOOL success ,
2005-10-18 07:24:00 +04:00
DOM_SID * sids , size_t num_sids ) ,
2005-06-25 00:25:18 +04:00
void * private_data )
2005-06-09 02:10:34 +04:00
{
struct winbindd_domain * domain ;
struct winbindd_request request ;
struct gettoken_state * state ;
2006-10-16 04:12:00 +04:00
state = TALLOC_ZERO_P ( mem_ctx , struct gettoken_state ) ;
2005-06-09 02:10:34 +04:00
if ( state = = NULL ) {
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , NULL , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
state - > mem_ctx = mem_ctx ;
sid_copy ( & state - > user_sid , user_sid ) ;
state - > alias_domain = find_our_domain ( ) ;
2006-03-25 01:04:16 +03:00
state - > local_alias_domain = find_domain_from_name ( get_global_sam_name ( ) ) ;
2005-06-09 02:10:34 +04:00
state - > builtin_domain = find_builtin_domain ( ) ;
state - > cont = cont ;
2005-06-25 00:25:18 +04:00
state - > private_data = private_data ;
2005-06-09 02:10:34 +04:00
domain = find_domain_from_sid_noinit ( user_sid ) ;
if ( domain = = NULL ) {
DEBUG ( 5 , ( " Could not find domain from SID %s \n " ,
sid_string_static ( user_sid ) ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , NULL , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
ZERO_STRUCT ( request ) ;
request . cmd = WINBINDD_GETUSERDOMGROUPS ;
fstrcpy ( request . data . sid , sid_string_static ( user_sid ) ) ;
do_async_domain ( mem_ctx , domain , & request , gettoken_recvdomgroups ,
NULL , state ) ;
}
static void gettoken_recvdomgroups ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
2005-06-25 00:25:18 +04:00
void * c , void * private_data )
2005-06-09 02:10:34 +04:00
{
struct gettoken_state * state =
2005-06-25 00:25:18 +04:00
talloc_get_type_abort ( private_data , struct gettoken_state ) ;
2005-06-09 02:10:34 +04:00
char * sids_str ;
if ( ! success ) {
DEBUG ( 10 , ( " Could not get domain groups \n " ) ) ;
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , False , NULL , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2006-07-11 22:01:26 +04:00
sids_str = ( char * ) response - > extra_data . data ;
2005-06-09 02:10:34 +04:00
if ( sids_str = = NULL ) {
2006-03-15 06:46:20 +03:00
/* This could be normal if we are dealing with a
local user and local groups */
if ( ! sid_check_is_in_our_domain ( & state - > user_sid ) ) {
DEBUG ( 10 , ( " Received no domain groups \n " ) ) ;
state - > cont ( state - > private_data , True , NULL , 0 ) ;
return ;
}
2005-06-09 02:10:34 +04:00
}
state - > sids = NULL ;
state - > num_sids = 0 ;
2006-12-09 05:58:18 +03:00
if ( ! add_sid_to_array ( mem_ctx , & state - > user_sid , & state - > sids ,
& state - > num_sids ) ) {
DEBUG ( 0 , ( " Out of memory \n " ) ) ;
state - > cont ( state - > private_data , False , NULL , 0 ) ;
return ;
}
2005-06-09 02:10:34 +04:00
2006-03-15 06:46:20 +03:00
if ( sids_str & & ! parse_sidlist ( mem_ctx , sids_str , & state - > sids ,
2005-06-09 02:10:34 +04:00
& state - > num_sids ) ) {
DEBUG ( 0 , ( " Could not parse sids \n " ) ) ;
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , False , NULL , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2006-04-12 18:10:39 +04:00
SAFE_FREE ( response - > extra_data . data ) ;
2005-06-09 02:10:34 +04:00
if ( state - > alias_domain = = NULL ) {
DEBUG ( 10 , ( " Don't expand domain local groups \n " ) ) ;
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , True , state - > sids ,
2005-06-09 02:10:34 +04:00
state - > num_sids ) ;
return ;
}
winbindd_getsidaliases_async ( state - > alias_domain , mem_ctx ,
state - > sids , state - > num_sids ,
gettoken_recvaliases , state ) ;
}
2005-06-25 00:25:18 +04:00
static void gettoken_recvaliases ( void * private_data , BOOL success ,
2005-06-09 02:10:34 +04:00
const DOM_SID * aliases ,
2005-10-18 07:24:00 +04:00
size_t num_aliases )
2005-06-09 02:10:34 +04:00
{
2006-07-11 22:01:26 +04:00
struct gettoken_state * state = ( struct gettoken_state * ) private_data ;
2005-10-18 07:24:00 +04:00
size_t i ;
2005-06-09 02:10:34 +04:00
if ( ! success ) {
DEBUG ( 10 , ( " Could not receive domain local groups \n " ) ) ;
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , False , NULL , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2006-12-09 05:58:18 +03:00
for ( i = 0 ; i < num_aliases ; i + + ) {
if ( ! add_sid_to_array ( state - > mem_ctx , & aliases [ i ] ,
& state - > sids , & state - > num_sids ) ) {
DEBUG ( 0 , ( " Out of memory \n " ) ) ;
state - > cont ( state - > private_data , False , NULL , 0 ) ;
return ;
}
}
2005-06-09 02:10:34 +04:00
2006-03-25 01:04:16 +03:00
if ( state - > local_alias_domain ! = NULL ) {
struct winbindd_domain * local_domain = state - > local_alias_domain ;
DEBUG ( 10 , ( " Expanding our own local groups \n " ) ) ;
state - > local_alias_domain = NULL ;
winbindd_getsidaliases_async ( local_domain , state - > mem_ctx ,
state - > sids , state - > num_sids ,
gettoken_recvaliases , state ) ;
return ;
}
2005-06-09 02:10:34 +04:00
if ( state - > builtin_domain ! = NULL ) {
struct winbindd_domain * builtin_domain = state - > builtin_domain ;
2006-03-25 01:04:16 +03:00
DEBUG ( 10 , ( " Expanding our own BUILTIN groups \n " ) ) ;
2005-06-09 02:10:34 +04:00
state - > builtin_domain = NULL ;
winbindd_getsidaliases_async ( builtin_domain , state - > mem_ctx ,
state - > sids , state - > num_sids ,
gettoken_recvaliases , state ) ;
return ;
}
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , True , state - > sids , state - > num_sids ) ;
2005-06-09 02:10:34 +04:00
}
static void query_user_recv ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
2005-06-25 00:25:18 +04:00
void * c , void * private_data )
2005-06-09 02:10:34 +04:00
{
void ( * cont ) ( void * priv , BOOL succ , const char * acct_name ,
2005-06-29 18:03:53 +04:00
const char * full_name , const char * homedir ,
2007-01-24 04:48:08 +03:00
const char * shell , uint32 gid , uint32 group_rid ) =
2006-07-11 22:01:26 +04:00
( void ( * ) ( void * , BOOL , const char * , const char * ,
2007-01-24 04:48:08 +03:00
const char * , const char * , uint32 , uint32 ) ) c ;
2005-06-09 02:10:34 +04:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger query_user \n " ) ) ;
2007-01-24 04:48:08 +03:00
cont ( private_data , False , NULL , NULL , NULL , NULL , - 1 , - 1 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2007-05-07 00:16:12 +04:00
if ( response - > result ! = WINBINDD_OK ) {
DEBUG ( 5 , ( " query_user returned an error \n " ) ) ;
cont ( private_data , False , NULL , NULL , NULL , NULL , - 1 , - 1 ) ;
return ;
}
2005-06-25 00:25:18 +04:00
cont ( private_data , True , response - > data . user_info . acct_name ,
2005-06-09 02:10:34 +04:00
response - > data . user_info . full_name ,
2005-06-29 18:03:53 +04:00
response - > data . user_info . homedir ,
response - > data . user_info . shell ,
2007-01-24 04:48:08 +03:00
response - > data . user_info . primary_gid ,
2005-06-09 02:10:34 +04:00
response - > data . user_info . group_rid ) ;
}
void query_user_async ( TALLOC_CTX * mem_ctx , struct winbindd_domain * domain ,
const DOM_SID * sid ,
2005-06-25 00:25:18 +04:00
void ( * cont ) ( void * private_data , BOOL success ,
2005-06-09 02:10:34 +04:00
const char * acct_name ,
const char * full_name ,
2005-06-29 18:03:53 +04:00
const char * homedir ,
const char * shell ,
2007-01-24 04:48:08 +03:00
gid_t gid ,
2005-06-09 02:10:34 +04:00
uint32 group_rid ) ,
2005-06-25 00:25:18 +04:00
void * private_data )
2005-06-09 02:10:34 +04:00
{
struct winbindd_request request ;
ZERO_STRUCT ( request ) ;
request . cmd = WINBINDD_DUAL_USERINFO ;
sid_to_string ( request . data . sid , sid ) ;
do_async_domain ( mem_ctx , domain , & request , query_user_recv ,
2006-07-11 22:01:26 +04:00
( void * ) cont , private_data ) ;
2005-06-09 02:10:34 +04:00
}
2006-08-08 19:33:09 +04:00
/* The following uid2sid/gid2sid functions has been contributed by
* Keith Reynolds < Keith . Reynolds @ centrify . com > */
static void winbindd_uid2sid_recv ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
void * c , void * private_data )
{
2006-08-18 18:05:25 +04:00
void ( * cont ) ( void * priv , BOOL succ , const char * sid ) =
( void ( * ) ( void * , BOOL , const char * ) ) c ;
2006-08-08 19:33:09 +04:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger uid2sid \n " ) ) ;
cont ( private_data , False , NULL ) ;
return ;
}
if ( response - > result ! = WINBINDD_OK ) {
DEBUG ( 5 , ( " uid2sid returned an error \n " ) ) ;
cont ( private_data , False , NULL ) ;
return ;
}
cont ( private_data , True , response - > data . sid . sid ) ;
}
void winbindd_uid2sid_async ( TALLOC_CTX * mem_ctx , uid_t uid ,
void ( * cont ) ( void * private_data , BOOL success , const char * sid ) ,
void * private_data )
{
struct winbindd_request request ;
ZERO_STRUCT ( request ) ;
request . cmd = WINBINDD_DUAL_UID2SID ;
request . data . uid = uid ;
2006-09-04 23:47:48 +04:00
do_async ( mem_ctx , idmap_child ( ) , & request , winbindd_uid2sid_recv ,
( void * ) cont , private_data ) ;
2006-08-08 19:33:09 +04:00
}
enum winbindd_result winbindd_dual_uid2sid ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
DOM_SID sid ;
NTSTATUS result ;
DEBUG ( 3 , ( " [%5lu]: uid to sid %lu \n " ,
( unsigned long ) state - > pid ,
( unsigned long ) state - > request . data . uid ) ) ;
/* Find sid for this uid and return it, possibly ask the slow remote idmap */
2006-12-12 17:52:13 +03:00
result = idmap_uid_to_sid ( & sid , state - > request . data . uid ) ;
2006-08-08 19:33:09 +04:00
if ( NT_STATUS_IS_OK ( result ) ) {
sid_to_string ( state - > response . data . sid . sid , & sid ) ;
state - > response . data . sid . type = SID_NAME_USER ;
return WINBINDD_OK ;
}
return WINBINDD_ERROR ;
}
static void winbindd_gid2sid_recv ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
void * c , void * private_data )
{
2006-08-18 18:05:25 +04:00
void ( * cont ) ( void * priv , BOOL succ , const char * sid ) =
( void ( * ) ( void * , BOOL , const char * ) ) c ;
2006-08-08 19:33:09 +04:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger gid2sid \n " ) ) ;
cont ( private_data , False , NULL ) ;
return ;
}
2006-08-08 22:38:33 +04:00
if ( response - > result ! = WINBINDD_OK ) {
DEBUG ( 5 , ( " gid2sid returned an error \n " ) ) ;
cont ( private_data , False , NULL ) ;
return ;
}
2006-08-08 19:33:09 +04:00
cont ( private_data , True , response - > data . sid . sid ) ;
}
void winbindd_gid2sid_async ( TALLOC_CTX * mem_ctx , gid_t gid ,
void ( * cont ) ( void * private_data , BOOL success , const char * sid ) ,
void * private_data )
{
struct winbindd_request request ;
ZERO_STRUCT ( request ) ;
request . cmd = WINBINDD_DUAL_GID2SID ;
request . data . gid = gid ;
2006-09-04 23:47:48 +04:00
do_async ( mem_ctx , idmap_child ( ) , & request , winbindd_gid2sid_recv ,
( void * ) cont , private_data ) ;
2006-08-08 19:33:09 +04:00
}
enum winbindd_result winbindd_dual_gid2sid ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
DOM_SID sid ;
NTSTATUS result ;
DEBUG ( 3 , ( " [%5lu]: gid %lu to sid \n " ,
( unsigned long ) state - > pid ,
( unsigned long ) state - > request . data . gid ) ) ;
/* Find sid for this gid and return it, possibly ask the slow remote idmap */
2006-12-12 17:52:13 +03:00
result = idmap_gid_to_sid ( & sid , state - > request . data . gid ) ;
2006-08-08 19:33:09 +04:00
if ( NT_STATUS_IS_OK ( result ) ) {
sid_to_string ( state - > response . data . sid . sid , & sid ) ;
DEBUG ( 10 , ( " [%5lu]: retrieved sid: %s \n " ,
( unsigned long ) state - > pid ,
state - > response . data . sid . sid ) ) ;
state - > response . data . sid . type = SID_NAME_DOM_GRP ;
return WINBINDD_OK ;
}
return WINBINDD_ERROR ;
}
2006-12-12 17:52:13 +03:00
static void winbindd_dump_id_maps_recv ( TALLOC_CTX * mem_ctx , BOOL success ,
struct winbindd_response * response ,
void * c , void * private_data )
{
void ( * cont ) ( void * priv , BOOL succ ) =
( void ( * ) ( void * , BOOL ) ) c ;
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger a map dump \n " ) ) ;
cont ( private_data , False ) ;
return ;
}
if ( response - > result ! = WINBINDD_OK ) {
DEBUG ( 5 , ( " idmap dump maps returned an error \n " ) ) ;
cont ( private_data , False ) ;
return ;
}
cont ( private_data , True ) ;
}
void winbindd_dump_maps_async ( TALLOC_CTX * mem_ctx , void * data , int size ,
void ( * cont ) ( void * private_data , BOOL success ) ,
void * private_data )
{
struct winbindd_request request ;
ZERO_STRUCT ( request ) ;
request . cmd = WINBINDD_DUAL_DUMP_MAPS ;
2006-12-27 13:26:32 +03:00
request . extra_data . data = ( char * ) data ;
2006-12-12 17:52:13 +03:00
request . extra_len = size ;
do_async ( mem_ctx , idmap_child ( ) , & request , winbindd_dump_id_maps_recv ,
( void * ) cont , private_data ) ;
}
enum winbindd_result winbindd_dual_dump_maps ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
DEBUG ( 3 , ( " [%5lu]: dual dump maps \n " , ( unsigned long ) state - > pid ) ) ;
idmap_dump_maps ( ( char * ) state - > request . extra_data . data ) ;
return WINBINDD_OK ;
}