2003-03-08 00:49:18 +00:00
/*
Unix SMB / CIFS implementation .
idmap TDB backend
Copyright ( C ) Tim Potter 2000
Copyright ( C ) Anthony Liguori 2003
Copyright ( C ) Simo Sorce 2003
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"
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_IDMAP
/* High water mark keys */
# define HWM_GROUP "GROUP HWM"
# define HWM_USER "USER HWM"
/* idmap version determines auto-conversion */
# define IDMAP_VERSION 2
/* Globals */
static TDB_CONTEXT * idmap_tdb ;
2003-04-02 10:36:02 +00:00
static struct idmap_state {
2003-03-08 17:29:40 +00:00
/* User and group id pool */
uid_t uid_low , uid_high ; /* Range of uids to allocate */
gid_t gid_low , gid_high ; /* Range of gids to allocate */
} idmap_state ;
2003-03-08 00:49:18 +00:00
/* Allocate either a user or group id from the pool */
2003-04-02 10:36:02 +00:00
static NTSTATUS db_allocate_id ( unid_t * id , int id_type )
2003-03-08 00:49:18 +00:00
{
2003-06-11 18:14:34 +00:00
BOOL ret ;
2003-03-08 00:49:18 +00:00
int hwm ;
2003-06-25 00:02:17 +00:00
if ( ! id )
return NT_STATUS_INVALID_PARAMETER ;
2003-03-08 00:49:18 +00:00
/* Get current high water mark */
2003-03-08 17:29:40 +00:00
switch ( id_type & ID_TYPEMASK ) {
2003-03-08 00:49:18 +00:00
case ID_USERID :
2003-06-25 00:02:17 +00:00
2003-03-08 00:49:18 +00:00
if ( ( hwm = tdb_fetch_int32 ( idmap_tdb , HWM_USER ) ) = = - 1 ) {
return NT_STATUS_INTERNAL_DB_ERROR ;
}
2003-06-11 18:14:34 +00:00
/* check it is in the range */
2003-03-08 17:29:40 +00:00
if ( hwm > idmap_state . uid_high ) {
2003-04-19 15:29:39 +00:00
DEBUG ( 0 , ( " idmap Fatal Error: UID range full!! (max: %u) \n " , idmap_state . uid_high ) ) ;
2003-03-08 00:49:18 +00:00
return NT_STATUS_UNSUCCESSFUL ;
}
2003-06-11 18:14:34 +00:00
/* fetch a new id and increment it */
ret = tdb_change_uint32_atomic ( idmap_tdb , HWM_USER , & hwm , 1 ) ;
if ( ! ret ) {
DEBUG ( 0 , ( " idmap_tdb: Fatal error while fetching a new id \n ! " ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
/* recheck it is in the range */
if ( hwm > idmap_state . uid_high ) {
DEBUG ( 0 , ( " idmap Fatal Error: UID range full!! (max: %u) \n " , idmap_state . uid_high ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
( * id ) . uid = hwm ;
2003-06-25 00:02:17 +00:00
DEBUG ( 10 , ( " db_allocate_id: ID_USERID (*id).uid = %d \n " , ( unsigned int ) hwm ) ) ;
2003-03-08 00:49:18 +00:00
break ;
case ID_GROUPID :
if ( ( hwm = tdb_fetch_int32 ( idmap_tdb , HWM_GROUP ) ) = = - 1 ) {
return NT_STATUS_INTERNAL_DB_ERROR ;
}
2003-06-11 18:14:34 +00:00
/* check it is in the range */
2003-03-08 17:29:40 +00:00
if ( hwm > idmap_state . gid_high ) {
2003-04-19 15:29:39 +00:00
DEBUG ( 0 , ( " idmap Fatal Error: GID range full!! (max: %u) \n " , idmap_state . gid_high ) ) ;
2003-03-08 00:49:18 +00:00
return NT_STATUS_UNSUCCESSFUL ;
}
2003-06-11 18:14:34 +00:00
/* fetch a new id and increment it */
2003-06-11 20:06:11 +00:00
ret = tdb_change_uint32_atomic ( idmap_tdb , HWM_GROUP , & hwm , 1 ) ;
2003-06-11 18:14:34 +00:00
if ( ! ret ) {
DEBUG ( 0 , ( " idmap_tdb: Fatal error while fetching a new id \n ! " ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
/* recheck it is in the range */
2003-06-11 20:06:11 +00:00
if ( hwm > idmap_state . gid_high ) {
DEBUG ( 0 , ( " idmap Fatal Error: GID range full!! (max: %u) \n " , idmap_state . gid_high ) ) ;
2003-06-11 18:14:34 +00:00
return NT_STATUS_UNSUCCESSFUL ;
}
( * id ) . gid = hwm ;
2003-06-25 00:02:17 +00:00
DEBUG ( 10 , ( " db_allocate_id: ID_GROUPID (*id).uid = %d \n " , ( unsigned int ) hwm ) ) ;
2003-03-08 00:49:18 +00:00
break ;
default :
return NT_STATUS_INVALID_PARAMETER ;
}
return NT_STATUS_OK ;
}
/* Get a sid from an id */
2003-06-21 08:31:18 +00:00
static NTSTATUS internal_get_sid_from_id ( DOM_SID * sid , unid_t id , int id_type )
2003-03-08 00:49:18 +00:00
{
TDB_DATA key , data ;
fstring keystr ;
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL ;
if ( ! sid ) return NT_STATUS_INVALID_PARAMETER ;
2003-03-08 17:29:40 +00:00
switch ( id_type & ID_TYPEMASK ) {
2003-03-08 00:49:18 +00:00
case ID_USERID :
2003-04-02 10:36:02 +00:00
slprintf ( keystr , sizeof ( keystr ) , " UID %d " , id . uid ) ;
break ;
2003-03-08 00:49:18 +00:00
case ID_GROUPID :
2003-04-02 10:36:02 +00:00
slprintf ( keystr , sizeof ( keystr ) , " GID %d " , id . gid ) ;
break ;
2003-03-08 00:49:18 +00:00
default :
2003-04-02 10:36:02 +00:00
return NT_STATUS_UNSUCCESSFUL ;
2003-03-08 00:49:18 +00:00
}
key . dptr = keystr ;
key . dsize = strlen ( keystr ) + 1 ;
2003-06-25 00:02:17 +00:00
DEBUG ( 10 , ( " internal_get_sid_from_id: fetching record %s \n " , keystr ) ) ;
2003-03-08 00:49:18 +00:00
data = tdb_fetch ( idmap_tdb , key ) ;
if ( data . dptr ) {
if ( string_to_sid ( sid , data . dptr ) ) {
2003-06-25 00:02:17 +00:00
DEBUG ( 10 , ( " internal_get_sid_from_id: fetching record %s -> %s \n " , keystr , data . dptr ) ) ;
2003-03-08 00:49:18 +00:00
ret = NT_STATUS_OK ;
}
SAFE_FREE ( data . dptr ) ;
}
return ret ;
}
2003-06-21 08:31:18 +00:00
static NTSTATUS internal_get_id_from_sid ( unid_t * id , int * id_type , const DOM_SID * sid )
2003-03-08 00:49:18 +00:00
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL ;
2003-06-21 08:31:18 +00:00
fstring keystr ;
TDB_DATA key , data ;
int type = * id_type & ID_TYPEMASK ;
2003-03-08 00:49:18 +00:00
/* Check if sid is present in database */
sid_to_string ( keystr , sid ) ;
key . dptr = keystr ;
key . dsize = strlen ( keystr ) + 1 ;
2003-06-25 00:02:17 +00:00
DEBUG ( 10 , ( " internal_get_id_from_sid: fetching record %s \n " , keystr ) ) ;
2003-03-08 00:49:18 +00:00
data = tdb_fetch ( idmap_tdb , key ) ;
2003-06-21 08:31:18 +00:00
if ( ! data . dptr )
return ret ;
2003-03-08 00:49:18 +00:00
2003-06-21 08:31:18 +00:00
if ( type = = ID_EMPTY | | type = = ID_USERID ) {
fstring scanstr ;
/* Parse and return existing uid */
fstrcpy ( scanstr , " UID %d " ) ;
if ( sscanf ( data . dptr , scanstr , & ( ( * id ) . uid ) ) = = 1 ) {
/* uid ok? */
if ( type = = ID_EMPTY ) {
* id_type = ID_USERID ;
}
2003-06-25 00:02:17 +00:00
DEBUG ( 10 , ( " internal_get_id_from_sid: %s fetching record %s -> %s \n " ,
( type = = ID_EMPTY ) ? " ID_EMPTY " : " ID_USERID " ,
keystr , data . dptr ) ) ;
2003-06-21 08:31:18 +00:00
ret = NT_STATUS_OK ;
}
}
if ( ! NT_STATUS_IS_OK ( ret )
& & ( type = = ID_EMPTY | | type = = ID_GROUPID ) ) {
2003-03-08 00:49:18 +00:00
fstring scanstr ;
2003-06-21 08:31:18 +00:00
/* Parse and return existing gid */
fstrcpy ( scanstr , " GID %d " ) ;
if ( sscanf ( data . dptr , scanstr , & ( ( * id ) . gid ) ) = = 1 ) {
/* gid ok? */
if ( type = = ID_EMPTY ) {
* id_type = ID_GROUPID ;
}
2003-06-25 00:02:17 +00:00
DEBUG ( 10 , ( " internal_get_id_from_sid: %s fetching record %s -> %s \n " ,
( type = = ID_EMPTY ) ? " ID_EMPTY " : " ID_GROUPID " ,
keystr , data . dptr ) ) ;
2003-06-21 08:31:18 +00:00
ret = NT_STATUS_OK ;
}
}
SAFE_FREE ( data . dptr ) ;
return ret ;
}
2003-03-08 00:49:18 +00:00
2003-06-21 08:31:18 +00:00
/* Get a sid from an id */
static NTSTATUS db_get_sid_from_id ( DOM_SID * sid , unid_t id , int id_type_in )
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL ;
int id_type = id_type_in & ID_TYPEMASK ;
unid_t id_tmp = id ;
int id_type_tmp = id_type ;
2003-03-08 00:49:18 +00:00
2003-06-21 08:31:18 +00:00
ret = internal_get_sid_from_id ( sid , id , id_type ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
return ret ;
}
ret = internal_get_id_from_sid ( & id_tmp , & id_type_tmp , sid ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
return ret ;
}
if ( id_type_tmp ! = id_type ) {
return NT_STATUS_UNSUCCESSFUL ;
} else if ( id_type = = ID_USERID ) {
if ( id_tmp . uid ! = id . uid ) {
return NT_STATUS_UNSUCCESSFUL ;
2003-03-08 00:49:18 +00:00
}
2003-06-21 08:31:18 +00:00
} else if ( id_type = = ID_GROUPID ) {
if ( id_tmp . gid ! = id . gid ) {
return NT_STATUS_UNSUCCESSFUL ;
}
} else {
return NT_STATUS_UNSUCCESSFUL ;
}
return ret ;
}
/* Get an id from a sid */
static NTSTATUS db_get_id_from_sid ( unid_t * id , int * id_type , const DOM_SID * sid )
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL ;
2003-03-08 00:49:18 +00:00
2003-06-25 00:02:17 +00:00
DEBUG ( 10 , ( " db_get_id_from_sid \n " ) ) ;
if ( ! sid | | ! id | | ! id_type )
return NT_STATUS_INVALID_PARAMETER ;
2003-03-08 00:49:18 +00:00
2003-06-21 08:31:18 +00:00
ret = internal_get_id_from_sid ( id , id_type , sid ) ;
if ( NT_STATUS_IS_OK ( ret ) ) {
DOM_SID sid_tmp ;
ret = internal_get_sid_from_id ( & sid_tmp , * id , * id_type ) ;
if ( NT_STATUS_IS_OK ( ret ) ) {
if ( ! sid_equal ( & sid_tmp , sid ) ) {
return ret = NT_STATUS_UNSUCCESSFUL ;
2003-03-08 00:49:18 +00:00
}
}
2003-06-21 08:31:18 +00:00
}
2003-03-08 00:49:18 +00:00
2003-06-21 08:31:18 +00:00
if ( ! ( * id_type & ID_NOMAP ) & & ( ! NT_STATUS_IS_OK ( ret ) ) & &
2003-03-08 17:29:40 +00:00
( ( ( * id_type & ID_TYPEMASK ) = = ID_USERID )
| | ( * id_type & ID_TYPEMASK ) = = ID_GROUPID ) ) {
2003-06-21 08:31:18 +00:00
TDB_DATA sid_data ;
TDB_DATA ugid_data ;
fstring sid_string ;
sid_to_string ( sid_string , sid ) ;
sid_data . dptr = sid_string ;
sid_data . dsize = strlen ( sid_string ) + 1 ;
do {
fstring ugid_str ;
/* Allocate a new id for this sid */
ret = db_allocate_id ( id , * id_type ) ;
if ( ! NT_STATUS_IS_OK ( ret ) )
break ;
2003-03-08 00:49:18 +00:00
/* Store new id */
2003-03-08 17:29:40 +00:00
if ( * id_type & ID_USERID ) {
2003-06-21 08:31:18 +00:00
slprintf ( ugid_str , sizeof ( ugid_str ) , " UID %d " , ( * id ) . uid ) ;
2003-03-08 17:29:40 +00:00
} else {
2003-06-21 08:31:18 +00:00
slprintf ( ugid_str , sizeof ( ugid_str ) , " GID %d " , ( * id ) . gid ) ;
2003-03-08 17:29:40 +00:00
}
2003-06-21 08:31:18 +00:00
ugid_data . dptr = ugid_str ;
ugid_data . dsize = strlen ( ugid_str ) + 1 ;
2003-03-08 00:49:18 +00:00
2003-06-25 00:02:17 +00:00
DEBUG ( 10 , ( " db_get_id_from_sid: storing %s -> %s \n " ,
ugid_data . dptr , sid_data . dptr ) ) ;
2003-06-21 08:31:18 +00:00
/* Store the UID side */
if ( tdb_store ( idmap_tdb , ugid_data , sid_data , TDB_INSERT ) ! = - 1 ) {
ret = NT_STATUS_OK ;
break ;
2003-03-08 17:29:40 +00:00
}
2003-06-21 08:31:18 +00:00
ret = NT_STATUS_UNSUCCESSFUL ;
} while ( idmap_tdb - > ecode = = TDB_ERR_EXISTS ) ;
if ( NT_STATUS_IS_OK ( ret ) ) {
if ( tdb_store ( idmap_tdb , sid_data , ugid_data , TDB_REPLACE ) = = - 1 ) {
2003-03-08 17:29:40 +00:00
/* TODO: print tdb error !! */
2003-03-08 00:49:18 +00:00
return NT_STATUS_UNSUCCESSFUL ;
2003-03-08 17:29:40 +00:00
}
2003-03-08 00:49:18 +00:00
}
}
2003-04-02 10:36:02 +00:00
2003-03-08 00:49:18 +00:00
return ret ;
}
2003-04-26 15:48:48 +00:00
static NTSTATUS db_set_mapping ( const DOM_SID * sid , unid_t id , int id_type )
2003-03-08 17:29:40 +00:00
{
2003-05-01 11:47:48 +00:00
TDB_DATA ksid , kid , data ;
2003-03-08 17:29:40 +00:00
fstring ksidstr ;
fstring kidstr ;
2003-06-25 00:02:17 +00:00
DEBUG ( 10 , ( " db_set_mapping \n " ) ) ;
if ( ! sid )
return NT_STATUS_INVALID_PARAMETER ;
2003-03-08 17:29:40 +00:00
sid_to_string ( ksidstr , sid ) ;
ksid . dptr = ksidstr ;
ksid . dsize = strlen ( ksidstr ) + 1 ;
if ( id_type & ID_USERID ) {
slprintf ( kidstr , sizeof ( kidstr ) , " UID %d " , id . uid ) ;
} else if ( id_type & ID_GROUPID ) {
slprintf ( kidstr , sizeof ( kidstr ) , " GID %d " , id . gid ) ;
} else {
return NT_STATUS_INVALID_PARAMETER ;
}
kid . dptr = kidstr ;
kid . dsize = strlen ( kidstr ) + 1 ;
2003-05-01 11:47:48 +00:00
/* *DELETE* prevoius mappings if any.
* This is done both SID and [ U | G ] ID passed in */
data = tdb_fetch ( idmap_tdb , ksid ) ;
if ( data . dptr ) {
2003-06-25 00:02:17 +00:00
DEBUG ( 10 , ( " db_set_mapping: deleting %s and %s \n " , data . dptr , ksid . dptr ) ) ;
2003-05-01 11:47:48 +00:00
tdb_delete ( idmap_tdb , data ) ;
tdb_delete ( idmap_tdb , ksid ) ;
2003-06-17 10:16:20 +00:00
SAFE_FREE ( data . dptr ) ;
2003-05-01 11:47:48 +00:00
}
data = tdb_fetch ( idmap_tdb , kid ) ;
if ( data . dptr ) {
2003-06-25 00:02:17 +00:00
DEBUG ( 10 , ( " db_set_mapping: deleting %s and %s \n " , data . dptr , kid . dptr ) ) ;
2003-05-01 11:47:48 +00:00
tdb_delete ( idmap_tdb , data ) ;
tdb_delete ( idmap_tdb , kid ) ;
2003-06-17 10:16:20 +00:00
SAFE_FREE ( data . dptr ) ;
2003-05-01 11:47:48 +00:00
}
2003-03-08 17:29:40 +00:00
if ( tdb_store ( idmap_tdb , ksid , kid , TDB_INSERT ) = = - 1 ) {
2003-04-17 14:25:52 +00:00
DEBUG ( 0 , ( " idb_set_mapping: tdb_store 1 error: %s \n " , tdb_errorstr ( idmap_tdb ) ) ) ;
2003-03-08 17:29:40 +00:00
return NT_STATUS_UNSUCCESSFUL ;
}
if ( tdb_store ( idmap_tdb , kid , ksid , TDB_INSERT ) = = - 1 ) {
2003-04-17 14:25:52 +00:00
DEBUG ( 0 , ( " idb_set_mapping: tdb_store 2 error: %s \n " , tdb_errorstr ( idmap_tdb ) ) ) ;
2003-03-08 17:29:40 +00:00
return NT_STATUS_UNSUCCESSFUL ;
}
2003-06-25 00:02:17 +00:00
DEBUG ( 10 , ( " db_set_mapping: stored %s -> %s and %s -> %s \n " , ksid . dptr , kid . dptr , kid . dptr , ksid . dptr ) ) ;
2003-06-21 08:31:18 +00:00
return NT_STATUS_OK ;
2003-03-08 17:29:40 +00:00
}
2003-03-08 00:49:18 +00:00
/*****************************************************************************
Initialise idmap database .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-06-25 00:02:17 +00:00
2003-06-06 13:48:39 +00:00
static NTSTATUS db_idmap_init ( char * params )
2003-03-08 00:49:18 +00:00
{
2003-04-06 09:35:16 +00:00
SMB_STRUCT_STAT stbuf ;
2003-04-29 22:06:16 +00:00
char * tdbfile = NULL ;
2003-04-26 15:48:48 +00:00
int32 version ;
2003-04-29 22:06:16 +00:00
BOOL tdb_is_new = False ;
2003-04-06 09:35:16 +00:00
2003-04-26 15:48:48 +00:00
/* use the old database if present */
2003-04-06 09:35:16 +00:00
if ( ! file_exist ( lock_path ( " idmap.tdb " ) , & stbuf ) ) {
if ( file_exist ( lock_path ( " winbindd_idmap.tdb " ) , & stbuf ) ) {
2003-04-26 15:48:48 +00:00
DEBUG ( 0 , ( " idmap_init: using winbindd_idmap.tdb file! \n " ) ) ;
tdbfile = strdup ( lock_path ( " winbindd_idmap.tdb " ) ) ;
if ( ! tdbfile ) {
DEBUG ( 0 , ( " idmap_init: out of memory! \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
2003-04-29 22:06:16 +00:00
} else {
tdb_is_new = True ;
2003-04-26 15:48:48 +00:00
}
2003-04-29 22:06:16 +00:00
}
if ( ! tdbfile ) {
2003-04-26 15:48:48 +00:00
tdbfile = strdup ( lock_path ( " idmap.tdb " ) ) ;
if ( ! tdbfile ) {
DEBUG ( 0 , ( " idmap_init: out of memory! \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
2003-04-06 09:35:16 +00:00
}
}
2003-06-25 00:02:17 +00:00
DEBUG ( 10 , ( " db_idmap_init: Opening tdbfile \n " , tdbfile ) ) ;
2003-03-08 00:49:18 +00:00
/* Open tdb cache */
2003-04-26 15:48:48 +00:00
if ( ! ( idmap_tdb = tdb_open_log ( tdbfile , 0 ,
2003-03-08 00:49:18 +00:00
TDB_DEFAULT , O_RDWR | O_CREAT ,
2003-06-18 13:28:37 +00:00
0644 ) ) ) {
2003-03-08 00:49:18 +00:00
DEBUG ( 0 , ( " idmap_init: Unable to open idmap database \n " ) ) ;
2003-04-26 15:48:48 +00:00
SAFE_FREE ( tdbfile ) ;
2003-03-08 00:49:18 +00:00
return NT_STATUS_UNSUCCESSFUL ;
}
2003-04-26 15:48:48 +00:00
SAFE_FREE ( tdbfile ) ;
/* check against earlier versions */
2003-04-29 22:06:16 +00:00
if ( tdb_is_new ) {
/* TODO: delete the file if this fail */
tdb_store_int32 ( idmap_tdb , " IDMAP_VERSION " , IDMAP_VERSION ) ;
} else {
version = tdb_fetch_int32 ( idmap_tdb , " IDMAP_VERSION " ) ;
if ( version ! = IDMAP_VERSION ) {
DEBUG ( 0 , ( " idmap_init: Unable to open idmap database, it's in an old format! \n " ) ) ;
return NT_STATUS_INTERNAL_DB_ERROR ;
}
2003-04-26 15:48:48 +00:00
}
2003-03-08 00:49:18 +00:00
/* Create high water marks for group and user id */
2003-04-19 15:29:39 +00:00
if ( ! lp_idmap_uid ( & idmap_state . uid_low , & idmap_state . uid_high ) ) {
2003-05-14 03:32:20 +00:00
DEBUG ( 1 , ( " idmap uid range missing or invalid \n " ) ) ;
DEBUGADD ( 1 , ( " idmap will be unable to map foreign SIDs \n " ) ) ;
2003-04-30 16:35:17 +00:00
} else {
if ( tdb_fetch_int32 ( idmap_tdb , HWM_USER ) = = - 1 ) {
if ( tdb_store_int32 ( idmap_tdb , HWM_USER , idmap_state . uid_low ) = = - 1 ) {
DEBUG ( 0 , ( " idmap_init: Unable to initialise user hwm in idmap database \n " ) ) ;
return NT_STATUS_INTERNAL_DB_ERROR ;
}
}
2003-04-19 15:29:39 +00:00
}
2003-04-30 16:35:17 +00:00
2003-04-19 15:29:39 +00:00
if ( ! lp_idmap_gid ( & idmap_state . gid_low , & idmap_state . gid_high ) ) {
2003-05-14 03:32:20 +00:00
DEBUG ( 1 , ( " idmap gid range missing or invalid \n " ) ) ;
DEBUGADD ( 1 , ( " idmap will be unable to map foreign SIDs \n " ) ) ;
2003-04-30 16:35:17 +00:00
} else {
if ( tdb_fetch_int32 ( idmap_tdb , HWM_GROUP ) = = - 1 ) {
if ( tdb_store_int32 ( idmap_tdb , HWM_GROUP , idmap_state . gid_low ) = = - 1 ) {
DEBUG ( 0 , ( " idmap_init: Unable to initialise group hwm in idmap database \n " ) ) ;
return NT_STATUS_INTERNAL_DB_ERROR ;
}
}
2003-04-19 15:29:39 +00:00
}
2003-04-30 16:35:17 +00:00
2003-03-08 00:49:18 +00:00
return NT_STATUS_OK ;
}
/* Close the tdb */
2003-04-02 10:36:02 +00:00
static NTSTATUS db_idmap_close ( void )
2003-03-08 00:49:18 +00:00
{
2003-03-08 17:29:40 +00:00
if ( idmap_tdb ) {
if ( tdb_close ( idmap_tdb ) = = 0 ) {
2003-03-08 00:49:18 +00:00
return NT_STATUS_OK ;
2003-03-08 17:29:40 +00:00
} else {
return NT_STATUS_UNSUCCESSFUL ;
}
}
2003-03-08 00:49:18 +00:00
return NT_STATUS_OK ;
}
/* Dump status information to log file. Display different stuff based on
the debug level :
Debug Level Information Displayed
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
0 Percentage of [ ug ] id range allocated
0 High water marks ( next allocated ids )
*/
# define DUMP_INFO 0
2003-04-02 10:36:02 +00:00
static void db_idmap_status ( void )
2003-03-08 00:49:18 +00:00
{
int user_hwm , group_hwm ;
DEBUG ( 0 , ( " winbindd idmap status: \n " ) ) ;
/* Get current high water marks */
if ( ( user_hwm = tdb_fetch_int32 ( idmap_tdb , HWM_USER ) ) = = - 1 ) {
DEBUG ( DUMP_INFO ,
( " \t Could not get userid high water mark! \n " ) ) ;
}
if ( ( group_hwm = tdb_fetch_int32 ( idmap_tdb , HWM_GROUP ) ) = = - 1 ) {
DEBUG ( DUMP_INFO ,
( " \t Could not get groupid high water mark! \n " ) ) ;
}
/* Display next ids to allocate */
if ( user_hwm ! = - 1 ) {
DEBUG ( DUMP_INFO ,
( " \t Next userid to allocate is %d \n " , user_hwm ) ) ;
}
if ( group_hwm ! = - 1 ) {
DEBUG ( DUMP_INFO ,
( " \t Next groupid to allocate is %d \n " , group_hwm ) ) ;
}
/* Display percentage of id range already allocated. */
if ( user_hwm ! = - 1 ) {
2003-03-08 17:29:40 +00:00
int num_users = user_hwm - idmap_state . uid_low ;
2003-03-08 00:49:18 +00:00
int total_users =
2003-03-08 17:29:40 +00:00
idmap_state . uid_high - idmap_state . uid_low ;
2003-03-08 00:49:18 +00:00
DEBUG ( DUMP_INFO ,
( " \t User id range is %d%% full (%d of %d) \n " ,
num_users * 100 / total_users , num_users ,
total_users ) ) ;
}
if ( group_hwm ! = - 1 ) {
2003-03-08 17:29:40 +00:00
int num_groups = group_hwm - idmap_state . gid_low ;
2003-03-08 00:49:18 +00:00
int total_groups =
2003-03-08 17:29:40 +00:00
idmap_state . gid_high - idmap_state . gid_low ;
2003-03-08 00:49:18 +00:00
DEBUG ( DUMP_INFO ,
( " \t Group id range is %d%% full (%d of %d) \n " ,
num_groups * 100 / total_groups , num_groups ,
total_groups ) ) ;
}
/* Display complete mapping of users and groups to rids */
}
2003-05-29 19:08:40 +00:00
static struct idmap_methods db_methods = {
2003-03-08 00:49:18 +00:00
2003-04-02 10:36:02 +00:00
db_idmap_init ,
db_get_sid_from_id ,
db_get_id_from_sid ,
db_set_mapping ,
db_idmap_close ,
db_idmap_status
2003-03-08 00:49:18 +00:00
} ;
2003-05-29 21:30:48 +00:00
NTSTATUS idmap_tdb_init ( void )
2003-03-08 00:49:18 +00:00
{
2003-05-29 19:08:40 +00:00
return smb_register_idmap ( SMB_IDMAP_INTERFACE_VERSION , " tdb " , & db_methods ) ;
2003-03-08 00:49:18 +00:00
}