2014-02-20 22:26:54 +04:00
/***
This file is part of systemd .
Copyright 2010 Lennart Poettering
systemd is free software ; you can redistribute it and / or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation ; either version 2.1 of the License , or
( at your option ) any later version .
systemd 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
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public License
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
# include <errno.h>
2015-12-03 23:13:37 +03:00
# include <fcntl.h>
2015-10-22 21:12:31 +03:00
# include <fnmatch.h>
2015-12-03 23:13:37 +03:00
# include <limits.h>
2015-10-22 21:12:31 +03:00
# include <stdlib.h>
2014-02-20 22:26:54 +04:00
# include <string.h>
2015-12-03 23:13:37 +03:00
# include <sys/stat.h>
# include <time.h>
2014-02-20 22:26:54 +04:00
# include <unistd.h>
2014-11-06 03:40:37 +03:00
# include "sd-id128.h"
2015-10-22 21:12:31 +03:00
2015-10-27 05:01:06 +03:00
# include "alloc-util.h"
2014-11-06 03:40:37 +03:00
# include "apparmor-util.h"
2015-10-22 21:12:31 +03:00
# include "architecture.h"
2015-10-27 01:32:16 +03:00
# include "audit-util.h"
2014-12-10 05:16:14 +03:00
# include "cap-list.h"
2015-10-25 15:14:12 +03:00
# include "condition.h"
2015-10-22 21:12:31 +03:00
# include "extract-word.h"
2015-10-25 15:14:12 +03:00
# include "fd-util.h"
2016-09-13 03:04:35 +03:00
# include "fileio.h"
2015-10-27 03:48:17 +03:00
# include "glob-util.h"
2015-05-18 18:10:07 +03:00
# include "hostname-util.h"
2015-10-22 21:12:31 +03:00
# include "ima-util.h"
2015-12-03 23:13:37 +03:00
# include "list.h"
# include "macro.h"
2015-10-26 20:44:13 +03:00
# include "mount-util.h"
2015-10-26 18:18:16 +03:00
# include "parse-util.h"
2015-10-22 21:12:31 +03:00
# include "path-util.h"
2015-10-27 02:06:29 +03:00
# include "proc-cmdline.h"
2015-10-22 21:12:31 +03:00
# include "selinux-util.h"
# include "smack-util.h"
2015-10-27 00:01:44 +03:00
# include "stat-util.h"
2015-10-27 00:31:05 +03:00
# include "string-table.h"
2015-10-24 23:58:24 +03:00
# include "string-util.h"
2015-10-22 21:12:31 +03:00
# include "util.h"
# include "virt.h"
2014-02-20 22:26:54 +04:00
Condition * condition_new ( ConditionType type , const char * parameter , bool trigger , bool negate ) {
Condition * c ;
2014-11-06 03:40:37 +03:00
int r ;
2014-02-20 22:26:54 +04:00
2014-11-06 04:11:08 +03:00
assert ( type > = 0 ) ;
2014-02-20 22:26:54 +04:00
assert ( type < _CONDITION_TYPE_MAX ) ;
2015-02-27 22:05:26 +03:00
assert ( ( ! parameter ) = = ( type = = CONDITION_NULL ) ) ;
2014-02-20 22:26:54 +04:00
c = new0 ( Condition , 1 ) ;
if ( ! c )
return NULL ;
c - > type = type ;
c - > trigger = trigger ;
c - > negate = negate ;
2014-11-06 03:40:37 +03:00
r = free_and_strdup ( & c - > parameter , parameter ) ;
if ( r < 0 ) {
free ( c ) ;
return NULL ;
2014-02-20 22:26:54 +04:00
}
return c ;
}
void condition_free ( Condition * c ) {
assert ( c ) ;
free ( c - > parameter ) ;
free ( c ) ;
}
2014-12-18 20:33:05 +03:00
Condition * condition_free_list ( Condition * first ) {
2014-02-20 22:26:54 +04:00
Condition * c , * n ;
LIST_FOREACH_SAFE ( conditions , c , n , first )
condition_free ( c ) ;
2014-12-18 20:33:05 +03:00
return NULL ;
2014-02-20 22:26:54 +04:00
}
2014-11-06 04:02:13 +03:00
static int condition_test_kernel_command_line ( Condition * c ) {
2014-11-05 21:43:55 +03:00
_cleanup_free_ char * line = NULL ;
const char * p ;
2014-02-20 22:26:54 +04:00
bool equal ;
int r ;
assert ( c ) ;
assert ( c - > parameter ) ;
assert ( c - > type = = CONDITION_KERNEL_COMMAND_LINE ) ;
r = proc_cmdline ( & line ) ;
if ( r < 0 )
2014-11-06 02:49:44 +03:00
return r ;
2014-02-20 22:26:54 +04:00
equal = ! ! strchr ( c - > parameter , ' = ' ) ;
2014-11-05 21:43:55 +03:00
p = line ;
for ( ; ; ) {
_cleanup_free_ char * word = NULL ;
bool found ;
2015-06-23 19:26:49 +03:00
r = extract_first_word ( & p , & word , NULL , EXTRACT_QUOTES | EXTRACT_RELAX ) ;
2014-11-06 02:49:44 +03:00
if ( r < 0 )
return r ;
if ( r = = 0 )
2014-11-06 04:02:13 +03:00
break ;
2014-11-05 21:43:55 +03:00
if ( equal )
found = streq ( word , c - > parameter ) ;
else {
const char * f ;
f = startswith ( word , c - > parameter ) ;
found = f & & ( * f = = ' = ' | | * f = = 0 ) ;
2014-02-20 22:26:54 +04:00
}
2014-11-05 21:43:55 +03:00
if ( found )
2014-11-06 04:02:13 +03:00
return true ;
2014-02-20 22:26:54 +04:00
}
2014-11-06 04:02:13 +03:00
return false ;
2014-02-20 22:26:54 +04:00
}
2014-11-06 04:02:13 +03:00
static int condition_test_virtualization ( Condition * c ) {
2014-02-24 01:05:18 +04:00
int b , v ;
2014-02-20 22:26:54 +04:00
assert ( c ) ;
assert ( c - > parameter ) ;
assert ( c - > type = = CONDITION_VIRTUALIZATION ) ;
2016-10-22 05:56:58 +03:00
if ( streq ( c - > parameter , " private-users " ) )
return running_in_userns ( ) ;
2015-09-07 14:42:47 +03:00
v = detect_virtualization ( ) ;
2014-11-06 02:49:44 +03:00
if ( v < 0 )
return v ;
2014-02-20 22:26:54 +04:00
/* First, compare with yes/no */
b = parse_boolean ( c - > parameter ) ;
2016-10-25 05:53:07 +03:00
if ( b > = 0 )
return b = = ! ! v ;
2014-02-20 22:26:54 +04:00
/* Then, compare categorization */
2016-10-25 05:53:07 +03:00
if ( streq ( c - > parameter , " vm " ) )
return VIRTUALIZATION_IS_VM ( v ) ;
2014-02-20 22:26:54 +04:00
2016-10-25 05:53:07 +03:00
if ( streq ( c - > parameter , " container " ) )
return VIRTUALIZATION_IS_CONTAINER ( v ) ;
2014-02-20 22:26:54 +04:00
/* Finally compare id */
2015-09-07 14:42:47 +03:00
return v ! = VIRTUALIZATION_NONE & & streq ( c - > parameter , virtualization_to_string ( v ) ) ;
2014-02-20 22:26:54 +04:00
}
2014-11-06 04:02:13 +03:00
static int condition_test_architecture ( Condition * c ) {
2014-11-06 02:49:44 +03:00
int a , b ;
2014-02-21 05:06:04 +04:00
assert ( c ) ;
assert ( c - > parameter ) ;
assert ( c - > type = = CONDITION_ARCHITECTURE ) ;
a = uname_architecture ( ) ;
if ( a < 0 )
2014-11-06 02:49:44 +03:00
return a ;
2014-02-21 05:06:04 +04:00
if ( streq ( c - > parameter , " native " ) )
b = native_architecture ( ) ;
2016-07-01 01:56:23 +03:00
else {
2014-02-21 05:06:04 +04:00
b = architecture_from_string ( c - > parameter ) ;
2016-07-01 01:56:23 +03:00
if ( b < 0 ) /* unknown architecture? Then it's definitely not ours */
return false ;
}
2014-02-21 05:06:04 +04:00
2014-11-06 04:02:13 +03:00
return a = = b ;
2014-02-21 05:06:04 +04:00
}
2014-11-06 04:02:13 +03:00
static int condition_test_host ( Condition * c ) {
2014-06-13 14:39:58 +04:00
_cleanup_free_ char * h = NULL ;
2014-02-20 22:26:54 +04:00
sd_id128_t x , y ;
int r ;
assert ( c ) ;
assert ( c - > parameter ) ;
assert ( c - > type = = CONDITION_HOST ) ;
if ( sd_id128_from_string ( c - > parameter , & x ) > = 0 ) {
r = sd_id128_get_machine ( & y ) ;
if ( r < 0 )
2014-11-06 02:49:44 +03:00
return r ;
2014-02-20 22:26:54 +04:00
2014-11-06 04:02:13 +03:00
return sd_id128_equal ( x , y ) ;
2014-02-20 22:26:54 +04:00
}
h = gethostname_malloc ( ) ;
if ( ! h )
2014-11-06 02:49:44 +03:00
return - ENOMEM ;
2014-02-20 22:26:54 +04:00
2014-11-06 04:02:13 +03:00
return fnmatch ( c - > parameter , h , FNM_CASEFOLD ) = = 0 ;
2014-02-20 22:26:54 +04:00
}
2014-11-06 04:02:13 +03:00
static int condition_test_ac_power ( Condition * c ) {
2014-02-20 22:26:54 +04:00
int r ;
assert ( c ) ;
assert ( c - > parameter ) ;
assert ( c - > type = = CONDITION_AC_POWER ) ;
r = parse_boolean ( c - > parameter ) ;
if ( r < 0 )
2014-11-06 02:49:44 +03:00
return r ;
2014-02-20 22:26:54 +04:00
2014-11-06 04:02:13 +03:00
return ( on_ac_power ( ) ! = 0 ) = = ! ! r ;
2014-02-20 22:26:54 +04:00
}
2014-11-06 03:40:37 +03:00
static int condition_test_security ( Condition * c ) {
assert ( c ) ;
assert ( c - > parameter ) ;
assert ( c - > type = = CONDITION_SECURITY ) ;
if ( streq ( c - > parameter , " selinux " ) )
2015-11-27 22:22:56 +03:00
return mac_selinux_have ( ) ;
2014-11-06 03:40:37 +03:00
if ( streq ( c - > parameter , " smack " ) )
2014-11-06 04:02:13 +03:00
return mac_smack_use ( ) ;
2014-11-06 03:40:37 +03:00
if ( streq ( c - > parameter , " apparmor " ) )
2014-11-06 04:02:13 +03:00
return mac_apparmor_use ( ) ;
2014-11-06 03:40:37 +03:00
if ( streq ( c - > parameter , " audit " ) )
2014-11-06 04:02:13 +03:00
return use_audit ( ) ;
2014-11-06 03:40:37 +03:00
if ( streq ( c - > parameter , " ima " ) )
2014-11-06 04:02:13 +03:00
return use_ima ( ) ;
2014-11-06 03:40:37 +03:00
2014-11-06 04:02:13 +03:00
return false ;
2014-11-06 03:40:37 +03:00
}
static int condition_test_capability ( Condition * c ) {
_cleanup_fclose_ FILE * f = NULL ;
2014-12-10 05:16:14 +03:00
int value ;
2014-11-06 03:40:37 +03:00
char line [ LINE_MAX ] ;
unsigned long long capabilities = - 1 ;
assert ( c ) ;
assert ( c - > parameter ) ;
assert ( c - > type = = CONDITION_CAPABILITY ) ;
/* If it's an invalid capability, we don't have it */
2014-12-10 05:16:14 +03:00
value = capability_from_name ( c - > parameter ) ;
if ( value < 0 )
2014-11-06 03:40:37 +03:00
return - EINVAL ;
/* If it's a valid capability we default to assume
* that we have it */
f = fopen ( " /proc/self/status " , " re " ) ;
if ( ! f )
return - errno ;
while ( fgets ( line , sizeof ( line ) , f ) ) {
truncate_nl ( line ) ;
if ( startswith ( line , " CapBnd: " ) ) {
( void ) sscanf ( line + 7 , " %llx " , & capabilities ) ;
break ;
}
}
2014-11-06 04:02:13 +03:00
return ! ! ( capabilities & ( 1ULL < < value ) ) ;
2014-11-06 03:40:37 +03:00
}
static int condition_test_needs_update ( Condition * c ) {
const char * p ;
struct stat usr , other ;
assert ( c ) ;
assert ( c - > parameter ) ;
assert ( c - > type = = CONDITION_NEEDS_UPDATE ) ;
/* If the file system is read-only we shouldn't suggest an update */
if ( path_is_read_only_fs ( c - > parameter ) > 0 )
2014-11-06 04:02:13 +03:00
return false ;
2014-11-06 03:40:37 +03:00
/* Any other failure means we should allow the condition to be true,
2016-02-08 15:27:22 +03:00
* so that we rather invoke too many update tools than too
2014-11-06 03:40:37 +03:00
* few . */
if ( ! path_is_absolute ( c - > parameter ) )
2014-11-06 04:02:13 +03:00
return true ;
2014-11-06 03:40:37 +03:00
2015-02-03 04:05:59 +03:00
p = strjoina ( c - > parameter , " /.updated " ) ;
2014-11-06 03:40:37 +03:00
if ( lstat ( p , & other ) < 0 )
2014-11-06 04:02:13 +03:00
return true ;
2014-11-06 03:40:37 +03:00
if ( lstat ( " /usr/ " , & usr ) < 0 )
2014-11-06 04:02:13 +03:00
return true ;
2014-11-06 03:40:37 +03:00
2016-09-13 03:04:35 +03:00
/*
* First , compare seconds as they are always accurate . . .
*/
if ( usr . st_mtim . tv_sec ! = other . st_mtim . tv_sec )
return usr . st_mtim . tv_sec > other . st_mtim . tv_sec ;
/*
* . . . then compare nanoseconds .
*
* A false positive is only possible when / usr ' s nanoseconds > 0
* ( otherwise / usr cannot be strictly newer than the target file )
* AND the target file ' s nanoseconds = = 0
* ( otherwise the filesystem supports nsec timestamps , see stat ( 2 ) ) .
*/
if ( usr . st_mtim . tv_nsec > 0 & & other . st_mtim . tv_nsec = = 0 ) {
_cleanup_free_ char * timestamp_str = NULL ;
uint64_t timestamp ;
int r ;
2016-10-21 19:26:30 +03:00
r = parse_env_file ( p , NULL , " TIMESTAMP_NSEC " , & timestamp_str , NULL ) ;
2016-09-13 03:04:35 +03:00
if ( r < 0 ) {
2016-10-21 19:26:30 +03:00
log_error_errno ( r , " Failed to parse timestamp file '%s', using mtime: %m " , p ) ;
2016-09-13 03:04:35 +03:00
return true ;
} else if ( r = = 0 ) {
log_debug ( " No data in timestamp file '%s', using mtime " , p ) ;
return true ;
}
r = safe_atou64 ( timestamp_str , & timestamp ) ;
if ( r < 0 ) {
2016-10-21 19:26:30 +03:00
log_error_errno ( r , " Failed to parse timestamp value '%s' in file '%s', using mtime: %m " , timestamp_str , p ) ;
2016-09-13 03:04:35 +03:00
return true ;
}
2016-10-21 19:26:30 +03:00
timespec_store ( & other . st_mtim , timestamp ) ;
2016-09-13 03:04:35 +03:00
}
return usr . st_mtim . tv_nsec > other . st_mtim . tv_nsec ;
2014-11-06 03:40:37 +03:00
}
static int condition_test_first_boot ( Condition * c ) {
int r ;
assert ( c ) ;
assert ( c - > parameter ) ;
assert ( c - > type = = CONDITION_FIRST_BOOT ) ;
r = parse_boolean ( c - > parameter ) ;
if ( r < 0 )
return r ;
2014-11-06 04:02:13 +03:00
return ( access ( " /run/systemd/first-boot " , F_OK ) > = 0 ) = = ! ! r ;
2014-11-06 03:40:37 +03:00
}
static int condition_test_path_exists ( Condition * c ) {
assert ( c ) ;
assert ( c - > parameter ) ;
assert ( c - > type = = CONDITION_PATH_EXISTS ) ;
2014-11-06 04:02:13 +03:00
return access ( c - > parameter , F_OK ) > = 0 ;
2014-11-06 03:40:37 +03:00
}
static int condition_test_path_exists_glob ( Condition * c ) {
assert ( c ) ;
assert ( c - > parameter ) ;
assert ( c - > type = = CONDITION_PATH_EXISTS_GLOB ) ;
2014-11-06 04:02:13 +03:00
return glob_exists ( c - > parameter ) > 0 ;
2014-11-06 03:40:37 +03:00
}
static int condition_test_path_is_directory ( Condition * c ) {
assert ( c ) ;
assert ( c - > parameter ) ;
assert ( c - > type = = CONDITION_PATH_IS_DIRECTORY ) ;
2014-11-06 04:02:13 +03:00
return is_dir ( c - > parameter , true ) > 0 ;
2014-11-06 03:40:37 +03:00
}
static int condition_test_path_is_symbolic_link ( Condition * c ) {
assert ( c ) ;
assert ( c - > parameter ) ;
assert ( c - > type = = CONDITION_PATH_IS_SYMBOLIC_LINK ) ;
2014-11-06 04:02:13 +03:00
return is_symlink ( c - > parameter ) > 0 ;
2014-11-06 03:40:37 +03:00
}
static int condition_test_path_is_mount_point ( Condition * c ) {
assert ( c ) ;
assert ( c - > parameter ) ;
assert ( c - > type = = CONDITION_PATH_IS_MOUNT_POINT ) ;
2015-05-29 18:13:12 +03:00
return path_is_mount_point ( c - > parameter , AT_SYMLINK_FOLLOW ) > 0 ;
2014-11-06 03:40:37 +03:00
}
static int condition_test_path_is_read_write ( Condition * c ) {
assert ( c ) ;
assert ( c - > parameter ) ;
assert ( c - > type = = CONDITION_PATH_IS_READ_WRITE ) ;
2014-11-06 04:02:13 +03:00
return path_is_read_only_fs ( c - > parameter ) < = 0 ;
2014-11-06 03:40:37 +03:00
}
static int condition_test_directory_not_empty ( Condition * c ) {
int r ;
assert ( c ) ;
assert ( c - > parameter ) ;
assert ( c - > type = = CONDITION_DIRECTORY_NOT_EMPTY ) ;
r = dir_is_empty ( c - > parameter ) ;
2014-11-06 04:02:13 +03:00
return r < = 0 & & r ! = - ENOENT ;
2014-11-06 03:40:37 +03:00
}
static int condition_test_file_not_empty ( Condition * c ) {
struct stat st ;
assert ( c ) ;
assert ( c - > parameter ) ;
assert ( c - > type = = CONDITION_FILE_NOT_EMPTY ) ;
return ( stat ( c - > parameter , & st ) > = 0 & &
S_ISREG ( st . st_mode ) & &
2014-11-06 04:02:13 +03:00
st . st_size > 0 ) ;
2014-11-06 03:40:37 +03:00
}
static int condition_test_file_is_executable ( Condition * c ) {
struct stat st ;
assert ( c ) ;
assert ( c - > parameter ) ;
assert ( c - > type = = CONDITION_FILE_IS_EXECUTABLE ) ;
return ( stat ( c - > parameter , & st ) > = 0 & &
S_ISREG ( st . st_mode ) & &
2014-11-06 04:02:13 +03:00
( st . st_mode & 0111 ) ) ;
2014-11-06 03:40:37 +03:00
}
static int condition_test_null ( Condition * c ) {
assert ( c ) ;
assert ( c - > type = = CONDITION_NULL ) ;
/* Note that during parsing we already evaluate the string and
* store it in c - > negate */
2014-11-06 04:02:13 +03:00
return true ;
2014-11-06 03:40:37 +03:00
}
int condition_test ( Condition * c ) {
static int ( * const condition_tests [ _CONDITION_TYPE_MAX ] ) ( Condition * c ) = {
[ CONDITION_PATH_EXISTS ] = condition_test_path_exists ,
[ CONDITION_PATH_EXISTS_GLOB ] = condition_test_path_exists_glob ,
[ CONDITION_PATH_IS_DIRECTORY ] = condition_test_path_is_directory ,
[ CONDITION_PATH_IS_SYMBOLIC_LINK ] = condition_test_path_is_symbolic_link ,
[ CONDITION_PATH_IS_MOUNT_POINT ] = condition_test_path_is_mount_point ,
[ CONDITION_PATH_IS_READ_WRITE ] = condition_test_path_is_read_write ,
[ CONDITION_DIRECTORY_NOT_EMPTY ] = condition_test_directory_not_empty ,
[ CONDITION_FILE_NOT_EMPTY ] = condition_test_file_not_empty ,
[ CONDITION_FILE_IS_EXECUTABLE ] = condition_test_file_is_executable ,
[ CONDITION_KERNEL_COMMAND_LINE ] = condition_test_kernel_command_line ,
[ CONDITION_VIRTUALIZATION ] = condition_test_virtualization ,
[ CONDITION_SECURITY ] = condition_test_security ,
[ CONDITION_CAPABILITY ] = condition_test_capability ,
[ CONDITION_HOST ] = condition_test_host ,
[ CONDITION_AC_POWER ] = condition_test_ac_power ,
[ CONDITION_ARCHITECTURE ] = condition_test_architecture ,
[ CONDITION_NEEDS_UPDATE ] = condition_test_needs_update ,
[ CONDITION_FIRST_BOOT ] = condition_test_first_boot ,
[ CONDITION_NULL ] = condition_test_null ,
} ;
2014-11-06 04:27:10 +03:00
int r , b ;
2014-11-06 03:40:37 +03:00
assert ( c ) ;
assert ( c - > type > = 0 ) ;
assert ( c - > type < _CONDITION_TYPE_MAX ) ;
2014-11-06 04:02:13 +03:00
r = condition_tests [ c - > type ] ( c ) ;
2014-11-06 04:27:10 +03:00
if ( r < 0 ) {
c - > result = CONDITION_ERROR ;
2014-11-06 04:02:13 +03:00
return r ;
2014-11-06 04:27:10 +03:00
}
2014-11-06 04:02:13 +03:00
2014-11-06 04:27:10 +03:00
b = ( r > 0 ) = = ! c - > negate ;
c - > result = b ? CONDITION_SUCCEEDED : CONDITION_FAILED ;
return b ;
2014-11-06 03:40:37 +03:00
}
2014-11-06 15:43:45 +03:00
void condition_dump ( Condition * c , FILE * f , const char * prefix , const char * ( * to_string ) ( ConditionType t ) ) {
2014-02-20 22:26:54 +04:00
assert ( c ) ;
assert ( f ) ;
if ( ! prefix )
prefix = " " ;
fprintf ( f ,
" %s \t %s: %s%s%s %s \n " ,
prefix ,
2014-11-06 15:43:45 +03:00
to_string ( c - > type ) ,
2014-02-20 22:26:54 +04:00
c - > trigger ? " | " : " " ,
c - > negate ? " ! " : " " ,
c - > parameter ,
2014-11-06 04:27:10 +03:00
condition_result_to_string ( c - > result ) ) ;
2014-02-20 22:26:54 +04:00
}
2014-11-06 15:43:45 +03:00
void condition_dump_list ( Condition * first , FILE * f , const char * prefix , const char * ( * to_string ) ( ConditionType t ) ) {
2014-02-20 22:26:54 +04:00
Condition * c ;
LIST_FOREACH ( conditions , c , first )
2014-11-06 15:43:45 +03:00
condition_dump ( c , f , prefix , to_string ) ;
2014-02-20 22:26:54 +04:00
}
static const char * const condition_type_table [ _CONDITION_TYPE_MAX ] = {
2014-11-06 15:56:22 +03:00
[ CONDITION_ARCHITECTURE ] = " ConditionArchitecture " ,
[ CONDITION_VIRTUALIZATION ] = " ConditionVirtualization " ,
[ CONDITION_HOST ] = " ConditionHost " ,
[ CONDITION_KERNEL_COMMAND_LINE ] = " ConditionKernelCommandLine " ,
[ CONDITION_SECURITY ] = " ConditionSecurity " ,
[ CONDITION_CAPABILITY ] = " ConditionCapability " ,
[ CONDITION_AC_POWER ] = " ConditionACPower " ,
[ CONDITION_NEEDS_UPDATE ] = " ConditionNeedsUpdate " ,
[ CONDITION_FIRST_BOOT ] = " ConditionFirstBoot " ,
2014-02-20 22:26:54 +04:00
[ CONDITION_PATH_EXISTS ] = " ConditionPathExists " ,
[ CONDITION_PATH_EXISTS_GLOB ] = " ConditionPathExistsGlob " ,
[ CONDITION_PATH_IS_DIRECTORY ] = " ConditionPathIsDirectory " ,
[ CONDITION_PATH_IS_SYMBOLIC_LINK ] = " ConditionPathIsSymbolicLink " ,
[ CONDITION_PATH_IS_MOUNT_POINT ] = " ConditionPathIsMountPoint " ,
[ CONDITION_PATH_IS_READ_WRITE ] = " ConditionPathIsReadWrite " ,
[ CONDITION_DIRECTORY_NOT_EMPTY ] = " ConditionDirectoryNotEmpty " ,
[ CONDITION_FILE_NOT_EMPTY ] = " ConditionFileNotEmpty " ,
[ CONDITION_FILE_IS_EXECUTABLE ] = " ConditionFileIsExecutable " ,
[ CONDITION_NULL ] = " ConditionNull "
} ;
DEFINE_STRING_TABLE_LOOKUP ( condition_type , ConditionType ) ;
2014-11-06 04:27:10 +03:00
2014-11-06 15:43:45 +03:00
static const char * const assert_type_table [ _CONDITION_TYPE_MAX ] = {
2014-11-06 15:56:22 +03:00
[ CONDITION_ARCHITECTURE ] = " AssertArchitecture " ,
[ CONDITION_VIRTUALIZATION ] = " AssertVirtualization " ,
[ CONDITION_HOST ] = " AssertHost " ,
[ CONDITION_KERNEL_COMMAND_LINE ] = " AssertKernelCommandLine " ,
[ CONDITION_SECURITY ] = " AssertSecurity " ,
[ CONDITION_CAPABILITY ] = " AssertCapability " ,
[ CONDITION_AC_POWER ] = " AssertACPower " ,
[ CONDITION_NEEDS_UPDATE ] = " AssertNeedsUpdate " ,
[ CONDITION_FIRST_BOOT ] = " AssertFirstBoot " ,
2014-11-06 15:43:45 +03:00
[ CONDITION_PATH_EXISTS ] = " AssertPathExists " ,
[ CONDITION_PATH_EXISTS_GLOB ] = " AssertPathExistsGlob " ,
[ CONDITION_PATH_IS_DIRECTORY ] = " AssertPathIsDirectory " ,
[ CONDITION_PATH_IS_SYMBOLIC_LINK ] = " AssertPathIsSymbolicLink " ,
[ CONDITION_PATH_IS_MOUNT_POINT ] = " AssertPathIsMountPoint " ,
[ CONDITION_PATH_IS_READ_WRITE ] = " AssertPathIsReadWrite " ,
[ CONDITION_DIRECTORY_NOT_EMPTY ] = " AssertDirectoryNotEmpty " ,
[ CONDITION_FILE_NOT_EMPTY ] = " AssertFileNotEmpty " ,
[ CONDITION_FILE_IS_EXECUTABLE ] = " AssertFileIsExecutable " ,
[ CONDITION_NULL ] = " AssertNull "
} ;
DEFINE_STRING_TABLE_LOOKUP ( assert_type , ConditionType ) ;
2014-11-06 04:27:10 +03:00
static const char * const condition_result_table [ _CONDITION_RESULT_MAX ] = {
[ CONDITION_UNTESTED ] = " untested " ,
[ CONDITION_SUCCEEDED ] = " succeeded " ,
[ CONDITION_FAILED ] = " failed " ,
[ CONDITION_ERROR ] = " error " ,
} ;
DEFINE_STRING_TABLE_LOOKUP ( condition_result , ConditionResult ) ;