2000-07-10 05:40:43 +00:00
/*
2002-01-30 06:08:46 +00:00
Unix SMB / CIFS implementation .
2000-07-10 05:40:43 +00:00
winbind client code
Copyright ( C ) Tim Potter 2000
Copyright ( C ) Andrew Tridgell 2000
This library is free software ; you can redistribute it and / or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation ; either
version 2 of the License , or ( at your option ) any later version .
This library 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
Library General Public License for more details .
You should have received a copy of the GNU Library General Public
License along with this library ; if not , write to the
Free Software Foundation , Inc . , 59 Temple Place - Suite 330 ,
Boston , MA 02111 - 1307 , USA .
*/
# include "includes.h"
2003-04-02 06:16:15 +00:00
# include "nsswitch/winbind_nss.h"
2000-07-10 05:40:43 +00:00
2002-07-15 10:35:28 +00:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_WINBIND
2005-06-24 20:25:18 +00:00
NSS_STATUS winbindd_request_response ( int req_type ,
2001-08-24 20:32:01 +00:00
struct winbindd_request * request ,
struct winbindd_response * response ) ;
2001-06-04 04:12:38 +00:00
2000-07-10 05:40:43 +00:00
/* Call winbindd to convert a name to a sid */
2002-01-26 09:55:38 +00:00
BOOL winbind_lookup_name ( const char * dom_name , const char * name , DOM_SID * sid ,
2006-09-08 14:28:06 +00:00
enum lsa_SidType * name_type )
2000-07-10 05:40:43 +00:00
{
struct winbindd_request request ;
2000-07-11 01:04:09 +00:00
struct winbindd_response response ;
2001-06-04 04:12:38 +00:00
NSS_STATUS result ;
2000-07-10 05:40:43 +00:00
2000-07-11 01:04:09 +00:00
if ( ! sid | | ! name_type )
return False ;
2000-07-10 05:40:43 +00:00
2000-07-11 01:04:09 +00:00
/* Send off request */
2000-07-10 05:40:43 +00:00
2000-07-11 01:04:09 +00:00
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
2000-07-10 05:40:43 +00:00
2002-01-26 09:55:38 +00:00
fstrcpy ( request . data . name . dom_name , dom_name ) ;
fstrcpy ( request . data . name . name , name ) ;
2001-06-04 04:12:38 +00:00
2005-06-24 20:25:18 +00:00
if ( ( result = winbindd_request_response ( WINBINDD_LOOKUPNAME , & request ,
2000-07-10 05:40:43 +00:00
& response ) ) = = NSS_STATUS_SUCCESS ) {
2003-02-18 07:15:52 +00:00
if ( ! string_to_sid ( sid , response . data . sid . sid ) )
return False ;
2006-09-08 14:28:06 +00:00
* name_type = ( enum lsa_SidType ) response . data . sid . type ;
2000-07-10 05:40:43 +00:00
}
2000-07-11 01:04:09 +00:00
return result = = NSS_STATUS_SUCCESS ;
2000-07-10 05:40:43 +00:00
}
/* Call winbindd to convert sid to name */
2005-12-03 18:34:13 +00:00
BOOL winbind_lookup_sid ( TALLOC_CTX * mem_ctx , const DOM_SID * sid ,
2006-12-19 14:01:05 +00:00
const char * * domain , const char * * name ,
2006-09-08 14:28:06 +00:00
enum lsa_SidType * name_type )
2000-07-10 05:40:43 +00:00
{
struct winbindd_request request ;
struct winbindd_response response ;
2001-06-04 04:12:38 +00:00
NSS_STATUS result ;
2000-07-10 05:40:43 +00:00
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
2005-12-03 18:34:13 +00:00
fstrcpy ( request . data . sid , sid_string_static ( sid ) ) ;
2000-07-10 05:40:43 +00:00
/* Make request */
2005-12-03 18:34:13 +00:00
result = winbindd_request_response ( WINBINDD_LOOKUPSID , & request ,
& response ) ;
2000-07-10 05:40:43 +00:00
2005-12-03 18:34:13 +00:00
if ( result ! = NSS_STATUS_SUCCESS ) {
return False ;
}
2000-07-10 05:40:43 +00:00
2005-12-03 18:34:13 +00:00
/* Copy out result */
2001-08-13 02:33:24 +00:00
2005-12-03 18:34:13 +00:00
if ( domain ! = NULL ) {
* domain = talloc_strdup ( mem_ctx , response . data . name . dom_name ) ;
if ( * domain = = NULL ) {
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
return False ;
}
2000-08-23 00:45:40 +00:00
}
2005-12-03 18:34:13 +00:00
if ( name ! = NULL ) {
* name = talloc_strdup ( mem_ctx , response . data . name . name ) ;
if ( * name = = NULL ) {
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
return False ;
}
}
2006-09-08 14:28:06 +00:00
* name_type = ( enum lsa_SidType ) response . data . name . type ;
2000-08-23 00:45:40 +00:00
2005-12-03 18:34:13 +00:00
DEBUG ( 10 , ( " winbind_lookup_sid: SUCCESS: SID %s -> %s %s \n " ,
2005-12-10 23:56:42 +00:00
sid_string_static ( sid ) , response . data . name . dom_name ,
response . data . name . name ) ) ;
2005-12-03 18:34:13 +00:00
return True ;
2000-08-23 00:45:40 +00:00
}
2006-07-11 18:01:26 +00:00
BOOL winbind_lookup_rids ( TALLOC_CTX * mem_ctx ,
const DOM_SID * domain_sid ,
int num_rids , uint32 * rids ,
const char * * domain_name ,
2006-09-08 14:28:06 +00:00
const char * * * names , enum lsa_SidType * * types )
2006-07-11 18:01:26 +00:00
{
size_t i , buflen ;
ssize_t len ;
char * ridlist ;
char * p ;
struct winbindd_request request ;
struct winbindd_response response ;
NSS_STATUS result ;
if ( num_rids = = 0 ) {
return False ;
}
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
fstrcpy ( request . data . sid , sid_string_static ( domain_sid ) ) ;
len = 0 ;
buflen = 0 ;
ridlist = NULL ;
for ( i = 0 ; i < num_rids ; i + + ) {
sprintf_append ( mem_ctx , & ridlist , & len , & buflen ,
" %ld \n " , rids [ i ] ) ;
}
if ( ( num_rids ! = 0 ) & & ( ridlist = = NULL ) ) {
return False ;
}
request . extra_data . data = ridlist ;
request . extra_len = strlen ( ridlist ) + 1 ;
result = winbindd_request_response ( WINBINDD_LOOKUPRIDS ,
& request , & response ) ;
TALLOC_FREE ( ridlist ) ;
if ( result ! = NSS_STATUS_SUCCESS ) {
return False ;
}
* domain_name = talloc_strdup ( mem_ctx , response . data . domain_name ) ;
2007-04-30 02:39:34 +00:00
if ( num_rids ) {
* names = TALLOC_ARRAY ( mem_ctx , const char * , num_rids ) ;
* types = TALLOC_ARRAY ( mem_ctx , enum lsa_SidType , num_rids ) ;
2006-07-11 18:01:26 +00:00
2007-04-30 02:39:34 +00:00
if ( ( * names = = NULL ) | | ( * types = = NULL ) ) {
goto fail ;
}
} else {
* names = NULL ;
* types = NULL ;
2006-07-11 18:01:26 +00:00
}
2006-07-31 20:51:55 +00:00
p = ( char * ) response . extra_data . data ;
2006-07-11 18:01:26 +00:00
for ( i = 0 ; i < num_rids ; i + + ) {
char * q ;
if ( * p = = ' \0 ' ) {
DEBUG ( 10 , ( " Got invalid reply: %s \n " ,
( char * ) response . extra_data . data ) ) ;
goto fail ;
}
2006-09-08 14:28:06 +00:00
( * types ) [ i ] = ( enum lsa_SidType ) strtoul ( p , & q , 10 ) ;
2006-07-11 18:01:26 +00:00
if ( * q ! = ' ' ) {
DEBUG ( 10 , ( " Got invalid reply: %s \n " ,
( char * ) response . extra_data . data ) ) ;
goto fail ;
}
p = q + 1 ;
q = strchr ( p , ' \n ' ) ;
if ( q = = NULL ) {
DEBUG ( 10 , ( " Got invalid reply: %s \n " ,
( char * ) response . extra_data . data ) ) ;
goto fail ;
}
* q = ' \0 ' ;
( * names ) [ i ] = talloc_strdup ( * names , p ) ;
p = q + 1 ;
}
if ( * p ! = ' \0 ' ) {
DEBUG ( 10 , ( " Got invalid reply: %s \n " ,
( char * ) response . extra_data . data ) ) ;
goto fail ;
}
SAFE_FREE ( response . extra_data . data ) ;
return True ;
fail :
TALLOC_FREE ( * names ) ;
TALLOC_FREE ( * types ) ;
return False ;
}
2000-08-23 00:45:40 +00:00
/* Call winbindd to convert SID to uid */
2002-08-17 17:00:51 +00:00
BOOL winbind_sid_to_uid ( uid_t * puid , const DOM_SID * sid )
2000-08-23 00:45:40 +00:00
{
struct winbindd_request request ;
struct winbindd_response response ;
int result ;
fstring sid_str ;
if ( ! puid )
return False ;
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
sid_to_string ( sid_str , sid ) ;
fstrcpy ( request . data . sid , sid_str ) ;
/* Make request */
2005-06-24 20:25:18 +00:00
result = winbindd_request_response ( WINBINDD_SID_TO_UID , & request , & response ) ;
2000-08-23 00:45:40 +00:00
/* Copy out result */
if ( result = = NSS_STATUS_SUCCESS ) {
* puid = response . data . uid ;
2000-07-10 05:40:43 +00:00
}
return ( result = = NSS_STATUS_SUCCESS ) ;
}
/* Call winbindd to convert uid to sid */
2000-10-13 01:59:14 +00:00
BOOL winbind_uid_to_sid ( DOM_SID * sid , uid_t uid )
2000-07-10 05:40:43 +00:00
{
struct winbindd_request request ;
struct winbindd_response response ;
int result ;
2000-08-02 02:11:55 +00:00
if ( ! sid )
return False ;
2000-07-10 05:40:43 +00:00
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
request . data . uid = uid ;
/* Make request */
2005-06-24 20:25:18 +00:00
result = winbindd_request_response ( WINBINDD_UID_TO_SID , & request , & response ) ;
2000-07-10 05:40:43 +00:00
/* Copy out result */
if ( result = = NSS_STATUS_SUCCESS ) {
2003-02-18 07:15:52 +00:00
if ( ! string_to_sid ( sid , response . data . sid . sid ) )
return False ;
2000-07-10 05:40:43 +00:00
} else {
sid_copy ( sid , & global_sid_NULL ) ;
}
return ( result = = NSS_STATUS_SUCCESS ) ;
}
2000-08-23 00:45:40 +00:00
/* Call winbindd to convert SID to gid */
2000-07-10 05:40:43 +00:00
2002-08-17 17:00:51 +00:00
BOOL winbind_sid_to_gid ( gid_t * pgid , const DOM_SID * sid )
2000-08-23 00:45:40 +00:00
{
struct winbindd_request request ;
struct winbindd_response response ;
int result ;
fstring sid_str ;
if ( ! pgid )
return False ;
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
sid_to_string ( sid_str , sid ) ;
fstrcpy ( request . data . sid , sid_str ) ;
/* Make request */
2005-06-24 20:25:18 +00:00
result = winbindd_request_response ( WINBINDD_SID_TO_GID , & request , & response ) ;
2000-08-23 00:45:40 +00:00
/* Copy out result */
if ( result = = NSS_STATUS_SUCCESS ) {
* pgid = response . data . gid ;
}
return ( result = = NSS_STATUS_SUCCESS ) ;
}
/* Call winbindd to convert gid to sid */
2000-10-13 01:59:14 +00:00
BOOL winbind_gid_to_sid ( DOM_SID * sid , gid_t gid )
2000-07-10 05:40:43 +00:00
{
struct winbindd_request request ;
struct winbindd_response response ;
int result ;
2000-08-02 02:11:55 +00:00
if ( ! sid )
return False ;
2000-07-10 05:40:43 +00:00
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
request . data . gid = gid ;
/* Make request */
2005-06-24 20:25:18 +00:00
result = winbindd_request_response ( WINBINDD_GID_TO_SID , & request , & response ) ;
2000-07-10 05:40:43 +00:00
/* Copy out result */
if ( result = = NSS_STATUS_SUCCESS ) {
2003-02-18 07:15:52 +00:00
if ( ! string_to_sid ( sid , response . data . sid . sid ) )
return False ;
2000-07-10 05:40:43 +00:00
} else {
sid_copy ( sid , & global_sid_NULL ) ;
}
return ( result = = NSS_STATUS_SUCCESS ) ;
}
2000-08-02 02:11:55 +00:00
2006-12-12 14:52:13 +00:00
/* Call winbindd to convert SID to uid */
BOOL winbind_sids_to_unixids ( struct id_map * ids , int num_ids )
{
struct winbindd_request request ;
struct winbindd_response response ;
int result ;
DOM_SID * sids ;
int i ;
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
request . extra_len = num_ids * sizeof ( DOM_SID ) ;
2006-12-27 10:26:32 +00:00
sids = ( DOM_SID * ) SMB_MALLOC ( request . extra_len ) ;
2006-12-12 14:52:13 +00:00
for ( i = 0 ; i < num_ids ; i + + ) {
sid_copy ( & sids [ i ] , ids [ i ] . sid ) ;
}
request . extra_data . data = ( char * ) sids ;
/* Make request */
result = winbindd_request_response ( WINBINDD_SIDS_TO_XIDS , & request , & response ) ;
/* Copy out result */
if ( result = = NSS_STATUS_SUCCESS ) {
struct unixid * wid = ( struct unixid * ) response . extra_data . data ;
for ( i = 0 ; i < num_ids ; i + + ) {
if ( wid [ i ] . type = = - 1 ) {
2007-01-14 17:58:24 +00:00
ids [ i ] . status = ID_UNMAPPED ;
2006-12-12 14:52:13 +00:00
} else {
2007-01-14 17:58:24 +00:00
ids [ i ] . status = ID_MAPPED ;
2006-12-12 14:52:13 +00:00
ids [ i ] . xid . type = wid [ i ] . type ;
ids [ i ] . xid . id = wid [ i ] . id ;
}
}
}
SAFE_FREE ( request . extra_data . data ) ;
SAFE_FREE ( response . extra_data . data ) ;
return ( result = = NSS_STATUS_SUCCESS ) ;
}
BOOL winbind_idmap_dump_maps ( TALLOC_CTX * memctx , const char * file )
{
struct winbindd_request request ;
struct winbindd_response response ;
int result ;
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
request . extra_data . data = SMB_STRDUP ( file ) ;
request . extra_len = strlen ( request . extra_data . data ) + 1 ;
result = winbindd_request_response ( WINBINDD_DUMP_MAPS , & request , & response ) ;
SAFE_FREE ( request . extra_data . data ) ;
return ( result = = NSS_STATUS_SUCCESS ) ;
}
2006-02-03 22:19:41 +00:00
BOOL winbind_allocate_uid ( uid_t * uid )
2004-04-07 12:43:44 +00:00
{
struct winbindd_request request ;
struct winbindd_response response ;
int result ;
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
/* Make request */
2006-02-03 22:19:41 +00:00
result = winbindd_request_response ( WINBINDD_ALLOCATE_UID ,
& request , & response ) ;
2004-04-07 12:43:44 +00:00
if ( result ! = NSS_STATUS_SUCCESS )
return False ;
/* Copy out result */
2006-02-03 22:19:41 +00:00
* uid = response . data . uid ;
2004-04-07 12:43:44 +00:00
return True ;
}
2006-02-03 22:19:41 +00:00
BOOL winbind_allocate_gid ( gid_t * gid )
2005-06-08 22:10:34 +00:00
{
struct winbindd_request request ;
struct winbindd_response response ;
int result ;
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
/* Make request */
2006-02-03 22:19:41 +00:00
result = winbindd_request_response ( WINBINDD_ALLOCATE_GID ,
& request , & response ) ;
2005-06-08 22:10:34 +00:00
if ( result ! = NSS_STATUS_SUCCESS )
return False ;
/* Copy out result */
2006-02-03 22:19:41 +00:00
* gid = response . data . gid ;
2005-06-08 22:10:34 +00:00
return True ;
}
2006-12-12 14:52:13 +00:00
BOOL winbind_set_mapping ( const struct id_map * map )
{
struct winbindd_request request ;
struct winbindd_response response ;
int result ;
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
/* Make request */
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 ) ;
result = winbindd_request_response ( WINBINDD_SET_MAPPING , & request , & response ) ;
return ( result = = NSS_STATUS_SUCCESS ) ;
}
BOOL winbind_set_uid_hwm ( unsigned long id )
{
struct winbindd_request request ;
struct winbindd_response response ;
int result ;
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
/* Make request */
request . data . dual_idmapset . id = id ;
request . data . dual_idmapset . type = ID_TYPE_UID ;
result = winbindd_request_response ( WINBINDD_SET_HWM , & request , & response ) ;
return ( result = = NSS_STATUS_SUCCESS ) ;
}
BOOL winbind_set_gid_hwm ( unsigned long id )
{
struct winbindd_request request ;
struct winbindd_response response ;
int result ;
/* Initialise request */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
/* Make request */
request . data . dual_idmapset . id = id ;
request . data . dual_idmapset . type = ID_TYPE_GID ;
result = winbindd_request_response ( WINBINDD_SET_HWM , & request , & response ) ;
return ( result = = NSS_STATUS_SUCCESS ) ;
}
2003-07-01 03:49:41 +00:00
/**********************************************************************
simple wrapper function to see if winbindd is alive
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL winbind_ping ( void )
{
NSS_STATUS result ;
2005-06-24 20:25:18 +00:00
result = winbindd_request_response ( WINBINDD_PING , NULL , NULL ) ;
2003-07-01 03:49:41 +00:00
return result = = NSS_STATUS_SUCCESS ;
}
2005-06-03 15:42:03 +00:00
/**********************************************************************
Is a domain trusted ?
result = = NSS_STATUS_UNAVAIL : winbind not around
result = = NSS_STATUS_NOTFOUND : winbind around , but domain missing
Due to a bad API NSS_STATUS_NOTFOUND is returned both when winbind_off and
when winbind return WINBINDD_ERROR . So the semantics of this routine depends
on winbind_on . Grepping for winbind_off I just found 3 places where winbind
is turned off , and this does not conflict ( as far as I have seen ) with the
callers of is_trusted_domains .
I * hate * global variables . . . .
Volker
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NSS_STATUS wb_is_trusted_domain ( const char * domain )
{
struct winbindd_request request ;
struct winbindd_response response ;
2003-07-09 16:44:47 +00:00
2005-06-03 15:42:03 +00:00
/* Call winbindd */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
fstrcpy ( request . domain_name , domain ) ;
2005-06-24 20:25:18 +00:00
return winbindd_request_response ( WINBINDD_DOMAIN_INFO , & request , & response ) ;
2005-06-03 15:42:03 +00:00
}