From cb33c54d000056565998d8d85f188bd63d458f08 Mon Sep 17 00:00:00 2001 From: IgnorantGuru Date: Mon, 27 Apr 2015 19:32:40 -0600 Subject: [PATCH] support git-style /** suffix for some udevil.conf patterns #37 allowed_files forbidden_files allowed_media_dirs patterns accept a /** suffix to indicate recursive match, if no other wildcards are used. ** is not accepted elsewhere. --- ChangeLog | 1 + etc/udevil.conf | 11 +++++++---- src/udevil.c | 40 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8e2aaca..5c1737e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,7 @@ udevil.conf allowed_options_ftpfs remove ip=*; add ip= after test #46 respect configure option --sysconfdir #31 #53 udisks2 compatibility: replace /run/media/$USER with /media/$USER #47 + support git-style /** suffix for some udevil.conf patterns #37 0.4.3 2013-12-09: fix default udevil.conf allowed_options missing fmask=0133 #35 0.4.2 2013-12-04: diff --git a/etc/udevil.conf b/etc/udevil.conf index c9983f2..75a4c0d 100644 --- a/etc/udevil.conf +++ b/etc/udevil.conf @@ -87,7 +87,7 @@ allowed_groups = * # /media/$USER). # The $USER variable, if included, will be replaced with the username of the # user running udevil. Wildcards may also be used in any directory EXCEPT the -# default. Wildcards will not match a / +# default. Wildcards will not match a /, except a /** suffix for recursion. # allowed_media_dirs_FSTYPE, if present, is used to override allowed_media_dirs # when mounting or unmounting a specific fstype (eg ext2, nfs). For example, # to cause /media/network to be used as the default media directory for @@ -184,9 +184,12 @@ forbidden_networks = # allowed_files is used to determine what files in what directories may be # un/mounted. A user must also have read permission on a file to mount it. # Note: Wildcards may be used, but a wildcard will never match a /, except -# for "allowed_files=*" which allows any file. For example, to allow only -# files in the /share directory to be mounted, use: +# for "allowed_files=*" which allows any file, and a /** suffix, which matches +# all files recursively. +# For example, to allow only files in the /share directory to be mounted, use: # allowed_files = /share/* +# To allow all files in the /share directory AND all subdirectories use: +# allowed_files = /share/** # NOTE: Specifying allowed_files_FSTYPE will NOT work because the fstype of # files is always 'file'. allowed_files = * @@ -195,7 +198,7 @@ allowed_files = * # forbidden_files is used to specify files that are never allowed, even if # 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 = *". +# for "forbidden_files = *", or a /** suffix, which matches all recursively. # NOTE: file paths are canonicalized before being tested, so forbidding # a link to a file will have no effect. forbidden_files = diff --git a/src/udevil.c b/src/udevil.c index 73c5dfe..ab1eae3 100644 --- a/src/udevil.c +++ b/src/udevil.c @@ -1172,7 +1172,6 @@ static void dump_log() static gboolean validate_in_list( const char* name, const char* type, const char* test ) { char* list = NULL; - char* str; char* comma; char* element; char* selement; @@ -1183,6 +1182,11 @@ static gboolean validate_in_list( const char* name, const char* type, const char if ( !( list = read_config( name, type ) ) ) return FALSE; + // these names support git-style /** suffix for recursive match + gboolean depth = !strcmp( name, "allowed_files" ) || + !strcmp( name, "forbidden_files" ) || + !strcmp( name, "allowed_media_dirs" ); + //printf("list[%s_%s] = {%s}\n", name, type, list ); while ( list && list[0] ) { @@ -1198,9 +1202,41 @@ static gboolean validate_in_list( const char* name, const char* type, const char } selement = g_strstrip( element ); if ( selement[0] == '\0' ) + { + g_free( element ); continue; + } //printf(" selement = {%s}\n", selement ); - if ( strcmp( selement, "*" ) == 0 || + + if ( strstr( selement, "**" ) ) + { + // test for valid git-style /** suffix + if ( depth && g_str_has_suffix( selement, "/**" ) ) + { + selement[strlen( selement ) - 2] = '\0'; + if ( !strchr( selement, '*' ) && !strchr( selement, '?' ) ) + { + if ( g_str_has_prefix( test, selement ) ) + { + g_free( element ); + return TRUE; + } + else + { + g_free( element ); + continue; + } + } + } + // fall thru means invalid use + if ( depth ) + wlog( _("udevil: warning 124: invalid use of /** suffix in pattern '%s'\n"), + selement, 1 ); + else + wlog( _("udevil: warning 125: ** wildcard not allowed in %s\n"), + name, 1 ); + } + else if ( strcmp( selement, "*" ) == 0 || fnmatch( selement, test, FNM_PATHNAME ) == 0 ) { g_free( element );