try u/mount as current user early; clean all mount points on unmount
This commit is contained in:
parent
9b2563f4dc
commit
c02e79769d
2
AUTHORS
2
AUTHORS
|
@ -2,7 +2,7 @@ IgnorantGuru <ignorantguru@gmx.com> http://igurublog.wordpress.com/
|
|||
|
||||
Source code taken from other projects:
|
||||
* spacefm (udev support)
|
||||
* mount (secure realpath)
|
||||
* util-linux (secure canonicalize)
|
||||
* udisks 1.0.4 (device info functions - modified)
|
||||
* pmount 0.99 (physical tty test function - modified)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
0.2.6+
|
||||
|
||||
try u/mount as current user early; clean all mount points on unmount
|
||||
0.2.6 2012-06-03:
|
||||
replace realpath.c with canonicalize.c
|
||||
0.2.5 2012-05-30:
|
||||
|
|
|
@ -39,9 +39,6 @@ log_keep_days = 10
|
|||
# the specific user 'USERNAME'. For example, to allow user 'jim' to mount
|
||||
# only vfat filesystems, add:
|
||||
# allowed_types_jim = vfat
|
||||
# Note: For greater control for specific users, including root, copy this
|
||||
# file to /etc/udevil/udevil-user-USERNAME.conf replacing USERNAME with the
|
||||
# desired username (eg /etc/udevil/udevil-user-jim.conf).
|
||||
# Setting allowed_types = * does NOT allow all types, as this is a security
|
||||
# risk, but does allow all recognized types.
|
||||
# allowed_types = $KNOWN_FILESYSTEMS, smbfs, nfs, ftpfs, curlftpfs, file
|
||||
|
@ -61,7 +58,8 @@ allowed_types = $KNOWN_FILESYSTEMS
|
|||
# the internal fstype of the file.
|
||||
# For example, to allow only user 'bob' to mount nfs shares, add:
|
||||
# allowed_users_nfs = bob
|
||||
# The root user is NOT automatically allowed to use udevil unless listed here.
|
||||
# The root user is NOT automatically allowed to use udevil in some cases unless
|
||||
# listed here (except for unmounting anything or mounting fstab devices).
|
||||
allowed_users = *
|
||||
|
||||
|
||||
|
@ -78,7 +76,8 @@ allowed_users = *
|
|||
# use both of these lines:
|
||||
# allowed_groups_smbfs = network
|
||||
# allowed_groups_nfs = network
|
||||
# The root group is NOT automatically allowed to use udevil unless listed here.
|
||||
# The root user is NOT automatically allowed to use udevil in some cases unless
|
||||
# listed here (except for unmounting anything or mounting fstab devices).
|
||||
allowed_groups = *
|
||||
|
||||
|
||||
|
@ -107,9 +106,9 @@ allowed_media_dirs = /media, /run/media/$USER
|
|||
|
||||
# allowed_devices is the first criteria for what block devices users may mount
|
||||
# or unmount. If a device is not listed in allowed_devices, it cannot be
|
||||
# un/mounted. However, even if a device is listed, other factors may prevent
|
||||
# its use. For example, access to system internal devices will be denied
|
||||
# to normal users even if they are included in allowed_devices.
|
||||
# un/mounted (unless in fstab). However, even if a device is listed, other
|
||||
# factors may prevent its use. For example, access to system internal devices
|
||||
# will be denied to normal users even if they are included in allowed_devices.
|
||||
# allowed_devices_FSTYPE, if present, is used to override allowed_devices when
|
||||
# mounting or unmounting a specific fstype (eg ext3, ntfs). For example, to
|
||||
# prevent all block devices containing an ext4 filesystem from being
|
||||
|
@ -144,7 +143,7 @@ allowed_devices = /dev/*
|
|||
|
||||
|
||||
# forbidden_devices is used to prevent block devices from being un/mounted
|
||||
# even if other settings would allow them.
|
||||
# even if other settings would allow them (except devices in fstab).
|
||||
# forbidden_devices_FSTYPE, if present, is used to override
|
||||
# forbidden_devices when mounting or unmounting a specific fstype
|
||||
# (eg ext3, ntfs). For example, to prevent device /dev/sdd1 from being
|
||||
|
@ -173,7 +172,7 @@ allowed_networks = *
|
|||
|
||||
|
||||
# forbidden_networks and forbidden_networks_FSTYPE are used to specify networks
|
||||
# that are never allowed, even if other settings allow them.
|
||||
# that are never allowed, even if other settings allow them (except fstab).
|
||||
# NO REVERSE LOOKUP IS PERFORMED, so including bad.com will only have an effect
|
||||
# if the user uses that hostname. IP lookup is always performed, so forbidding
|
||||
# an IP address will also forbid all corresponding hostnames.
|
||||
|
@ -192,7 +191,7 @@ allowed_files = *
|
|||
|
||||
|
||||
# forbidden_files is used to specify files that are never allowed, even if
|
||||
# other settings allow them. Specify a full path.
|
||||
# other settings allow them (except fstab). Specify a full path.
|
||||
# Note: Wildcards may be used, but a wildcard will never match a /, except
|
||||
# for "forbidden_files = *".
|
||||
# NOTE: file paths are canonicalized before being tested, so forbidding
|
||||
|
|
157
src/udevil.c
157
src/udevil.c
|
@ -61,6 +61,8 @@
|
|||
#define ALLOWED_TYPES "$KNOWN_FILESYSTEMS,smbfs,nfs,ftpfs,curlftpfs,file"
|
||||
#define MAX_LOG_DAYS 60 // don't set this too high
|
||||
|
||||
static int command_clean();
|
||||
|
||||
int verbose = 1;
|
||||
char* logfile = NULL;
|
||||
char* logmem = NULL;
|
||||
|
@ -1804,6 +1806,69 @@ static int exec_program( const char* var, const char* msg, gboolean show_error,
|
|||
return exit_status;
|
||||
}
|
||||
|
||||
static int try_umount( const char* device_file, gboolean force, gboolean lazy )
|
||||
{
|
||||
// setup command
|
||||
int status = 0;
|
||||
int exit_status = 1;
|
||||
gchar *argv[6] = { NULL };
|
||||
char* sstdout = NULL;
|
||||
char* sstderr = NULL;
|
||||
|
||||
int a = 0;
|
||||
argv[a++] = g_strdup( read_config( "umount_program", NULL ) );
|
||||
if ( !argv[0] )
|
||||
return 1;
|
||||
if ( verbose == 0 )
|
||||
argv[a++] = g_strdup( "-v" );
|
||||
if ( force )
|
||||
argv[a++] = g_strdup( "-f" );
|
||||
if ( lazy )
|
||||
argv[a++] = g_strdup( "-l" );
|
||||
argv[a++] = g_strdup( device_file );
|
||||
char* allarg = g_strjoinv( " ", argv );
|
||||
|
||||
// insurance
|
||||
drop_privileges( 0 );
|
||||
|
||||
// log
|
||||
wlog( "udevil: trying umount as current user\n", NULL, 0 );
|
||||
wlog( "USER: %s\n", allarg, 0 );
|
||||
g_free( allarg );
|
||||
|
||||
// run
|
||||
if ( g_spawn_sync( NULL, argv, NULL, 0, NULL, NULL, &sstdout, &sstderr, &status, NULL ) )
|
||||
{
|
||||
if ( status && WIFEXITED( status ) )
|
||||
exit_status = WEXITSTATUS( status );
|
||||
else
|
||||
exit_status = 0;
|
||||
}
|
||||
else
|
||||
wlog( "udevil: warning: unable to run umount (%s)\n",
|
||||
read_config( "umount_program", NULL ), 1 );
|
||||
|
||||
if ( exit_status )
|
||||
{
|
||||
char* str = g_strdup_printf( " umount exit status = %d\n", exit_status );
|
||||
wlog( str, NULL, 0 );
|
||||
g_free( str );
|
||||
g_free( sstdout );
|
||||
g_free( sstderr );
|
||||
return 1;
|
||||
}
|
||||
|
||||
// success - show output
|
||||
wlog( "udevil: success running umount as current user\n", NULL, 1 );
|
||||
if ( sstderr )
|
||||
fprintf( stderr, sstderr );
|
||||
if ( sstdout )
|
||||
fprintf( stdout, sstdout );
|
||||
g_free( sstdout );
|
||||
g_free( sstderr );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int umount_path( const char* path, gboolean force, gboolean lazy )
|
||||
{
|
||||
// setup command
|
||||
|
@ -2488,6 +2553,77 @@ _get_type:
|
|||
}
|
||||
}
|
||||
|
||||
// try normal user u/mount early
|
||||
if ( !data->point )
|
||||
{
|
||||
if ( data->cmd_type == CMD_UNMOUNT )
|
||||
{
|
||||
ret = try_umount( type == MOUNT_NET ? netmount->url : data->device_file,
|
||||
data->force, data->lazy );
|
||||
if ( ret == 0 )
|
||||
{
|
||||
// success_exec
|
||||
str = g_strdup_printf( "%s unmounted %s", g_get_user_name(),
|
||||
type == MOUNT_NET ? netmount->url : data->device_file );
|
||||
exec_program( "success_rootexec", str, FALSE, TRUE );
|
||||
exec_program( "success_exec", str, FALSE, FALSE );
|
||||
g_free( str );
|
||||
if ( orig_euid == 0 )
|
||||
command_clean();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if ( data->cmd_type == CMD_MOUNT
|
||||
&& !( data->options && strstr( data->options, "remount" ) ) )
|
||||
{
|
||||
if ( mount_knows( type == MOUNT_NET ? netmount->url : data->device_file ) )
|
||||
{
|
||||
// mount knows (in fstab) so mount as normal user with only specified opts
|
||||
wlog( "udevil: %s is known to mount - running mount as current user\n",
|
||||
type == MOUNT_NET ? netmount->url : data->device_file, 1 );
|
||||
if ( data->fstype )
|
||||
wlog( "udevil: warning: fstype ignored for device in fstab (or specify mount point)\n",
|
||||
NULL, 1 );
|
||||
if ( data->options )
|
||||
wlog( "udevil: warning: options ignored for device in fstab (or specify mount point)\n",
|
||||
NULL, 1 );
|
||||
|
||||
ret = mount_device( type == MOUNT_NET ? netmount->url : data->device_file,
|
||||
NULL, NULL, NULL, FALSE );
|
||||
// print
|
||||
if ( !ret )
|
||||
{
|
||||
if ( device_is_mounted_mtab(
|
||||
type == MOUNT_NET ? netmount->url : data->device_file,
|
||||
&str, NULL ) )
|
||||
{
|
||||
str = g_strdup_printf( "Mounted %s at %s\n",
|
||||
type == MOUNT_NET ? netmount->url : data->device_file,
|
||||
str );
|
||||
}
|
||||
else
|
||||
str = g_strdup_printf( "Mounted %s\n",
|
||||
type == MOUNT_NET ? netmount->url : data->device_file );
|
||||
wlog( str, NULL, -1 );
|
||||
g_free( str );
|
||||
|
||||
// success_exec
|
||||
if ( !ret )
|
||||
{
|
||||
str = g_strdup_printf( "%s mounted %s (in fstab)",
|
||||
g_get_user_name(),
|
||||
type == MOUNT_NET ? netmount->url : data->device_file );
|
||||
exec_program( "success_rootexec", str, FALSE, TRUE );
|
||||
exec_program( "success_exec", str, FALSE, FALSE );
|
||||
g_free( str );
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
// determine device from unmount point
|
||||
if ( data->cmd_type == CMD_UNMOUNT && type == MOUNT_FILE )
|
||||
{
|
||||
|
@ -2579,6 +2715,7 @@ _get_type:
|
|||
}
|
||||
|
||||
// get fstype and device info
|
||||
ret = 0;
|
||||
if ( type == MOUNT_NET )
|
||||
{
|
||||
fstype = g_strdup( netmount->fstype );
|
||||
|
@ -3059,24 +3196,16 @@ _get_type:
|
|||
if ( data->point && !( ret = umount_path( data->point, data->force,
|
||||
data->lazy ) ) )
|
||||
{
|
||||
// remove mount point if udevil created
|
||||
str = g_build_filename( data->point, ".udevil-mount-point", NULL );
|
||||
restore_privileges(); // needed for stat and rm
|
||||
if ( stat64( str, &statbuf ) == 0 && statbuf.st_uid == 0 )
|
||||
{
|
||||
// .udevil-mount-point exists and is root-owned
|
||||
unlink ( str );
|
||||
rmdir( data->point );
|
||||
}
|
||||
g_free( str );
|
||||
drop_privileges( 0 );
|
||||
|
||||
// success_exec
|
||||
str = g_strdup_printf( "%s unmounted %s", g_get_user_name(),
|
||||
data->point );
|
||||
exec_program( "success_rootexec", str, FALSE, TRUE );
|
||||
exec_program( "success_exec", str, FALSE, FALSE );
|
||||
g_free( str );
|
||||
|
||||
// cleanup mount points
|
||||
if ( orig_euid == 0 )
|
||||
command_clean();
|
||||
}
|
||||
goto _finish;
|
||||
}
|
||||
|
@ -3288,8 +3417,8 @@ _get_type:
|
|||
if ( mount_knows( type == MOUNT_NET ? netmount->url : data->device_file ) )
|
||||
{
|
||||
// mount knows (in fstab) so mount as normal user with only specified opts
|
||||
wlog( "udevil: %s is known to mount - running mount as normal user\n",
|
||||
data->device_file, 1 );
|
||||
wlog( "udevil: %s is known to mount - running mount as current user\n",
|
||||
type == MOUNT_NET ? netmount->url : data->device_file, 1 );
|
||||
if ( data->fstype )
|
||||
wlog( "udevil: warning: fstype ignored for device in fstab (or specify mount point)\n",
|
||||
NULL, 1 );
|
||||
|
|
Loading…
Reference in New Issue
Block a user