2001-03-23 03:50:31 +03:00
/*
2002-01-30 09:08:46 +03:00
* Unix SMB / CIFS implementation .
2001-03-23 03:50:31 +03: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"
static TDB_CONTEXT * tdb ; /* used for driver files */
2002-01-09 08:24:07 +03:00
# define DATABASE_VERSION_V1 1 /* native byte format. */
# define DATABASE_VERSION_V2 2 /* le format. */
2001-03-23 03:50:31 +03:00
# define GROUP_PREFIX "UNIXGROUP / "
PRIVS privs [ ] = {
2001-11-23 18:11:22 +03:00
{ SE_PRIV_NONE , " no_privs " , " No privilege " } , /* this one MUST be first */
{ SE_PRIV_ADD_MACHINES , " SeMachineAccountPrivilege " , " Add workstations to the domain " } ,
{ SE_PRIV_SEC_PRIV , " SeSecurityPrivilege " , " Manage the audit logs " } ,
{ SE_PRIV_TAKE_OWNER , " SeTakeOwnershipPrivilege " , " Take ownership of file " } ,
{ SE_PRIV_ADD_USERS , " SaAddUsers " , " Add users to the domain - Samba " } ,
{ SE_PRIV_PRINT_OPERATOR , " SaPrintOp " , " Add or remove printers - Samba " } ,
{ SE_PRIV_ALL , " SaAllPrivs " , " all privileges " }
2001-03-23 03:50:31 +03:00
} ;
/*
PRIVS privs [ ] = {
{ 2 , " SeCreateTokenPrivilege " } ,
{ 3 , " SeAssignPrimaryTokenPrivilege " } ,
{ 4 , " SeLockMemoryPrivilege " } ,
{ 5 , " SeIncreaseQuotaPrivilege " } ,
{ 6 , " SeMachineAccountPrivilege " } ,
{ 7 , " SeTcbPrivilege " } ,
{ 8 , " SeSecurityPrivilege " } ,
{ 9 , " SeTakeOwnershipPrivilege " } ,
{ 10 , " SeLoadDriverPrivilege " } ,
{ 11 , " SeSystemProfilePrivilege " } ,
{ 12 , " SeSystemtimePrivilege " } ,
{ 13 , " SeProfileSingleProcessPrivilege " } ,
{ 14 , " SeIncreaseBasePriorityPrivilege " } ,
{ 15 , " SeCreatePagefilePrivilege " } ,
{ 16 , " SeCreatePermanentPrivilege " } ,
{ 17 , " SeBackupPrivilege " } ,
{ 18 , " SeRestorePrivilege " } ,
{ 19 , " SeShutdownPrivilege " } ,
{ 20 , " SeDebugPrivilege " } ,
{ 21 , " SeAuditPrivilege " } ,
{ 22 , " SeSystemEnvironmentPrivilege " } ,
{ 23 , " SeChangeNotifyPrivilege " } ,
{ 24 , " SeRemoteShutdownPrivilege " } ,
2001-11-23 18:11:22 +03:00
{ 25 , " SeUndockPrivilege " } ,
{ 26 , " SeSyncAgentPrivilege " } ,
{ 27 , " SeEnableDelegationPrivilege " } ,
2001-03-23 03:50:31 +03:00
} ;
*/
2001-11-29 19:05:05 +03:00
/*
* Those are not really privileges like the other ones .
* They are handled in a special case and called
* system privileges .
*
* SeNetworkLogonRight
* SeUnsolicitedInputPrivilege
* SeBatchLogonRight
* SeServiceLogonRight
* SeInteractiveLogonRight
* SeDenyInteractiveLogonRight
* SeDenyNetworkLogonRight
* SeDenyBatchLogonRight
* SeDenyBatchLogonRight
*/
2001-03-23 03:50:31 +03:00
#if 0
/****************************************************************************
check if the user has the required privilege .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL se_priv_access_check ( NT_USER_TOKEN * token , uint32 privilege )
{
/* no token, no privilege */
if ( token = = NULL )
return False ;
if ( ( token - > privilege & privilege ) = = privilege )
return True ;
return False ;
}
# endif
/****************************************************************************
dump the mapping group mapping to a text file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
char * decode_sid_name_use ( fstring group , enum SID_NAME_USE name_use )
{
static fstring group_type ;
switch ( name_use ) {
case SID_NAME_USER :
fstrcpy ( group_type , " User " ) ;
break ;
case SID_NAME_DOM_GRP :
fstrcpy ( group_type , " Domain group " ) ;
break ;
case SID_NAME_DOMAIN :
fstrcpy ( group_type , " Domain " ) ;
break ;
case SID_NAME_ALIAS :
fstrcpy ( group_type , " Local group " ) ;
break ;
case SID_NAME_WKN_GRP :
fstrcpy ( group_type , " Builtin group " ) ;
break ;
case SID_NAME_DELETED :
fstrcpy ( group_type , " Deleted " ) ;
break ;
case SID_NAME_INVALID :
fstrcpy ( group_type , " Invalid " ) ;
break ;
case SID_NAME_UNKNOWN :
default :
fstrcpy ( group_type , " Unknown type " ) ;
break ;
}
fstrcpy ( group , group_type ) ;
return group_type ;
}
2002-01-29 04:01:14 +03:00
/****************************************************************************
initialise first time the mapping list - called from init_group_mapping ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL default_group_mapping ( void )
{
DOM_SID sid_admins ;
DOM_SID sid_users ;
DOM_SID sid_guests ;
fstring str_admins ;
fstring str_users ;
fstring str_guests ;
LUID_ATTR set ;
PRIVILEGE_SET privilege_none ;
PRIVILEGE_SET privilege_all ;
PRIVILEGE_SET privilege_print_op ;
init_privilege ( & privilege_none ) ;
init_privilege ( & privilege_all ) ;
init_privilege ( & privilege_print_op ) ;
set . attr = 0 ;
set . luid . high = 0 ;
set . luid . low = SE_PRIV_PRINT_OPERATOR ;
add_privilege ( & privilege_print_op , set ) ;
add_all_privilege ( & privilege_all ) ;
/* Add the Wellknown groups */
2003-05-12 22:12:31 +04:00
add_initial_entry ( - 1 , " S-1-5-32-544 " , SID_NAME_WKN_GRP , " Administrators " , " " , privilege_all , PR_ACCESS_FROM_NETWORK | PR_LOG_ON_LOCALLY ) ;
add_initial_entry ( - 1 , " S-1-5-32-545 " , SID_NAME_WKN_GRP , " Users " , " " , privilege_none , PR_ACCESS_FROM_NETWORK | PR_LOG_ON_LOCALLY ) ;
add_initial_entry ( - 1 , " S-1-5-32-546 " , SID_NAME_WKN_GRP , " Guests " , " " , privilege_none , PR_ACCESS_FROM_NETWORK ) ;
add_initial_entry ( - 1 , " S-1-5-32-547 " , SID_NAME_WKN_GRP , " Power Users " , " " , privilege_none , PR_ACCESS_FROM_NETWORK | PR_LOG_ON_LOCALLY ) ;
2002-01-29 04:01:14 +03:00
2003-05-12 22:12:31 +04:00
add_initial_entry ( - 1 , " S-1-5-32-548 " , SID_NAME_WKN_GRP , " Account Operators " , " " , privilege_none , PR_ACCESS_FROM_NETWORK | PR_LOG_ON_LOCALLY ) ;
add_initial_entry ( - 1 , " S-1-5-32-549 " , SID_NAME_WKN_GRP , " System Operators " , " " , privilege_none , PR_ACCESS_FROM_NETWORK | PR_LOG_ON_LOCALLY ) ;
add_initial_entry ( - 1 , " S-1-5-32-550 " , SID_NAME_WKN_GRP , " Print Operators " , " " , privilege_print_op , PR_ACCESS_FROM_NETWORK | PR_LOG_ON_LOCALLY ) ;
add_initial_entry ( - 1 , " S-1-5-32-551 " , SID_NAME_WKN_GRP , " Backup Operators " , " " , privilege_none , PR_ACCESS_FROM_NETWORK | PR_LOG_ON_LOCALLY ) ;
2002-01-29 04:01:14 +03:00
2003-05-12 22:12:31 +04:00
add_initial_entry ( - 1 , " S-1-5-32-552 " , SID_NAME_WKN_GRP , " Replicators " , " " , privilege_none , PR_ACCESS_FROM_NETWORK ) ;
2002-01-29 04:01:14 +03:00
/* Add the defaults domain groups */
2002-07-15 14:35:28 +04:00
sid_copy ( & sid_admins , get_global_sam_sid ( ) ) ;
2002-01-29 04:01:14 +03:00
sid_append_rid ( & sid_admins , DOMAIN_GROUP_RID_ADMINS ) ;
sid_to_string ( str_admins , & sid_admins ) ;
add_initial_entry ( - 1 , str_admins , SID_NAME_DOM_GRP , " Domain Admins " , " " , privilege_all , PR_ACCESS_FROM_NETWORK | PR_LOG_ON_LOCALLY ) ;
2002-07-15 14:35:28 +04:00
sid_copy ( & sid_users , get_global_sam_sid ( ) ) ;
2002-01-29 04:01:14 +03:00
sid_append_rid ( & sid_users , DOMAIN_GROUP_RID_USERS ) ;
sid_to_string ( str_users , & sid_users ) ;
add_initial_entry ( - 1 , str_users , SID_NAME_DOM_GRP , " Domain Users " , " " , privilege_none , PR_ACCESS_FROM_NETWORK | PR_LOG_ON_LOCALLY ) ;
2002-07-15 14:35:28 +04:00
sid_copy ( & sid_guests , get_global_sam_sid ( ) ) ;
2002-01-29 04:01:14 +03:00
sid_append_rid ( & sid_guests , DOMAIN_GROUP_RID_GUESTS ) ;
sid_to_string ( str_guests , & sid_guests ) ;
add_initial_entry ( - 1 , str_guests , SID_NAME_DOM_GRP , " Domain Guests " , " " , privilege_none , PR_ACCESS_FROM_NETWORK ) ;
return True ;
}
2001-03-23 03:50:31 +03:00
/****************************************************************************
2002-01-09 07:13:30 +03:00
Open the group mapping tdb .
2001-03-23 03:50:31 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-01-09 07:13:30 +03:00
2002-01-29 04:01:14 +03:00
static BOOL init_group_mapping ( void )
2001-03-23 03:50:31 +03:00
{
static pid_t local_pid ;
2003-01-03 11:28:12 +03:00
const char * vstring = " INFO/version " ;
2002-01-09 07:13:30 +03:00
int32 vers_id ;
if ( tdb & & local_pid = = sys_getpid ( ) )
return True ;
2001-09-07 02:08:19 +04:00
tdb = tdb_open_log ( lock_path ( " group_mapping.tdb " ) , 0 , TDB_DEFAULT , O_RDWR | O_CREAT , 0600 ) ;
2001-03-23 03:50:31 +03:00
if ( ! tdb ) {
DEBUG ( 0 , ( " Failed to open group mapping database \n " ) ) ;
return False ;
}
local_pid = sys_getpid ( ) ;
/* handle a Samba upgrade */
2002-10-05 02:53:18 +04:00
tdb_lock_bystring ( tdb , vstring , 0 ) ;
2002-01-09 07:13:30 +03:00
/* Cope with byte-reversed older versions of the db. */
vers_id = tdb_fetch_int32 ( tdb , vstring ) ;
2002-01-09 08:24:07 +03:00
if ( ( vers_id = = DATABASE_VERSION_V1 ) | | ( IREV ( vers_id ) = = DATABASE_VERSION_V1 ) ) {
2002-01-09 07:13:30 +03:00
/* Written on a bigendian machine with old fetch_int code. Save as le. */
2002-01-09 08:24:07 +03:00
tdb_store_int32 ( tdb , vstring , DATABASE_VERSION_V2 ) ;
vers_id = DATABASE_VERSION_V2 ;
2002-01-09 07:13:30 +03:00
}
2002-01-09 08:24:07 +03:00
if ( vers_id ! = DATABASE_VERSION_V2 ) {
2002-01-04 01:48:48 +03:00
tdb_traverse ( tdb , tdb_traverse_delete_fn , NULL ) ;
2002-01-09 08:24:07 +03:00
tdb_store_int32 ( tdb , vstring , DATABASE_VERSION_V2 ) ;
2001-03-23 03:50:31 +03:00
}
2002-01-09 07:13:30 +03:00
2001-03-23 03:50:31 +03:00
tdb_unlock_bystring ( tdb , vstring ) ;
2001-12-03 20:14:23 +03:00
/* write a list of default groups */
if ( ! default_group_mapping ( ) )
return False ;
2001-03-23 03:50:31 +03:00
return True ;
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-03-23 14:45:01 +03:00
static BOOL add_mapping_entry ( GROUP_MAP * map , int flag )
2001-03-23 03:50:31 +03:00
{
TDB_DATA kbuf , dbuf ;
pstring key , buf ;
2001-07-09 22:17:00 +04:00
fstring string_sid = " " ;
2001-03-23 03:50:31 +03:00
int len ;
2001-11-23 18:11:22 +03:00
int i ;
2001-11-29 19:05:05 +03:00
PRIVILEGE_SET * set ;
2001-12-03 03:00:43 +03:00
2002-01-27 13:53:43 +03:00
if ( ! init_group_mapping ( ) ) {
DEBUG ( 0 , ( " failed to initialize group mapping " ) ) ;
return ( False ) ;
}
2001-03-23 03:50:31 +03:00
sid_to_string ( string_sid , & map - > sid ) ;
2001-11-29 19:05:05 +03:00
len = tdb_pack ( buf , sizeof ( buf ) , " ddffd " ,
map - > gid , map - > sid_name_use , map - > nt_name , map - > comment , map - > systemaccount ) ;
2001-11-23 18:11:22 +03:00
2001-11-29 19:05:05 +03:00
/* write the privilege list in the TDB database */
2001-03-23 03:50:31 +03:00
2001-11-29 19:05:05 +03:00
set = & map - > priv_set ;
len + = tdb_pack ( buf + len , sizeof ( buf ) - len , " d " , set - > count ) ;
for ( i = 0 ; i < set - > count ; i + + )
len + = tdb_pack ( buf + len , sizeof ( buf ) - len , " ddd " ,
set - > set [ i ] . luid . low , set - > set [ i ] . luid . high , set - > set [ i ] . attr ) ;
if ( len > sizeof ( buf ) )
return False ;
2001-03-23 03:50:31 +03:00
slprintf ( key , sizeof ( key ) , " %s%s " , GROUP_PREFIX , string_sid ) ;
kbuf . dsize = strlen ( key ) + 1 ;
kbuf . dptr = key ;
dbuf . dsize = len ;
dbuf . dptr = buf ;
if ( tdb_store ( tdb , kbuf , dbuf , flag ) ! = 0 ) return False ;
return True ;
}
/****************************************************************************
initialise first time the mapping list
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-01-03 11:28:12 +03:00
BOOL add_initial_entry ( gid_t gid , const char * sid , enum SID_NAME_USE sid_name_use ,
const char * nt_name , const char * comment , PRIVILEGE_SET priv_set , uint32 systemaccount )
2001-03-23 03:50:31 +03:00
{
GROUP_MAP map ;
2002-01-29 04:01:14 +03:00
if ( ! init_group_mapping ( ) ) {
DEBUG ( 0 , ( " failed to initialize group mapping " ) ) ;
return ( False ) ;
}
2001-03-23 03:50:31 +03:00
map . gid = gid ;
2003-02-18 10:05:02 +03:00
if ( ! string_to_sid ( & map . sid , sid ) ) {
DEBUG ( 0 , ( " string_to_sid failed: %s " , sid ) ) ;
return False ;
}
2001-03-23 03:50:31 +03:00
map . sid_name_use = sid_name_use ;
fstrcpy ( map . nt_name , nt_name ) ;
fstrcpy ( map . comment , comment ) ;
2001-11-29 19:05:05 +03:00
map . systemaccount = systemaccount ;
map . priv_set . count = priv_set . count ;
map . priv_set . set = priv_set . set ;
2001-03-23 03:50:31 +03:00
2002-11-02 06:47:48 +03:00
pdb_add_group_mapping_entry ( & map ) ;
2001-03-23 03:50:31 +03:00
return True ;
}
2001-11-23 18:11:22 +03:00
/****************************************************************************
initialise a privilege list
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-29 19:05:05 +03:00
void init_privilege ( PRIVILEGE_SET * priv_set )
2001-11-23 18:11:22 +03:00
{
2001-11-29 19:05:05 +03:00
priv_set - > count = 0 ;
priv_set - > control = 0 ;
priv_set - > set = NULL ;
}
2001-11-23 18:11:22 +03:00
2001-11-29 19:05:05 +03:00
/****************************************************************************
free a privilege list
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL free_privilege ( PRIVILEGE_SET * priv_set )
{
if ( priv_set - > count = = 0 ) {
2001-12-05 00:53:47 +03:00
DEBUG ( 100 , ( " free_privilege: count=0, nothing to clear ? \n " ) ) ;
2001-11-29 19:05:05 +03:00
return False ;
}
if ( priv_set - > set = = NULL ) {
DEBUG ( 0 , ( " free_privilege: list ptr is NULL, very strange ! \n " ) ) ;
return False ;
}
safe_free ( priv_set - > set ) ;
priv_set - > count = 0 ;
priv_set - > control = 0 ;
priv_set - > set = NULL ;
2001-11-30 03:46:40 +03:00
return True ;
2001-11-23 18:11:22 +03:00
}
/****************************************************************************
add a privilege to a privilege array
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-29 19:05:05 +03:00
BOOL add_privilege ( PRIVILEGE_SET * priv_set , LUID_ATTR set )
2001-11-23 18:11:22 +03:00
{
2001-11-29 19:05:05 +03:00
LUID_ATTR * new_set ;
2001-11-23 18:11:22 +03:00
2001-11-29 19:05:05 +03:00
/* check if the privilege is not already in the list */
if ( check_priv_in_privilege ( priv_set , set ) )
2001-11-23 18:11:22 +03:00
return False ;
2001-11-29 19:05:05 +03:00
/* we can allocate memory to add the new privilege */
new_set = ( LUID_ATTR * ) Realloc ( priv_set - > set , ( priv_set - > count + 1 ) * ( sizeof ( LUID_ATTR ) ) ) ;
if ( new_set = = NULL ) {
DEBUG ( 0 , ( " add_privilege: could not Realloc memory to add a new privilege \n " ) ) ;
2001-11-23 18:11:22 +03:00
return False ;
}
2001-11-29 19:05:05 +03:00
new_set [ priv_set - > count ] . luid . high = set . luid . high ;
new_set [ priv_set - > count ] . luid . low = set . luid . low ;
new_set [ priv_set - > count ] . attr = set . attr ;
priv_set - > count + + ;
priv_set - > set = new_set ;
2001-11-23 18:11:22 +03:00
return True ;
}
/****************************************************************************
add all the privileges to a privilege array
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-29 19:05:05 +03:00
BOOL add_all_privilege ( PRIVILEGE_SET * priv_set )
2001-11-23 18:11:22 +03:00
{
2001-11-29 19:05:05 +03:00
LUID_ATTR set ;
set . attr = 0 ;
set . luid . high = 0 ;
set . luid . low = SE_PRIV_ADD_USERS ;
add_privilege ( priv_set , set ) ;
set . luid . low = SE_PRIV_ADD_MACHINES ;
add_privilege ( priv_set , set ) ;
set . luid . low = SE_PRIV_PRINT_OPERATOR ;
add_privilege ( priv_set , set ) ;
2001-11-24 17:16:41 +03:00
return True ;
2001-11-23 18:11:22 +03:00
}
/****************************************************************************
check if the privilege list is empty
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-29 19:05:05 +03:00
BOOL check_empty_privilege ( PRIVILEGE_SET * priv_set )
2001-11-23 18:11:22 +03:00
{
2002-01-29 04:01:14 +03:00
return ( priv_set - > count = = 0 ) ;
2001-11-23 18:11:22 +03:00
}
/****************************************************************************
check if the privilege is in the privilege list
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-29 19:05:05 +03:00
BOOL check_priv_in_privilege ( PRIVILEGE_SET * priv_set , LUID_ATTR set )
2001-11-23 18:11:22 +03:00
{
int i ;
2001-11-29 19:05:05 +03:00
/* if the list is empty, obviously we can't have it */
if ( check_empty_privilege ( priv_set ) )
return False ;
for ( i = 0 ; i < priv_set - > count ; i + + ) {
LUID_ATTR * cur_set ;
cur_set = & priv_set - > set [ i ] ;
/* check only the low and high part. Checking the attr field has no meaning */
if ( ( cur_set - > luid . low = = set . luid . low ) & & ( cur_set - > luid . high = = set . luid . high ) )
2001-11-23 18:11:22 +03:00
return True ;
2001-11-29 19:05:05 +03:00
}
2001-11-23 18:11:22 +03:00
return False ;
}
2001-11-29 19:05:05 +03:00
/****************************************************************************
2002-09-25 19:19:00 +04:00
remove a privilege from a privilege array
2001-11-29 19:05:05 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL remove_privilege ( PRIVILEGE_SET * priv_set , LUID_ATTR set )
{
LUID_ATTR * new_set ;
LUID_ATTR * old_set ;
int i , j ;
/* check if the privilege is in the list */
if ( ! check_priv_in_privilege ( priv_set , set ) )
return False ;
/* special case if it's the only privilege in the list */
if ( priv_set - > count = = 1 ) {
free_privilege ( priv_set ) ;
init_privilege ( priv_set ) ;
return True ;
}
/*
* the privilege is there , create a new list ,
* and copy the other privileges
*/
old_set = priv_set - > set ;
new_set = ( LUID_ATTR * ) malloc ( ( priv_set - > count - 1 ) * ( sizeof ( LUID_ATTR ) ) ) ;
if ( new_set = = NULL ) {
DEBUG ( 0 , ( " remove_privilege: could not malloc memory for new privilege list \n " ) ) ;
return False ;
}
for ( i = 0 , j = 0 ; i < priv_set - > count ; i + + ) {
if ( ( old_set [ i ] . luid . low = = set . luid . low ) & &
( old_set [ i ] . luid . high = = set . luid . high ) ) {
continue ;
}
new_set [ j ] . luid . low = old_set [ i ] . luid . low ;
new_set [ j ] . luid . high = old_set [ i ] . luid . high ;
new_set [ j ] . attr = old_set [ i ] . attr ;
j + + ;
}
if ( j ! = priv_set - > count - 1 ) {
DEBUG ( 0 , ( " remove_privilege: mismatch ! difference is not -1 \n " ) ) ;
DEBUGADD ( 0 , ( " old count:%d, new count:%d \n " , priv_set - > count , j ) ) ;
safe_free ( new_set ) ;
return False ;
}
/* ok everything is fine */
priv_set - > count - - ;
priv_set - > set = new_set ;
safe_free ( old_set ) ;
return True ;
}
2001-03-23 03:50:31 +03:00
/****************************************************************************
2002-11-23 05:52:36 +03:00
Return the sid and the type of the unix group .
2001-03-23 03:50:31 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-23 05:52:36 +03:00
2003-03-23 14:45:01 +03:00
static BOOL get_group_map_from_sid ( DOM_SID sid , GROUP_MAP * map , BOOL with_priv )
2001-03-23 03:50:31 +03:00
{
TDB_DATA kbuf , dbuf ;
pstring key ;
fstring string_sid ;
int ret ;
2001-11-23 18:11:22 +03:00
int i ;
2001-11-29 19:05:05 +03:00
PRIVILEGE_SET * set ;
2001-03-23 03:50:31 +03:00
2002-01-27 13:53:43 +03:00
if ( ! init_group_mapping ( ) ) {
DEBUG ( 0 , ( " failed to initialize group mapping " ) ) ;
return ( False ) ;
}
2001-12-03 03:00:43 +03:00
2001-03-23 03:50:31 +03:00
/* the key is the SID, retrieving is direct */
sid_to_string ( string_sid , & sid ) ;
slprintf ( key , sizeof ( key ) , " %s%s " , GROUP_PREFIX , string_sid ) ;
kbuf . dptr = key ;
kbuf . dsize = strlen ( key ) + 1 ;
dbuf = tdb_fetch ( tdb , kbuf ) ;
2002-11-23 05:52:36 +03:00
if ( ! dbuf . dptr )
return False ;
2001-03-23 03:50:31 +03:00
2001-11-29 19:05:05 +03:00
ret = tdb_unpack ( dbuf . dptr , dbuf . dsize , " ddffd " ,
& map - > gid , & map - > sid_name_use , & map - > nt_name , & map - > comment , & map - > systemaccount ) ;
set = & map - > priv_set ;
init_privilege ( set ) ;
ret + = tdb_unpack ( dbuf . dptr + ret , dbuf . dsize - ret , " d " , & set - > count ) ;
DEBUG ( 10 , ( " get_group_map_from_sid: %d privileges \n " , map - > priv_set . count ) ) ;
2002-01-13 14:46:04 +03:00
set - > set = NULL ;
if ( set - > count ) {
set - > set = ( LUID_ATTR * ) smb_xmalloc ( set - > count * sizeof ( LUID_ATTR ) ) ;
2001-11-29 19:05:05 +03:00
}
2001-11-23 18:11:22 +03:00
2001-11-29 19:05:05 +03:00
for ( i = 0 ; i < set - > count ; i + + )
ret + = tdb_unpack ( dbuf . dptr + ret , dbuf . dsize - ret , " ddd " ,
& ( set - > set [ i ] . luid . low ) , & ( set - > set [ i ] . luid . high ) , & ( set - > set [ i ] . attr ) ) ;
2001-03-23 03:50:31 +03:00
2001-09-17 04:58:15 +04:00
SAFE_FREE ( dbuf . dptr ) ;
2001-03-23 03:50:31 +03:00
if ( ret ! = dbuf . dsize ) {
2001-11-23 18:11:22 +03:00
DEBUG ( 0 , ( " get_group_map_from_sid: group mapping TDB corrupted ? \n " ) ) ;
2001-11-29 19:05:05 +03:00
free_privilege ( set ) ;
2001-03-23 03:50:31 +03:00
return False ;
}
2001-12-05 00:53:47 +03:00
/* we don't want the privileges */
if ( with_priv = = MAPPING_WITHOUT_PRIV )
free_privilege ( set ) ;
2001-03-23 03:50:31 +03:00
sid_copy ( & map - > sid , & sid ) ;
return True ;
}
/****************************************************************************
2002-11-23 05:52:36 +03:00
Return the sid and the type of the unix group .
2001-03-23 03:50:31 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-23 05:52:36 +03:00
2003-03-23 14:45:01 +03:00
static BOOL get_group_map_from_gid ( gid_t gid , GROUP_MAP * map , BOOL with_priv )
2001-03-23 03:50:31 +03:00
{
TDB_DATA kbuf , dbuf , newkey ;
fstring string_sid ;
int ret ;
2001-11-23 18:11:22 +03:00
int i ;
2001-11-29 19:05:05 +03:00
PRIVILEGE_SET * set ;
2001-03-23 03:50:31 +03:00
2002-01-27 13:53:43 +03:00
if ( ! init_group_mapping ( ) ) {
DEBUG ( 0 , ( " failed to initialize group mapping " ) ) ;
return ( False ) ;
}
2001-12-03 03:00:43 +03:00
2001-03-23 03:50:31 +03:00
/* we need to enumerate the TDB to find the GID */
for ( kbuf = tdb_firstkey ( tdb ) ;
kbuf . dptr ;
2001-09-17 08:16:35 +04:00
newkey = tdb_nextkey ( tdb , kbuf ) , safe_free ( kbuf . dptr ) , kbuf = newkey ) {
2001-03-23 03:50:31 +03:00
if ( strncmp ( kbuf . dptr , GROUP_PREFIX , strlen ( GROUP_PREFIX ) ) ! = 0 ) continue ;
dbuf = tdb_fetch ( tdb , kbuf ) ;
2002-11-23 05:52:36 +03:00
if ( ! dbuf . dptr )
continue ;
2001-03-23 03:50:31 +03:00
fstrcpy ( string_sid , kbuf . dptr + strlen ( GROUP_PREFIX ) ) ;
string_to_sid ( & map - > sid , string_sid ) ;
2001-11-29 19:05:05 +03:00
ret = tdb_unpack ( dbuf . dptr , dbuf . dsize , " ddffd " ,
& map - > gid , & map - > sid_name_use , & map - > nt_name , & map - > comment , & map - > systemaccount ) ;
2001-11-23 18:11:22 +03:00
2001-11-29 19:05:05 +03:00
set = & map - > priv_set ;
ret + = tdb_unpack ( dbuf . dptr + ret , dbuf . dsize - ret , " d " , & set - > count ) ;
2002-01-13 14:46:04 +03:00
set - > set = NULL ;
if ( set - > count ) {
set - > set = ( LUID_ATTR * ) smb_xmalloc ( set - > count * sizeof ( LUID_ATTR ) ) ;
2001-11-29 19:05:05 +03:00
}
for ( i = 0 ; i < set - > count ; i + + )
ret + = tdb_unpack ( dbuf . dptr + ret , dbuf . dsize - ret , " ddd " ,
& ( set - > set [ i ] . luid . low ) , & ( set - > set [ i ] . luid . high ) , & ( set - > set [ i ] . attr ) ) ;
2001-03-23 03:50:31 +03:00
2001-09-17 04:58:15 +04:00
SAFE_FREE ( dbuf . dptr ) ;
2001-11-29 19:05:05 +03:00
if ( ret ! = dbuf . dsize ) {
free_privilege ( set ) ;
continue ;
}
2001-03-23 03:50:31 +03:00
2001-12-05 00:53:47 +03:00
if ( gid = = map - > gid ) {
if ( ! with_priv )
free_privilege ( & map - > priv_set ) ;
2001-03-23 03:50:31 +03:00
return True ;
2001-12-05 00:53:47 +03:00
}
2001-11-29 19:05:05 +03:00
free_privilege ( set ) ;
2001-03-23 03:50:31 +03:00
}
return False ;
}
/****************************************************************************
2002-11-23 05:52:36 +03:00
Return the sid and the type of the unix group .
2001-03-23 03:50:31 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-23 05:52:36 +03:00
2003-03-23 14:45:01 +03:00
static BOOL get_group_map_from_ntname ( char * name , GROUP_MAP * map , BOOL with_priv )
2001-03-23 03:50:31 +03:00
{
TDB_DATA kbuf , dbuf , newkey ;
fstring string_sid ;
int ret ;
2001-11-23 18:11:22 +03:00
int i ;
2001-11-29 19:05:05 +03:00
PRIVILEGE_SET * set ;
2001-03-23 03:50:31 +03:00
2002-01-27 13:53:43 +03:00
if ( ! init_group_mapping ( ) ) {
2002-07-15 14:35:28 +04:00
DEBUG ( 0 , ( " get_group_map_from_ntname:failed to initialize group mapping " ) ) ;
2002-01-27 13:53:43 +03:00
return ( False ) ;
}
2001-12-03 03:00:43 +03:00
2001-11-29 19:05:05 +03:00
/* we need to enumerate the TDB to find the name */
2001-03-23 03:50:31 +03:00
for ( kbuf = tdb_firstkey ( tdb ) ;
kbuf . dptr ;
2001-09-17 08:16:35 +04:00
newkey = tdb_nextkey ( tdb , kbuf ) , safe_free ( kbuf . dptr ) , kbuf = newkey ) {
2001-03-23 03:50:31 +03:00
if ( strncmp ( kbuf . dptr , GROUP_PREFIX , strlen ( GROUP_PREFIX ) ) ! = 0 ) continue ;
dbuf = tdb_fetch ( tdb , kbuf ) ;
2002-11-23 05:52:36 +03:00
if ( ! dbuf . dptr )
continue ;
2001-03-23 03:50:31 +03:00
fstrcpy ( string_sid , kbuf . dptr + strlen ( GROUP_PREFIX ) ) ;
string_to_sid ( & map - > sid , string_sid ) ;
2001-11-29 19:05:05 +03:00
ret = tdb_unpack ( dbuf . dptr , dbuf . dsize , " ddffd " ,
& map - > gid , & map - > sid_name_use , & map - > nt_name , & map - > comment , & map - > systemaccount ) ;
set = & map - > priv_set ;
ret + = tdb_unpack ( dbuf . dptr + ret , dbuf . dsize - ret , " d " , & set - > count ) ;
set - > set = ( LUID_ATTR * ) malloc ( set - > count * sizeof ( LUID_ATTR ) ) ;
if ( set - > set = = NULL ) {
2001-12-05 00:53:47 +03:00
DEBUG ( 0 , ( " get_group_map_from_ntname: could not allocate memory for privileges \n " ) ) ;
2001-11-29 19:05:05 +03:00
return False ;
}
2001-11-23 18:11:22 +03:00
2001-11-29 19:05:05 +03:00
for ( i = 0 ; i < set - > count ; i + + )
ret + = tdb_unpack ( dbuf . dptr + ret , dbuf . dsize - ret , " ddd " ,
& ( set - > set [ i ] . luid . low ) , & ( set - > set [ i ] . luid . high ) , & ( set - > set [ i ] . attr ) ) ;
2001-03-23 03:50:31 +03:00
2001-09-17 04:58:15 +04:00
SAFE_FREE ( dbuf . dptr ) ;
2001-11-29 19:05:05 +03:00
if ( ret ! = dbuf . dsize ) {
free_privilege ( set ) ;
continue ;
}
2001-03-23 03:50:31 +03:00
2001-12-05 00:53:47 +03:00
if ( StrCaseCmp ( name , map - > nt_name ) = = 0 ) {
if ( ! with_priv )
free_privilege ( & map - > priv_set ) ;
2001-03-23 03:50:31 +03:00
return True ;
2001-12-05 00:53:47 +03:00
}
2001-03-23 03:50:31 +03:00
2001-11-29 19:05:05 +03:00
free_privilege ( set ) ;
2001-03-23 03:50:31 +03:00
}
return False ;
}
/****************************************************************************
2002-11-23 05:52:36 +03:00
Remove a group mapping entry .
2001-03-23 03:50:31 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-23 05:52:36 +03:00
2003-03-23 14:45:01 +03:00
static BOOL group_map_remove ( DOM_SID sid )
2001-03-23 03:50:31 +03:00
{
TDB_DATA kbuf , dbuf ;
pstring key ;
fstring string_sid ;
2002-01-27 13:53:43 +03:00
if ( ! init_group_mapping ( ) ) {
DEBUG ( 0 , ( " failed to initialize group mapping " ) ) ;
return ( False ) ;
}
2001-12-03 03:00:43 +03:00
2001-03-23 03:50:31 +03:00
/* the key is the SID, retrieving is direct */
sid_to_string ( string_sid , & sid ) ;
slprintf ( key , sizeof ( key ) , " %s%s " , GROUP_PREFIX , string_sid ) ;
kbuf . dptr = key ;
kbuf . dsize = strlen ( key ) + 1 ;
dbuf = tdb_fetch ( tdb , kbuf ) ;
2002-11-23 05:52:36 +03:00
if ( ! dbuf . dptr )
return False ;
2001-03-23 03:50:31 +03:00
2001-09-17 04:58:15 +04:00
SAFE_FREE ( dbuf . dptr ) ;
2001-03-23 03:50:31 +03:00
if ( tdb_delete ( tdb , kbuf ) ! = TDB_SUCCESS )
return False ;
return True ;
}
/****************************************************************************
2002-11-23 05:52:36 +03:00
Enumerate the group mapping .
2001-03-23 03:50:31 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-23 05:52:36 +03:00
2003-03-23 14:45:01 +03:00
static BOOL enum_group_mapping ( enum SID_NAME_USE sid_name_use , GROUP_MAP * * rmap ,
2001-12-05 00:53:47 +03:00
int * num_entries , BOOL unix_only , BOOL with_priv )
2001-03-23 03:50:31 +03:00
{
TDB_DATA kbuf , dbuf , newkey ;
fstring string_sid ;
fstring group_type ;
GROUP_MAP map ;
2001-08-12 21:30:01 +04:00
GROUP_MAP * mapt ;
2001-03-23 03:50:31 +03:00
int ret ;
int entries = 0 ;
2001-11-23 18:11:22 +03:00
int i ;
2001-11-29 19:05:05 +03:00
PRIVILEGE_SET * set ;
2001-03-23 03:50:31 +03:00
2002-01-27 13:53:43 +03:00
if ( ! init_group_mapping ( ) ) {
DEBUG ( 0 , ( " failed to initialize group mapping " ) ) ;
return ( False ) ;
}
2001-12-03 03:00:43 +03:00
2001-03-23 03:50:31 +03:00
* num_entries = 0 ;
* rmap = NULL ;
for ( kbuf = tdb_firstkey ( tdb ) ;
kbuf . dptr ;
2001-09-17 08:16:35 +04:00
newkey = tdb_nextkey ( tdb , kbuf ) , safe_free ( kbuf . dptr ) , kbuf = newkey ) {
2001-03-23 03:50:31 +03:00
2001-05-04 19:44:27 +04:00
if ( strncmp ( kbuf . dptr , GROUP_PREFIX , strlen ( GROUP_PREFIX ) ) ! = 0 )
continue ;
2003-05-12 22:12:31 +04:00
2001-03-23 03:50:31 +03:00
dbuf = tdb_fetch ( tdb , kbuf ) ;
2001-05-04 19:44:27 +04:00
if ( ! dbuf . dptr )
continue ;
2001-03-23 03:50:31 +03:00
fstrcpy ( string_sid , kbuf . dptr + strlen ( GROUP_PREFIX ) ) ;
2001-11-29 19:05:05 +03:00
ret = tdb_unpack ( dbuf . dptr , dbuf . dsize , " ddffd " ,
& map . gid , & map . sid_name_use , & map . nt_name , & map . comment , & map . systemaccount ) ;
set = & map . priv_set ;
init_privilege ( set ) ;
ret + = tdb_unpack ( dbuf . dptr + ret , dbuf . dsize - ret , " d " , & set - > count ) ;
if ( set - > count ! = 0 ) {
set - > set = ( LUID_ATTR * ) malloc ( set - > count * sizeof ( LUID_ATTR ) ) ;
if ( set - > set = = NULL ) {
DEBUG ( 0 , ( " enum_group_mapping: could not allocate memory for privileges \n " ) ) ;
return False ;
}
}
2001-11-23 18:11:22 +03:00
2001-11-29 19:05:05 +03:00
for ( i = 0 ; i < set - > count ; i + + )
ret + = tdb_unpack ( dbuf . dptr + ret , dbuf . dsize - ret , " ddd " ,
& ( set - > set [ i ] . luid . low ) , & ( set - > set [ i ] . luid . high ) , & ( set - > set [ i ] . attr ) ) ;
2001-03-23 03:50:31 +03:00
2001-09-17 04:58:15 +04:00
SAFE_FREE ( dbuf . dptr ) ;
2001-11-29 19:05:05 +03:00
if ( ret ! = dbuf . dsize ) {
2001-12-05 00:53:47 +03:00
DEBUG ( 11 , ( " enum_group_mapping: error in memory size \n " ) ) ;
2001-11-29 19:05:05 +03:00
free_privilege ( set ) ;
2001-05-04 19:44:27 +04:00
continue ;
2001-11-29 19:05:05 +03:00
}
2001-03-23 03:50:31 +03:00
/* list only the type or everything if UNKNOWN */
2001-11-29 19:05:05 +03:00
if ( sid_name_use ! = SID_NAME_UNKNOWN & & sid_name_use ! = map . sid_name_use ) {
2001-12-05 00:53:47 +03:00
DEBUG ( 11 , ( " enum_group_mapping: group %s is not of the requested type \n " , map . nt_name ) ) ;
2001-11-29 19:05:05 +03:00
free_privilege ( set ) ;
2001-05-04 19:44:27 +04:00
continue ;
2001-11-29 19:05:05 +03:00
}
2003-05-12 22:12:31 +04:00
2001-11-29 19:05:05 +03:00
if ( unix_only = = ENUM_ONLY_MAPPED & & map . gid = = - 1 ) {
2001-12-05 00:53:47 +03:00
DEBUG ( 11 , ( " enum_group_mapping: group %s is non mapped \n " , map . nt_name ) ) ;
2001-11-29 19:05:05 +03:00
free_privilege ( set ) ;
2001-05-04 19:44:27 +04:00
continue ;
2001-11-29 19:05:05 +03:00
}
2001-03-23 03:50:31 +03:00
string_to_sid ( & map . sid , string_sid ) ;
decode_sid_name_use ( group_type , map . sid_name_use ) ;
2001-12-05 00:53:47 +03:00
DEBUG ( 11 , ( " enum_group_mapping: returning group %s of type %s \n " , map . nt_name , group_type ) ) ;
2001-03-23 03:50:31 +03:00
2001-08-12 21:30:01 +04:00
mapt = ( GROUP_MAP * ) Realloc ( ( * rmap ) , ( entries + 1 ) * sizeof ( GROUP_MAP ) ) ;
if ( ! mapt ) {
DEBUG ( 0 , ( " enum_group_mapping: Unable to enlarge group map! \n " ) ) ;
2001-09-17 04:58:15 +04:00
SAFE_FREE ( * rmap ) ;
2001-11-29 19:05:05 +03:00
free_privilege ( set ) ;
2001-08-12 21:30:01 +04:00
return False ;
}
2001-11-29 19:05:05 +03:00
else
( * rmap ) = mapt ;
2001-03-23 03:50:31 +03:00
mapt [ entries ] . gid = map . gid ;
sid_copy ( & mapt [ entries ] . sid , & map . sid ) ;
mapt [ entries ] . sid_name_use = map . sid_name_use ;
fstrcpy ( mapt [ entries ] . nt_name , map . nt_name ) ;
fstrcpy ( mapt [ entries ] . comment , map . comment ) ;
2001-11-29 19:05:05 +03:00
mapt [ entries ] . systemaccount = map . systemaccount ;
mapt [ entries ] . priv_set . count = set - > count ;
mapt [ entries ] . priv_set . control = set - > control ;
mapt [ entries ] . priv_set . set = set - > set ;
2001-12-05 00:53:47 +03:00
if ( ! with_priv )
free_privilege ( & ( mapt [ entries ] . priv_set ) ) ;
2001-03-23 03:50:31 +03:00
entries + + ;
2003-05-12 22:12:31 +04:00
2001-03-23 03:50:31 +03:00
}
* num_entries = entries ;
2003-03-22 12:03:46 +03:00
2001-03-23 03:50:31 +03:00
return True ;
}
/****************************************************************************
2001-11-23 18:11:22 +03:00
convert a privilege string to a privilege array
2001-03-23 03:50:31 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-29 19:05:05 +03:00
void convert_priv_from_text ( PRIVILEGE_SET * se_priv , char * privilege )
2001-03-23 03:50:31 +03:00
{
pstring tok ;
2002-11-13 02:20:50 +03:00
const char * p = privilege ;
2001-03-23 03:50:31 +03:00
int i ;
2001-11-29 19:05:05 +03:00
LUID_ATTR set ;
2001-03-23 03:50:31 +03:00
/* By default no privilege */
2001-11-23 18:11:22 +03:00
init_privilege ( se_priv ) ;
2001-03-23 03:50:31 +03:00
if ( privilege = = NULL )
return ;
while ( next_token ( & p , tok , " " , sizeof ( tok ) ) ) {
for ( i = 0 ; i < = PRIV_ALL_INDEX ; i + + ) {
2001-11-29 19:05:05 +03:00
if ( StrCaseCmp ( privs [ i ] . priv , tok ) = = 0 ) {
set . attr = 0 ;
set . luid . high = 0 ;
set . luid . low = privs [ i ] . se_priv ;
add_privilege ( se_priv , set ) ;
}
2001-03-23 03:50:31 +03:00
}
}
}
/****************************************************************************
2001-11-23 18:11:22 +03:00
convert a privilege array to a privilege string
2001-03-23 03:50:31 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-29 19:05:05 +03:00
void convert_priv_to_text ( PRIVILEGE_SET * se_priv , char * privilege )
2001-03-23 03:50:31 +03:00
{
2001-11-29 19:05:05 +03:00
int i , j ;
2001-03-23 03:50:31 +03:00
if ( privilege = = NULL )
return ;
ZERO_STRUCTP ( privilege ) ;
2001-11-23 18:11:22 +03:00
if ( check_empty_privilege ( se_priv ) ) {
fstrcat ( privilege , " No privilege " ) ;
2001-03-23 03:50:31 +03:00
return ;
}
2001-11-29 19:05:05 +03:00
for ( i = 0 ; i < se_priv - > count ; i + + ) {
2001-11-23 18:11:22 +03:00
j = 1 ;
2001-11-29 19:05:05 +03:00
while ( privs [ j ] . se_priv ! = se_priv - > set [ i ] . luid . low & & j < = PRIV_ALL_INDEX ) {
2001-11-23 18:11:22 +03:00
j + + ;
2001-11-29 19:05:05 +03:00
}
2001-03-23 03:50:31 +03:00
2001-11-23 18:11:22 +03:00
fstrcat ( privilege , privs [ j ] . priv ) ;
fstrcat ( privilege , " " ) ;
2001-03-23 03:50:31 +03:00
}
}
/*
*
* High level functions
* better to use them than the lower ones .
*
* we are checking if the group is in the mapping file
* and if the group is an existing unix group
*
*/
/* get a domain group from it's SID */
2001-12-05 00:53:47 +03:00
BOOL get_domain_group_from_sid ( DOM_SID sid , GROUP_MAP * map , BOOL with_priv )
2001-03-23 03:50:31 +03:00
{
struct group * grp ;
2002-01-29 04:01:14 +03:00
if ( ! init_group_mapping ( ) ) {
DEBUG ( 0 , ( " failed to initialize group mapping " ) ) ;
return ( False ) ;
}
2001-05-04 19:44:27 +04:00
DEBUG ( 10 , ( " get_domain_group_from_sid \n " ) ) ;
2001-03-23 03:50:31 +03:00
/* if the group is NOT in the database, it CAN NOT be a domain group */
2002-11-02 06:47:48 +03:00
if ( ! pdb_getgrsid ( map , sid , with_priv ) )
2001-03-23 03:50:31 +03:00
return False ;
2001-05-04 19:44:27 +04:00
DEBUG ( 10 , ( " get_domain_group_from_sid: SID found in the TDB \n " ) ) ;
2001-03-23 03:50:31 +03:00
/* if it's not a domain group, continue */
2001-12-05 00:53:47 +03:00
if ( map - > sid_name_use ! = SID_NAME_DOM_GRP ) {
if ( with_priv )
free_privilege ( & map - > priv_set ) ;
2001-03-23 03:50:31 +03:00
return False ;
2001-12-05 00:53:47 +03:00
}
2001-05-04 19:44:27 +04:00
DEBUG ( 10 , ( " get_domain_group_from_sid: SID is a domain group \n " ) ) ;
2001-03-23 03:50:31 +03:00
2001-12-05 00:53:47 +03:00
if ( map - > gid = = - 1 ) {
if ( with_priv )
free_privilege ( & map - > priv_set ) ;
2001-03-23 03:50:31 +03:00
return False ;
2001-12-05 00:53:47 +03:00
}
2001-03-23 03:50:31 +03:00
2001-05-04 19:44:27 +04:00
DEBUG ( 10 , ( " get_domain_group_from_sid: SID is mapped to gid:%d \n " , map - > gid ) ) ;
2001-12-02 02:56:05 +03:00
if ( ( grp = getgrgid ( map - > gid ) ) = = NULL ) {
DEBUG ( 10 , ( " get_domain_group_from_sid: gid DOESN'T exist in UNIX security \n " ) ) ;
2001-12-05 00:53:47 +03:00
if ( with_priv )
free_privilege ( & map - > priv_set ) ;
2001-05-04 19:44:27 +04:00
return False ;
2001-12-02 02:56:05 +03:00
}
2001-05-04 19:44:27 +04:00
DEBUG ( 10 , ( " get_domain_group_from_sid: gid exists in UNIX security \n " ) ) ;
2001-03-23 03:50:31 +03:00
return True ;
}
/* get a local (alias) group from it's SID */
2001-12-05 00:53:47 +03:00
BOOL get_local_group_from_sid ( DOM_SID sid , GROUP_MAP * map , BOOL with_priv )
2001-03-23 03:50:31 +03:00
{
struct group * grp ;
2002-01-29 04:01:14 +03:00
if ( ! init_group_mapping ( ) ) {
DEBUG ( 0 , ( " failed to initialize group mapping " ) ) ;
return ( False ) ;
}
2001-03-23 03:50:31 +03:00
/* The group is in the mapping table */
2002-11-02 06:47:48 +03:00
if ( pdb_getgrsid ( map , sid , with_priv ) ) {
2001-12-05 00:53:47 +03:00
if ( map - > sid_name_use ! = SID_NAME_ALIAS ) {
if ( with_priv )
free_privilege ( & map - > priv_set ) ;
2001-03-23 03:50:31 +03:00
return False ;
2001-12-05 00:53:47 +03:00
}
if ( map - > gid = = - 1 ) {
if ( with_priv )
free_privilege ( & map - > priv_set ) ;
2001-03-23 03:50:31 +03:00
return False ;
2001-12-05 00:53:47 +03:00
}
2001-03-23 03:50:31 +03:00
2001-12-05 00:53:47 +03:00
if ( ( grp = getgrgid ( map - > gid ) ) = = NULL ) {
if ( with_priv )
free_privilege ( & map - > priv_set ) ;
2001-03-23 03:50:31 +03:00
return False ;
2001-12-05 00:53:47 +03:00
}
2001-03-23 03:50:31 +03:00
} else {
/* the group isn't in the mapping table.
* make one based on the unix information */
uint32 alias_rid ;
2001-07-09 22:17:00 +04:00
sid_peek_rid ( & sid , & alias_rid ) ;
2001-12-02 02:56:05 +03:00
map - > gid = pdb_group_rid_to_gid ( alias_rid ) ;
2001-03-23 03:50:31 +03:00
if ( ( grp = getgrgid ( map - > gid ) ) = = NULL )
return False ;
map - > sid_name_use = SID_NAME_ALIAS ;
2001-11-29 19:05:05 +03:00
map - > systemaccount = PR_ACCESS_FROM_NETWORK ;
2001-03-23 03:50:31 +03:00
fstrcpy ( map - > nt_name , grp - > gr_name ) ;
fstrcpy ( map - > comment , " Local Unix Group " ) ;
2001-11-29 19:05:05 +03:00
init_privilege ( & map - > priv_set ) ;
2001-03-23 03:50:31 +03:00
2001-07-09 22:17:00 +04:00
sid_copy ( & map - > sid , & sid ) ;
2001-03-23 03:50:31 +03:00
}
return True ;
}
/* get a builtin group from it's SID */
2001-12-05 00:53:47 +03:00
BOOL get_builtin_group_from_sid ( DOM_SID sid , GROUP_MAP * map , BOOL with_priv )
2001-03-23 03:50:31 +03:00
{
struct group * grp ;
2002-01-29 04:01:14 +03:00
if ( ! init_group_mapping ( ) ) {
DEBUG ( 0 , ( " failed to initialize group mapping " ) ) ;
return ( False ) ;
}
2002-11-02 06:47:48 +03:00
if ( ! pdb_getgrsid ( map , sid , with_priv ) )
2001-03-23 03:50:31 +03:00
return False ;
2001-12-05 00:53:47 +03:00
if ( map - > sid_name_use ! = SID_NAME_WKN_GRP ) {
if ( with_priv )
free_privilege ( & map - > priv_set ) ;
2001-03-23 03:50:31 +03:00
return False ;
2001-12-05 00:53:47 +03:00
}
2001-03-23 03:50:31 +03:00
2001-12-05 00:53:47 +03:00
if ( map - > gid = = - 1 ) {
if ( with_priv )
free_privilege ( & map - > priv_set ) ;
2001-03-23 03:50:31 +03:00
return False ;
2001-12-05 00:53:47 +03:00
}
2001-03-23 03:50:31 +03:00
2001-12-05 00:53:47 +03:00
if ( ( grp = getgrgid ( map - > gid ) ) = = NULL ) {
if ( with_priv )
free_privilege ( & map - > priv_set ) ;
2001-03-23 03:50:31 +03:00
return False ;
2001-12-05 00:53:47 +03:00
}
2001-03-23 03:50:31 +03:00
return True ;
}
/****************************************************************************
Returns a GROUP_MAP struct based on the gid .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-12-05 00:53:47 +03:00
BOOL get_group_from_gid ( gid_t gid , GROUP_MAP * map , BOOL with_priv )
2001-03-23 03:50:31 +03:00
{
struct group * grp ;
2002-01-29 04:01:14 +03:00
if ( ! init_group_mapping ( ) ) {
DEBUG ( 0 , ( " failed to initialize group mapping " ) ) ;
return ( False ) ;
}
2001-03-23 03:50:31 +03:00
if ( ( grp = getgrgid ( gid ) ) = = NULL )
return False ;
/*
* make a group map from scratch if doesn ' t exist .
*/
2002-11-02 06:47:48 +03:00
if ( ! pdb_getgrgid ( map , gid , with_priv ) ) {
2001-03-23 03:50:31 +03:00
map - > gid = gid ;
map - > sid_name_use = SID_NAME_ALIAS ;
2001-11-29 19:05:05 +03:00
map - > systemaccount = PR_ACCESS_FROM_NETWORK ;
init_privilege ( & map - > priv_set ) ;
2001-03-23 03:50:31 +03:00
2001-12-02 02:56:05 +03:00
/* interim solution until we have a last RID allocated */
2002-07-15 14:35:28 +04:00
sid_copy ( & map - > sid , get_global_sam_sid ( ) ) ;
2001-05-04 19:44:27 +04:00
sid_append_rid ( & map - > sid , pdb_gid_to_group_rid ( gid ) ) ;
2001-03-23 03:50:31 +03:00
fstrcpy ( map - > nt_name , grp - > gr_name ) ;
fstrcpy ( map - > comment , " Local Unix Group " ) ;
}
return True ;
}
/****************************************************************************
Get the member users of a group and
all the users who have that group as primary .
give back an array of uid
return the grand number of users
TODO : sort the list and remove duplicate . JFM .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL get_uid_list_of_group ( gid_t gid , uid_t * * uid , int * num_uids )
{
struct group * grp ;
struct passwd * pwd ;
int i = 0 ;
char * gr ;
2001-08-12 21:30:01 +04:00
uid_t * u ;
2001-03-23 03:50:31 +03:00
2002-01-29 04:01:14 +03:00
if ( ! init_group_mapping ( ) ) {
DEBUG ( 0 , ( " failed to initialize group mapping " ) ) ;
return ( False ) ;
}
2001-03-23 03:50:31 +03:00
* num_uids = 0 ;
2001-05-08 20:33:18 +04:00
* uid = NULL ;
2001-03-23 03:50:31 +03:00
if ( ( grp = getgrgid ( gid ) ) = = NULL )
return False ;
gr = grp - > gr_mem [ 0 ] ;
DEBUG ( 10 , ( " getting members \n " ) ) ;
2001-05-17 04:24:34 +04:00
while ( gr & & ( * gr ! = ( char ) ' \0 ' ) ) {
2001-08-12 21:30:01 +04:00
u = Realloc ( ( * uid ) , sizeof ( uid_t ) * ( * num_uids + 1 ) ) ;
if ( ! u ) {
DEBUG ( 0 , ( " get_uid_list_of_group: unable to enlarge uid list! \n " ) ) ;
return False ;
}
else ( * uid ) = u ;
2001-03-23 03:50:31 +03:00
2002-01-17 11:45:58 +03:00
if ( ( pwd = getpwnam_alloc ( gr ) ) ! = NULL ) {
2001-03-23 03:50:31 +03:00
( * uid ) [ * num_uids ] = pwd - > pw_uid ;
( * num_uids ) + + ;
}
2002-01-17 11:45:58 +03:00
passwd_free ( & pwd ) ;
2001-03-23 03:50:31 +03:00
gr = grp - > gr_mem [ + + i ] ;
}
DEBUG ( 10 , ( " got [%d] members \n " , * num_uids ) ) ;
setpwent ( ) ;
while ( ( pwd = getpwent ( ) ) ! = NULL ) {
if ( pwd - > pw_gid = = gid ) {
2001-08-12 21:30:01 +04:00
u = Realloc ( ( * uid ) , sizeof ( uid_t ) * ( * num_uids + 1 ) ) ;
if ( ! u ) {
DEBUG ( 0 , ( " get_uid_list_of_group: unable to enlarge uid list! \n " ) ) ;
return False ;
}
else ( * uid ) = u ;
2001-03-23 03:50:31 +03:00
( * uid ) [ * num_uids ] = pwd - > pw_uid ;
( * num_uids ) + + ;
}
}
endpwent ( ) ;
DEBUG ( 10 , ( " got primary groups, members: [%d] \n " , * num_uids ) ) ;
return True ;
}
/****************************************************************************
Create a UNIX group on demand .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-25 19:19:00 +04:00
int smb_create_group ( char * unix_group , gid_t * new_gid )
2001-03-23 03:50:31 +03:00
{
pstring add_script ;
int ret ;
2002-09-25 19:19:00 +04:00
int fd = 0 ;
2001-03-23 03:50:31 +03:00
pstrcpy ( add_script , lp_addgroup_script ( ) ) ;
if ( ! * add_script ) return - 1 ;
pstring_sub ( add_script , " %g " , unix_group ) ;
2002-09-25 19:19:00 +04:00
ret = smbrun ( add_script , ( new_gid ! = NULL ) ? & fd : NULL ) ;
2001-03-23 03:50:31 +03:00
DEBUG ( 3 , ( " smb_create_group: Running the command `%s' gave %d \n " , add_script , ret ) ) ;
2002-09-25 19:19:00 +04:00
if ( ret ! = 0 )
return ret ;
if ( fd ! = 0 ) {
fstring output ;
* new_gid = 0 ;
if ( read ( fd , output , sizeof ( output ) ) > 0 ) {
* new_gid = ( gid_t ) strtoul ( output , NULL , 10 ) ;
}
close ( fd ) ;
if ( * new_gid = = 0 ) {
/* The output was garbage. We assume nobody
will create group 0 via smbd . Now we try to
get the group via getgrnam . */
struct group * grp = getgrnam ( unix_group ) ;
if ( grp ! = NULL )
* new_gid = grp - > gr_gid ;
else
return 1 ;
}
}
2001-03-23 03:50:31 +03:00
return ret ;
}
/****************************************************************************
Delete a UNIX group on demand .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int smb_delete_group ( char * unix_group )
{
pstring del_script ;
int ret ;
pstrcpy ( del_script , lp_delgroup_script ( ) ) ;
if ( ! * del_script ) return - 1 ;
pstring_sub ( del_script , " %g " , unix_group ) ;
2001-04-13 23:12:06 +04:00
ret = smbrun ( del_script , NULL ) ;
2001-03-23 03:50:31 +03:00
DEBUG ( 3 , ( " smb_delete_group: Running the command `%s' gave %d \n " , del_script , ret ) ) ;
return ret ;
}
/****************************************************************************
2002-09-25 19:19:00 +04:00
Set a user ' s primary UNIX group .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int smb_set_primary_group ( const char * unix_group , const char * unix_user )
{
pstring add_script ;
int ret ;
pstrcpy ( add_script , lp_setprimarygroup_script ( ) ) ;
if ( ! * add_script ) return - 1 ;
all_string_sub ( add_script , " %g " , unix_group , sizeof ( add_script ) ) ;
all_string_sub ( add_script , " %u " , unix_user , sizeof ( add_script ) ) ;
ret = smbrun ( add_script , NULL ) ;
DEBUG ( 3 , ( " smb_set_primary_group: "
" Running the command `%s' gave %d \n " , add_script , ret ) ) ;
return ret ;
}
/****************************************************************************
Add a user to a UNIX group .
2001-03-23 03:50:31 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int smb_add_user_group ( char * unix_group , char * unix_user )
{
pstring add_script ;
int ret ;
pstrcpy ( add_script , lp_addusertogroup_script ( ) ) ;
if ( ! * add_script ) return - 1 ;
pstring_sub ( add_script , " %g " , unix_group ) ;
pstring_sub ( add_script , " %u " , unix_user ) ;
2001-04-13 23:12:06 +04:00
ret = smbrun ( add_script , NULL ) ;
2001-03-23 03:50:31 +03:00
DEBUG ( 3 , ( " smb_add_user_group: Running the command `%s' gave %d \n " , add_script , ret ) ) ;
return ret ;
}
/****************************************************************************
2002-09-25 19:19:00 +04:00
Delete a user from a UNIX group
2001-03-23 03:50:31 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-01-02 10:41:54 +03:00
int smb_delete_user_group ( const char * unix_group , const char * unix_user )
2001-03-23 03:50:31 +03:00
{
pstring del_script ;
int ret ;
pstrcpy ( del_script , lp_deluserfromgroup_script ( ) ) ;
if ( ! * del_script ) return - 1 ;
pstring_sub ( del_script , " %g " , unix_group ) ;
pstring_sub ( del_script , " %u " , unix_user ) ;
2001-04-13 23:12:06 +04:00
ret = smbrun ( del_script , NULL ) ;
2001-03-23 03:50:31 +03:00
DEBUG ( 3 , ( " smb_delete_user_group: Running the command `%s' gave %d \n " , del_script , ret ) ) ;
return ret ;
}
2003-03-22 12:03:46 +03:00
NTSTATUS pdb_default_getgrsid ( struct pdb_methods * methods , GROUP_MAP * map ,
DOM_SID sid , BOOL with_priv )
{
return get_group_map_from_sid ( sid , map , with_priv ) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
NTSTATUS pdb_default_getgrgid ( struct pdb_methods * methods , GROUP_MAP * map ,
gid_t gid , BOOL with_priv )
{
return get_group_map_from_gid ( gid , map , with_priv ) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
NTSTATUS pdb_default_getgrnam ( struct pdb_methods * methods , GROUP_MAP * map ,
char * name , BOOL with_priv )
{
return get_group_map_from_ntname ( name , map , with_priv ) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
NTSTATUS pdb_default_add_group_mapping_entry ( struct pdb_methods * methods ,
GROUP_MAP * map )
{
return add_mapping_entry ( map , TDB_INSERT ) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
NTSTATUS pdb_default_update_group_mapping_entry ( struct pdb_methods * methods ,
GROUP_MAP * map )
{
return add_mapping_entry ( map , TDB_REPLACE ) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
NTSTATUS pdb_default_delete_group_mapping_entry ( struct pdb_methods * methods ,
DOM_SID sid )
{
return group_map_remove ( sid ) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
NTSTATUS pdb_default_enum_group_mapping ( struct pdb_methods * methods ,
enum SID_NAME_USE sid_name_use ,
GROUP_MAP * * rmap , int * num_entries ,
BOOL unix_only , BOOL with_priv )
{
return enum_group_mapping ( sid_name_use , rmap , num_entries , unix_only ,
with_priv ) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
2003-04-29 09:31:06 +04:00
/**********************************************************************
no ops for passdb backends that don ' t implement group mapping
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS pdb_nop_getgrsid ( struct pdb_methods * methods , GROUP_MAP * map ,
DOM_SID sid , BOOL with_priv )
{
return NT_STATUS_UNSUCCESSFUL ;
}
NTSTATUS pdb_nop_getgrgid ( struct pdb_methods * methods , GROUP_MAP * map ,
gid_t gid , BOOL with_priv )
{
return NT_STATUS_UNSUCCESSFUL ;
}
NTSTATUS pdb_nop_getgrnam ( struct pdb_methods * methods , GROUP_MAP * map ,
char * name , BOOL with_priv )
{
return NT_STATUS_UNSUCCESSFUL ;
}
NTSTATUS pdb_nop_add_group_mapping_entry ( struct pdb_methods * methods ,
GROUP_MAP * map )
{
return NT_STATUS_UNSUCCESSFUL ;
}
NTSTATUS pdb_nop_update_group_mapping_entry ( struct pdb_methods * methods ,
GROUP_MAP * map )
{
return NT_STATUS_UNSUCCESSFUL ;
}
NTSTATUS pdb_nop_delete_group_mapping_entry ( struct pdb_methods * methods ,
DOM_SID sid )
{
return NT_STATUS_UNSUCCESSFUL ;
}
NTSTATUS pdb_nop_enum_group_mapping ( struct pdb_methods * methods ,
enum SID_NAME_USE sid_name_use ,
GROUP_MAP * * rmap , int * num_entries ,
BOOL unix_only , BOOL with_priv )
{
return NT_STATUS_UNSUCCESSFUL ;
}