finalize 0.2.8

This commit is contained in:
IgnorantGuru 2012-06-15 13:07:22 -06:00
parent 8d4a73dd81
commit e77f191147
8 changed files with 349 additions and 322 deletions

View File

@ -1,5 +1,8 @@
0.2.7+
0.2.8
ssh:// support
use cifs by default instead of smbfs
fix denied when passing mount option uid= on command line
updated default udevil.conf
0.2.7 2012-06-04:
try u/mount as current user early; clean all mount points on unmount
0.2.6 2012-06-03:

75
README
View File

@ -1,4 +1,4 @@
README for udevil v0.2.7+ ALPHA TEST VERSION
README for udevil v0.2.8 ALPHA TEST VERSION
THIS RELEASE IS FOR TESTING PURPOSES - USE AT YOUR OWN RISK.
@ -32,7 +32,7 @@ CONTENTS
DESCRIPTION
Mounts and unmounts optical and removable devices without a password (set
Mounts and unmounts removable devices and networks without a password (set
suid), shows device info, monitors device changes. Emulates mount's and
udisks's command line usage and udisks v1's output. Includes the devmon
automounting daemon.
@ -63,6 +63,9 @@ PACKAGES
For signatures and SHA256 sums see
http://ignorantguru.github.com/udevil/udevil.SHA256.txt
Gentoo ebuild available:
http://git.overlays.gentoo.org/gitweb/?p=user/Armageddon.git;a=tree;f=sys-apps/udevil;
Other: See INSTALLER below
NOTE: See POST INSTALL section below for post-installation steps.
@ -100,8 +103,10 @@ BUILD
libglib2.0-0 libglib2.0-dev libudev0 (>=143) libudev-dev
autotools-dev build-essential fakeroot intltool pkg-config
Also recommended for network support: cifs-utils curlftpfs sshfs
Also recommended if using devmon: eject zenity
configure will report anything missing when you run it as shown below.
2) Use these commands to download the udevil tarball and build:
@ -154,9 +159,10 @@ CREATE DEB PACKAGE
1) Install build dependencies (see BUILD section above) plus 'debhelper'.
2) Use these commands to download and extract the SpaceFM tarball:
2) Use these commands to download and extract the udevil tarball (be sure
to USE A TMP BUILD PATH THAT DOES NOT CONTAIN SPACES):
mkdir /tmp/udevil-build && cd /tmp/udevil-build
mkdir /tmp/udevil-build && cd /tmp/udevil-build # no spaces in path
# Note: you can change "master" to "next" if you want the next branch:
wget -O udevil.tar.gz https://github.com/IgnorantGuru/udevil/tarball/master
tar xzf udevil.tar.gz
@ -181,6 +187,32 @@ POST INSTALL
udevil. See ENABLE KERNEL POLLING section below.
Networks and Files
------------------
By default, /etc/udevil/udevil.conf is set to allow only local fileystems
to be mounted, with mounting of networks and ISO files disallowed. To
allow networks and files to be mounted, in /etc/udevil/udevil.conf set:
allowed_types = $KNOWN_FILESYSTEMS, file, cifs, nfs, curlftpfs, sshfs
You may also need to install curlftpfs or ftpfs (ftp://), cifs or smbfs
(smb://), and sshfs (ssh://).
NTFS-3G
-------
If local ntfs filesystems aren't mounted writable, you may need to
configure your system to mount ntfs with ntfs-3g (on some distros this is
already done). For example:
sudo ln -s /sbin/mount.ntfs-3g /sbin/mount.ntfs
# OR if mount.ntfs-3g is located in /usr/bin:
sudo ln -s /usr/bin/mount.ntfs-3g /usr/bin/mount.ntfs
Set SUID
--------
@ -208,39 +240,6 @@ POST INSTALL
You can also limit users and groups by editing /etc/udevil/udevil.conf
Networks and Files
------------------
By default, /etc/udevil/udevil.conf is set to allow only normal fileystems
to be mounted, with mounting of networks and files disallowed. To allow
networks and files to be mounted, in /etc/udevil/udevil.conf set:
allowed_types = $KNOWN_FILESYSTEMS, smbfs, nfs, ftpfs, curlftpfs, file
FTP Support
-----------
To mount 'ftp://' URLs with udevil, you also need curlftpfs installed:
http://linuxconfig.org/mount-remote-ftp-directory-host-locally-into-linux-filesystem
OR you need the ftpfs kernel module:
http://www.techrepublic.com/article/mount-ftp-volumes-locally-with-ftpfs/5031896
NTFS-3G
-------
If ntfs filesystems aren't mounted writable, you may need to configure your
system to mount ntfs with ntfs-3g (on some distros this is already done).
For example:
sudo ln -s /sbin/mount.ntfs-3g /sbin/mount.ntfs
# OR if mount.ntfs-3g is located in /usr/bin:
sudo ln -s /usr/bin/mount.ntfs-3g /usr/bin/mount.ntfs
ENABLE KERNEL POLLING
You may need to enable kernel polling for device media to be detected by

2
configure vendored
View File

@ -2730,7 +2730,7 @@ fi
# Define the identity of the package.
PACKAGE=udevil
VERSION=0.2.7+
VERSION=0.2.8
cat >>confdefs.h <<_ACEOF

View File

@ -3,7 +3,7 @@ AC_PREREQ(2.52)
AC_INIT(src/udevil.c)
AM_CONFIG_HEADER(config.h)
AC_CONFIG_SRCDIR(src)
AM_INIT_AUTOMAKE(udevil, 0.2.7+)
AM_INIT_AUTOMAKE(udevil, 0.2.8)
AC_PROG_INTLTOOL([0.21])

8
debian/control vendored
View File

@ -12,10 +12,10 @@ Package: udevil
Architecture: any
Depends: libc6, libglib2.0-0, libudev0 (>=143)
Recommends:
Suggests: eject
Suggests: eject cifs-utils curlftpfs sshfs
Conflicts: devmon
Provides: devmon
Description: Mounts and unmounts optical and removable devices without a
password (set suid), shows device info, monitors device changes. Includes the
devmon automounting script.
Description: Mounts and unmounts removable devices and networks without a
password (set suid), shows device info, monitors device changes. Includes
the devmon automounting script.

View File

@ -33,7 +33,7 @@ log_keep_days = 10
# network filesystems may be un/mounted.
# It may also include the 'file' keyword, indicating that the user is allowed
# to mount files (eg an ISO file). The $KNOWN_FILESYSTEMS variable may
# be included to include common filesystems as well as those listed in
# be included to include common local filesystems as well as those listed in
# /etc/filesystems and /proc/filesystems.
# allowed_types_USERNAME, if present, is used to override allowed_types for
# the specific user 'USERNAME'. For example, to allow user 'jim' to mount
@ -41,7 +41,7 @@ log_keep_days = 10
# allowed_types_jim = vfat
# 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
# allowed_types = $KNOWN_FILESYSTEMS, file, cifs, smbfs, nfs, curlftpfs, ftpfs, sshfs
allowed_types = $KNOWN_FILESYSTEMS
@ -155,19 +155,19 @@ forbidden_devices =
# allowed_networks determines what hosts may be un/mounted by udevil users when
# using nfs, smbfs, ftpfs, and curlftpfs. Hosts may be specified using
# a hostname (eg myserver.com) or IP address (192.168.1.100).
# using nfs, cifs, smbfs, curlftpfs, ftpfs, or sshfs. Hosts may be specified
# using a hostname (eg myserver.com) or IP address (192.168.1.100).
# Wildcards may be used in hostnames and IP addresses, but CIDR notation
# (192.168.1.0/16) is NOT supported. IP v6 is supported. For example:
# allowed_networks = 127.0.0.1, 192.168.1.*, 10.0.0.*, localmachine, *.okay.com
# Or, to prevent un/mounting of any network shares, set:
# allowed_networks =
# allowed_networks_FSTYPE, if present, is used to override allowed_networks
# when mounting or unmounting a specific network fstype (eg nfs, smbfs, ftpfs,
# when mounting or unmounting a specific network fstype (eg nfs, cifs, sshfs,
# curlftpfs). For example, to limit nfs and samba shares to only local
# networks, use these two lines:
# allowed_networks_nfs = 192.168.1.*, 10.0.0.*
# allowed_networks_smbfs = 192.168.1.*, 10.0.0.*
# allowed_networks_cifs = 192.168.1.*, 10.0.0.*
allowed_networks = *
@ -204,10 +204,10 @@ forbidden_files =
# Note: When a device is present in /etc/fstab, and the user does not specify
# a mount point, the device is mounted with normal user permissions using
# the fstab entry, without these options.
# The variables $USER, $UID, and $GID are changed to the user's username, UID,
# and GID.
# default_options_FSTYPE, if present, is used to override default_options
# when mounting a specific fstype (eg ext2, nfs).
# The variables $USER, $UID, and $GID are changed to the user's username, UID,
# and GID.
# FOR GOOD SECURITY, default_options SHOULD ALWAYS INCLUDE: nosuid,noexec,nodev
# WARNING: OPTIONS PRESENT OR MISSING CAN CAUSE SERIOUS SECURITY PROBLEMS.
default_options = nosuid, noexec, nodev, noatime
@ -218,6 +218,9 @@ default_options_udf = nosuid, noexec, nodev, noatime, uid=$UID, gid=$GID,
default_options_vfat = nosuid, noexec, nodev, noatime, fmask=0022, dmask=0022, uid=$UID, gid=$GID
default_options_msdos = nosuid, noexec, nodev, noatime, fmask=0022, dmask=0022, uid=$UID, gid=$GID
default_options_umsdos = nosuid, noexec, nodev, noatime, fmask=0022, dmask=0022, uid=$UID, gid=$GID
default_options_cifs = nosuid, noexec, nodev, noatime, uid=$UID, gid=$GID, utf8
default_options_smbfs = nosuid, noexec, nodev, noatime, uid=$UID, gid=$GID, utf8
default_options_sshfs = nosuid, noexec, nodev, noatime, uid=$UID, gid=$GID, nonempty, allow_other
default_options_curlftpfs = nosuid, noexec, nodev, noatime, uid=$UID, gid=$GID, nonempty, allow_other
default_options_ftpfs = nosuid, noexec, nodev, noatime, uid=$UID, gid=$GID
@ -228,11 +231,15 @@ default_options_ftpfs = nosuid, noexec, nodev, noatime, uid=$UID, gid=$GID
# here, an error will result. Wildcards may be used.
# allowed_options_FSTYPE, if present, is used to override allowed_options
# when mounting a specific fstype (eg ext2, nfs).
# The variables $USER, $UID, and $GID are changed to the user's username, UID,
# and GID.
# If you want to forbid remounts, remove 'remount' from here.
# WARNING: OPTIONS HERE CAN CAUSE SERIOUS SECURITY PROBLEMS - CHOOSE CAREFULLY
allowed_options = nosuid, noexec, nodev, noatime, fmask=0022, dmask=0022, uid=$UID, gid=$GID, ro, rw, remount
allowed_options_nfs = nosuid, noexec, nodev, noatime, ro, rw, remount, port=*, rsize=*, wsize=*, hard, proto=*, timeo=*, retrans=*
allowed_options_smbfs = nosuid, noexec, nodev, noatime, ro, rw, remount, port=*, user=*, username=*, pass=*, password=*, guest, uid=$UID, gid=$GID, credentials=*
allowed_options_cifs = nosuid, noexec, nodev, noatime, ro, rw, remount, port=*, user=*, username=*, pass=*, password=*, guest, uid=$UID, gid=$GID, credentials=*, utf8
allowed_options_smbfs = nosuid, noexec, nodev, noatime, ro, rw, remount, port=*, user=*, username=*, pass=*, password=*, guest, uid=$UID, gid=$GID, credentials=*, utf8
allowed_options_sshfs = nosuid, noexec, nodev, noatime, ro, rw, uid=$UID, gid=$GID, nonempty, allow_other, idmap=user, BatchMode=yes
allowed_options_curlftpfs = nosuid, noexec, nodev, noatime, ro, rw, uid=$UID, gid=$GID, nonempty, allow_other
allowed_options_ftpfs = nosuid, noexec, nodev, noatime, ro, rw, port=*, user=*, pass=*, ip=*, root=*, uid=$UID, gid=$GID
@ -245,7 +252,8 @@ allowed_options_ftpfs = nosuid, noexec, nodev, noatime, ro, rw, port=*, user
# when mounting a specific fstype (eg ext2, nfs).
# NOT SETTING A MODE CAN HAVE SECURITY IMPLICATIONS FOR SOME FSTYPES
mount_point_mode = 0755
# don't set a mode for curlftpfs:
# don't set a mode for some types:
mount_point_mode_sshfs =
mount_point_mode_curlftpfs =
mount_point_mode_ftpfs =

View File

@ -19,7 +19,7 @@
GETTEXT_PACKAGE = udevil
PACKAGE = udevil
VERSION = 0.2.7+
VERSION = 0.2.8
SHELL = /bin/bash

View File

@ -830,7 +830,9 @@ static char* parse_config()
fclose( file );
return NULL;
}
if ( g_str_has_prefix( var, "allowed_media_dirs" ) )
if ( g_str_has_prefix( var, "allowed_media_dirs" ) ||
g_str_has_prefix( var, "allowed_options" ) ||
g_str_has_prefix( var, "default_options" ) )
{
const char* user = g_get_user_name();
if ( user && user[0] != '\0' )
@ -2174,37 +2176,73 @@ static int parse_network_url( const char* url, const char* fstype,
nm->pass = NULL;
nm->path = NULL;
if ( fstype && ( !strcmp( fstype, "nfs" ) || !strcmp( fstype, "smbfs" ) ) )
ret = 2;
if ( fstype && ( !strcmp( fstype, "nfs" ) || !strcmp( fstype, "smbfs" )
|| !strcmp( fstype, "cifs" ) || !strcmp( fstype, "sshfs" )
|| !strcmp( fstype, "nfs4" ) ) )
ret = 2; //invalid as default response
char* orig_url = strdup( url );
char* xurl = orig_url;
if ( g_str_has_prefix( xurl, "ftp:" ) || g_str_has_prefix( xurl, "smb:" )
|| g_str_has_prefix( xurl, "nfs:" ) || g_str_has_prefix( xurl, "curlftpfs#ftp:" )
|| ( fstype && ( !strcmp( fstype, "curlftpfs" ) || !strcmp( fstype, "ftpfs" ) ) ) )
gboolean is_colon = FALSE;
// determine url type
if ( g_str_has_prefix( xurl, "smb:" ) || g_str_has_prefix( xurl, "smbfs:" )
|| g_str_has_prefix( xurl, "cifs:" )
|| g_str_has_prefix( xurl, "//" ) )
{
// mount nfs|smb|ftp:[//][<user>[:<pass>]@]<host>[:<port>]/<path>
// mount -t [curl]ftpfs [<user>[:<pass>]@]<host>[:<port>][/<path>]
if ( g_str_has_prefix( xurl, "smb:" ) )
ret = 2;
// mount [-t smbfs] //host[:<port>]/<path>
if ( !g_str_has_prefix( xurl, "//" ) )
is_colon = TRUE;
if ( fstype && strcmp( fstype, "smbfs" ) && strcmp( fstype, "cifs" ) )
{
wlog( "udevil: error: invalid type '%s' for SMB share - must be cifs or smbfs\n",
fstype, 2 );
goto _net_free;
}
if ( !g_strcmp0( fstype, "smbfs" ) || g_str_has_prefix( xurl, "smbfs:" ) )
nm->fstype = g_strdup( "smbfs" );
xurl += 4;
}
else if ( g_str_has_prefix( xurl, "nfs:" ) )
else
nm->fstype = g_strdup( "cifs" );
}
else if ( g_str_has_prefix( xurl, "nfs:" ) )
{
ret = 2;
is_colon = TRUE;
if ( fstype && strcmp( fstype, "nfs" ) && strcmp( fstype, "nfs4" ) )
{
nm->fstype = g_strdup( "nfs" );
xurl += 4;
wlog( "udevil: error: invalid type '%s' for NFS share - must be nfs or nfs4\n",
fstype, 2 );
goto _net_free;
}
else if ( fstype && ( !strcmp( fstype, "curlftpfs" )
|| !strcmp( fstype, "ftpfs" ) ) )
nm->fstype = g_strdup( "nfs" );
}
else if ( g_str_has_prefix( xurl, "curlftpfs#" ) )
{
ret = 2;
if ( g_str_has_prefix( xurl, "curlftpfs#ftp:" ) )
is_colon = TRUE;
if ( fstype && strcmp( fstype, "curlftpfs" ) )
{
if ( g_str_has_prefix( xurl, "ftp:" ) )
xurl += 4;
else if ( g_str_has_prefix( xurl, "curlftpfs#ftp:" ) )
xurl += 14;
wlog( "udevil: error: invalid type '%s' for curlftpfs share - must be curlftpfs\n",
fstype, 2 );
goto _net_free;
}
nm->fstype = g_strdup( "curlftpfs" );
}
else if ( g_str_has_prefix( xurl, "ftp:" ) )
{
ret = 2;
is_colon = TRUE;
if ( fstype && strcmp( fstype, "ftpfs" ) && strcmp( fstype, "curlftpfs" ) )
{
wlog( "udevil: error: invalid type '%s' for FTP share - must be curlftpfs or ftpfs\n",
fstype, 2 );
goto _net_free;
}
if ( fstype )
nm->fstype = g_strdup( fstype );
}
else if ( g_str_has_prefix( xurl, "ftp:" ) )
else
{
// detect curlftpfs or ftpfs
if ( str = g_find_program_in_path( "curlftpfs" ) )
@ -2212,232 +2250,192 @@ static int parse_network_url( const char* url, const char* fstype,
else
nm->fstype = g_strdup( "ftpfs" );
g_free( str );
xurl += 4;
}
else if ( g_str_has_prefix( xurl, "curlftpfs#ftp:" ) )
{
nm->fstype = g_strdup( "curlftpfs" );
xurl += 14;
}
ret = 2;
while ( xurl[0] == '/' )
xurl++;
char* trim_url = g_strdup( xurl );
// path
if ( str = strchr( xurl, '/' ) )
{
nm->path = g_strdup( str );
str[0] = '\0';
}
// user:pass
if ( str = strchr( xurl, '@' ) )
{
str[0] = '\0';
if ( str2 = strchr( xurl, ':' ) )
{
str2[0] = '\0';
if ( str2[1] != '\0' )
nm->pass = g_strdup( str2 + 1 );
}
if ( xurl[0] != '\0' )
nm->user = g_strdup( xurl );
xurl = str + 1;
}
// host:port
if ( xurl[0] == '[' )
{
// ipv6 literal
if ( str = strchr( xurl, ']' ) )
{
str[0] = '\0';
if ( xurl[1] != '\0' )
nm->host = g_strdup( xurl + 1 );
if ( str[1] == ':' && str[2] != '\0' )
nm->port = g_strdup( str + 1 );
}
}
else if ( xurl[0] != '\0' )
{
if ( str = strchr( xurl, ':' ) )
{
str[0] = '\0';
if ( str[1] != '\0' )
nm->port = g_strdup( str + 1 );
}
nm->host = g_strdup( xurl );
}
// url
if ( nm->host )
{
if ( g_str_has_prefix( url, "smb:" ) )
nm->url = g_strdup_printf( "//%s%s", nm->host, nm->path ? nm->path : "/" );
else if ( g_str_has_prefix( url, "nfs:" ) )
nm->url = g_strdup_printf( "%s:%s", nm->host, nm->path ? nm->path : "/" );
else if ( !g_strcmp0( nm->fstype, "curlftpfs" ) )
nm->url = g_strdup_printf( "curlftpfs#ftp://%s%s%s%s%s%s%s%s",
nm->user ? nm->user : "",
nm->pass ? ":" : "",
nm->pass ? nm->pass : "",
nm->user || nm->pass ? "@" : "",
nm->host,
nm->port ? ":" : "",
nm->port ? nm->port : "",
nm->path ? nm->path : "/" );
else if ( !g_strcmp0( nm->fstype, "ftpfs" ) )
nm->url = g_strdup( "none" );
else
nm->url = g_strdup( trim_url );
}
g_free( trim_url );
}
else if ( g_str_has_prefix( xurl, "//" ) )
{
// mount [-t smbfs] //host[:<port>]/<path>
nm->fstype = g_strdup( "smbfs" );
nm->url = g_strdup( xurl );
ret = 2;
while ( xurl[0] == '/' )
xurl++;
// path
if ( str = strchr( xurl, '/' ) )
{
nm->path = g_strdup( str );
str[0] = '\0';
}
// host:port
if ( xurl[0] == '[' )
{
// ipv6 literal
if ( str = strchr( xurl, ']' ) )
{
str[0] = '\0';
if ( xurl[1] != '\0' )
nm->host = g_strdup( xurl + 1 );
if ( str[1] == ':' && str[2] != '\0' )
nm->port = g_strdup( str + 1 );
}
}
else if ( xurl[0] != '\0' )
{
if ( str = strchr( xurl, ':' ) )
{
str[0] = '\0';
if ( str[1] != '\0' )
nm->port = g_strdup( str + 1 );
}
nm->host = g_strdup( xurl );
}
}
else if ( strstr( xurl, ":/" ) && xurl[0] != ':' && xurl[0] != '/' )
else if ( g_str_has_prefix( xurl, "sshfs#" ) )
{
ret = 2;
if ( g_str_has_prefix( xurl, "sshfs#ssh:" )
|| g_str_has_prefix( xurl, "sshfs#sshfs:" )
|| g_str_has_prefix( xurl, "sshfs#sftp:" ) )
is_colon = TRUE;
if ( fstype && strcmp( fstype, "sshfs" ) )
{
wlog( "udevil: error: invalid type '%s' for sshfs share - must be sshfs\n",
fstype, 2 );
goto _net_free;
}
nm->fstype = g_strdup( "sshfs" );
}
else if ( g_str_has_prefix( xurl, "ssh:" ) || g_str_has_prefix( xurl, "sshfs:" )
|| g_str_has_prefix( xurl, "sftp:" ) )
{
ret = 2;
is_colon = TRUE;
if ( fstype && strcmp( fstype, "sshfs" ) )
{
wlog( "udevil: error: invalid type '%s' for sshfs share - must be sshfs\n",
fstype, 2 );
goto _net_free;
}
nm->fstype = g_strdup( "sshfs" );
}
else if ( ( str = strstr( xurl, ":/" ) ) && xurl[0] != ':' && xurl[0] != '/' )
{
// mount [-t nfs] host:/path
nm->fstype = g_strdup( "nfs" );
nm->url = g_strdup( xurl );
ret = 2;
// path
str = strstr( xurl, ":/" );
nm->path = g_strdup( str + 1 );
str[0] = '\0';
// host
if ( xurl[0] == '[' )
if ( strchr( xurl, '@' ) || !g_strcmp0( fstype, "sshfs" ) )
{
// ipv6 literal
if ( str = strchr( xurl, ']' ) )
nm->fstype = g_strdup( "sshfs" );
if ( fstype && strcmp( fstype, "sshfs" ) )
{
str[0] = '\0';
if ( xurl[1] != '\0' )
nm->host = g_strdup( xurl + 1 );
}
}
else if ( xurl[0] != '\0' )
nm->host = g_strdup( xurl );
}
g_free( orig_url );
// check user supplied fstype
gboolean bad_type = FALSE;
if ( fstype && ret == 2 && nm->host )
{
if ( !strcmp( nm->fstype, "nfs" ) && strcmp( fstype, "nfs" ) )
{
wlog( "udevil: error: invalid type '%s' for NFS share - must be 'nfs'\n",
fstype, 2 );
bad_type = TRUE;
}
else if ( !strcmp( nm->fstype, "smbfs" ) && strcmp( fstype, "smbfs" ) )
{
wlog( "udevil: error: invalid type '%s' for SMB share - must be 'smbfs'\n",
fstype, 2 );
bad_type = TRUE;
}
else if ( !strcmp( nm->fstype, "ftpfs" ) || !strcmp( nm->fstype, "curlftpfs" ) )
{
if ( strcmp( fstype, "ftpfs" ) && strcmp( fstype, "curlftpfs" ) )
{
wlog( "udevil: error: invalid type '%s' for FTP share - must be 'ftpfs' or 'curlftpfs'\n",
wlog( "udevil: error: invalid type '%s' for sshfs share - must be sshfs\n",
fstype, 2 );
bad_type = TRUE;
}
else
{
g_free( nm->fstype );
nm->fstype = g_strdup( fstype );
}
}
}
// check user pass port
if ( ret == 2 && !bad_type && nm->host )
{
if ( ( nm->user && strchr( nm->user, ' ' ) )
|| ( nm->pass && strchr( nm->pass, ' ' ) )
|| ( nm->port && strchr( nm->port, ' ' ) ) )
{
wlog( "udevil: error: invalid network url\n", fstype, 2 );
bad_type = TRUE;
}
}
// lookup ip
if ( ret == 2 && !bad_type )
{
if ( nm->host )
{
if ( !( nm->ip = get_ip( nm->host ) ) || ( nm->ip && nm->ip[0] == '\0' ) )
{
wlog( "udevil: error: lookup host '%s' failed\n", nm->host, 2 );
g_free( nm->host );
nm->host = NULL;
goto _net_free;
}
}
else
wlog( "udevil: error: '%s' is not a recognized network url\n", url, 2 );
{
// mount [-t nfs] host:/path
nm->fstype = g_strdup( "nfs" );
if ( fstype && strcmp( fstype, "nfs" ) && strcmp( fstype, "nfs4" ) )
{
wlog( "udevil: error: invalid type '%s' for NFS share - must be nfs or nfs4\n",
fstype, 2 );
goto _net_free;
}
}
str[0] = ':';
}
if ( ret == 0 || !nm->host || bad_type )
if ( ret != 2 )
goto _net_free;
// parse
if ( is_colon && ( str = strchr( xurl, ':' ) ) )
{
g_free( nm->url );
g_free( nm->fstype );
g_free( nm->host );
g_free( nm->ip );
g_free( nm->port );
g_free( nm->user );
g_free( nm->pass );
g_free( nm->path );
g_slice_free( netmount_t, nm );
return ret;
xurl = str + 1;
}
while ( xurl[0] == '/' )
xurl++;
char* trim_url = g_strdup( xurl );
// path
if ( str = strchr( xurl, '/' ) )
{
nm->path = g_strdup( str );
str[0] = '\0';
}
// user:pass
if ( str = strchr( xurl, '@' ) )
{
str[0] = '\0';
if ( str2 = strchr( xurl, ':' ) )
{
str2[0] = '\0';
if ( str2[1] != '\0' )
nm->pass = g_strdup( str2 + 1 );
}
if ( xurl[0] != '\0' )
nm->user = g_strdup( xurl );
xurl = str + 1;
}
// host:port
if ( xurl[0] == '[' )
{
// ipv6 literal
if ( str = strchr( xurl, ']' ) )
{
str[0] = '\0';
if ( xurl[1] != '\0' )
nm->host = g_strdup( xurl + 1 );
if ( str[1] == ':' && str[2] != '\0' )
nm->port = g_strdup( str + 1 );
}
}
else if ( xurl[0] != '\0' )
{
if ( str = strchr( xurl, ':' ) )
{
str[0] = '\0';
if ( str[1] != '\0' )
nm->port = g_strdup( str + 1 );
}
nm->host = g_strdup( xurl );
}
// url
if ( nm->host )
{
if ( !strcmp( nm->fstype, "cifs" ) || !strcmp( nm->fstype, "smbfs" ) )
nm->url = g_strdup_printf( "//%s%s", nm->host, nm->path ? nm->path : "/" );
else if ( !strcmp( nm->fstype, "nfs" ) )
nm->url = g_strdup_printf( "%s:%s", nm->host, nm->path ? nm->path : "/" );
else if ( !g_strcmp0( nm->fstype, "curlftpfs" ) )
nm->url = g_strdup_printf( "curlftpfs#ftp://%s%s%s%s%s%s%s%s",
nm->user ? nm->user : "",
nm->pass ? ":" : "",
nm->pass ? nm->pass : "",
nm->user || nm->pass ? "@" : "",
nm->host,
nm->port ? ":" : "",
nm->port ? nm->port : "",
nm->path ? nm->path : "/" );
else if ( !g_strcmp0( nm->fstype, "ftpfs" ) )
nm->url = g_strdup( "none" );
else if ( !g_strcmp0( nm->fstype, "sshfs" ) )
nm->url = g_strdup_printf( "sshfs#%s%s%s%s%s:%s%s",
nm->user ? nm->user : "",
nm->pass ? ":" : "",
nm->pass ? nm->pass : "",
nm->user || nm->pass ? "@" : "",
nm->host,
nm->port ? nm->port : "",
nm->path ? nm->path : "/" );
else
nm->url = g_strdup( trim_url );
}
g_free( trim_url );
g_free( orig_url );
if ( !nm->host )
{
wlog( "udevil: error: '%s' is not a recognized network url\n", url, 2 );
goto _net_free;
}
// check user pass port
if ( ( nm->user && strchr( nm->user, ' ' ) )
|| ( nm->pass && strchr( nm->pass, ' ' ) )
|| ( nm->port && strchr( nm->port, ' ' ) ) )
{
wlog( "udevil: error: invalid network url\n", fstype, 2 );
goto _net_free;
}
// lookup ip
if ( !( nm->ip = get_ip( nm->host ) ) || ( nm->ip && nm->ip[0] == '\0' ) )
{
wlog( "udevil: error: lookup host '%s' failed\n", nm->host, 2 );
goto _net_free;
}
// valid
*netmount = nm;
return 1;
_net_free:
g_free( nm->url );
g_free( nm->fstype );
g_free( nm->host );
g_free( nm->ip );
g_free( nm->port );
g_free( nm->user );
g_free( nm->pass );
g_free( nm->path );
g_slice_free( netmount_t, nm );
return ret;
}
static int command_mount( CommandData* data )
@ -2497,6 +2495,14 @@ _get_type:
goto _finish;
}
type = MOUNT_NET;
if ( data->cmd_type == CMD_UNMOUNT
&& g_str_has_prefix( netmount->url, "sshfs#" ) )
{
// sshfs doesn't include sshfs# prefix in mtab
str = netmount->url;
netmount->url = g_strdup( str + 6 );
g_free( str );
}
}
else
{
@ -3282,7 +3288,7 @@ _get_type:
if ( netmount->port )
net_opts = g_strdup_printf( "port=%s", netmount->port );
}
else if ( !strcmp( fstype, "smbfs" ) )
else if ( !strcmp( fstype, "smbfs" ) || !strcmp( fstype, "cifs" ) )
{
net_opts = g_strdup( "" );
if ( netmount->user )
@ -3321,34 +3327,6 @@ _get_type:
g_free( net_opts );
}
// test options
if ( ( i = strspn( options,
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-=+_,.\"'$/" ) )
!= strlen( options ) )
{
str = g_strdup_printf( "udevil: error: options contain an invalid character ('%c')\n",
options[i] );
wlog( str, NULL, 2 );
g_free( str );
ret = 1;
goto _finish;
}
if ( str = validate_options( "allowed_options", fstype, options ) )
{
wlog( "udevil: denied: option '%s' is not an allowed option\n", str, 2 );
g_free( str );
ret = 2;
goto _finish;
}
if ( remount && type == MOUNT_NET && ( !strcmp( fstype, "ftpfs" )
|| !strcmp( fstype, "curlftpfs" ) ) )
{
wlog( "udevil: denied: cannot use remount option with FTP share\n",
NULL, 2 );
ret = 1;
goto _finish;
}
// replace option variables
if ( strstr( options, "$UID" ) )
{
@ -3373,8 +3351,40 @@ _get_type:
g_free( str );
}
// replace fstype
if ( type == MOUNT_NET && !strcmp( fstype, "curlftpfs" ) )
// test options
if ( ( i = strspn( options,
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-=+_,.\"'$/" ) )
!= strlen( options ) )
{
str = g_strdup_printf( "udevil: error: options contain an invalid character ('%c')\n",
options[i] );
wlog( str, NULL, 2 );
g_free( str );
ret = 1;
goto _finish;
}
if ( str = validate_options( "allowed_options", fstype, options ) )
{
wlog( "udevil: denied: option '%s' is not an allowed option\n", str, 2 );
g_free( str );
ret = 2;
goto _finish;
}
// check for net remount
if ( remount && type == MOUNT_NET && ( !strcmp( fstype, "ftpfs" )
|| !strcmp( fstype, "curlftpfs" )
|| !strcmp( fstype, "sshfs" ) ) )
{
wlog( "udevil: denied: cannot use remount option with FTP or sshfs share\n",
NULL, 2 );
ret = 1;
goto _finish;
}
// replace fuse fstype
if ( type == MOUNT_NET && ( !strcmp( fstype, "curlftpfs" )
|| !strcmp( fstype, "sshfs" ) ) )
{
g_free( fstype );
fstype = g_strdup( "fuse" );
@ -3571,8 +3581,11 @@ _get_type:
{
if ( !strcmp( netmount->fstype, "nfs" ) )
str = "nfs";
else if ( !strcmp( netmount->fstype, "smbfs" ) )
else if ( !strcmp( netmount->fstype, "cifs" )
|| !strcmp( netmount->fstype, "smbfs" ) )
str = "smb";
else if ( !strcmp( netmount->fstype, "sshfs" ) )
str = "ssh";
else
str = "ftp";
@ -4032,7 +4045,7 @@ static void show_help()
//printf( " udevil mount -L 'Disk Label'\n" );
printf( " udevil mount /tmp/example.iso # ISO file\n" );
printf( " udevil mount ftp://sys.domain # ftp site - requires\n" );
printf( " ftpfs or curlftpfs\n" );
printf( " curlftpfs or ftpfs\n" );
printf( " udevil mount ftp://user:pass@sys.domain/share # ftp share with\n" );
printf( " user and password\n" );
printf( " udevil mount ftp://user:pass@sys.domain:21/share # ftp share with\n" );
@ -4042,9 +4055,13 @@ static void show_help()
printf( " udevil mount -t curlftpfs user:pass@sys.domain # ftp site with curl u/p\n" );
printf( " udevil mount nfs://sys.domain:/share # nfs share\n" );
printf( " udevil mount sys.domain:/share # nfs share\n" );
printf( " udevil mount smb://sys.domain/share # samba share\n" );
printf( " udevil mount smb://sys.domain/share # samba share w/ cifs\n" );
printf( " udevil mount smb://user:pass@10.0.0.1:50/share # samba share w/ u/p/port\n" );
printf( " udevil mount //sys.domain/share # samba share\n" );
printf( " udevil mount //sys.domain/share # samba share w/ cifs\n" );
printf( " udevil mount //sys.domain/share -t smbfs # samba share w/ smbfs\n" );
printf( " udevil mount ssh://user@sys.domain # sshfs with user - \n" );
printf( " requires sshfs\n" );
printf( " udevil mount -t sshfs user@sys.domain # sshfs with user\n" );
printf( "UNMOUNT - Unmount DEVICE or DIR with UNMOUNT-OPTIONS:\n" );
printf( " udevil umount|unmount|--unmount|--umount [UNMOUNT-OPTIONS] \n" );
printf( " {[-b|--block-device] DEVICE}|DIR\n" );