2006-12-12 17:52:13 +03:00
/*
Unix SMB / CIFS implementation .
ID Mapping
Copyright ( C ) Simo Sorce 2003
Copyright ( C ) Jeremy Allison 2006
2011-01-03 00:05:36 +03:00
Copyright ( C ) Michael Adam 2010
2006-12-12 17:52:13 +03:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2006-12-12 17:52:13 +03:00
( 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
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.*/
2006-12-12 17:52:13 +03:00
# include "includes.h"
2009-03-09 23:50:50 +03:00
# include "winbindd.h"
# include "winbindd_proto.h"
2010-08-18 20:13:42 +04:00
# include "idmap.h"
# include "idmap_cache.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2006-12-12 17:52:13 +03:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_IDMAP
/*****************************************************************
Returns the SID mapped to the given UID .
If mapping is not possible returns an error .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-05-21 05:25:01 +04:00
NTSTATUS idmap_uid_to_sid ( const char * domname , struct dom_sid * sid , uid_t uid )
2006-12-12 17:52:13 +03:00
{
NTSTATUS ret ;
struct id_map map ;
2008-07-13 14:07:40 +04:00
bool expired ;
2006-12-12 17:52:13 +03:00
2008-11-28 12:05:19 +03:00
DEBUG ( 10 , ( " idmap_uid_to_sid: uid = [%lu], domain = '%s' \n " ,
( unsigned long ) uid , domname ? domname : " NULL " ) ) ;
2006-12-12 17:52:13 +03:00
2009-03-09 23:50:50 +03:00
if ( winbindd_use_idmap_cache ( )
& & idmap_cache_find_uid2sid ( uid , sid , & expired ) ) {
2009-05-12 08:56:57 +04:00
DEBUG ( 10 , ( " idmap_cache_find_uid2sid found %u%s \n " ,
( unsigned int ) uid ,
2008-07-13 14:07:40 +04:00
expired ? " (expired) " : " " ) ) ;
if ( expired & & idmap_is_online ( ) ) {
DEBUG ( 10 , ( " revalidating expired entry \n " ) ) ;
goto backend ;
}
if ( is_null_sid ( sid ) ) {
DEBUG ( 10 , ( " Returning negative cache entry \n " ) ) ;
return NT_STATUS_NONE_MAPPED ;
}
DEBUG ( 10 , ( " Returning positive cache entry \n " ) ) ;
return NT_STATUS_OK ;
}
backend :
2011-11-09 23:48:23 +04:00
ZERO_STRUCT ( map ) ;
2006-12-12 17:52:13 +03:00
map . sid = sid ;
map . xid . type = ID_TYPE_UID ;
map . xid . id = uid ;
2008-07-13 14:07:40 +04:00
ret = idmap_backends_unixid_to_sid ( domname , & map ) ;
2006-12-12 17:52:13 +03:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
DEBUG ( 10 , ( " error mapping uid [%lu] \n " , ( unsigned long ) uid ) ) ;
return ret ;
}
2007-01-14 20:58:24 +03:00
if ( map . status ! = ID_MAPPED ) {
2009-03-09 23:50:50 +03:00
if ( winbindd_use_idmap_cache ( ) ) {
struct dom_sid null_sid ;
2012-03-23 14:11:33 +04:00
struct unixid id ;
id . type = ID_TYPE_UID ;
id . id = uid ;
2009-03-09 23:50:50 +03:00
ZERO_STRUCT ( null_sid ) ;
2012-03-23 14:11:33 +04:00
idmap_cache_set_sid2unixid ( & null_sid , & id ) ;
2009-03-09 23:50:50 +03:00
}
2006-12-12 17:52:13 +03:00
DEBUG ( 10 , ( " uid [%lu] not mapped \n " , ( unsigned long ) uid ) ) ;
return NT_STATUS_NONE_MAPPED ;
}
2009-03-09 23:50:50 +03:00
if ( winbindd_use_idmap_cache ( ) ) {
2012-03-23 14:11:33 +04:00
idmap_cache_set_sid2unixid ( sid , & map . xid ) ;
2009-03-09 23:50:50 +03:00
}
2008-07-13 14:07:40 +04:00
2006-12-12 17:52:13 +03:00
return NT_STATUS_OK ;
}
/*****************************************************************
Returns SID mapped to the given GID .
If mapping is not possible returns an error .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-05-21 05:25:01 +04:00
NTSTATUS idmap_gid_to_sid ( const char * domname , struct dom_sid * sid , gid_t gid )
2006-12-12 17:52:13 +03:00
{
NTSTATUS ret ;
struct id_map map ;
2008-07-13 14:07:40 +04:00
bool expired ;
2006-12-12 17:52:13 +03:00
2009-05-16 18:05:37 +04:00
DEBUG ( 10 , ( " idmap_gid_to_sid: gid = [%lu], domain = '%s' \n " ,
2008-11-28 12:05:19 +03:00
( unsigned long ) gid , domname ? domname : " NULL " ) ) ;
2006-12-12 17:52:13 +03:00
2009-03-09 23:50:50 +03:00
if ( winbindd_use_idmap_cache ( )
& & idmap_cache_find_gid2sid ( gid , sid , & expired ) ) {
2009-05-12 08:56:57 +04:00
DEBUG ( 10 , ( " idmap_cache_find_gid2sid found %u%s \n " ,
( unsigned int ) gid ,
2008-07-13 14:07:40 +04:00
expired ? " (expired) " : " " ) ) ;
if ( expired & & idmap_is_online ( ) ) {
DEBUG ( 10 , ( " revalidating expired entry \n " ) ) ;
goto backend ;
}
if ( is_null_sid ( sid ) ) {
DEBUG ( 10 , ( " Returning negative cache entry \n " ) ) ;
return NT_STATUS_NONE_MAPPED ;
}
DEBUG ( 10 , ( " Returning positive cache entry \n " ) ) ;
return NT_STATUS_OK ;
}
backend :
2011-11-09 23:48:23 +04:00
ZERO_STRUCT ( map ) ;
2006-12-12 17:52:13 +03:00
map . sid = sid ;
map . xid . type = ID_TYPE_GID ;
map . xid . id = gid ;
2008-07-13 14:07:40 +04:00
ret = idmap_backends_unixid_to_sid ( domname , & map ) ;
2006-12-12 17:52:13 +03:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
DEBUG ( 10 , ( " error mapping gid [%lu] \n " , ( unsigned long ) gid ) ) ;
return ret ;
}
2007-01-14 20:58:24 +03:00
if ( map . status ! = ID_MAPPED ) {
2009-03-09 23:50:50 +03:00
if ( winbindd_use_idmap_cache ( ) ) {
struct dom_sid null_sid ;
2012-03-23 14:11:33 +04:00
struct unixid id ;
id . type = ID_TYPE_GID ;
id . id = gid ;
2009-03-09 23:50:50 +03:00
ZERO_STRUCT ( null_sid ) ;
2012-03-23 14:11:33 +04:00
idmap_cache_set_sid2unixid ( & null_sid , & id ) ;
2009-03-09 23:50:50 +03:00
}
2006-12-12 17:52:13 +03:00
DEBUG ( 10 , ( " gid [%lu] not mapped \n " , ( unsigned long ) gid ) ) ;
return NT_STATUS_NONE_MAPPED ;
}
2009-03-09 23:50:50 +03:00
if ( winbindd_use_idmap_cache ( ) ) {
2012-03-23 14:11:33 +04:00
idmap_cache_set_sid2unixid ( sid , & map . xid ) ;
2009-03-09 23:50:50 +03:00
}
2008-07-13 14:07:40 +04:00
2006-12-12 17:52:13 +03:00
return NT_STATUS_OK ;
}
/*****************************************************************
Returns the UID mapped to the given SID .
If mapping is not possible or SID maps to a GID returns an error .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-05-21 05:25:01 +04:00
NTSTATUS idmap_sid_to_uid ( const char * dom_name , struct dom_sid * sid , uid_t * uid )
2006-12-12 17:52:13 +03:00
{
NTSTATUS ret ;
struct id_map map ;
2008-07-13 14:07:40 +04:00
bool expired ;
2006-12-12 17:52:13 +03:00
2008-11-28 12:05:19 +03:00
DEBUG ( 10 , ( " idmap_sid_to_uid: sid = [%s], domain = '%s' \n " ,
sid_string_dbg ( sid ) , dom_name ) ) ;
2006-12-12 17:52:13 +03:00
2009-03-09 23:50:50 +03:00
if ( winbindd_use_idmap_cache ( )
& & idmap_cache_find_sid2uid ( sid , uid , & expired ) ) {
2008-07-13 14:07:40 +04:00
DEBUG ( 10 , ( " idmap_cache_find_sid2uid found %d%s \n " ,
( int ) ( * uid ) , expired ? " (expired) " : " " ) ) ;
if ( expired & & idmap_is_online ( ) ) {
DEBUG ( 10 , ( " revalidating expired entry \n " ) ) ;
goto backend ;
}
if ( ( * uid ) = = - 1 ) {
DEBUG ( 10 , ( " Returning negative cache entry \n " ) ) ;
return NT_STATUS_NONE_MAPPED ;
}
DEBUG ( 10 , ( " Returning positive cache entry \n " ) ) ;
return NT_STATUS_OK ;
}
backend :
2011-11-09 23:48:23 +04:00
ZERO_STRUCT ( map ) ;
2006-12-12 17:52:13 +03:00
map . sid = sid ;
2011-11-09 23:48:23 +04:00
map . xid . type = ID_TYPE_UID ;
2008-07-14 14:32:18 +04:00
2008-07-13 14:07:40 +04:00
ret = idmap_backends_sid_to_unixid ( dom_name , & map ) ;
2010-05-14 18:18:16 +04:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
DEBUG ( 10 , ( " idmap_backends_sid_to_unixid failed: %s \n " ,
nt_errstr ( ret ) ) ) ;
if ( winbindd_use_idmap_cache ( ) ) {
idmap_cache_set_sid2uid ( sid , - 1 ) ;
2008-07-13 14:07:40 +04:00
}
2010-05-14 18:18:16 +04:00
return ret ;
2006-12-12 17:52:13 +03:00
}
2010-05-14 18:18:16 +04:00
if ( map . status ! = ID_MAPPED ) {
2010-05-16 02:31:39 +04:00
DEBUG ( 10 , ( " sid [%s] is not mapped \n " , sid_string_dbg ( sid ) ) ) ;
2009-03-09 23:50:50 +03:00
if ( winbindd_use_idmap_cache ( ) ) {
idmap_cache_set_sid2uid ( sid , - 1 ) ;
}
2008-07-29 11:04:17 +04:00
return NT_STATUS_NONE_MAPPED ;
}
2010-05-14 18:18:16 +04:00
if ( map . xid . type ! = ID_TYPE_UID ) {
DEBUG ( 10 , ( " sid [%s] not mapped to a uid "
" [%u,%u,%u] \n " ,
sid_string_dbg ( sid ) ,
map . status ,
map . xid . type ,
map . xid . id ) ) ;
2009-03-09 23:50:50 +03:00
if ( winbindd_use_idmap_cache ( ) ) {
idmap_cache_set_sid2uid ( sid , - 1 ) ;
}
2010-05-14 18:18:16 +04:00
return NT_STATUS_NONE_MAPPED ;
2008-07-13 14:07:40 +04:00
}
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
* uid = ( uid_t ) map . xid . id ;
2009-03-09 23:50:50 +03:00
if ( winbindd_use_idmap_cache ( ) ) {
2012-03-23 14:11:33 +04:00
idmap_cache_set_sid2unixid ( sid , & map . xid ) ;
2009-03-09 23:50:50 +03:00
}
2006-12-12 17:52:13 +03:00
return NT_STATUS_OK ;
}
/*****************************************************************
Returns the GID mapped to the given SID .
If mapping is not possible or SID maps to a UID returns an error .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-05-21 05:25:01 +04:00
NTSTATUS idmap_sid_to_gid ( const char * domname , struct dom_sid * sid , gid_t * gid )
2006-12-12 17:52:13 +03:00
{
NTSTATUS ret ;
struct id_map map ;
2008-07-13 14:07:40 +04:00
bool expired ;
2006-12-12 17:52:13 +03:00
2008-11-28 12:05:19 +03:00
DEBUG ( 10 , ( " idmap_sid_to_gid: sid = [%s], domain = '%s' \n " ,
sid_string_dbg ( sid ) , domname ) ) ;
2006-12-12 17:52:13 +03:00
2009-03-09 23:50:50 +03:00
if ( winbindd_use_idmap_cache ( )
& & idmap_cache_find_sid2gid ( sid , gid , & expired ) ) {
2008-07-13 14:07:40 +04:00
DEBUG ( 10 , ( " idmap_cache_find_sid2gid found %d%s \n " ,
( int ) ( * gid ) , expired ? " (expired) " : " " ) ) ;
if ( expired & & idmap_is_online ( ) ) {
DEBUG ( 10 , ( " revalidating expired entry \n " ) ) ;
goto backend ;
}
if ( ( * gid ) = = - 1 ) {
DEBUG ( 10 , ( " Returning negative cache entry \n " ) ) ;
return NT_STATUS_NONE_MAPPED ;
}
DEBUG ( 10 , ( " Returning positive cache entry \n " ) ) ;
return NT_STATUS_OK ;
}
backend :
2011-11-09 23:48:23 +04:00
ZERO_STRUCT ( map ) ;
2006-12-12 17:52:13 +03:00
map . sid = sid ;
2007-04-20 02:26:09 +04:00
map . xid . type = ID_TYPE_GID ;
2008-07-14 14:32:18 +04:00
2008-07-13 14:07:40 +04:00
ret = idmap_backends_sid_to_unixid ( domname , & map ) ;
2010-05-14 18:19:46 +04:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
DEBUG ( 10 , ( " idmap_backends_sid_to_unixid failed: %s \n " ,
nt_errstr ( ret ) ) ) ;
if ( winbindd_use_idmap_cache ( ) ) {
2010-11-24 13:57:59 +03:00
idmap_cache_set_sid2gid ( sid , - 1 ) ;
2008-07-13 14:07:40 +04:00
}
2010-05-14 18:19:46 +04:00
return ret ;
2006-12-12 17:52:13 +03:00
}
2010-05-14 18:19:46 +04:00
if ( map . status ! = ID_MAPPED ) {
2010-05-16 02:32:10 +04:00
DEBUG ( 10 , ( " sid [%s] is not mapped \n " , sid_string_dbg ( sid ) ) ) ;
2009-03-09 23:50:50 +03:00
if ( winbindd_use_idmap_cache ( ) ) {
2010-11-24 13:57:59 +03:00
idmap_cache_set_sid2gid ( sid , - 1 ) ;
2009-03-09 23:50:50 +03:00
}
2008-07-29 11:04:17 +04:00
return NT_STATUS_NONE_MAPPED ;
}
2010-05-14 18:19:46 +04:00
if ( map . xid . type ! = ID_TYPE_GID ) {
DEBUG ( 10 , ( " sid [%s] not mapped to a gid "
" [%u,%u,%u] \n " ,
sid_string_dbg ( sid ) ,
map . status ,
map . xid . type ,
map . xid . id ) ) ;
2009-03-09 23:50:50 +03:00
if ( winbindd_use_idmap_cache ( ) ) {
idmap_cache_set_sid2gid ( sid , - 1 ) ;
}
2010-05-14 18:19:46 +04:00
return NT_STATUS_NONE_MAPPED ;
2006-12-12 17:52:13 +03:00
}
* gid = map . xid . id ;
2009-03-09 23:50:50 +03:00
if ( winbindd_use_idmap_cache ( ) ) {
2012-03-23 14:11:33 +04:00
idmap_cache_set_sid2unixid ( sid , & map . xid ) ;
2009-03-09 23:50:50 +03:00
}
2006-12-12 17:52:13 +03:00
return NT_STATUS_OK ;
}
2010-06-16 18:59:26 +04:00
/**
* check whether a given unix id is inside the filter range of an idmap domain
*/
bool idmap_unix_id_is_in_range ( uint32_t id , struct idmap_domain * dom )
{
if ( id = = 0 ) {
/* 0 is not an allowed unix id for id mapping */
return false ;
}
if ( ( dom - > low_id & & ( id < dom - > low_id ) ) | |
( dom - > high_id & & ( id > dom - > high_id ) ) )
{
return false ;
}
return true ;
}