2023-01-24 13:03:28 +03:00
/*
2008-01-16 12:27:29 +03:00
Unix SMB / CIFS implementation .
idmap TDB2 backend , used for clustered Samba setups .
2008-08-07 05:59:39 +04:00
This uses dbwrap to access tdb files . The location can be set
using tdb : idmap2 . tdb = " in smb.conf
2008-01-16 12:27:29 +03:00
Copyright ( C ) Andrew Tridgell 2007
This is heavily based upon idmap_tdb . c , which is :
Copyright ( C ) Tim Potter 2000
Copyright ( C ) Jim McDonough < jmcd @ us . ibm . com > 2003
Copyright ( C ) Jeremy Allison 2006
Copyright ( C ) Simo Sorce 2003 - 2006
2010-06-17 11:39:24 +04:00
Copyright ( C ) Michael Adam 2009 - 2010
2010-04-29 14:09:48 +04:00
2008-01-16 12:27:29 +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
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
2010-04-29 14:09:48 +04:00
2008-01-16 12:27:29 +03:00
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 .
2010-04-29 14:09:48 +04:00
2008-01-16 12:27:29 +03:00
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"
2011-04-04 13:46:31 +04:00
# include "system/filesys.h"
2008-01-16 12:27:29 +03:00
# include "winbindd.h"
2010-08-18 20:13:42 +04:00
# include "idmap.h"
2010-06-23 14:01:47 +04:00
# include "idmap_rw.h"
2011-07-07 19:42:08 +04:00
# include "dbwrap/dbwrap.h"
2011-07-06 18:40:21 +04:00
# include "dbwrap/dbwrap_open.h"
2010-10-18 17:55:47 +04:00
# include "../libcli/security/dom_sid.h"
2011-05-05 13:25:29 +04:00
# include "util_tdb.h"
2012-02-17 20:34:03 +04:00
# include "idmap_tdb_common.h"
2008-01-16 12:27:29 +03:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_IDMAP
2010-06-16 17:31:05 +04:00
struct idmap_tdb2_context {
2010-06-16 17:47:23 +04:00
const char * script ; /* script to provide idmaps */
2010-06-16 17:31:05 +04:00
} ;
2008-01-16 12:27:29 +03:00
/* High water mark keys */
# define HWM_GROUP "GROUP HWM"
# define HWM_USER "USER HWM"
/*
2010-06-16 19:30:07 +04:00
* check and initialize high / low water marks in the db
*/
static NTSTATUS idmap_tdb2_init_hwm ( struct idmap_domain * dom )
2008-01-16 12:27:29 +03:00
{
2011-03-13 12:41:27 +03:00
NTSTATUS status ;
2015-04-24 05:04:23 +03:00
uint32_t low_id ;
2012-02-17 20:34:03 +04:00
struct idmap_tdb_common_context * ctx ;
2010-06-16 19:40:12 +04:00
2012-02-17 20:34:03 +04:00
ctx = talloc_get_type ( dom - > private_data ,
struct idmap_tdb_common_context ) ;
2008-01-16 12:27:29 +03:00
2009-01-26 15:07:59 +03:00
/* Create high water marks for group and user id */
2012-06-18 11:07:57 +04:00
status = dbwrap_fetch_uint32_bystring ( ctx - > db , HWM_USER , & low_id ) ;
2011-10-06 23:07:27 +04:00
if ( ! NT_STATUS_IS_OK ( status ) | | ( low_id < dom - > low_id ) ) {
2012-06-18 12:27:54 +04:00
status = dbwrap_trans_store_uint32_bystring ( ctx - > db , HWM_USER ,
dom - > low_id ) ;
2011-03-13 12:41:27 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-07-16 18:51:46 +04:00
DEBUG ( 0 , ( " Unable to initialise user hwm in idmap "
2011-03-13 12:41:27 +03:00
" database: %s \n " , nt_errstr ( status ) ) ) ;
2008-07-16 18:51:46 +04:00
return NT_STATUS_INTERNAL_DB_ERROR ;
2008-01-16 12:27:29 +03:00
}
}
2012-06-18 11:07:57 +04:00
status = dbwrap_fetch_uint32_bystring ( ctx - > db , HWM_GROUP , & low_id ) ;
2011-10-06 23:07:27 +04:00
if ( ! NT_STATUS_IS_OK ( status ) | | ( low_id < dom - > low_id ) ) {
2012-06-18 12:27:54 +04:00
status = dbwrap_trans_store_uint32_bystring ( ctx - > db , HWM_GROUP ,
dom - > low_id ) ;
2011-03-13 12:41:27 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-07-16 18:51:46 +04:00
DEBUG ( 0 , ( " Unable to initialise group hwm in idmap "
2011-03-13 12:41:27 +03:00
" database: %s \n " , nt_errstr ( status ) ) ) ;
2008-07-16 18:51:46 +04:00
return NT_STATUS_INTERNAL_DB_ERROR ;
2008-01-16 12:27:29 +03:00
}
}
return NT_STATUS_OK ;
}
2010-06-16 19:28:34 +04:00
/*
open the permanent tdb
*/
static NTSTATUS idmap_tdb2_open_db ( struct idmap_domain * dom )
{
char * db_path ;
2012-02-17 20:34:03 +04:00
struct idmap_tdb_common_context * ctx ;
2010-06-16 19:40:12 +04:00
2012-02-17 20:34:03 +04:00
ctx = talloc_get_type ( dom - > private_data ,
struct idmap_tdb_common_context ) ;
2010-06-16 19:28:34 +04:00
2010-06-16 19:40:12 +04:00
if ( ctx - > db ) {
2010-06-16 19:28:34 +04:00
/* its already open */
return NT_STATUS_OK ;
}
2011-06-24 12:15:02 +04:00
db_path = talloc_asprintf ( NULL , " %s/idmap2.tdb " , lp_private_dir ( ) ) ;
2010-06-16 19:28:34 +04:00
NT_STATUS_HAVE_NO_MEMORY ( db_path ) ;
/* Open idmap repository */
2012-01-06 20:19:54 +04:00
ctx - > db = db_open ( ctx , db_path , 0 , TDB_DEFAULT , O_RDWR | O_CREAT , 0644 ,
2014-01-27 17:49:12 +04:00
DBWRAP_LOCK_ORDER_1 , DBWRAP_FLAG_NONE ) ;
2010-06-16 19:40:12 +04:00
if ( ctx - > db = = NULL ) {
2010-06-16 19:28:34 +04:00
DEBUG ( 0 , ( " Unable to open idmap_tdb2 database '%s' \n " ,
db_path ) ) ;
2019-05-08 18:05:58 +03:00
TALLOC_FREE ( db_path ) ;
2010-06-16 19:28:34 +04:00
return NT_STATUS_UNSUCCESSFUL ;
}
2019-05-08 18:05:58 +03:00
TALLOC_FREE ( db_path ) ;
2010-06-16 19:28:34 +04:00
2010-06-16 19:30:07 +04:00
return idmap_tdb2_init_hwm ( dom ) ;
2010-06-16 19:28:34 +04:00
}
2010-06-17 10:23:25 +04:00
/**
* store a mapping in the database .
*/
2009-07-28 15:31:09 +04:00
struct idmap_tdb2_set_mapping_context {
const char * ksidstr ;
const char * kidstr ;
} ;
static NTSTATUS idmap_tdb2_set_mapping_action ( struct db_context * db ,
void * private_data )
{
TDB_DATA data ;
NTSTATUS ret ;
struct idmap_tdb2_set_mapping_context * state ;
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
state = ( struct idmap_tdb2_set_mapping_context * ) private_data ;
2009-08-20 17:28:19 +04:00
DEBUG ( 10 , ( " Storing %s <-> %s map \n " , state - > ksidstr , state - > kidstr ) ) ;
2023-07-18 12:45:25 +03:00
/* check whether sid mapping is already present in db */
2011-08-24 15:08:13 +04:00
ret = dbwrap_fetch_bystring ( db , tmp_ctx , state - > ksidstr , & data ) ;
2012-02-26 20:49:23 +04:00
if ( NT_STATUS_IS_OK ( ret ) ) {
2009-07-28 15:31:09 +04:00
ret = NT_STATUS_OBJECT_NAME_COLLISION ;
goto done ;
}
ret = dbwrap_store_bystring ( db , state - > ksidstr ,
string_term_tdb_data ( state - > kidstr ) ,
TDB_INSERT ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
DEBUG ( 0 , ( " Error storing SID -> ID: %s \n " , nt_errstr ( ret ) ) ) ;
goto done ;
}
ret = dbwrap_store_bystring ( db , state - > kidstr ,
string_term_tdb_data ( state - > ksidstr ) ,
TDB_INSERT ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
DEBUG ( 0 , ( " Error storing ID -> SID: %s \n " , nt_errstr ( ret ) ) ) ;
/* try to remove the previous stored SID -> ID map */
dbwrap_delete_bystring ( db , state - > ksidstr ) ;
goto done ;
}
DEBUG ( 10 , ( " Stored %s <-> %s \n " , state - > ksidstr , state - > kidstr ) ) ;
done :
talloc_free ( tmp_ctx ) ;
return ret ;
}
2010-06-17 10:23:25 +04:00
static NTSTATUS idmap_tdb2_set_mapping ( struct idmap_domain * dom , const struct id_map * map )
{
struct idmap_tdb2_context * ctx ;
NTSTATUS ret ;
2018-12-10 14:32:12 +03:00
char * kidstr ;
struct dom_sid_buf sid_str ;
2012-02-17 20:34:03 +04:00
struct idmap_tdb_common_context * commonctx ;
2010-06-17 10:23:25 +04:00
struct idmap_tdb2_set_mapping_context state ;
if ( ! map | | ! map - > sid ) {
return NT_STATUS_INVALID_PARAMETER ;
}
2018-12-10 14:32:12 +03:00
kidstr = NULL ;
2010-06-17 10:23:25 +04:00
/* TODO: should we filter a set_mapping using low/high filters ? */
2012-02-17 20:34:03 +04:00
commonctx = talloc_get_type ( dom - > private_data ,
struct idmap_tdb_common_context ) ;
ctx = talloc_get_type ( commonctx - > private_data ,
struct idmap_tdb2_context ) ;
2010-06-17 10:23:25 +04:00
switch ( map - > xid . type ) {
case ID_TYPE_UID :
kidstr = talloc_asprintf ( ctx , " UID %lu " , ( unsigned long ) map - > xid . id ) ;
break ;
case ID_TYPE_GID :
kidstr = talloc_asprintf ( ctx , " GID %lu " , ( unsigned long ) map - > xid . id ) ;
break ;
default :
DEBUG ( 2 , ( " INVALID unix ID type: 0x02%x \n " , map - > xid . type ) ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
if ( kidstr = = NULL ) {
DEBUG ( 0 , ( " ERROR: Out of memory! \n " ) ) ;
ret = NT_STATUS_NO_MEMORY ;
goto done ;
}
2018-12-10 14:32:12 +03:00
state . ksidstr = dom_sid_str_buf ( map - > sid , & sid_str ) ;
2010-06-17 10:23:25 +04:00
state . kidstr = kidstr ;
2012-02-17 20:34:03 +04:00
ret = dbwrap_trans_do ( commonctx - > db , idmap_tdb2_set_mapping_action ,
2010-06-17 10:23:25 +04:00
& state ) ;
done :
talloc_free ( kidstr ) ;
return ret ;
}
2008-01-16 12:27:29 +03:00
/*
run a script to perform a mapping
The script should the following command lines :
SIDTOID S - 1 - xxxx
IDTOSID UID xxxx
IDTOSID GID xxxx
and should return one of the following as a single line of text
UID : xxxx
GID : xxxx
SID : xxxx
ERR : xxxx
*/
2016-08-08 07:22:30 +03:00
static NTSTATUS idmap_tdb2_script ( struct idmap_tdb2_context * ctx ,
struct id_map * map , const char * fmt , . . . )
PRINTF_ATTRIBUTE ( 3 , 4 ) ;
2008-01-16 12:27:29 +03:00
static NTSTATUS idmap_tdb2_script ( struct idmap_tdb2_context * ctx , struct id_map * map ,
const char * fmt , . . . )
{
va_list ap ;
char * cmd ;
FILE * p ;
char line [ 64 ] ;
unsigned long v ;
2010-06-16 17:47:23 +04:00
cmd = talloc_asprintf ( ctx , " %s " , ctx - > script ) ;
2023-01-24 13:03:28 +03:00
NT_STATUS_HAVE_NO_MEMORY ( cmd ) ;
2008-01-16 12:27:29 +03:00
va_start ( ap , fmt ) ;
cmd = talloc_vasprintf_append ( cmd , fmt , ap ) ;
va_end ( ap ) ;
NT_STATUS_HAVE_NO_MEMORY ( cmd ) ;
p = popen ( cmd , " r " ) ;
talloc_free ( cmd ) ;
if ( p = = NULL ) {
return NT_STATUS_NONE_MAPPED ;
}
if ( fgets ( line , sizeof ( line ) - 1 , p ) = = NULL ) {
pclose ( p ) ;
return NT_STATUS_NONE_MAPPED ;
}
pclose ( p ) ;
DEBUG ( 10 , ( " idmap script gave: %s \n " , line ) ) ;
if ( sscanf ( line , " UID:%lu " , & v ) = = 1 ) {
map - > xid . id = v ;
map - > xid . type = ID_TYPE_UID ;
} else if ( sscanf ( line , " GID:%lu " , & v ) = = 1 ) {
map - > xid . id = v ;
2023-01-24 13:03:28 +03:00
map - > xid . type = ID_TYPE_GID ;
2008-01-16 12:27:29 +03:00
} else if ( strncmp ( line , " SID:S- " , 6 ) = = 0 ) {
if ( ! string_to_sid ( map - > sid , & line [ 4 ] ) ) {
DEBUG ( 0 , ( " Bad SID in '%s' from idmap script %s \n " ,
2010-06-16 17:47:23 +04:00
line , ctx - > script ) ) ;
2023-01-24 13:03:28 +03:00
return NT_STATUS_NONE_MAPPED ;
2008-01-16 12:27:29 +03:00
}
} else {
DEBUG ( 0 , ( " Bad reply '%s' from idmap script %s \n " ,
2010-06-16 17:47:23 +04:00
line , ctx - > script ) ) ;
2008-01-16 12:27:29 +03:00
return NT_STATUS_NONE_MAPPED ;
}
return NT_STATUS_OK ;
}
/*
2023-01-24 13:03:28 +03:00
Single id to sid lookup function .
2008-01-16 12:27:29 +03:00
*/
2010-06-16 18:02:07 +04:00
static NTSTATUS idmap_tdb2_id_to_sid ( struct idmap_domain * dom , struct id_map * map )
2008-01-16 12:27:29 +03:00
{
NTSTATUS ret ;
TDB_DATA data ;
char * keystr ;
2008-09-17 10:15:40 +04:00
NTSTATUS status ;
2012-02-17 20:34:03 +04:00
struct idmap_tdb_common_context * commonctx ;
2010-06-16 18:02:07 +04:00
struct idmap_tdb2_context * ctx ;
2008-09-17 10:15:40 +04:00
2010-06-16 18:02:07 +04:00
if ( ! dom | | ! map ) {
2008-01-16 12:27:29 +03:00
return NT_STATUS_INVALID_PARAMETER ;
}
2010-06-16 19:21:27 +04:00
status = idmap_tdb2_open_db ( dom ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
2012-02-17 20:34:03 +04:00
commonctx = talloc_get_type ( dom - > private_data ,
struct idmap_tdb_common_context ) ;
ctx = talloc_get_type ( commonctx - > private_data ,
struct idmap_tdb2_context ) ;
2010-06-16 18:02:07 +04:00
2008-01-16 12:27:29 +03:00
/* apply filters before checking */
2010-06-16 19:12:44 +04:00
if ( ! idmap_unix_id_is_in_range ( map - > xid . id , dom ) ) {
2008-01-16 12:27:29 +03:00
DEBUG ( 5 , ( " Requested id (%u) out of range (%u - %u). Filtered! \n " ,
2010-06-16 19:12:44 +04:00
map - > xid . id , dom - > low_id , dom - > high_id ) ) ;
2008-01-16 12:27:29 +03:00
return NT_STATUS_NONE_MAPPED ;
}
switch ( map - > xid . type ) {
case ID_TYPE_UID :
keystr = talloc_asprintf ( ctx , " UID %lu " , ( unsigned long ) map - > xid . id ) ;
break ;
2010-04-29 14:09:48 +04:00
2008-01-16 12:27:29 +03:00
case ID_TYPE_GID :
keystr = talloc_asprintf ( ctx , " GID %lu " , ( unsigned long ) map - > xid . id ) ;
break ;
default :
DEBUG ( 2 , ( " INVALID unix ID type: 0x02%x \n " , map - > xid . type ) ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
if ( keystr = = NULL ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
ret = NT_STATUS_NO_MEMORY ;
goto done ;
}
DEBUG ( 10 , ( " Fetching record %s \n " , keystr ) ) ;
/* Check if the mapping exists */
2012-02-17 20:34:03 +04:00
status = dbwrap_fetch_bystring ( commonctx - > db , keystr , keystr , & data ) ;
2008-01-16 12:27:29 +03:00
2011-08-24 15:08:13 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2018-12-10 14:32:12 +03:00
struct dom_sid_buf sidstr ;
2009-07-29 15:36:18 +04:00
struct idmap_tdb2_set_mapping_context store_state ;
2008-01-16 12:27:29 +03:00
DEBUG ( 10 , ( " Record %s not found \n " , keystr ) ) ;
2010-06-16 17:47:23 +04:00
if ( ctx - > script = = NULL ) {
2008-01-16 12:27:29 +03:00
ret = NT_STATUS_NONE_MAPPED ;
goto done ;
}
ret = idmap_tdb2_script ( ctx , map , " IDTOSID %s " , keystr ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
goto done ;
}
2018-12-10 14:32:12 +03:00
store_state . ksidstr = dom_sid_str_buf ( map - > sid , & sidstr ) ;
2009-07-29 15:36:18 +04:00
store_state . kidstr = keystr ;
2012-02-17 20:34:03 +04:00
ret = dbwrap_trans_do ( commonctx - > db ,
idmap_tdb2_set_mapping_action ,
2009-07-29 15:36:18 +04:00
& store_state ) ;
2008-01-16 12:27:29 +03:00
goto done ;
}
2010-04-29 14:09:48 +04:00
2008-01-16 12:27:29 +03:00
if ( ! string_to_sid ( map - > sid , ( const char * ) data . dptr ) ) {
DEBUG ( 10 , ( " INVALID SID (%s) in record %s \n " ,
( const char * ) data . dptr , keystr ) ) ;
ret = NT_STATUS_INTERNAL_DB_ERROR ;
goto done ;
}
DEBUG ( 10 , ( " Found record %s -> %s \n " , keystr , ( const char * ) data . dptr ) ) ;
ret = NT_STATUS_OK ;
done :
talloc_free ( keystr ) ;
return ret ;
}
/*
2023-01-24 13:03:28 +03:00
Single sid to id lookup function .
2008-01-16 12:27:29 +03:00
*/
2010-06-16 19:06:17 +04:00
static NTSTATUS idmap_tdb2_sid_to_id ( struct idmap_domain * dom , struct id_map * map )
2008-01-16 12:27:29 +03:00
{
NTSTATUS ret ;
TDB_DATA data ;
2018-12-10 14:32:12 +03:00
struct dom_sid_buf keystr ;
2008-01-16 12:27:29 +03:00
unsigned long rec_id = 0 ;
2012-02-17 20:34:03 +04:00
struct idmap_tdb_common_context * commonctx ;
2010-06-16 19:06:17 +04:00
struct idmap_tdb2_context * ctx ;
2009-01-25 01:52:23 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
2008-09-17 10:15:40 +04:00
2010-06-16 19:21:27 +04:00
ret = idmap_tdb2_open_db ( dom ) ;
2009-01-25 01:52:23 +03:00
NT_STATUS_NOT_OK_RETURN ( ret ) ;
2008-01-16 12:27:29 +03:00
2012-02-17 20:34:03 +04:00
commonctx = talloc_get_type ( dom - > private_data ,
struct idmap_tdb_common_context ) ;
ctx = talloc_get_type ( commonctx - > private_data ,
struct idmap_tdb2_context ) ;
2010-06-16 19:06:17 +04:00
2018-12-10 14:32:12 +03:00
dom_sid_str_buf ( map - > sid , & keystr ) ;
2008-01-16 12:27:29 +03:00
2018-12-10 14:32:12 +03:00
DEBUG ( 10 , ( " Fetching record %s \n " , keystr . buf ) ) ;
2008-01-16 12:27:29 +03:00
/* Check if sid is present in database */
2018-12-10 14:32:12 +03:00
ret = dbwrap_fetch_bystring ( commonctx - > db , tmp_ctx , keystr . buf , & data ) ;
2011-08-24 15:08:13 +04:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
2009-07-29 15:43:29 +04:00
char * idstr ;
struct idmap_tdb2_set_mapping_context store_state ;
2008-01-16 12:27:29 +03:00
2018-12-10 14:32:12 +03:00
DBG_DEBUG ( " Record %s not found \n " , keystr . buf ) ;
2008-01-16 12:27:29 +03:00
2010-06-16 17:47:23 +04:00
if ( ctx - > script = = NULL ) {
2008-01-16 12:27:29 +03:00
ret = NT_STATUS_NONE_MAPPED ;
goto done ;
}
2010-04-29 14:09:48 +04:00
2018-12-10 14:32:12 +03:00
ret = idmap_tdb2_script ( ctx , map , " SIDTOID %s " , keystr . buf ) ;
2008-01-16 12:27:29 +03:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
goto done ;
}
2010-04-29 14:14:08 +04:00
/* apply filters before returning result */
2010-06-16 19:12:44 +04:00
if ( ! idmap_unix_id_is_in_range ( map - > xid . id , dom ) ) {
2010-04-29 14:14:08 +04:00
DEBUG ( 5 , ( " Script returned id (%u) out of range "
" (%u - %u). Filtered! \n " ,
2010-06-16 19:12:44 +04:00
map - > xid . id , dom - > low_id , dom - > high_id ) ) ;
2010-04-29 14:14:08 +04:00
ret = NT_STATUS_NONE_MAPPED ;
goto done ;
}
2009-07-29 15:43:29 +04:00
idstr = talloc_asprintf ( tmp_ctx , " %cID %lu " ,
map - > xid . type = = ID_TYPE_UID ? ' U ' : ' G ' ,
( unsigned long ) map - > xid . id ) ;
if ( idstr = = NULL ) {
ret = NT_STATUS_NO_MEMORY ;
goto done ;
}
2018-12-10 14:32:12 +03:00
store_state . ksidstr = keystr . buf ;
2009-07-29 15:43:29 +04:00
store_state . kidstr = idstr ;
2012-02-17 20:34:03 +04:00
ret = dbwrap_trans_do ( commonctx - > db ,
idmap_tdb2_set_mapping_action ,
2009-07-29 15:43:29 +04:00
& store_state ) ;
2008-01-16 12:27:29 +03:00
goto done ;
}
/* What type of record is this ? */
if ( sscanf ( ( const char * ) data . dptr , " UID %lu " , & rec_id ) = = 1 ) { /* Try a UID record. */
map - > xid . id = rec_id ;
map - > xid . type = ID_TYPE_UID ;
2018-12-10 14:32:12 +03:00
DBG_DEBUG ( " Found uid record %s -> %s \n " ,
keystr . buf ,
( const char * ) data . dptr ) ;
2008-01-16 12:27:29 +03:00
ret = NT_STATUS_OK ;
} else if ( sscanf ( ( const char * ) data . dptr , " GID %lu " , & rec_id ) = = 1 ) { /* Try a GID record. */
map - > xid . id = rec_id ;
map - > xid . type = ID_TYPE_GID ;
2018-12-10 14:32:12 +03:00
DBG_DEBUG ( " Found gid record %s -> %s \n " ,
keystr . buf ,
( const char * ) data . dptr ) ;
2008-01-16 12:27:29 +03:00
ret = NT_STATUS_OK ;
} else { /* Unknown record type ! */
2018-12-10 14:32:12 +03:00
DBG_WARNING ( " Found INVALID record %s -> %s \n " ,
keystr . buf ,
( const char * ) data . dptr ) ;
2008-01-16 12:27:29 +03:00
ret = NT_STATUS_INTERNAL_DB_ERROR ;
2010-04-29 14:11:04 +04:00
goto done ;
2008-01-16 12:27:29 +03:00
}
2010-04-29 14:09:48 +04:00
2008-01-16 12:27:29 +03:00
/* apply filters before returning result */
2010-06-16 19:12:44 +04:00
if ( ! idmap_unix_id_is_in_range ( map - > xid . id , dom ) ) {
2008-01-16 12:27:29 +03:00
DEBUG ( 5 , ( " Requested id (%u) out of range (%u - %u). Filtered! \n " ,
2010-06-16 19:12:44 +04:00
map - > xid . id , dom - > low_id , dom - > high_id ) ) ;
2008-01-16 12:27:29 +03:00
ret = NT_STATUS_NONE_MAPPED ;
}
done :
2009-01-25 01:52:23 +03:00
talloc_free ( tmp_ctx ) ;
2008-01-16 12:27:29 +03:00
return ret ;
}
/*
2012-02-17 20:34:03 +04:00
Initialise idmap database .
2008-01-16 12:27:29 +03:00
*/
2012-02-17 20:34:03 +04:00
static NTSTATUS idmap_tdb2_db_init ( struct idmap_domain * dom )
2008-01-16 12:27:29 +03:00
{
NTSTATUS ret ;
2012-02-17 20:34:03 +04:00
struct idmap_tdb_common_context * commonctx ;
struct idmap_tdb2_context * ctx ;
const char * idmap_script = NULL ;
2019-05-23 23:33:21 +03:00
const char * ctx_script = NULL ;
2008-01-16 12:27:29 +03:00
2012-02-17 20:34:03 +04:00
commonctx = talloc_zero ( dom , struct idmap_tdb_common_context ) ;
if ( ! commonctx ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
2009-03-02 09:19:50 +03:00
}
2010-04-29 14:09:48 +04:00
2012-02-17 20:34:03 +04:00
commonctx - > rw_ops = talloc_zero ( commonctx , struct idmap_rw_ops ) ;
if ( commonctx - > rw_ops = = NULL ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
ret = NT_STATUS_NO_MEMORY ;
goto failed ;
2008-01-16 12:27:29 +03:00
}
2012-02-17 20:34:03 +04:00
ctx = talloc_zero ( commonctx , struct idmap_tdb2_context ) ;
if ( ! ctx ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
ret = NT_STATUS_NO_MEMORY ;
goto failed ;
}
2010-07-30 01:13:54 +04:00
2019-05-23 23:33:21 +03:00
ctx_script = idmap_config_const_string ( dom - > name , " script " , NULL ) ;
2010-04-29 14:09:48 +04:00
2012-02-17 20:34:03 +04:00
idmap_script = lp_parm_const_string ( - 1 , " idmap " , " script " , NULL ) ;
if ( idmap_script ! = NULL ) {
DEBUG ( 0 , ( " Warning: 'idmap:script' is deprecated. "
" Please use 'idmap config * : script' instead! \n " ) ) ;
2010-07-30 01:13:54 +04:00
}
2008-01-16 12:27:29 +03:00
2019-05-23 23:33:21 +03:00
if ( strequal ( dom - > name , " * " ) & & ctx_script = = NULL ) {
2012-02-17 20:34:03 +04:00
/* fall back to idmap:script for backwards compatibility */
2019-05-23 23:33:21 +03:00
ctx_script = idmap_script ;
2012-02-17 20:34:03 +04:00
}
2010-07-30 01:13:54 +04:00
2019-05-23 23:33:21 +03:00
if ( ctx_script ) {
DEBUG ( 1 , ( " using idmap script '%s' \n " , ctx_script ) ) ;
/*
* We must ensure this memory is owned by ctx .
* The ctx_script const pointer is a pointer into
* the config file data and may become invalid
* on config file reload . BUG : 13956
*/
ctx - > script = talloc_strdup ( ctx , ctx_script ) ;
if ( ctx - > script = = NULL ) {
ret = NT_STATUS_NO_MEMORY ;
goto failed ;
}
2012-02-17 20:34:03 +04:00
}
2010-06-16 19:40:12 +04:00
2012-02-17 20:34:03 +04:00
commonctx - > max_id = dom - > high_id ;
commonctx - > hwmkey_uid = HWM_USER ;
commonctx - > hwmkey_gid = HWM_GROUP ;
2010-07-30 01:13:54 +04:00
2012-02-17 20:34:03 +04:00
commonctx - > sid_to_unixid_fn = idmap_tdb2_sid_to_id ;
commonctx - > unixid_to_sid_fn = idmap_tdb2_id_to_sid ;
2008-01-16 12:27:29 +03:00
2012-02-17 20:34:03 +04:00
commonctx - > rw_ops - > get_new_id = idmap_tdb_common_get_new_id ;
commonctx - > rw_ops - > set_mapping = idmap_tdb2_set_mapping ;
2010-07-30 01:13:54 +04:00
2012-02-17 20:34:03 +04:00
commonctx - > private_data = ctx ;
dom - > private_data = commonctx ;
2010-07-30 01:13:54 +04:00
2012-02-17 20:34:03 +04:00
ret = idmap_tdb2_open_db ( dom ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
goto failed ;
2010-07-30 01:13:54 +04:00
}
2008-01-16 12:27:29 +03:00
2012-02-17 20:34:03 +04:00
return NT_STATUS_OK ;
failed :
talloc_free ( commonctx ) ;
2008-01-16 12:27:29 +03:00
return ret ;
}
2019-03-21 14:30:37 +03:00
static const struct idmap_methods db_methods = {
2008-01-16 12:27:29 +03:00
. init = idmap_tdb2_db_init ,
2012-02-17 20:34:03 +04:00
. unixids_to_sids = idmap_tdb_common_unixids_to_sids ,
. sids_to_unixids = idmap_tdb_common_sids_to_unixids ,
. allocate_id = idmap_tdb_common_get_new_id
2008-01-16 12:27:29 +03:00
} ;
2015-08-13 19:16:20 +03:00
static_decl_idmap ;
2017-04-20 22:24:43 +03:00
NTSTATUS idmap_tdb2_init ( TALLOC_CTX * ctx )
2008-01-16 12:27:29 +03:00
{
return smb_register_idmap ( SMB_IDMAP_INTERFACE_VERSION , " tdb2 " , & db_methods ) ;
}