2005-06-09 02:10:34 +04:00
/*
Unix SMB / CIFS implementation .
Async helpers for blocking functions
Copyright ( C ) Volker Lendecke 2005
2006-03-15 06:46:20 +03:00
Copyright ( C ) Volker Lendecke 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 ;
state = TALLOC_P ( mem_ctx , struct do_async_state ) ;
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 ;
state = TALLOC_P ( mem_ctx , struct do_async_state ) ;
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 ) ;
}
static void idmap_set_mapping_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 ) = c ;
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
}
void idmap_set_mapping_async ( TALLOC_CTX * mem_ctx , const DOM_SID * sid ,
unid_t id , int id_type ,
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 ) ;
request . cmd = WINBINDD_DUAL_IDMAPSET ;
if ( id_type = = ID_USERID )
request . data . dual_idmapset . uid = id . uid ;
else
request . data . dual_idmapset . gid = id . gid ;
request . data . dual_idmapset . type = id_type ;
sid_to_string ( request . data . dual_idmapset . sid , sid ) ;
do_async ( mem_ctx , idmap_child ( ) , & request , idmap_set_mapping_recv ,
2005-06-25 00:25:18 +04:00
cont , private_data ) ;
2005-06-09 02:10:34 +04:00
}
enum winbindd_result winbindd_dual_idmapset ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
DOM_SID sid ;
unid_t id ;
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 ;
if ( state - > request . data . dual_idmapset . type = = ID_USERID )
id . uid = state - > request . data . dual_idmapset . uid ;
else
id . gid = state - > request . data . dual_idmapset . gid ;
result = idmap_set_mapping ( & sid , id ,
state - > request . data . dual_idmapset . type ) ;
return NT_STATUS_IS_OK ( result ) ? WINBINDD_OK : WINBINDD_ERROR ;
}
static void idmap_sid2uid_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 idmap_sid2uid_async ( TALLOC_CTX * mem_ctx , const DOM_SID * sid , BOOL alloc ,
2005-06-25 00:25:18 +04:00
void ( * cont ) ( void * private_data , BOOL success , uid_t uid ) ,
void * private_data )
2005-06-09 02:10:34 +04:00
{
struct winbindd_request request ;
ZERO_STRUCT ( request ) ;
request . cmd = WINBINDD_DUAL_SID2UID ;
sid_to_string ( request . data . dual_sid2id . sid , sid ) ;
request . data . dual_sid2id . alloc = alloc ;
do_async ( mem_ctx , idmap_child ( ) , & request , idmap_sid2uid_recv ,
2005-06-25 00:25:18 +04:00
cont , private_data ) ;
2005-06-09 02:10:34 +04:00
}
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 ) ,
state - > request . data . dual_sid2id . alloc ?
0 : ID_QUERY_ONLY ) ;
return NT_STATUS_IS_OK ( result ) ? WINBINDD_OK : WINBINDD_ERROR ;
}
static void idmap_sid2uid_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 , uid_t uid ) = c ;
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
}
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 ,
2005-06-25 00:25:18 +04:00
cont , private_data ) ;
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 ;
}
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 ( * cont ) ( void * priv , BOOL succ , const char * name ) = c ;
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 ,
2005-06-25 00:25:18 +04:00
cont , private_data ) ;
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 ;
}
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
{
void ( * cont ) ( void * priv , BOOL succ , uid_t uid ) = c ;
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
}
static void idmap_sid2gid_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 idmap_sid2gid_async ( TALLOC_CTX * mem_ctx , const DOM_SID * sid , BOOL alloc ,
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
DEBUG ( 7 , ( " idmap_sid2gid_async: Resolving %s to a gid \n " ,
request . data . dual_sid2id . sid ) ) ;
2005-06-09 02:10:34 +04:00
request . data . dual_sid2id . alloc = alloc ;
do_async ( mem_ctx , idmap_child ( ) , & request , idmap_sid2gid_recv ,
2005-06-25 00:25:18 +04:00
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 ;
}
/* Find gid for this sid and return it, possibly ask the slow remote
* idmap */
result = idmap_sid_to_gid ( & sid , & ( state - > response . data . gid ) ,
state - > request . data . dual_sid2id . alloc ?
0 : ID_QUERY_ONLY ) ;
2006-03-15 06:46:20 +03:00
/* If the lookup failed, the perhaps we need to look
at the passdb for local groups */
if ( ! NT_STATUS_IS_OK ( result ) ) {
if ( sid_to_gid ( & sid , & ( state - > response . data . gid ) ) ) {
result = NT_STATUS_OK ;
}
}
2005-06-09 02:10:34 +04:00
return NT_STATUS_IS_OK ( result ) ? WINBINDD_OK : WINBINDD_ERROR ;
}
static void idmap_sid2gid_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 , gid_t gid ) = c ;
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger sid2gid \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 , ( " sid2gid 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
}
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
{
void ( * cont ) ( void * priv , BOOL succ , const char * name ) = c ;
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 ,
2005-06-25 00:25:18 +04:00
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 ;
}
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 ,
2005-06-25 00:25:18 +04:00
cont , private_data ) ;
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 ;
}
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
{
void ( * cont ) ( void * priv , BOOL succ , gid_t gid ) = c ;
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
}
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 ,
const char * name , enum SID_NAME_USE type ) = c ;
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger lookupsid \n " ) ) ;
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 ;
}
if ( response - > result ! = WINBINDD_OK ) {
DEBUG ( 5 , ( " lookupsid returned an error \n " ) ) ;
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 ;
}
2005-06-25 00:25:18 +04:00
cont ( private_data , True , response - > data . name . dom_name ,
2005-06-09 02:10:34 +04:00
response - > data . name . name , response - > data . name . type ) ;
}
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 ,
enum SID_NAME_USE 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 ;
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 ) ) ;
do_async_domain ( mem_ctx , domain , & request , lookupsid_recv ,
2005-06-25 00:25:18 +04:00
cont , private_data ) ;
2005-06-09 02:10:34 +04:00
}
enum winbindd_result winbindd_dual_lookupsid ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
enum SID_NAME_USE type ;
DOM_SID sid ;
fstring name ;
fstring dom_name ;
/* 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 */
if ( ! winbindd_lookup_name_by_sid ( state - > mem_ctx , & sid , dom_name , name ,
& type ) ) {
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 ;
return WINBINDD_OK ;
}
static void lookupname_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 DOM_SID * sid ,
enum SID_NAME_USE type ) = c ;
DOM_SID sid ;
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger lookup_name \n " ) ) ;
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 ;
}
if ( response - > result ! = WINBINDD_OK ) {
DEBUG ( 5 , ( " lookup_name returned an error \n " ) ) ;
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 ;
}
if ( ! string_to_sid ( & sid , response - > data . sid . sid ) ) {
DEBUG ( 0 , ( " Could not convert string %s to sid \n " ,
response - > data . sid . sid ) ) ;
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 ;
}
2005-06-25 00:25:18 +04:00
cont ( private_data , True , & sid , response - > data . sid . type ) ;
2005-06-09 02:10:34 +04:00
}
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 ,
enum SID_NAME_USE 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 ;
domain = find_lookup_domain_from_name ( dom_name ) ;
if ( domain = = NULL ) {
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 ) ;
do_async_domain ( mem_ctx , domain , & request , lookupname_recv ,
2005-06-25 00:25:18 +04:00
cont , private_data ) ;
2005-06-09 02:10:34 +04:00
}
enum winbindd_result winbindd_dual_lookupname ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
enum SID_NAME_USE type ;
char * name_domain , * name_user ;
DOM_SID sid ;
char * p ;
/* Ensure null termination */
state - > request . data . sid [ sizeof ( state - > request . data . name . dom_name ) - 1 ] = ' \0 ' ;
/* Ensure null termination */
state - > request . data . sid [ sizeof ( state - > request . data . name . name ) - 1 ] = ' \0 ' ;
/* 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 ) ) ;
/* Lookup name from PDC using lsa_lookup_names() */
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 ;
}
2005-09-30 21:13:37 +04:00
BOOL parse_sidlist ( TALLOC_CTX * mem_ctx , char * sidstr ,
2005-10-18 07:24:00 +04:00
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 ;
}
add_sid_to_array ( mem_ctx , & sid , sids , num_sids ) ;
p = q ;
}
return True ;
}
2005-10-18 07:24:00 +04:00
BOOL print_ridlist ( TALLOC_CTX * mem_ctx , uint32 * rids , size_t num_rids ,
2005-09-30 21:13:37 +04:00
char * * result , ssize_t * len )
{
2005-10-18 07:24:00 +04:00
size_t i ;
2005-09-30 21:13:37 +04:00
size_t buflen = 0 ;
* len = 0 ;
* result = NULL ;
for ( i = 0 ; i < num_rids ; i + + ) {
sprintf_append ( mem_ctx , result , len , & buflen ,
" %ld \n " , rids [ i ] ) ;
}
if ( ( num_rids ! = 0 ) & & ( * result = = NULL ) ) {
return False ;
}
return True ;
}
BOOL parse_ridlist ( TALLOC_CTX * mem_ctx , char * ridstr ,
2005-10-18 07:24:00 +04:00
uint32 * * sids , 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 ;
ADD_TO_ARRAY ( mem_ctx , uint32 , rid , sids , num_rids ) ;
}
return True ;
}
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 ,
2005-10-18 07:24:00 +04:00
DOM_SID * aliases , size_t num_aliases ) = 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 ;
}
aliases_str = response - > extra_data ;
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 ;
}
SAFE_FREE ( response - > extra_data ) ;
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 ;
request . extra_data = sidstr ;
2005-06-09 02:10:34 +04:00
do_async_domain ( mem_ctx , domain , & request , getsidaliases_recv ,
2005-06-25 00:25:18 +04:00
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 ;
2005-06-09 02:10:34 +04:00
char * sidstr ;
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 ) ) ;
2005-09-30 21:13:37 +04:00
sidstr = state - > request . extra_data ;
2005-06-09 02:10:34 +04:00
if ( sidstr = = NULL )
sidstr = talloc_strdup ( state - > mem_ctx , " \n " ) ; /* No SID */
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 ;
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 ] ) ;
add_sid_to_array ( state - > mem_ctx , & sid , & sids , & num_sids ) ;
}
if ( ! print_sidlist ( NULL , sids , num_sids ,
2005-09-30 21:13:37 +04:00
( char * * ) & state - > response . extra_data , & len ) ) {
2005-06-09 02:10:34 +04:00
DEBUG ( 0 , ( " Could not print_sidlist \n " ) ) ;
return WINBINDD_ERROR ;
}
if ( state - > response . extra_data ! = NULL ) {
DEBUG ( 10 , ( " aliases_list: %s \n " ,
( char * ) state - > response . extra_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 ;
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 ;
state = TALLOC_P ( mem_ctx , struct gettoken_state ) ;
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 ( ) ;
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 ;
}
sids_str = response - > extra_data ;
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 ;
add_sid_to_array ( mem_ctx , & state - > user_sid , & state - > sids ,
& state - > num_sids ) ;
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 ;
}
SAFE_FREE ( response - > extra_data ) ;
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
{
2005-06-25 00:25:18 +04:00
struct gettoken_state * 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 ;
}
for ( i = 0 ; i < num_aliases ; i + + )
add_sid_to_array ( state - > mem_ctx , & aliases [ i ] ,
& state - > sids , & state - > num_sids ) ;
if ( state - > builtin_domain ! = NULL ) {
struct winbindd_domain * builtin_domain = state - > builtin_domain ;
DEBUG ( 10 , ( " Expanding our own local groups \n " ) ) ;
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
}
struct sid2uid_state {
TALLOC_CTX * mem_ctx ;
DOM_SID sid ;
char * username ;
uid_t uid ;
2005-06-25 00:25:18 +04:00
void ( * cont ) ( void * private_data , BOOL success , uid_t uid ) ;
void * private_data ;
2005-06-09 02:10:34 +04:00
} ;
2005-06-25 00:25:18 +04:00
static void sid2uid_lookup_sid_recv ( void * private_data , BOOL success ,
2005-06-09 02:10:34 +04:00
const char * dom_name , const char * name ,
enum SID_NAME_USE type ) ;
2005-06-25 00:25:18 +04:00
static void sid2uid_noalloc_recv ( void * private_data , BOOL success , uid_t uid ) ;
static void sid2uid_alloc_recv ( void * private_data , BOOL success , uid_t uid ) ;
static void sid2uid_name2uid_recv ( void * private_data , BOOL success , uid_t uid ) ;
static void sid2uid_set_mapping_recv ( void * private_data , BOOL success ) ;
2005-06-09 02:10:34 +04:00
void winbindd_sid2uid_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
uid_t uid ) ,
2005-06-25 00:25:18 +04:00
void * private_data )
2005-06-09 02:10:34 +04:00
{
struct sid2uid_state * state ;
NTSTATUS result ;
uid_t uid ;
if ( idmap_proxyonly ( ) ) {
DEBUG ( 10 , ( " idmap proxy only \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
/* Query only the local tdb, everything else might possibly block */
result = idmap_sid_to_uid ( sid , & uid , ID_QUERY_ONLY | ID_CACHE_ONLY ) ;
if ( NT_STATUS_IS_OK ( result ) ) {
2005-06-25 00:25:18 +04:00
cont ( private_data , True , uid ) ;
2005-06-09 02:10:34 +04:00
return ;
}
state = TALLOC_P ( mem_ctx , struct sid2uid_state ) ;
if ( state = = NULL ) {
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
state - > mem_ctx = mem_ctx ;
state - > sid = * sid ;
state - > cont = cont ;
2005-06-25 00:25:18 +04:00
state - > private_data = private_data ;
2005-06-09 02:10:34 +04:00
/* Let's see if it's really a user before allocating a uid */
winbindd_lookupsid_async ( mem_ctx , sid , sid2uid_lookup_sid_recv , state ) ;
}
2005-06-25 00:25:18 +04:00
static void sid2uid_lookup_sid_recv ( void * private_data , BOOL success ,
2005-06-09 02:10:34 +04:00
const char * dom_name , const char * name ,
enum SID_NAME_USE type )
{
struct sid2uid_state * state =
2005-06-25 00:25:18 +04:00
talloc_get_type_abort ( private_data , struct sid2uid_state ) ;
2005-06-09 02:10:34 +04:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger lookup_sid \n " ) ) ;
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
if ( ( type ! = SID_NAME_USER ) & & ( type ! = SID_NAME_COMPUTER ) ) {
DEBUG ( 5 , ( " SID is not a user \n " ) ) ;
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
state - > username = talloc_strdup ( state - > mem_ctx , name ) ;
/* Ask the possibly blocking remote IDMAP */
idmap_sid2uid_async ( state - > mem_ctx , & state - > sid , False ,
sid2uid_noalloc_recv , state ) ;
}
2005-06-25 00:25:18 +04:00
static void sid2uid_noalloc_recv ( void * private_data , BOOL success , uid_t uid )
2005-06-09 02:10:34 +04:00
{
struct sid2uid_state * state =
2005-06-25 00:25:18 +04:00
talloc_get_type_abort ( private_data , struct sid2uid_state ) ;
2005-06-09 02:10:34 +04:00
if ( success ) {
DEBUG ( 10 , ( " found uid for sid %s in remote backend \n " ,
sid_string_static ( & state - > sid ) ) ) ;
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , True , uid ) ;
2005-06-09 02:10:34 +04:00
return ;
}
if ( lp_winbind_trusted_domains_only ( ) & &
( sid_compare_domain ( & state - > sid , & find_our_domain ( ) - > sid ) = = 0 ) ) {
DEBUG ( 10 , ( " Trying to go via nss \n " ) ) ;
winbindd_name2uid_async ( state - > mem_ctx , state - > username ,
sid2uid_name2uid_recv , state ) ;
return ;
}
/* To be done: Here we're going to try the unixinfo pipe */
/* Now allocate a uid */
idmap_sid2uid_async ( state - > mem_ctx , & state - > sid , True ,
sid2uid_alloc_recv , state ) ;
}
2005-06-25 00:25:18 +04:00
static void sid2uid_alloc_recv ( void * private_data , BOOL success , uid_t uid )
2005-06-09 02:10:34 +04:00
{
struct sid2uid_state * state =
2005-06-25 00:25:18 +04:00
talloc_get_type_abort ( private_data , struct sid2uid_state ) ;
2005-06-09 02:10:34 +04:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not allocate uid \n " ) ) ;
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , True , uid ) ;
2005-06-09 02:10:34 +04:00
}
2005-06-25 00:25:18 +04:00
static void sid2uid_name2uid_recv ( void * private_data , BOOL success , uid_t uid )
2005-06-09 02:10:34 +04:00
{
struct sid2uid_state * state =
2005-06-25 00:25:18 +04:00
talloc_get_type_abort ( private_data , struct sid2uid_state ) ;
2005-06-09 02:10:34 +04:00
unid_t id ;
if ( ! success ) {
DEBUG ( 5 , ( " Could not find uid for name %s \n " ,
state - > username ) ) ;
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
state - > uid = uid ;
id . uid = uid ;
idmap_set_mapping_async ( state - > mem_ctx , & state - > sid , id , ID_USERID ,
sid2uid_set_mapping_recv , state ) ;
}
2005-06-25 00:25:18 +04:00
static void sid2uid_set_mapping_recv ( void * private_data , BOOL success )
2005-06-09 02:10:34 +04:00
{
struct sid2uid_state * state =
2005-06-25 00:25:18 +04:00
talloc_get_type_abort ( private_data , struct sid2uid_state ) ;
2005-06-09 02:10:34 +04:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not set ID mapping for sid %s \n " ,
sid_string_static ( & state - > sid ) ) ) ;
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , True , state - > uid ) ;
2005-06-09 02:10:34 +04:00
}
struct sid2gid_state {
TALLOC_CTX * mem_ctx ;
DOM_SID sid ;
char * groupname ;
gid_t gid ;
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
} ;
2005-06-25 00:25:18 +04:00
static void sid2gid_lookup_sid_recv ( void * private_data , BOOL success ,
2005-06-09 02:10:34 +04:00
const char * dom_name , const char * name ,
enum SID_NAME_USE type ) ;
2005-06-25 00:25:18 +04:00
static void sid2gid_noalloc_recv ( void * private_data , BOOL success , gid_t gid ) ;
static void sid2gid_alloc_recv ( void * private_data , BOOL success , gid_t gid ) ;
static void sid2gid_name2gid_recv ( void * private_data , BOOL success , gid_t gid ) ;
static void sid2gid_set_mapping_recv ( void * private_data , BOOL success ) ;
2005-06-09 02:10:34 +04:00
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 ,
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 sid2gid_state * state ;
NTSTATUS result ;
gid_t gid ;
if ( idmap_proxyonly ( ) ) {
DEBUG ( 10 , ( " idmap proxy only \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
/* Query only the local tdb, everything else might possibly block */
result = idmap_sid_to_gid ( sid , & gid , ID_QUERY_ONLY | ID_CACHE_ONLY ) ;
if ( NT_STATUS_IS_OK ( result ) ) {
2005-06-25 00:25:18 +04:00
cont ( private_data , True , gid ) ;
2005-06-09 02:10:34 +04:00
return ;
}
state = TALLOC_P ( mem_ctx , struct sid2gid_state ) ;
if ( state = = NULL ) {
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
2005-06-25 00:25:18 +04:00
cont ( private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
state - > mem_ctx = mem_ctx ;
state - > sid = * sid ;
state - > cont = cont ;
2005-06-25 00:25:18 +04:00
state - > private_data = private_data ;
2005-06-09 02:10:34 +04:00
/* Let's see if it's really a user before allocating a gid */
winbindd_lookupsid_async ( mem_ctx , sid , sid2gid_lookup_sid_recv , state ) ;
}
2005-06-25 00:25:18 +04:00
static void sid2gid_lookup_sid_recv ( void * private_data , BOOL success ,
2005-06-09 02:10:34 +04:00
const char * dom_name , const char * name ,
enum SID_NAME_USE type )
{
struct sid2gid_state * state =
2005-06-25 00:25:18 +04:00
talloc_get_type_abort ( private_data , struct sid2gid_state ) ;
2005-06-09 02:10:34 +04:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger lookup_sid \n " ) ) ;
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
if ( ( ( type ! = SID_NAME_DOM_GRP ) & & ( type ! = SID_NAME_ALIAS ) & &
( type ! = SID_NAME_WKN_GRP ) ) ) {
DEBUG ( 5 , ( " SID is not a group \n " ) ) ;
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
state - > groupname = talloc_strdup ( state - > mem_ctx , name ) ;
/* Ask the possibly blocking remote IDMAP and allocate */
idmap_sid2gid_async ( state - > mem_ctx , & state - > sid , False ,
sid2gid_noalloc_recv , state ) ;
}
2005-06-25 00:25:18 +04:00
static void sid2gid_noalloc_recv ( void * private_data , BOOL success , gid_t gid )
2005-06-09 02:10:34 +04:00
{
struct sid2gid_state * state =
2005-06-25 00:25:18 +04:00
talloc_get_type_abort ( private_data , struct sid2gid_state ) ;
2005-06-09 02:10:34 +04:00
if ( success ) {
DEBUG ( 10 , ( " found gid for sid %s in remote backend \n " ,
sid_string_static ( & state - > sid ) ) ) ;
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , True , gid ) ;
2005-06-09 02:10:34 +04:00
return ;
}
if ( lp_winbind_trusted_domains_only ( ) & &
( sid_compare_domain ( & state - > sid , & find_our_domain ( ) - > sid ) = = 0 ) ) {
DEBUG ( 10 , ( " Trying to go via nss \n " ) ) ;
winbindd_name2gid_async ( state - > mem_ctx , state - > groupname ,
sid2gid_name2gid_recv , state ) ;
return ;
}
/* To be done: Here we're going to try the unixinfo pipe */
/* Now allocate a gid */
idmap_sid2gid_async ( state - > mem_ctx , & state - > sid , True ,
sid2gid_alloc_recv , state ) ;
}
2005-06-25 00:25:18 +04:00
static void sid2gid_alloc_recv ( void * private_data , BOOL success , gid_t gid )
2005-06-09 02:10:34 +04:00
{
struct sid2gid_state * state =
2005-06-25 00:25:18 +04:00
talloc_get_type_abort ( private_data , struct sid2gid_state ) ;
2005-06-09 02:10:34 +04:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not allocate gid \n " ) ) ;
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , True , gid ) ;
2005-06-09 02:10:34 +04:00
}
2005-06-25 00:25:18 +04:00
static void sid2gid_name2gid_recv ( void * private_data , BOOL success , gid_t gid )
2005-06-09 02:10:34 +04:00
{
struct sid2gid_state * state =
2005-06-25 00:25:18 +04:00
talloc_get_type_abort ( private_data , struct sid2gid_state ) ;
2005-06-09 02:10:34 +04:00
unid_t id ;
if ( ! success ) {
DEBUG ( 5 , ( " Could not find gid for name %s \n " ,
state - > groupname ) ) ;
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
state - > gid = gid ;
id . gid = gid ;
idmap_set_mapping_async ( state - > mem_ctx , & state - > sid , id , ID_GROUPID ,
sid2gid_set_mapping_recv , state ) ;
}
2005-06-25 00:25:18 +04:00
static void sid2gid_set_mapping_recv ( void * private_data , BOOL success )
2005-06-09 02:10:34 +04:00
{
struct sid2gid_state * state =
2005-06-25 00:25:18 +04:00
talloc_get_type_abort ( private_data , struct sid2gid_state ) ;
2005-06-09 02:10:34 +04:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not set ID mapping for sid %s \n " ,
sid_string_static ( & state - > sid ) ) ) ;
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , False , 0 ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2005-06-25 00:25:18 +04:00
state - > cont ( state - > private_data , True , state - > gid ) ;
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 ,
const char * shell , uint32 group_rid ) = c ;
2005-06-09 02:10:34 +04:00
if ( ! success ) {
DEBUG ( 5 , ( " Could not trigger query_user \n " ) ) ;
2005-06-29 18:03:53 +04:00
cont ( private_data , False , NULL , NULL , NULL , NULL , - 1 ) ;
2005-06-09 02:10:34 +04:00
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 ,
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 ,
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 ,
2005-06-25 00:25:18 +04:00
cont , private_data ) ;
2005-06-09 02:10:34 +04:00
}