1998-11-24 00:54:19 +03:00
/*
Unix SMB / Netbios implementation .
Version 1.9 .
Groupname handling
Copyright ( C ) Jeremy Allison 1998.
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 .
*/
1999-12-13 16:27:58 +03:00
# ifdef USING_GROUPNAME_MAP
# include "includes.h"
extern int DEBUGLEVEL ;
extern DOM_SID global_sam_sid ;
/**************************************************************************
Groupname map functionality . The code loads a groupname map file and
( currently ) loads it into a linked list . This is slow and memory
hungry , but can be changed into a more efficient storage format
if the demands on it become excessive .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
typedef struct groupname_map {
ubi_slNode next ;
char * windows_name ;
DOM_SID windows_sid ;
char * unix_name ;
gid_t unix_gid ;
} groupname_map_entry ;
static ubi_slList groupname_map_list ;
/**************************************************************************
Delete all the entries in the groupname map list .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void delete_groupname_map_list ( void )
{
groupname_map_entry * gmep ;
while ( ( gmep = ( groupname_map_entry * ) ubi_slRemHead ( & groupname_map_list ) ) ! = NULL ) {
if ( gmep - > windows_name )
free ( gmep - > windows_name ) ;
if ( gmep - > unix_name )
free ( gmep - > unix_name ) ;
free ( ( char * ) gmep ) ;
}
}
/**************************************************************************
Load a groupname map file . Sets last accessed timestamp .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void load_groupname_map ( void )
{
static time_t groupmap_file_last_modified = ( time_t ) 0 ;
static BOOL initialized = False ;
char * groupname_map_file = lp_groupname_map ( ) ;
SMB_STRUCT_STAT st ;
2000-04-16 15:17:19 +04:00
char * * lines ;
int i ;
1999-12-13 16:27:58 +03:00
groupname_map_entry * new_ep ;
if ( ! initialized ) {
ubi_slInitList ( & groupname_map_list ) ;
initialized = True ;
}
if ( ! * groupname_map_file )
return ;
if ( sys_stat ( groupname_map_file , & st ) ! = 0 ) {
DEBUG ( 0 , ( " load_groupname_map: Unable to stat file %s. Error was %s \n " ,
groupname_map_file , strerror ( errno ) ) ) ;
return ;
}
/*
* Check if file has changed .
*/
if ( st . st_mtime < = groupmap_file_last_modified )
return ;
groupmap_file_last_modified = st . st_mtime ;
/*
* Load the file .
*/
2000-12-07 22:26:04 +03:00
lines = file_lines_load ( groupname_map_file , NULL , False ) ;
2000-04-16 15:17:19 +04:00
if ( ! lines ) {
1999-12-13 16:27:58 +03:00
DEBUG ( 0 , ( " load_groupname_map: can't open groupname map %s. Error was %s \n " ,
groupname_map_file , strerror ( errno ) ) ) ;
return ;
}
2000-04-16 15:17:19 +04:00
file_lines_slashcont ( lines ) ;
1999-12-13 16:27:58 +03:00
/*
* Throw away any previous list .
*/
delete_groupname_map_list ( ) ;
DEBUG ( 4 , ( " load_groupname_map: Scanning groupname map %s \n " , groupname_map_file ) ) ;
2000-04-16 15:17:19 +04:00
for ( i = 0 ; lines [ i ] ; i + + ) {
1999-12-13 16:27:58 +03:00
pstring unixname ;
pstring windows_name ;
2000-10-13 05:59:14 +04:00
gid_t gid ;
1999-12-13 16:27:58 +03:00
DOM_SID tmp_sid ;
2000-04-16 15:17:19 +04:00
char * s = lines [ i ] ;
1999-12-13 16:27:58 +03:00
DEBUG ( 10 , ( " load_groupname_map: Read line |%s| \n " , s ) ) ;
if ( ! * s | | strchr ( " #; " , * s ) )
continue ;
if ( ! next_token ( & s , unixname , " \t \n \r = " , sizeof ( unixname ) ) )
continue ;
if ( ! next_token ( & s , windows_name , " \t \n \r = " , sizeof ( windows_name ) ) )
continue ;
trim_string ( unixname , " " , " " ) ;
trim_string ( windows_name , " " , " " ) ;
if ( ! * windows_name )
continue ;
if ( ! * unixname )
continue ;
DEBUG ( 5 , ( " load_groupname_map: unixname = %s, windowsname = %s. \n " ,
unixname , windows_name ) ) ;
/*
* Attempt to get the unix gid_t for this name .
*/
2000-10-13 05:59:14 +04:00
if ( ( gid = nametogid ( unixname ) ) = = ( gid_t ) - 1 )
DEBUG ( 0 , ( " load_groupname_map: nametogid for group %s failed. \
1999-12-13 16:27:58 +03:00
Error was % s . \ n " , unixname, strerror(errno) ));
continue ;
}
/*
* Now map to an NT SID .
*/
if ( ! lookup_wellknown_sid_from_name ( windows_name , & tmp_sid ) ) {
/*
* It ' s not a well known name , convert the UNIX gid_t
* to a rid within this domain SID .
*/
tmp_sid = global_sam_sid ;
tmp_sid . sub_auths [ tmp_sid . num_auths + + ] =
2000-10-13 05:59:14 +04:00
pdb_gid_to_group_rid ( gid ) ;
1999-12-13 16:27:58 +03:00
}
/*
* Create the list entry and add it onto the list .
*/
if ( ( new_ep = ( groupname_map_entry * ) malloc ( sizeof ( groupname_map_entry ) ) ) = = NULL ) {
DEBUG ( 0 , ( " load_groupname_map: malloc fail for groupname_map_entry. \n " ) ) ;
fclose ( fp ) ;
return ;
}
2000-10-13 05:59:14 +04:00
new_ep - > unix_gid = gid ;
1999-12-13 16:27:58 +03:00
new_ep - > windows_sid = tmp_sid ;
new_ep - > windows_name = strdup ( windows_name ) ;
new_ep - > unix_name = strdup ( unixname ) ;
if ( new_ep - > windows_name = = NULL | | new_ep - > unix_name = = NULL ) {
DEBUG ( 0 , ( " load_groupname_map: malloc fail for names in groupname_map_entry. \n " ) ) ;
fclose ( fp ) ;
if ( new_ep - > windows_name ! = NULL )
free ( new_ep - > windows_name ) ;
if ( new_ep - > unix_name ! = NULL )
free ( new_ep - > unix_name ) ;
free ( ( char * ) new_ep ) ;
2000-04-19 00:41:04 +04:00
file_lines_free ( lines ) ;
1999-12-13 16:27:58 +03:00
return ;
}
memset ( ( char * ) & new_ep - > next , ' \0 ' , sizeof ( new_ep - > next ) ) ;
ubi_slAddHead ( & groupname_map_list , ( ubi_slNode * ) new_ep ) ;
}
DEBUG ( 10 , ( " load_groupname_map: Added %ld entries to groupname map. \n " ,
ubi_slCount ( & groupname_map_list ) ) ) ;
2000-04-16 15:17:19 +04:00
file_lines_free ( lines ) ;
1999-12-13 16:27:58 +03:00
}
/***********************************************************
Lookup a SID entry by gid_t .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void map_gid_to_sid ( gid_t gid , DOM_SID * psid )
{
groupname_map_entry * gmep ;
/*
* Initialize and load if not already loaded .
*/
load_groupname_map ( ) ;
for ( gmep = ( groupname_map_entry * ) ubi_slFirst ( & groupname_map_list ) ;
gmep ; gmep = ( groupname_map_entry * ) ubi_slNext ( gmep ) ) {
if ( gmep - > unix_gid = = gid ) {
* psid = gmep - > windows_sid ;
DEBUG ( 7 , ( " map_gid_to_sid: Mapping unix group %s to windows group %s. \n " ,
gmep - > unix_name , gmep - > windows_name ) ) ;
return ;
}
}
/*
* If there ' s no map , convert the UNIX gid_t
* to a rid within this domain SID .
*/
* psid = global_sam_sid ;
psid - > sub_auths [ psid - > num_auths + + ] = pdb_gid_to_group_rid ( gid ) ;
return ;
}
# else /* USING_GROUPNAME_MAP */
void load_groupname_map ( void ) { ; }
# endif /* USING_GROUPNAME_MAP */