2003-06-21 12:35:30 +04:00
/*
Samba Unix / Linux SMB client library
Distributed SMB / CIFS Server Management Utility
Copyright ( C ) 2003 Andrew Bartlett ( abartlet @ samba . org )
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"
2004-10-07 08:01:18 +04:00
# include "utils/net.h"
2003-06-21 12:35:30 +04:00
/***********************************************************
Helper function for net_idmap_dump . Dump one entry .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int net_idmap_dump_one_entry ( TDB_CONTEXT * tdb ,
TDB_DATA key ,
TDB_DATA data ,
void * unused )
{
if ( strcmp ( key . dptr , " USER HWM " ) = = 0 ) {
printf ( " USER HWM %d \n " , IVAL ( data . dptr , 0 ) ) ;
return 0 ;
}
if ( strcmp ( key . dptr , " GROUP HWM " ) = = 0 ) {
printf ( " GROUP HWM %d \n " , IVAL ( data . dptr , 0 ) ) ;
return 0 ;
}
if ( strncmp ( key . dptr , " S- " , 2 ) ! = 0 )
return 0 ;
printf ( " %s %s \n " , data . dptr , key . dptr ) ;
return 0 ;
}
/***********************************************************
Dump the current idmap
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int net_idmap_dump ( int argc , const char * * argv )
{
TDB_CONTEXT * idmap_tdb ;
if ( argc ! = 1 )
return net_help_idmap ( argc , argv ) ;
idmap_tdb = tdb_open_log ( argv [ 0 ] , 0 , TDB_DEFAULT , O_RDONLY , 0 ) ;
if ( idmap_tdb = = NULL ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not open idmap: %s \n " , argv [ 0 ] ) ;
2003-06-21 12:35:30 +04:00
return - 1 ;
}
tdb_traverse ( idmap_tdb , net_idmap_dump_one_entry , NULL ) ;
tdb_close ( idmap_tdb ) ;
return 0 ;
}
2004-02-24 18:45:10 +03:00
/***********************************************************
Fix up the HWMs after a idmap restore .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct hwms {
BOOL ok ;
2005-10-18 07:24:00 +04:00
uid_t user_hwm ;
gid_t group_hwm ;
2004-02-24 18:45:10 +03:00
} ;
static int net_idmap_find_max_id ( TDB_CONTEXT * tdb , TDB_DATA key , TDB_DATA data ,
void * handle )
{
struct hwms * hwms = ( struct hwms * ) handle ;
2005-10-18 22:02:37 +04:00
void * idptr = NULL ;
BOOL isgid = False ;
2004-02-24 18:45:10 +03:00
int id ;
if ( strncmp ( key . dptr , " S- " , 2 ) ! = 0 )
return 0 ;
if ( sscanf ( data . dptr , " GID %d " , & id ) = = 1 ) {
2005-10-18 22:02:37 +04:00
idptr = ( void * ) & hwms - > group_hwm ;
isgid = True ;
2004-02-24 18:45:10 +03:00
}
if ( sscanf ( data . dptr , " UID %d " , & id ) = = 1 ) {
2005-10-18 22:02:37 +04:00
idptr = ( void * ) & hwms - > user_hwm ;
isgid = False ;
2004-02-24 18:45:10 +03:00
}
if ( idptr = = NULL ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Illegal idmap entry: [%s]->[%s] \n " ,
2004-02-24 18:45:10 +03:00
key . dptr , data . dptr ) ;
hwms - > ok = False ;
return - 1 ;
}
2005-10-18 22:02:37 +04:00
if ( isgid ) {
if ( hwms - > group_hwm < = ( gid_t ) id ) {
hwms - > group_hwm = ( gid_t ) ( id + 1 ) ;
}
} else {
if ( hwms - > user_hwm < = ( uid_t ) id ) {
hwms - > user_hwm = ( uid_t ) ( id + 1 ) ;
}
}
2004-02-24 18:45:10 +03:00
return 0 ;
}
static NTSTATUS net_idmap_fixup_hwm ( void )
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
TDB_CONTEXT * idmap_tdb ;
char * tdbfile = NULL ;
struct hwms hwms ;
struct hwms highest ;
if ( ! lp_idmap_uid ( & hwms . user_hwm , & highest . user_hwm ) | |
! lp_idmap_gid ( & hwms . group_hwm , & highest . group_hwm ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " idmap range missing \n " ) ;
2004-02-24 18:45:10 +03:00
return NT_STATUS_UNSUCCESSFUL ;
}
2004-12-07 21:25:53 +03:00
tdbfile = SMB_STRDUP ( lock_path ( " winbindd_idmap.tdb " ) ) ;
2004-02-24 18:45:10 +03:00
if ( ! tdbfile ) {
DEBUG ( 0 , ( " idmap_init: out of memory! \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
idmap_tdb = tdb_open_log ( tdbfile , 0 , TDB_DEFAULT , O_RDWR , 0 ) ;
if ( idmap_tdb = = NULL ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not open idmap: %s \n " , tdbfile ) ;
2004-02-24 18:45:10 +03:00
return NT_STATUS_NO_SUCH_FILE ;
}
hwms . ok = True ;
tdb_traverse ( idmap_tdb , net_idmap_find_max_id , & hwms ) ;
if ( ! hwms . ok ) {
goto done ;
}
d_printf ( " USER HWM: %d GROUP HWM: %d \n " ,
hwms . user_hwm , hwms . group_hwm ) ;
if ( hwms . user_hwm > = highest . user_hwm ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Highest UID out of uid range \n " ) ;
2004-02-24 18:45:10 +03:00
goto done ;
}
if ( hwms . group_hwm > = highest . group_hwm ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Highest GID out of gid range \n " ) ;
2004-02-24 18:45:10 +03:00
goto done ;
}
2005-10-18 07:24:00 +04:00
if ( ( tdb_store_int32 ( idmap_tdb , " USER HWM " , ( int32 ) hwms . user_hwm ) ! = 0 ) | |
( tdb_store_int32 ( idmap_tdb , " GROUP HWM " , ( int32 ) hwms . group_hwm ) ! = 0 ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not store HWMs \n " ) ;
2004-02-24 18:45:10 +03:00
goto done ;
}
result = NT_STATUS_OK ;
done :
tdb_close ( idmap_tdb ) ;
return result ;
}
2003-06-21 12:35:30 +04:00
/***********************************************************
Write entries from stdin to current local idmap
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-07-11 22:01:26 +04:00
2003-06-21 12:35:30 +04:00
static int net_idmap_restore ( int argc , const char * * argv )
{
2003-06-28 00:55:48 +04:00
if ( ! idmap_init ( lp_idmap_backend ( ) ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not init idmap \n " ) ;
2003-06-21 12:35:30 +04:00
return - 1 ;
}
while ( ! feof ( stdin ) ) {
2006-07-11 22:01:26 +04:00
fstring line , sid_string , fmt_string1 , fmt_string2 ;
2003-06-21 12:35:30 +04:00
int len ;
unid_t id ;
2006-07-11 22:01:26 +04:00
enum idmap_type type ;
unsigned long idval ;
2003-06-21 12:35:30 +04:00
DOM_SID sid ;
if ( fgets ( line , sizeof ( line ) - 1 , stdin ) = = NULL )
break ;
len = strlen ( line ) ;
if ( ( len > 0 ) & & ( line [ len - 1 ] = = ' \n ' ) )
line [ len - 1 ] = ' \0 ' ;
2006-07-11 22:01:26 +04:00
snprintf ( fmt_string1 , sizeof ( fmt_string1 ) , " GID %%ul %%%us " , FSTRING_LEN ) ;
snprintf ( fmt_string2 , sizeof ( fmt_string2 ) , " UID %%ul %%%us " , FSTRING_LEN ) ;
2003-07-22 08:31:20 +04:00
2006-07-11 22:01:26 +04:00
if ( sscanf ( line , fmt_string1 , & idval , sid_string ) = = 2 ) {
type = ID_GROUPID ;
id . gid = ( gid_t ) idval ;
} else if ( sscanf ( line , fmt_string2 , & idval , sid_string ) = = 2 ) {
2003-06-21 12:35:30 +04:00
type = ID_USERID ;
2006-07-11 22:01:26 +04:00
id . uid = ( uid_t ) idval ;
} else {
2003-06-21 12:35:30 +04:00
d_printf ( " ignoring invalid line [%s] \n " , line ) ;
continue ;
}
if ( ! string_to_sid ( & sid , sid_string ) ) {
d_printf ( " ignoring invalid sid [%s] \n " , sid_string ) ;
continue ;
}
if ( ! NT_STATUS_IS_OK ( idmap_set_mapping ( & sid , id , type ) ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not set mapping of %s %lu to sid %s \n " ,
2003-06-21 12:35:30 +04:00
( type = = ID_GROUPID ) ? " GID " : " UID " ,
2003-07-22 10:52:39 +04:00
( type = = ID_GROUPID ) ? ( unsigned long ) id . gid :
( unsigned long ) id . uid ,
2003-06-21 12:35:30 +04:00
sid_string_static ( & sid ) ) ;
continue ;
}
}
idmap_close ( ) ;
2004-02-24 18:45:10 +03:00
return NT_STATUS_IS_OK ( net_idmap_fixup_hwm ( ) ) ? 0 : - 1 ;
2003-06-21 12:35:30 +04:00
}
2004-12-17 13:20:53 +03:00
/***********************************************************
Delete a SID mapping from a winbindd_idmap . tdb
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int net_idmap_delete ( int argc , const char * * argv )
{
TDB_CONTEXT * idmap_tdb ;
TDB_DATA key , data ;
fstring sid ;
if ( argc ! = 2 )
return net_help_idmap ( argc , argv ) ;
idmap_tdb = tdb_open_log ( argv [ 0 ] , 0 , TDB_DEFAULT , O_RDWR , 0 ) ;
if ( idmap_tdb = = NULL ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not open idmap: %s \n " , argv [ 0 ] ) ;
2004-12-17 13:20:53 +03:00
return - 1 ;
}
fstrcpy ( sid , argv [ 1 ] ) ;
if ( strncmp ( sid , " S-1-5- " , strlen ( " S-1-5- " ) ) ! = 0 ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Can only delete SIDs, %s is does not start with "
2004-12-17 13:20:53 +03:00
" S-1-5- \n " , sid ) ;
return - 1 ;
}
key . dptr = sid ;
key . dsize = strlen ( key . dptr ) + 1 ;
data = tdb_fetch ( idmap_tdb , key ) ;
if ( data . dptr = = NULL ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not find sid %s \n " , argv [ 1 ] ) ;
2004-12-17 13:20:53 +03:00
return - 1 ;
}
if ( tdb_delete ( idmap_tdb , key ) ! = 0 ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not delete key %s \n " , argv [ 1 ] ) ;
2004-12-17 13:20:53 +03:00
return - 1 ;
}
if ( tdb_delete ( idmap_tdb , data ) ! = 0 ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not delete key %s \n " , data . dptr ) ;
2004-12-17 13:20:53 +03:00
return - 1 ;
}
return 0 ;
}
2003-06-21 12:35:30 +04:00
int net_help_idmap ( int argc , const char * * argv )
{
2005-01-25 04:19:02 +03:00
d_printf ( " net idmap dump <tdbfile> " \
2003-06-21 12:35:30 +04:00
" \n Dump current id mapping \n " ) ;
d_printf ( " net idmap restore " \
" \n Restore entries from stdin to current local idmap \n " ) ;
2004-12-17 13:20:53 +03:00
/* Deliberately *not* document net idmap delete */
2003-06-21 12:35:30 +04:00
return - 1 ;
}
/***********************************************************
Look at the current idmap
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int net_idmap ( int argc , const char * * argv )
{
struct functable func [ ] = {
{ " dump " , net_idmap_dump } ,
{ " restore " , net_idmap_restore } ,
2004-12-17 13:20:53 +03:00
{ " delete " , net_idmap_delete } ,
2003-06-21 12:35:30 +04:00
{ " help " , net_help_idmap } ,
{ NULL , NULL }
} ;
return net_run_function ( argc , argv , func , net_help_idmap ) ;
}