2006-09-24 06:52:25 +04:00
/*
* Unix SMB / CIFS implementation .
* RPC Pipe client / server routines
* Copyright ( C ) Andrew Tridgell 1992 - 2006 ,
2018-05-07 15:04:17 +03:00
* Copyright ( C ) Jean François Micouleau 1998 - 2001.
2006-09-24 06:52:25 +04:00
* Copyright ( C ) Volker Lendecke 2006.
* Copyright ( C ) Gerald Carter 2006.
*
* 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-09-24 06:52:25 +04: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 09:23:25 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2006-09-24 06:52:25 +04:00
*/
# include "includes.h"
2011-02-26 01:20:06 +03:00
# include "system/filesys.h"
2011-03-18 20:58:37 +03:00
# include "passdb.h"
2006-09-24 06:52:25 +04:00
# include "groupdb/mapping.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"
2011-05-05 13:25:29 +04:00
# include "util_tdb.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2011-10-12 13:17:57 +04:00
# include "groupdb/mapping_tdb.h"
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
static struct db_context * db ; /* used for driver files */
2006-09-24 06:52:25 +04:00
2010-05-21 05:25:01 +04:00
static bool enum_group_mapping ( const struct dom_sid * domsid ,
2010-02-26 23:16:23 +03:00
enum lsa_SidType sid_name_use ,
2011-09-27 01:55:47 +04:00
GROUP_MAP * * * pp_rmap ,
2010-02-26 23:16:23 +03:00
size_t * p_num_entries ,
bool unix_only ) ;
2010-05-21 05:25:01 +04:00
static bool group_map_remove ( const struct dom_sid * sid ) ;
2010-02-26 23:16:23 +03:00
static bool mapping_switch ( const char * ldb_path ) ;
2006-09-24 06:52:25 +04:00
/****************************************************************************
Open the group mapping tdb .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
static bool init_group_mapping ( void )
2006-09-24 06:52:25 +04:00
{
2014-11-02 22:21:23 +03:00
char * tdb_path ;
char * ldb_path ;
2010-02-26 23:16:23 +03:00
2008-03-11 16:15:52 +03:00
if ( db ! = NULL ) {
return true ;
2006-09-24 06:52:25 +04:00
}
2018-08-16 11:51:44 +03:00
tdb_path = state_path ( talloc_tos ( ) , " group_mapping.tdb " ) ;
2014-11-02 22:21:23 +03:00
if ( tdb_path = = NULL ) {
return false ;
}
db = db_open ( NULL , tdb_path , 0 ,
2012-01-06 20:19:54 +04:00
TDB_DEFAULT , O_RDWR | O_CREAT , 0600 ,
2014-01-27 17:49:12 +04:00
DBWRAP_LOCK_ORDER_1 , DBWRAP_FLAG_NONE ) ;
2008-03-11 16:15:52 +03:00
if ( db = = NULL ) {
DEBUG ( 0 , ( " Failed to open group mapping database: %s \n " ,
strerror ( errno ) ) ) ;
2014-11-02 22:21:23 +03:00
talloc_free ( tdb_path ) ;
2008-03-11 16:15:52 +03:00
return false ;
2006-09-24 06:52:25 +04:00
}
2018-08-16 11:51:44 +03:00
ldb_path = state_path ( talloc_tos ( ) , " group_mapping.ldb " ) ;
2014-11-02 22:21:23 +03:00
if ( ldb_path = = NULL ) {
2014-11-03 16:33:06 +03:00
talloc_free ( tdb_path ) ;
2014-11-02 22:21:23 +03:00
return false ;
}
2010-02-26 23:16:23 +03:00
if ( file_exist ( ldb_path ) & & ! mapping_switch ( ldb_path ) ) {
2014-11-02 22:21:23 +03:00
unlink ( tdb_path ) ;
talloc_free ( tdb_path ) ;
talloc_free ( ldb_path ) ;
2010-02-26 23:16:23 +03:00
return false ;
} else {
/* handle upgrade from old versions of the database */
#if 0 /* -- Needs conversion to dbwrap -- */
2008-03-11 16:15:52 +03:00
const char * vstring = " INFO/version " ;
int32 vers_id ;
GROUP_MAP * map_table = NULL ;
size_t num_entries = 0 ;
/* handle a Samba upgrade */
tdb_lock_bystring ( tdb , vstring ) ;
/* Cope with byte-reversed older versions of the db. */
vers_id = tdb_fetch_int32 ( tdb , vstring ) ;
if ( ( vers_id = = DATABASE_VERSION_V1 )
| | ( IREV ( vers_id ) = = DATABASE_VERSION_V1 ) ) {
/*
* Written on a bigendian machine with old fetch_int
* code . Save as le .
*/
tdb_store_int32 ( tdb , vstring , DATABASE_VERSION_V2 ) ;
vers_id = DATABASE_VERSION_V2 ;
}
2006-09-24 06:52:25 +04:00
2015-03-29 19:17:46 +03:00
/* if its an unknown version we remove everything in the db */
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
if ( vers_id ! = DATABASE_VERSION_V2 ) {
2008-03-26 13:13:47 +03:00
tdb_wipe_all ( tdb ) ;
2008-03-11 16:15:52 +03:00
tdb_store_int32 ( tdb , vstring , DATABASE_VERSION_V2 ) ;
}
tdb_unlock_bystring ( tdb , vstring ) ;
/* cleanup any map entries with a gid == -1 */
if ( enum_group_mapping ( NULL , SID_NAME_UNKNOWN , & map_table ,
& num_entries , False ) ) {
int i ;
for ( i = 0 ; i < num_entries ; i + + ) {
if ( map_table [ i ] . gid = = - 1 ) {
group_map_remove ( & map_table [ i ] . sid ) ;
}
2006-09-24 06:52:25 +04:00
}
2008-03-11 16:15:52 +03:00
SAFE_FREE ( map_table ) ;
2006-09-24 06:52:25 +04:00
}
2008-03-11 16:15:52 +03:00
# endif
2010-02-26 23:16:23 +03:00
}
2014-11-02 22:21:23 +03:00
talloc_free ( tdb_path ) ;
talloc_free ( ldb_path ) ;
2008-03-11 16:15:52 +03:00
return true ;
}
2010-05-21 05:25:01 +04:00
static char * group_mapping_key ( TALLOC_CTX * mem_ctx , const struct dom_sid * sid )
2008-03-11 16:15:52 +03:00
{
2018-10-26 09:25:14 +03:00
struct dom_sid_buf sidstr ;
2006-09-24 06:52:25 +04:00
2018-10-26 09:25:14 +03:00
return talloc_asprintf (
mem_ctx , " %s%s " , GROUP_PREFIX , dom_sid_str_buf ( sid , & sidstr ) ) ;
2006-09-24 06:52:25 +04:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
static bool add_mapping_entry ( GROUP_MAP * map , int flag )
2006-09-24 06:52:25 +04:00
{
2008-03-11 16:15:52 +03:00
char * key , * buf ;
2006-09-24 06:52:25 +04:00
int len ;
2008-03-28 13:53:00 +03:00
NTSTATUS status ;
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
key = group_mapping_key ( talloc_tos ( ) , & map - > sid ) ;
if ( key = = NULL ) {
2008-07-03 13:09:32 +04:00
return false ;
2008-03-11 14:53:50 +03:00
}
2006-09-24 06:52:25 +04:00
2008-03-28 12:34:37 +03:00
len = tdb_pack ( NULL , 0 , " ddff " ,
2007-11-14 02:00:48 +03:00
map - > gid , map - > sid_name_use , map - > nt_name , map - > comment ) ;
2006-09-24 06:52:25 +04:00
2011-06-07 05:30:12 +04:00
buf = talloc_array ( key , char , len ) ;
2008-03-11 16:15:52 +03:00
if ( ! buf ) {
TALLOC_FREE ( key ) ;
2007-11-14 02:00:48 +03:00
return false ;
}
2015-05-14 03:03:05 +03:00
len = tdb_pack ( ( uint8_t * ) buf , len , " ddff " , map - > gid ,
2008-03-11 16:15:52 +03:00
map - > sid_name_use , map - > nt_name , map - > comment ) ;
2006-09-24 06:52:25 +04:00
2008-03-28 13:53:00 +03:00
status = dbwrap_trans_store (
2008-03-27 19:10:31 +03:00
db , string_term_tdb_data ( key ) ,
2008-03-31 13:24:10 +04:00
make_tdb_data ( ( uint8_t * ) buf , len ) , TDB_REPLACE ) ;
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
TALLOC_FREE ( key ) ;
2007-11-14 02:00:48 +03:00
2008-03-28 13:53:00 +03:00
return NT_STATUS_IS_OK ( status ) ;
2006-09-24 06:52:25 +04:00
}
/****************************************************************************
Return the sid and the type of the unix group .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-05-21 05:25:01 +04:00
static bool get_group_map_from_sid ( struct dom_sid sid , GROUP_MAP * map )
2006-09-24 06:52:25 +04:00
{
2007-03-27 13:17:31 +04:00
TDB_DATA dbuf ;
2008-03-11 16:15:52 +03:00
char * key ;
2006-09-24 06:52:25 +04:00
int ret = 0 ;
2011-08-24 15:08:13 +04:00
NTSTATUS status ;
2011-09-27 01:55:47 +04:00
fstring nt_name ;
fstring comment ;
2007-11-14 02:00:48 +03:00
2006-09-24 06:52:25 +04:00
/* the key is the SID, retrieving is direct */
2008-03-28 14:20:06 +03:00
key = group_mapping_key ( talloc_tos ( ) , & sid ) ;
2008-03-11 16:15:52 +03:00
if ( key = = NULL ) {
2007-11-14 02:00:48 +03:00
return false ;
}
2006-09-24 06:52:25 +04:00
2011-08-24 15:08:13 +04:00
status = dbwrap_fetch_bystring ( db , key , key , & dbuf ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-03-11 16:15:52 +03:00
TALLOC_FREE ( key ) ;
2007-11-14 02:00:48 +03:00
return false ;
}
2006-09-24 06:52:25 +04:00
ret = tdb_unpack ( dbuf . dptr , dbuf . dsize , " ddff " ,
2007-11-14 02:00:48 +03:00
& map - > gid , & map - > sid_name_use ,
2011-09-27 01:55:47 +04:00
& nt_name , & comment ) ;
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
TALLOC_FREE ( key ) ;
2007-11-14 02:00:48 +03:00
2006-09-24 06:52:25 +04:00
if ( ret = = - 1 ) {
DEBUG ( 3 , ( " get_group_map_from_sid: tdb_unpack failure \n " ) ) ;
2008-03-11 16:15:52 +03:00
return false ;
2006-09-24 06:52:25 +04:00
}
sid_copy ( & map - > sid , & sid ) ;
2007-11-14 02:00:48 +03:00
2011-09-27 01:55:47 +04:00
map - > nt_name = talloc_strdup ( map , nt_name ) ;
if ( ! map - > nt_name ) {
return false ;
}
map - > comment = talloc_strdup ( map , comment ) ;
if ( ! map - > comment ) {
return false ;
}
2008-03-11 16:15:52 +03:00
return true ;
2006-09-24 06:52:25 +04:00
}
2008-03-11 16:15:52 +03:00
static bool dbrec2map ( const struct db_record * rec , GROUP_MAP * map )
2006-09-24 06:52:25 +04:00
{
2011-08-17 13:18:49 +04:00
TDB_DATA key = dbwrap_record_get_key ( rec ) ;
TDB_DATA value = dbwrap_record_get_value ( rec ) ;
2011-09-27 01:55:47 +04:00
int ret = 0 ;
fstring nt_name ;
fstring comment ;
2011-08-17 13:18:49 +04:00
if ( ( key . dsize < strlen ( GROUP_PREFIX ) )
| | ( strncmp ( ( char * ) key . dptr , GROUP_PREFIX ,
2008-03-11 16:15:52 +03:00
GROUP_PREFIX_LEN ) ! = 0 ) ) {
return False ;
}
2007-11-14 02:00:48 +03:00
2011-08-17 13:18:49 +04:00
if ( ! string_to_sid ( & map - > sid , ( const char * ) key . dptr
2008-03-11 16:15:52 +03:00
+ GROUP_PREFIX_LEN ) ) {
return False ;
}
2006-09-24 06:52:25 +04:00
2011-09-27 01:55:47 +04:00
ret = tdb_unpack ( value . dptr , value . dsize , " ddff " ,
& map - > gid , & map - > sid_name_use ,
& nt_name , & comment ) ;
if ( ret = = - 1 ) {
DEBUG ( 3 , ( " dbrec2map: tdb_unpack failure \n " ) ) ;
return false ;
}
map - > nt_name = talloc_strdup ( map , nt_name ) ;
if ( ! map - > nt_name ) {
return false ;
}
map - > comment = talloc_strdup ( map , comment ) ;
if ( ! map - > comment ) {
return false ;
}
return true ;
2008-03-11 16:15:52 +03:00
}
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
struct find_map_state {
bool found ;
const char * name ; /* If != NULL, look for name */
gid_t gid ; /* valid iff name == NULL */
GROUP_MAP * map ;
} ;
2007-11-14 02:00:48 +03:00
2008-03-11 16:15:52 +03:00
static int find_map ( struct db_record * rec , void * private_data )
{
struct find_map_state * state = ( struct find_map_state * ) private_data ;
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
if ( ! dbrec2map ( rec , state - > map ) ) {
DEBUG ( 10 , ( " failed to unpack map \n " ) ) ;
return 0 ;
}
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
if ( state - > name ! = NULL ) {
if ( strequal ( state - > name , state - > map - > nt_name ) ) {
state - > found = true ;
return 1 ;
2006-09-24 06:52:25 +04:00
}
2008-03-11 16:15:52 +03:00
}
else {
if ( state - > map - > gid = = state - > gid ) {
state - > found = true ;
return 1 ;
2006-09-24 06:52:25 +04:00
}
}
2008-03-11 16:15:52 +03:00
return 0 ;
2006-09-24 06:52:25 +04:00
}
/****************************************************************************
Return the sid and the type of the unix group .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-03-11 16:15:52 +03:00
static bool get_group_map_from_gid ( gid_t gid , GROUP_MAP * map )
2006-09-24 06:52:25 +04:00
{
2008-03-11 16:15:52 +03:00
struct find_map_state state ;
2007-11-14 02:00:48 +03:00
2008-03-11 16:15:52 +03:00
state . found = false ;
state . name = NULL ; /* Indicate we're looking for gid */
state . gid = gid ;
state . map = map ;
2006-09-24 06:52:25 +04:00
2011-08-17 13:18:49 +04:00
dbwrap_traverse_read ( db , find_map , ( void * ) & state , NULL ) ;
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
return state . found ;
}
2007-11-14 02:00:48 +03:00
2008-03-11 16:15:52 +03:00
/****************************************************************************
Return the sid and the type of the unix group .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
static bool get_group_map_from_ntname ( const char * name , GROUP_MAP * map )
{
struct find_map_state state ;
2007-11-14 02:00:48 +03:00
2008-03-11 16:15:52 +03:00
state . found = false ;
state . name = name ;
state . map = map ;
2006-09-24 06:52:25 +04:00
2011-08-17 13:18:49 +04:00
dbwrap_traverse_read ( db , find_map , ( void * ) & state , NULL ) ;
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
return state . found ;
2006-09-24 06:52:25 +04:00
}
/****************************************************************************
Remove a group mapping entry .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-05-21 05:25:01 +04:00
static bool group_map_remove ( const struct dom_sid * sid )
2006-09-24 06:52:25 +04:00
{
2008-03-11 16:15:52 +03:00
char * key ;
2008-03-28 13:57:54 +03:00
NTSTATUS status ;
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
key = group_mapping_key ( talloc_tos ( ) , sid ) ;
if ( key = = NULL ) {
2007-11-14 02:00:48 +03:00
return false ;
}
2006-09-24 06:52:25 +04:00
2008-03-28 13:57:54 +03:00
status = dbwrap_trans_delete ( db , string_term_tdb_data ( key ) ) ;
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
TALLOC_FREE ( key ) ;
2008-03-28 13:57:54 +03:00
return NT_STATUS_IS_OK ( status ) ;
2006-09-24 06:52:25 +04:00
}
/****************************************************************************
Enumerate the group mapping .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-03-11 16:15:52 +03:00
struct enum_map_state {
2010-05-21 05:25:01 +04:00
const struct dom_sid * domsid ;
2008-03-11 16:15:52 +03:00
enum lsa_SidType sid_name_use ;
bool unix_only ;
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
size_t num_maps ;
2011-09-27 01:55:47 +04:00
GROUP_MAP * * maps ;
2008-03-11 16:15:52 +03:00
} ;
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
static int collect_map ( struct db_record * rec , void * private_data )
{
struct enum_map_state * state = ( struct enum_map_state * ) private_data ;
2011-09-27 01:55:47 +04:00
GROUP_MAP * map ;
GROUP_MAP * * tmp ;
map = talloc_zero ( NULL , GROUP_MAP ) ;
if ( ! map ) {
DEBUG ( 0 , ( " Unable to allocate group map! \n " ) ) ;
return 1 ;
}
2006-09-24 06:52:25 +04:00
2011-09-27 01:55:47 +04:00
if ( ! dbrec2map ( rec , map ) ) {
TALLOC_FREE ( map ) ;
2008-03-11 16:15:52 +03:00
return 0 ;
}
/* list only the type or everything if UNKNOWN */
if ( state - > sid_name_use ! = SID_NAME_UNKNOWN
2011-09-27 01:55:47 +04:00
& & state - > sid_name_use ! = map - > sid_name_use ) {
2008-03-11 16:15:52 +03:00
DEBUG ( 11 , ( " enum_group_mapping: group %s is not of the "
2011-09-27 01:55:47 +04:00
" requested type \n " , map - > nt_name ) ) ;
TALLOC_FREE ( map ) ;
2008-03-11 16:15:52 +03:00
return 0 ;
}
2006-09-24 06:52:25 +04:00
2011-09-27 01:55:47 +04:00
if ( ( state - > unix_only = = ENUM_ONLY_MAPPED ) & & ( map - > gid = = - 1 ) ) {
2008-03-11 16:15:52 +03:00
DEBUG ( 11 , ( " enum_group_mapping: group %s is non mapped \n " ,
2011-09-27 01:55:47 +04:00
map - > nt_name ) ) ;
TALLOC_FREE ( map ) ;
2008-03-11 16:15:52 +03:00
return 0 ;
}
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
if ( ( state - > domsid ! = NULL ) & &
2011-09-27 01:55:47 +04:00
( dom_sid_compare_domain ( state - > domsid , & map - > sid ) ! = 0 ) ) {
2018-12-11 15:56:03 +03:00
struct dom_sid_buf buf ;
2008-03-11 16:15:52 +03:00
DEBUG ( 11 , ( " enum_group_mapping: group %s is not in domain \n " ,
2018-12-11 15:56:03 +03:00
dom_sid_str_buf ( & map - > sid , & buf ) ) ) ;
2011-09-27 01:55:47 +04:00
TALLOC_FREE ( map ) ;
2008-03-11 16:15:52 +03:00
return 0 ;
}
2006-09-24 06:52:25 +04:00
2011-09-27 01:55:47 +04:00
tmp = talloc_realloc ( NULL , state - > maps , GROUP_MAP * ,
state - > num_maps + 1 ) ;
if ( ! tmp ) {
2008-03-11 16:15:52 +03:00
DEBUG ( 0 , ( " enum_group_mapping: Unable to enlarge group "
" map! \n " ) ) ;
2011-09-27 01:55:47 +04:00
TALLOC_FREE ( map ) ;
2008-03-11 16:15:52 +03:00
return 1 ;
}
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
state - > maps = tmp ;
2011-09-27 01:55:47 +04:00
state - > maps [ state - > num_maps ] = talloc_move ( state - > maps , & map ) ;
2008-03-11 16:15:52 +03:00
state - > num_maps + + ;
return 0 ;
}
2006-09-24 06:52:25 +04:00
2010-05-21 05:25:01 +04:00
static bool enum_group_mapping ( const struct dom_sid * domsid ,
2008-03-11 16:15:52 +03:00
enum lsa_SidType sid_name_use ,
2011-09-27 01:55:47 +04:00
GROUP_MAP * * * pp_rmap ,
2008-03-11 16:15:52 +03:00
size_t * p_num_entries , bool unix_only )
{
struct enum_map_state state ;
2011-08-17 13:18:49 +04:00
NTSTATUS status ;
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
state . domsid = domsid ;
state . sid_name_use = sid_name_use ;
state . unix_only = unix_only ;
state . num_maps = 0 ;
state . maps = NULL ;
2006-09-24 06:52:25 +04:00
2011-08-17 13:18:49 +04:00
status = dbwrap_traverse_read ( db , collect_map , ( void * ) & state , NULL ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-09-27 01:55:47 +04:00
TALLOC_FREE ( state . maps ) ;
2008-03-11 16:15:52 +03:00
return false ;
2006-09-24 06:52:25 +04:00
}
2008-03-11 16:15:52 +03:00
* pp_rmap = state . maps ;
* p_num_entries = state . num_maps ;
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
return true ;
2006-09-24 06:52:25 +04:00
}
/* This operation happens on session setup, so it should better be fast. We
* store a list of aliases a SID is member of hanging off MEMBEROF / SID . */
2010-05-21 05:25:01 +04:00
static NTSTATUS one_alias_membership ( const struct dom_sid * member ,
struct dom_sid * * sids , size_t * num )
2006-09-24 06:52:25 +04:00
{
2018-11-02 22:58:59 +03:00
struct dom_sid_buf tmp ;
2007-12-08 04:32:32 +03:00
fstring key ;
char * string_sid ;
2007-03-27 13:17:31 +04:00
TDB_DATA dbuf ;
2006-09-24 06:52:25 +04:00
const char * p ;
2008-01-16 02:09:13 +03:00
NTSTATUS status = NT_STATUS_OK ;
2008-03-11 16:15:52 +03:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2006-09-24 06:52:25 +04:00
2007-12-15 13:38:28 +03:00
slprintf ( key , sizeof ( key ) , " %s%s " , MEMBEROF_PREFIX ,
2018-11-02 22:58:59 +03:00
dom_sid_str_buf ( member , & tmp ) ) ;
2006-09-24 06:52:25 +04:00
2011-08-24 15:08:13 +04:00
status = dbwrap_fetch_bystring ( db , frame , key , & dbuf ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-03-11 16:15:52 +03:00
TALLOC_FREE ( frame ) ;
2006-09-24 06:52:25 +04:00
return NT_STATUS_OK ;
}
2007-03-29 13:35:51 +04:00
p = ( const char * ) dbuf . dptr ;
2008-03-11 16:15:52 +03:00
2007-12-08 04:32:32 +03:00
while ( next_token_talloc ( frame , & p , & string_sid , " " ) ) {
2010-05-21 05:25:01 +04:00
struct dom_sid alias ;
2010-08-26 14:54:13 +04:00
uint32_t num_sids ;
2006-09-24 06:52:25 +04:00
if ( ! string_to_sid ( & alias , string_sid ) )
continue ;
2010-08-26 14:54:13 +04:00
num_sids = * num ;
status = add_sid_to_array_unique ( NULL , & alias , sids , & num_sids ) ;
2008-01-09 02:11:31 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-01-08 23:51:07 +03:00
goto done ;
2006-12-09 05:58:18 +03:00
}
2010-08-26 14:54:13 +04:00
* num = num_sids ;
2006-09-24 06:52:25 +04:00
}
2008-01-08 23:51:07 +03:00
done :
2007-12-08 04:32:32 +03:00
TALLOC_FREE ( frame ) ;
2008-01-08 23:51:07 +03:00
return status ;
2006-09-24 06:52:25 +04:00
}
2010-05-21 05:25:01 +04:00
static NTSTATUS alias_memberships ( const struct dom_sid * members , size_t num_members ,
struct dom_sid * * sids , size_t * num )
2006-09-24 06:52:25 +04:00
{
size_t i ;
* num = 0 ;
* sids = NULL ;
for ( i = 0 ; i < num_members ; i + + ) {
NTSTATUS status = one_alias_membership ( & members [ i ] , sids , num ) ;
if ( ! NT_STATUS_IS_OK ( status ) )
return status ;
}
return NT_STATUS_OK ;
}
2010-05-21 05:25:01 +04:00
static bool is_aliasmem ( const struct dom_sid * alias , const struct dom_sid * member )
2006-09-24 06:52:25 +04:00
{
2010-05-21 05:25:01 +04:00
struct dom_sid * sids ;
2010-08-26 14:54:13 +04:00
size_t i ;
size_t num ;
2006-09-24 06:52:25 +04:00
/* This feels the wrong way round, but the on-disk data structure
* dictates it this way . */
if ( ! NT_STATUS_IS_OK ( alias_memberships ( member , 1 , & sids , & num ) ) )
return False ;
for ( i = 0 ; i < num ; i + + ) {
2010-08-26 17:48:50 +04:00
if ( dom_sid_compare ( alias , & sids [ i ] ) = = 0 ) {
2007-04-25 13:32:03 +04:00
TALLOC_FREE ( sids ) ;
2006-09-24 06:52:25 +04:00
return True ;
}
}
2007-04-25 13:32:03 +04:00
TALLOC_FREE ( sids ) ;
2006-09-24 06:52:25 +04:00
return False ;
}
2010-05-21 05:25:01 +04:00
static NTSTATUS add_aliasmem ( const struct dom_sid * alias , const struct dom_sid * member )
2006-09-24 06:52:25 +04:00
{
2011-09-27 01:55:47 +04:00
GROUP_MAP * map ;
2008-03-11 16:15:52 +03:00
char * key ;
2018-11-02 22:58:59 +03:00
struct dom_sid_buf string_sid ;
2006-09-24 06:52:25 +04:00
char * new_memberstring ;
2008-03-11 16:15:52 +03:00
struct db_record * rec ;
NTSTATUS status ;
2011-08-17 13:18:49 +04:00
TDB_DATA value ;
2006-09-24 06:52:25 +04:00
2011-09-27 01:55:47 +04:00
map = talloc_zero ( talloc_tos ( ) , GROUP_MAP ) ;
if ( ! map ) {
return NT_STATUS_NO_MEMORY ;
}
if ( ! get_group_map_from_sid ( * alias , map ) ) {
TALLOC_FREE ( map ) ;
2006-09-24 06:52:25 +04:00
return NT_STATUS_NO_SUCH_ALIAS ;
2011-09-27 01:55:47 +04:00
}
2006-09-24 06:52:25 +04:00
2011-09-27 01:55:47 +04:00
if ( ( map - > sid_name_use ! = SID_NAME_ALIAS ) & &
( map - > sid_name_use ! = SID_NAME_WKN_GRP ) ) {
TALLOC_FREE ( map ) ;
2006-09-24 06:52:25 +04:00
return NT_STATUS_NO_SUCH_ALIAS ;
2011-09-27 01:55:47 +04:00
}
TALLOC_FREE ( map ) ;
2006-09-24 06:52:25 +04:00
if ( is_aliasmem ( alias , member ) )
return NT_STATUS_MEMBER_IN_ALIAS ;
2008-03-11 16:15:52 +03:00
key = talloc_asprintf ( talloc_tos ( ) , " %s%s " , MEMBEROF_PREFIX ,
2018-11-02 22:58:59 +03:00
dom_sid_str_buf ( member , & string_sid ) ) ;
2008-03-11 16:15:52 +03:00
if ( key = = NULL ) {
2007-11-14 02:00:48 +03:00
return NT_STATUS_NO_MEMORY ;
}
2006-09-24 06:52:25 +04:00
2011-08-17 13:18:49 +04:00
if ( dbwrap_transaction_start ( db ) ! = 0 ) {
2008-03-27 19:10:31 +03:00
DEBUG ( 0 , ( " transaction_start failed \n " ) ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2011-08-17 13:18:49 +04:00
rec = dbwrap_fetch_locked ( db , key , string_term_tdb_data ( key ) ) ;
2008-03-11 16:15:52 +03:00
if ( rec = = NULL ) {
DEBUG ( 10 , ( " fetch_lock failed \n " ) ) ;
TALLOC_FREE ( key ) ;
2008-03-27 19:10:31 +03:00
status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
goto cancel ;
2008-03-11 16:15:52 +03:00
}
2006-09-24 06:52:25 +04:00
2011-08-17 13:18:49 +04:00
value = dbwrap_record_get_value ( rec ) ;
2018-11-02 22:58:59 +03:00
dom_sid_str_buf ( alias , & string_sid ) ;
2006-09-24 06:52:25 +04:00
2011-08-17 13:18:49 +04:00
if ( value . dptr ! = NULL ) {
2008-03-11 16:15:52 +03:00
new_memberstring = talloc_asprintf (
2018-11-02 22:58:59 +03:00
key , " %s %s " , ( char * ) ( value . dptr ) , string_sid . buf ) ;
2006-09-24 06:52:25 +04:00
} else {
2018-11-02 22:58:59 +03:00
new_memberstring = talloc_strdup ( key , string_sid . buf ) ;
2006-09-24 06:52:25 +04:00
}
2007-11-14 02:00:48 +03:00
if ( new_memberstring = = NULL ) {
2008-03-11 16:15:52 +03:00
TALLOC_FREE ( key ) ;
2008-03-27 19:10:31 +03:00
status = NT_STATUS_NO_MEMORY ;
goto cancel ;
2007-11-14 02:00:48 +03:00
}
2006-09-24 06:52:25 +04:00
2011-08-17 13:18:49 +04:00
status = dbwrap_record_store ( rec , string_term_tdb_data ( new_memberstring ) , 0 ) ;
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
TALLOC_FREE ( key ) ;
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 10 , ( " Could not store record: %s \n " , nt_errstr ( status ) ) ) ;
2008-03-27 19:10:31 +03:00
goto cancel ;
}
2011-08-17 13:18:49 +04:00
if ( dbwrap_transaction_commit ( db ) ! = 0 ) {
2008-03-27 19:10:31 +03:00
DEBUG ( 0 , ( " transaction_commit failed \n " ) ) ;
status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
2008-08-08 05:42:06 +04:00
return status ;
2008-03-27 19:10:31 +03:00
}
return NT_STATUS_OK ;
cancel :
2011-08-17 13:18:49 +04:00
if ( dbwrap_transaction_cancel ( db ) ! = 0 ) {
2008-03-27 19:10:31 +03:00
smb_panic ( " transaction_cancel failed " ) ;
2008-03-11 16:15:52 +03:00
}
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
return status ;
2006-09-24 06:52:25 +04:00
}
2008-03-11 16:15:52 +03:00
struct aliasmem_state {
2009-06-08 21:43:01 +04:00
TALLOC_CTX * mem_ctx ;
2010-05-21 05:25:01 +04:00
const struct dom_sid * alias ;
struct dom_sid * * sids ;
2006-09-24 06:52:25 +04:00
size_t * num ;
} ;
2008-03-11 16:15:52 +03:00
static int collect_aliasmem ( struct db_record * rec , void * priv )
2006-09-24 06:52:25 +04:00
{
2008-03-11 16:15:52 +03:00
struct aliasmem_state * state = ( struct aliasmem_state * ) priv ;
2006-09-24 06:52:25 +04:00
const char * p ;
2007-12-08 04:32:32 +03:00
char * alias_string ;
TALLOC_CTX * frame ;
2011-08-17 13:18:49 +04:00
TDB_DATA key = dbwrap_record_get_key ( rec ) ;
TDB_DATA value = dbwrap_record_get_value ( rec ) ;
2006-09-24 06:52:25 +04:00
2011-08-17 13:18:49 +04:00
if ( strncmp ( ( const char * ) key . dptr , MEMBEROF_PREFIX ,
2008-03-11 16:15:52 +03:00
MEMBEROF_PREFIX_LEN ) ! = 0 )
2006-09-24 06:52:25 +04:00
return 0 ;
2011-08-17 13:18:49 +04:00
p = ( const char * ) value . dptr ;
2006-09-24 06:52:25 +04:00
2007-12-08 04:32:32 +03:00
frame = talloc_stackframe ( ) ;
2008-03-11 16:15:52 +03:00
2007-12-08 04:32:32 +03:00
while ( next_token_talloc ( frame , & p , & alias_string , " " ) ) {
2010-05-21 05:25:01 +04:00
struct dom_sid alias , member ;
2006-09-24 06:52:25 +04:00
const char * member_string ;
2010-08-26 14:54:13 +04:00
uint32_t num_sids ;
2006-09-24 06:52:25 +04:00
if ( ! string_to_sid ( & alias , alias_string ) )
continue ;
2010-08-26 17:48:50 +04:00
if ( dom_sid_compare ( state - > alias , & alias ) ! = 0 )
2006-09-24 06:52:25 +04:00
continue ;
/* Ok, we found the alias we're looking for in the membership
* list currently scanned . The key represents the alias
* member . Add that . */
2011-08-17 13:18:49 +04:00
member_string = strchr ( ( const char * ) key . dptr , ' / ' ) ;
2006-09-24 06:52:25 +04:00
/* Above we tested for MEMBEROF_PREFIX which includes the
* slash . */
SMB_ASSERT ( member_string ! = NULL ) ;
member_string + = 1 ;
if ( ! string_to_sid ( & member , member_string ) )
continue ;
2007-12-08 04:32:32 +03:00
2010-08-26 14:54:13 +04:00
num_sids = * state - > num ;
2009-06-08 21:43:01 +04:00
if ( ! NT_STATUS_IS_OK ( add_sid_to_array ( state - > mem_ctx , & member ,
2008-03-11 16:15:52 +03:00
state - > sids ,
2010-08-26 14:54:13 +04:00
& num_sids ) ) )
2008-01-09 02:11:31 +03:00
{
2006-12-09 05:58:18 +03:00
/* talloc fail. */
break ;
}
2010-08-26 14:54:13 +04:00
* state - > num = num_sids ;
2006-09-24 06:52:25 +04:00
}
2007-12-08 04:32:32 +03:00
TALLOC_FREE ( frame ) ;
2006-09-24 06:52:25 +04:00
return 0 ;
}
2010-05-21 05:25:01 +04:00
static NTSTATUS enum_aliasmem ( const struct dom_sid * alias , TALLOC_CTX * mem_ctx ,
struct dom_sid * * sids , size_t * num )
2006-09-24 06:52:25 +04:00
{
2011-09-27 01:55:47 +04:00
GROUP_MAP * map ;
2008-03-11 16:15:52 +03:00
struct aliasmem_state state ;
2006-09-24 06:52:25 +04:00
2011-09-27 01:55:47 +04:00
map = talloc_zero ( talloc_tos ( ) , GROUP_MAP ) ;
if ( ! map ) {
return NT_STATUS_NO_MEMORY ;
}
if ( ! get_group_map_from_sid ( * alias , map ) ) {
TALLOC_FREE ( map ) ;
2006-09-24 06:52:25 +04:00
return NT_STATUS_NO_SUCH_ALIAS ;
2011-09-27 01:55:47 +04:00
}
2006-09-24 06:52:25 +04:00
2011-09-27 01:55:47 +04:00
if ( ( map - > sid_name_use ! = SID_NAME_ALIAS ) & &
( map - > sid_name_use ! = SID_NAME_WKN_GRP ) ) {
TALLOC_FREE ( map ) ;
2006-09-24 06:52:25 +04:00
return NT_STATUS_NO_SUCH_ALIAS ;
2011-09-27 01:55:47 +04:00
}
TALLOC_FREE ( map ) ;
2006-09-24 06:52:25 +04:00
* sids = NULL ;
* num = 0 ;
2008-03-11 16:15:52 +03:00
state . alias = alias ;
state . sids = sids ;
state . num = num ;
2009-06-08 21:43:01 +04:00
state . mem_ctx = mem_ctx ;
2006-09-24 06:52:25 +04:00
2011-08-17 13:18:49 +04:00
dbwrap_traverse_read ( db , collect_aliasmem , & state , NULL ) ;
2006-09-24 06:52:25 +04:00
return NT_STATUS_OK ;
}
2010-05-21 05:25:01 +04:00
static NTSTATUS del_aliasmem ( const struct dom_sid * alias , const struct dom_sid * member )
2006-09-24 06:52:25 +04:00
{
2008-03-11 16:15:52 +03:00
NTSTATUS status ;
2010-05-21 05:25:01 +04:00
struct dom_sid * sids ;
2006-09-24 06:52:25 +04:00
size_t i , num ;
2007-10-19 04:40:25 +04:00
bool found = False ;
2006-09-24 06:52:25 +04:00
char * member_string ;
2008-03-11 16:15:52 +03:00
char * key ;
2018-11-02 22:58:59 +03:00
struct dom_sid_buf sid_string ;
2006-09-24 06:52:25 +04:00
2011-08-17 13:18:49 +04:00
if ( dbwrap_transaction_start ( db ) ! = 0 ) {
2008-03-27 19:10:31 +03:00
DEBUG ( 0 , ( " transaction_start failed \n " ) ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2008-03-11 16:15:52 +03:00
status = alias_memberships ( member , 1 , & sids , & num ) ;
2006-09-24 06:52:25 +04:00
2008-03-27 19:10:31 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto cancel ;
}
2006-09-24 06:52:25 +04:00
for ( i = 0 ; i < num ; i + + ) {
2010-08-26 17:48:50 +04:00
if ( dom_sid_compare ( & sids [ i ] , alias ) = = 0 ) {
2006-09-24 06:52:25 +04:00
found = True ;
break ;
}
}
if ( ! found ) {
2007-04-25 13:32:03 +04:00
TALLOC_FREE ( sids ) ;
2008-03-27 19:10:31 +03:00
status = NT_STATUS_MEMBER_NOT_IN_ALIAS ;
goto cancel ;
2006-09-24 06:52:25 +04:00
}
if ( i < num )
sids [ i ] = sids [ num - 1 ] ;
num - = 1 ;
2018-11-02 22:58:59 +03:00
key = talloc_asprintf (
sids ,
" %s%s " ,
MEMBEROF_PREFIX ,
dom_sid_str_buf ( member , & sid_string ) ) ;
2008-03-11 16:15:52 +03:00
if ( key = = NULL ) {
2007-11-14 02:00:48 +03:00
TALLOC_FREE ( sids ) ;
2008-03-27 19:10:31 +03:00
status = NT_STATUS_NO_MEMORY ;
goto cancel ;
2007-11-14 02:00:48 +03:00
}
2006-09-24 06:52:25 +04:00
2007-11-14 02:00:48 +03:00
if ( num = = 0 ) {
2008-03-11 16:15:52 +03:00
status = dbwrap_delete_bystring ( db , key ) ;
2008-09-18 07:01:47 +04:00
goto commit ;
2007-11-14 02:00:48 +03:00
}
2006-09-24 06:52:25 +04:00
2008-03-11 16:15:52 +03:00
member_string = talloc_strdup ( sids , " " ) ;
2006-09-24 06:52:25 +04:00
if ( member_string = = NULL ) {
2007-04-25 13:32:03 +04:00
TALLOC_FREE ( sids ) ;
2008-03-27 19:10:31 +03:00
status = NT_STATUS_NO_MEMORY ;
goto cancel ;
2006-09-24 06:52:25 +04:00
}
for ( i = 0 ; i < num ; i + + ) {
2008-03-11 16:15:52 +03:00
member_string = talloc_asprintf_append_buffer (
2018-11-02 22:58:59 +03:00
member_string ,
" %s " ,
dom_sid_str_buf ( & sids [ i ] , & sid_string ) ) ;
2008-03-11 16:15:52 +03:00
2006-09-24 06:52:25 +04:00
if ( member_string = = NULL ) {
2007-04-25 13:32:03 +04:00
TALLOC_FREE ( sids ) ;
2008-03-27 19:10:31 +03:00
status = NT_STATUS_NO_MEMORY ;
goto cancel ;
2006-09-24 06:52:25 +04:00
}
}
2008-03-11 16:15:52 +03:00
status = dbwrap_store_bystring (
db , key , string_term_tdb_data ( member_string ) , 0 ) ;
2008-09-18 07:01:47 +04:00
commit :
2007-04-25 13:32:03 +04:00
TALLOC_FREE ( sids ) ;
2006-09-24 06:52:25 +04:00
2008-03-27 19:10:31 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 10 , ( " dbwrap_store_bystring failed: %s \n " ,
nt_errstr ( status ) ) ) ;
goto cancel ;
}
2011-08-17 13:18:49 +04:00
if ( dbwrap_transaction_commit ( db ) ! = 0 ) {
2008-03-27 19:10:31 +03:00
DEBUG ( 0 , ( " transaction_commit failed \n " ) ) ;
status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
2008-08-08 05:42:06 +04:00
return status ;
2008-03-27 19:10:31 +03:00
}
return NT_STATUS_OK ;
cancel :
2011-08-17 13:18:49 +04:00
if ( dbwrap_transaction_cancel ( db ) ! = 0 ) {
2008-03-27 19:10:31 +03:00
smb_panic ( " transaction_cancel failed " ) ;
}
2008-03-11 16:15:52 +03:00
return status ;
2006-09-24 06:52:25 +04:00
}
2010-02-26 23:16:23 +03:00
/* -- ldb->tdb switching code -------------------------------------------- */
/* change this if the data format ever changes */
# define LTDB_PACKING_FORMAT 0x26011967
/* old packing formats (not supported for now,
* it was never used for group mapping AFAIK ) */
# define LTDB_PACKING_FORMAT_NODN 0x26011966
static unsigned int pull_uint32 ( uint8_t * p , int ofs )
{
p + = ofs ;
return p [ 0 ] | ( p [ 1 ] < < 8 ) | ( p [ 2 ] < < 16 ) | ( p [ 3 ] < < 24 ) ;
}
/*
unpack a ldb message from a linear buffer in TDB_DATA
*/
static int convert_ldb_record ( TDB_CONTEXT * ltdb , TDB_DATA key ,
TDB_DATA data , void * ptr )
{
TALLOC_CTX * tmp_ctx = talloc_tos ( ) ;
2011-09-27 01:55:47 +04:00
GROUP_MAP * map = NULL ;
2010-02-26 23:16:23 +03:00
uint8_t * p ;
uint32_t format ;
uint32_t num_el ;
unsigned int remaining ;
unsigned int i , j ;
size_t len ;
char * name ;
char * val ;
char * q ;
uint32_t num_mem = 0 ;
2010-05-21 05:25:01 +04:00
struct dom_sid * members = NULL ;
2010-02-26 23:16:23 +03:00
p = ( uint8_t * ) data . dptr ;
if ( data . dsize < 8 ) {
errno = EIO ;
goto failed ;
}
format = pull_uint32 ( p , 0 ) ;
num_el = pull_uint32 ( p , 4 ) ;
p + = 8 ;
remaining = data . dsize - 8 ;
switch ( format ) {
case LTDB_PACKING_FORMAT :
len = strnlen ( ( char * ) p , remaining ) ;
if ( len = = remaining ) {
errno = EIO ;
goto failed ;
}
if ( * p = = ' @ ' ) {
/* ignore special LDB attributes */
return 0 ;
}
if ( strncmp ( ( char * ) p , " rid= " , 4 ) ) {
/* unknown entry, ignore */
DEBUG ( 3 , ( " Found unknown entry in group mapping "
" database named [%s] \n " , ( char * ) p ) ) ;
return 0 ;
}
remaining - = len + 1 ;
p + = len + 1 ;
break ;
case LTDB_PACKING_FORMAT_NODN :
default :
errno = EIO ;
goto failed ;
}
if ( num_el = = 0 ) {
/* bad entry, ignore */
return 0 ;
}
if ( num_el > remaining / 6 ) {
errno = EIO ;
goto failed ;
}
2011-09-27 01:55:47 +04:00
map = talloc_zero ( NULL , GROUP_MAP ) ;
if ( ! map ) {
errno = ENOMEM ;
goto failed ;
}
2010-02-26 23:16:23 +03:00
for ( i = 0 ; i < num_el ; i + + ) {
uint32_t num_vals ;
if ( remaining < 10 ) {
errno = EIO ;
goto failed ;
}
len = strnlen ( ( char * ) p , remaining - 6 ) ;
if ( len = = remaining - 6 ) {
errno = EIO ;
goto failed ;
}
name = talloc_strndup ( tmp_ctx , ( char * ) p , len ) ;
if ( name = = NULL ) {
errno = ENOMEM ;
goto failed ;
}
remaining - = len + 1 ;
p + = len + 1 ;
num_vals = pull_uint32 ( p , 0 ) ;
2011-05-13 22:21:30 +04:00
if ( strcasecmp_m ( name , " member " ) = = 0 ) {
2010-02-26 23:16:23 +03:00
num_mem = num_vals ;
2010-05-21 05:25:01 +04:00
members = talloc_array ( tmp_ctx , struct dom_sid , num_mem ) ;
2010-02-26 23:16:23 +03:00
if ( members = = NULL ) {
errno = ENOMEM ;
goto failed ;
}
} else if ( num_vals ! = 1 ) {
errno = EIO ;
goto failed ;
}
p + = 4 ;
remaining - = 4 ;
for ( j = 0 ; j < num_vals ; j + + ) {
len = pull_uint32 ( p , 0 ) ;
if ( len > remaining - 5 ) {
errno = EIO ;
goto failed ;
}
val = talloc_strndup ( tmp_ctx , ( char * ) ( p + 4 ) , len ) ;
if ( val = = NULL ) {
errno = ENOMEM ;
goto failed ;
}
remaining - = len + 4 + 1 ;
p + = len + 4 + 1 ;
/* we ignore unknown or uninteresting attributes
* ( objectclass , etc . ) */
2011-05-13 22:21:30 +04:00
if ( strcasecmp_m ( name , " gidNumber " ) = = 0 ) {
2011-09-27 01:55:47 +04:00
map - > gid = strtoul ( val , & q , 10 ) ;
2010-02-26 23:16:23 +03:00
if ( * q ) {
errno = EIO ;
goto failed ;
}
2011-05-13 22:21:30 +04:00
} else if ( strcasecmp_m ( name , " sid " ) = = 0 ) {
2011-09-27 01:55:47 +04:00
if ( ! string_to_sid ( & map - > sid , val ) ) {
2010-02-26 23:16:23 +03:00
errno = EIO ;
goto failed ;
}
2011-05-13 22:21:30 +04:00
} else if ( strcasecmp_m ( name , " sidNameUse " ) = = 0 ) {
2011-09-27 01:55:47 +04:00
map - > sid_name_use = strtoul ( val , & q , 10 ) ;
2010-02-26 23:16:23 +03:00
if ( * q ) {
errno = EIO ;
goto failed ;
}
2011-05-13 22:21:30 +04:00
} else if ( strcasecmp_m ( name , " ntname " ) = = 0 ) {
2011-09-27 01:55:47 +04:00
map - > nt_name = talloc_strdup ( map , val ) ;
if ( ! map - > nt_name ) {
errno = ENOMEM ;
goto failed ;
}
2011-05-13 22:21:30 +04:00
} else if ( strcasecmp_m ( name , " comment " ) = = 0 ) {
2011-09-27 01:55:47 +04:00
map - > comment = talloc_strdup ( map , val ) ;
if ( ! map - > comment ) {
errno = ENOMEM ;
goto failed ;
}
2011-05-13 22:21:30 +04:00
} else if ( strcasecmp_m ( name , " member " ) = = 0 ) {
2010-02-26 23:16:23 +03:00
if ( ! string_to_sid ( & members [ j ] , val ) ) {
errno = EIO ;
goto failed ;
}
}
TALLOC_FREE ( val ) ;
}
TALLOC_FREE ( name ) ;
}
2011-11-28 13:44:42 +04:00
if ( map - > nt_name = = NULL ) {
errno = EIO ;
goto failed ;
}
if ( map - > comment = = NULL ) {
map - > comment = talloc_strdup ( map , " " ) ;
}
if ( map - > comment = = NULL ) {
errno = ENOMEM ;
goto failed ;
}
2011-09-27 01:55:47 +04:00
if ( ! add_mapping_entry ( map , 0 ) ) {
2010-02-26 23:16:23 +03:00
errno = EIO ;
goto failed ;
}
if ( num_mem ) {
for ( j = 0 ; j < num_mem ; j + + ) {
NTSTATUS status ;
2011-09-27 01:55:47 +04:00
status = add_aliasmem ( & map - > sid , & members [ j ] ) ;
2010-02-26 23:16:23 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = EIO ;
goto failed ;
}
}
}
if ( remaining ! = 0 ) {
2017-02-17 22:52:09 +03:00
DEBUG ( 0 , ( " Error: %d bytes unread in ltdb_unpack_data \n " ,
2010-02-26 23:16:23 +03:00
remaining ) ) ;
}
2011-09-27 01:55:47 +04:00
TALLOC_FREE ( map ) ;
2010-02-26 23:16:23 +03:00
return 0 ;
failed :
2011-09-27 01:55:47 +04:00
TALLOC_FREE ( map ) ;
2010-02-26 23:16:23 +03:00
return - 1 ;
}
static bool mapping_switch ( const char * ldb_path )
{
2010-03-02 16:05:19 +03:00
TDB_CONTEXT * ltdb ;
2010-02-26 23:16:23 +03:00
TALLOC_CTX * frame ;
char * new_path ;
int ret ;
frame = talloc_stackframe ( ) ;
ltdb = tdb_open_log ( ldb_path , 0 , TDB_DEFAULT , O_RDONLY , 0600 ) ;
if ( ltdb = = NULL ) goto failed ;
/* ldb is just a very fancy tdb, read out raw data and perform
* conversion */
ret = tdb_traverse ( ltdb , convert_ldb_record , NULL ) ;
2011-06-20 13:10:31 +04:00
if ( ret < 0 ) goto failed ;
2010-02-26 23:16:23 +03:00
if ( ltdb ) {
tdb_close ( ltdb ) ;
ltdb = NULL ;
}
/* now rename the old db out of the way */
2018-08-16 11:51:44 +03:00
new_path = state_path ( talloc_tos ( ) , " group_mapping.ldb.replaced " ) ;
2010-02-26 23:16:23 +03:00
if ( ! new_path ) {
goto failed ;
}
if ( rename ( ldb_path , new_path ) ! = 0 ) {
DEBUG ( 0 , ( " Failed to rename old group mapping database \n " ) ) ;
goto failed ;
}
TALLOC_FREE ( frame ) ;
return True ;
failed :
2010-04-14 23:48:38 +04:00
DEBUG ( 0 , ( " Failed to switch to tdb group mapping database \n " ) ) ;
2010-02-26 23:16:23 +03:00
if ( ltdb ) tdb_close ( ltdb ) ;
TALLOC_FREE ( frame ) ;
return False ;
}
2007-06-04 05:51:18 +04:00
static const struct mapping_backend tdb_backend = {
. add_mapping_entry = add_mapping_entry ,
. get_group_map_from_sid = get_group_map_from_sid ,
. get_group_map_from_gid = get_group_map_from_gid ,
. get_group_map_from_ntname = get_group_map_from_ntname ,
. group_map_remove = group_map_remove ,
. enum_group_mapping = enum_group_mapping ,
. one_alias_membership = one_alias_membership ,
. add_aliasmem = add_aliasmem ,
. del_aliasmem = del_aliasmem ,
. enum_aliasmem = enum_aliasmem
} ;
/*
initialise the tdb mapping backend
*/
const struct mapping_backend * groupdb_tdb_init ( void )
{
if ( ! init_group_mapping ( ) ) {
DEBUG ( 0 , ( " Failed to initialise tdb mapping backend \n " ) ) ;
return NULL ;
}
return & tdb_backend ;
}