2001-03-23 00:50:31 +00:00
/*
2002-01-30 06:08:46 +00:00
* Unix SMB / CIFS implementation .
2001-03-23 00:50:31 +00:00
* RPC Pipe client / server routines
* Copyright ( C ) Andrew Tridgell 1992 - 2000 ,
* Copyright ( C ) Jean Fran <EFBFBD> ois Micouleau 1998 - 2001.
*
* 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"
extern pstring global_myname ;
2002-07-20 12:03:11 +00:00
extern fstring global_myworkgroup ;
2001-03-23 00:50:31 +00:00
/*
* Next two lines needed for SunOS and don ' t
* hurt anything else . . .
*/
extern char * optarg ;
extern int optind ;
/*********************************************************
Print command usage on stderr and die .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void usage ( void )
{
if ( getuid ( ) = = 0 ) {
2001-11-23 15:11:22 +00:00
printf ( " smbgroupedit options \n " ) ;
2001-03-23 00:50:31 +00:00
} else {
printf ( " You need to be root to use this tool! \n " ) ;
}
printf ( " options: \n " ) ;
printf ( " -a group create new group \n " ) ;
printf ( " -n group NT group name \n " ) ;
printf ( " -p privilege only local \n " ) ;
2002-07-20 06:52:42 +00:00
printf ( " -d description group description \n " ) ;
2001-03-23 00:50:31 +00:00
printf ( " -v list groups \n " ) ;
2001-11-23 15:11:22 +00:00
printf ( " -l long list (include details) \n " ) ;
printf ( " -s short list (default) \n " ) ;
2001-05-04 15:44:27 +00:00
printf ( " -c SID change group \n " ) ;
printf ( " -u unix group \n " ) ;
2002-07-20 06:52:42 +00:00
printf ( " -d description group description \n " ) ;
2001-03-23 00:50:31 +00:00
printf ( " -x group delete this group \n " ) ;
printf ( " \n " ) ;
printf ( " -t[b|d|l] type: builtin, domain, local \n " ) ;
exit ( 1 ) ;
}
2002-02-03 03:25:26 +00:00
/*********************************************************
Figure out if the input was an NT group or a SID string .
Return the SID .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL get_sid_from_input ( DOM_SID * sid , char * input )
{
GROUP_MAP map ;
if ( StrnCaseCmp ( input , " S- " , 2 ) ) {
/* Perhaps its the NT group name? */
if ( ! get_group_map_from_ntname ( input , & map , MAPPING_WITHOUT_PRIV ) ) {
printf ( " NT Group %s doesn't exist in mapping DB \n " , input ) ;
return False ;
} else {
* sid = map . sid ;
}
} else {
if ( ! string_to_sid ( sid , input ) ) {
printf ( " converting sid %s from a string failed! \n " , input ) ;
return False ;
}
}
return True ;
}
2001-03-23 00:50:31 +00:00
/*********************************************************
add a group .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-02-03 03:25:26 +00:00
static int addgroup ( char * group , enum SID_NAME_USE sid_type , char * ntgroup , char * ntcomment , char * privilege )
2001-03-23 00:50:31 +00:00
{
2001-11-29 16:05:05 +00:00
PRIVILEGE_SET se_priv ;
2001-03-23 00:50:31 +00:00
gid_t gid ;
DOM_SID sid ;
fstring string_sid ;
fstring name , comment ;
gid = nametogid ( group ) ;
2002-02-03 03:25:26 +00:00
if ( gid = = - 1 ) {
printf ( " unix group %s doesn't exist! \n " , group ) ;
2001-03-23 00:50:31 +00:00
return - 1 ;
2002-02-03 03:25:26 +00:00
}
2001-03-23 00:50:31 +00:00
local_gid_to_sid ( & sid , gid ) ;
2002-02-03 03:25:26 +00:00
sid_to_string ( string_sid , & sid ) ;
2001-03-23 00:50:31 +00:00
if ( ntgroup = = NULL )
fstrcpy ( name , group ) ;
else
fstrcpy ( name , ntgroup ) ;
if ( ntcomment = = NULL )
fstrcpy ( comment , " Local Unix group " ) ;
else
fstrcpy ( comment , ntcomment ) ;
2001-11-29 16:05:05 +00:00
init_privilege ( & se_priv ) ;
2001-11-23 15:11:22 +00:00
if ( privilege ! = NULL )
2001-11-29 16:05:05 +00:00
convert_priv_from_text ( & se_priv , privilege ) ;
2001-11-23 15:11:22 +00:00
2001-12-04 21:53:47 +00:00
if ( ! add_initial_entry ( gid , string_sid , sid_type , name , comment , se_priv , PR_ACCESS_FROM_NETWORK ) ) {
2002-02-03 03:25:26 +00:00
printf ( " adding entry for group %s failed! \n " , group ) ;
2001-12-04 21:53:47 +00:00
free_privilege ( & se_priv ) ;
2001-03-23 01:19:21 +00:00
return - 1 ;
2001-12-04 21:53:47 +00:00
}
2001-03-23 00:50:31 +00:00
2001-12-04 21:53:47 +00:00
free_privilege ( & se_priv ) ;
2001-03-23 01:19:21 +00:00
return 0 ;
2001-03-23 00:50:31 +00:00
}
/*********************************************************
Change a group .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-02-03 03:25:26 +00:00
static int changegroup ( char * sid_string , char * group , enum SID_NAME_USE sid_type , char * ntgroup , char * groupdesc , char * privilege )
2001-03-23 00:50:31 +00:00
{
DOM_SID sid ;
GROUP_MAP map ;
gid_t gid ;
2002-02-03 03:25:26 +00:00
if ( ! get_sid_from_input ( & sid , sid_string ) ) {
return - 1 ;
}
2001-03-23 00:50:31 +00:00
/* Get the current mapping from the database */
2001-12-04 21:53:47 +00:00
if ( ! get_group_map_from_sid ( sid , & map , MAPPING_WITH_PRIV ) ) {
2001-03-23 00:50:31 +00:00
printf ( " This SID does not exist in the database \n " ) ;
return - 1 ;
}
/* If a new Unix group is specified, check and change */
if ( group ! = NULL ) {
gid = nametogid ( group ) ;
if ( gid = = - 1 ) {
printf ( " The UNIX group does not exist \n " ) ;
return - 1 ;
} else
map . gid = gid ;
}
/*
* Allow changing of group type only between domain and local
* We disallow changing Builtin groups ! ! ! ( SID problem )
*/
2002-02-03 03:25:26 +00:00
if ( sid_type = = SID_NAME_ALIAS
| | sid_type = = SID_NAME_DOM_GRP
| | sid_type = = SID_NAME_UNKNOWN ) {
if ( map . sid_name_use = = SID_NAME_ALIAS
| | map . sid_name_use = = SID_NAME_DOM_GRP
| | map . sid_name_use = = SID_NAME_UNKNOWN ) {
2001-03-23 00:50:31 +00:00
map . sid_name_use = sid_type ;
2002-02-03 03:25:26 +00:00
} else {
printf ( " cannot change group type to builtin \n " ) ;
} ;
} else {
printf ( " cannot change group type from builtin \n " ) ;
}
2001-03-23 00:50:31 +00:00
2001-07-09 18:15:28 +00:00
if ( ntgroup ! = NULL )
fstrcpy ( map . nt_name , ntgroup ) ;
2001-03-23 00:50:31 +00:00
/* Change comment if new one */
if ( groupdesc ! = NULL )
fstrcpy ( map . comment , groupdesc ) ;
/* Change the privilege if new one */
2001-11-29 16:05:05 +00:00
if ( privilege ! = NULL )
convert_priv_from_text ( & map . priv_set , privilege ) ;
2001-03-23 00:50:31 +00:00
if ( ! add_mapping_entry ( & map , TDB_REPLACE ) ) {
printf ( " Count not update group database \n " ) ;
2001-12-04 21:53:47 +00:00
free_privilege ( & map . priv_set ) ;
2001-03-23 00:50:31 +00:00
return - 1 ;
}
2001-12-04 21:53:47 +00:00
free_privilege ( & map . priv_set ) ;
2001-03-23 01:19:21 +00:00
return 0 ;
2001-03-23 00:50:31 +00:00
}
/*********************************************************
2001-03-23 01:19:21 +00:00
Delete the group .
2001-03-23 00:50:31 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-02-03 03:25:26 +00:00
static int deletegroup ( char * group )
2001-03-23 00:50:31 +00:00
{
2001-03-23 01:19:21 +00:00
DOM_SID sid ;
2001-03-23 00:50:31 +00:00
2002-02-03 03:25:26 +00:00
if ( ! get_sid_from_input ( & sid , group ) ) {
return - 1 ;
}
2001-03-23 01:19:21 +00:00
2002-02-03 03:25:26 +00:00
if ( ! group_map_remove ( sid ) ) {
printf ( " removing group %s from the mapping db failed! \n " , group ) ;
return - 1 ;
}
return 0 ;
2001-03-23 00:50:31 +00:00
}
/*********************************************************
List the groups .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-02-03 03:25:26 +00:00
static int listgroup ( enum SID_NAME_USE sid_type , BOOL long_list )
2001-03-23 00:50:31 +00:00
{
int entries , i ;
GROUP_MAP * map = NULL ;
fstring string_sid ;
fstring group_type ;
fstring priv_text ;
2001-11-23 15:11:22 +00:00
if ( ! long_list )
printf ( " NT group (SID) -> Unix group \n " ) ;
2001-03-23 00:50:31 +00:00
2001-12-04 21:53:47 +00:00
if ( ! enum_group_mapping ( sid_type , & map , & entries , ENUM_ALL_MAPPED , MAPPING_WITH_PRIV ) )
2001-03-23 01:19:21 +00:00
return - 1 ;
2001-03-23 00:50:31 +00:00
for ( i = 0 ; i < entries ; i + + ) {
decode_sid_name_use ( group_type , ( map [ i ] ) . sid_name_use ) ;
sid_to_string ( string_sid , & map [ i ] . sid ) ;
2001-11-29 16:05:05 +00:00
convert_priv_to_text ( & ( map [ i ] . priv_set ) , priv_text ) ;
free_privilege ( & ( map [ i ] . priv_set ) ) ;
2001-11-23 15:11:22 +00:00
if ( ! long_list )
printf ( " %s (%s) -> %s \n " , map [ i ] . nt_name , string_sid , gidtoname ( map [ i ] . gid ) ) ;
else {
printf ( " %s \n " , map [ i ] . nt_name ) ;
printf ( " \t SID : %s \n " , string_sid ) ;
printf ( " \t Unix group: %s \n " , gidtoname ( map [ i ] . gid ) ) ;
printf ( " \t Group type: %s \n " , group_type ) ;
printf ( " \t Comment : %s \n " , map [ i ] . comment ) ;
printf ( " \t Privilege : %s \n \n " , priv_text ) ;
}
2001-03-23 00:50:31 +00:00
}
2001-03-23 01:19:21 +00:00
return 0 ;
2001-03-23 00:50:31 +00:00
}
/*********************************************************
Start here .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int main ( int argc , char * * argv )
{
int ch ;
BOOL add_group = False ;
BOOL view_group = False ;
BOOL change_group = False ;
BOOL delete_group = False ;
BOOL nt_group = False ;
BOOL priv = False ;
BOOL group_type = False ;
2001-11-23 15:11:22 +00:00
BOOL long_list = False ;
2001-03-23 00:50:31 +00:00
char * group = NULL ;
char * sid = NULL ;
char * ntgroup = NULL ;
char * privilege = NULL ;
char * groupt = NULL ;
char * group_desc = NULL ;
enum SID_NAME_USE sid_type ;
setup_logging ( " groupedit " , True ) ;
if ( argc < 2 ) {
usage ( ) ;
return 0 ;
}
2001-11-22 23:50:16 +00:00
if ( ! lp_load ( dyn_CONFIGFILE , True , False , False ) ) {
2001-03-23 00:50:31 +00:00
fprintf ( stderr , " Can't load %s - run testparm to debug it \n " ,
2001-11-22 23:50:16 +00:00
dyn_CONFIGFILE ) ;
2001-03-23 00:50:31 +00:00
exit ( 1 ) ;
}
2002-04-16 15:49:24 +00:00
if ( ! * global_myname ) {
char * p ;
pstrcpy ( global_myname , myhostname ( ) ) ;
p = strchr_m ( global_myname , ' . ' ) ;
if ( p )
* p = 0 ;
}
strupper ( global_myname ) ;
fstrcpy ( global_myworkgroup , lp_workgroup ( ) ) ;
2001-03-23 00:50:31 +00:00
2002-01-26 06:16:36 +00:00
if ( ! initialize_password_db ( True ) ) {
fprintf ( stderr , " Can't setup password database vectors. \n " ) ;
exit ( 1 ) ;
}
2002-06-07 14:33:33 +00:00
if ( get_global_sam_sid ( ) = = False ) {
2002-04-16 15:49:24 +00:00
fprintf ( stderr , " Can not read machine SID \n " ) ;
2001-12-03 17:14:23 +00:00
return 0 ;
}
2001-11-23 15:11:22 +00:00
while ( ( ch = getopt ( argc , argv , " a:c:d:ln:p:st:u:vx: " ) ) ! = EOF ) {
2001-03-23 00:50:31 +00:00
switch ( ch ) {
case ' a ' :
add_group = True ;
group = optarg ;
break ;
case ' c ' :
change_group = True ;
sid = optarg ;
break ;
case ' d ' :
group_desc = optarg ;
break ;
2001-11-23 15:11:22 +00:00
case ' l ' :
long_list = True ;
break ;
2001-03-23 00:50:31 +00:00
case ' n ' :
nt_group = True ;
ntgroup = optarg ;
break ;
case ' p ' :
priv = True ;
privilege = optarg ;
break ;
2001-11-23 15:11:22 +00:00
case ' s ' :
long_list = False ;
break ;
2001-03-23 00:50:31 +00:00
case ' t ' :
group_type = True ;
groupt = optarg ;
break ;
case ' u ' :
group = optarg ;
break ;
case ' v ' :
view_group = True ;
break ;
case ' x ' :
delete_group = True ;
group = optarg ;
break ;
/*default:
usage ( ) ; */
}
}
if ( ( ( add_group ? 1 : 0 ) + ( view_group ? 1 : 0 ) + ( change_group ? 1 : 0 ) + ( delete_group ? 1 : 0 ) ) > 1 ) {
fprintf ( stderr , " Incompatible options on command line! \n " ) ;
usage ( ) ;
exit ( 1 ) ;
}
/* no option on command line -> list groups */
if ( ( ( add_group ? 1 : 0 ) + ( view_group ? 1 : 0 ) + ( change_group ? 1 : 0 ) + ( delete_group ? 1 : 0 ) ) = = 0 )
view_group = True ;
if ( group_type = = False )
sid_type = SID_NAME_UNKNOWN ;
else {
switch ( groupt [ 0 ] ) {
case ' l ' :
case ' L ' :
sid_type = SID_NAME_ALIAS ;
break ;
case ' d ' :
case ' D ' :
sid_type = SID_NAME_DOM_GRP ;
break ;
case ' b ' :
case ' B ' :
sid_type = SID_NAME_WKN_GRP ;
break ;
default :
sid_type = SID_NAME_UNKNOWN ;
break ;
}
}
if ( add_group )
return addgroup ( group , sid_type , ntgroup , group_desc , privilege ) ;
if ( view_group )
2001-11-23 15:11:22 +00:00
return listgroup ( sid_type , long_list ) ;
2001-03-23 00:50:31 +00:00
if ( delete_group )
return deletegroup ( group ) ;
if ( change_group ) {
2001-07-09 18:15:28 +00:00
return changegroup ( sid , group , sid_type , ntgroup , group_desc , privilege ) ;
2001-03-23 00:50:31 +00:00
}
usage ( ) ;
return 0 ;
}