diff options
Diffstat (limited to 'src/logicalfile/LMI_UnixFileProvider.c')
-rw-r--r-- | src/logicalfile/LMI_UnixFileProvider.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/logicalfile/LMI_UnixFileProvider.c b/src/logicalfile/LMI_UnixFileProvider.c index 937fa04..d822565 100644 --- a/src/logicalfile/LMI_UnixFileProvider.c +++ b/src/logicalfile/LMI_UnixFileProvider.c @@ -18,13 +18,50 @@ * Authors: Jan Synacek <jsynacek@redhat.com> */ #include <konkret/konkret.h> +#include <sys/time.h> #include "LMI_UnixFile.h" #include "file.h" static const CMPIBroker* _cb = NULL; +#ifdef LOGICALFILE_SELINUX +#include <selinux/selinux.h> +#include <selinux/label.h> + +static struct selabel_handle *_selabel_hnd = NULL; +static struct selabel_handle *get_selabel_handle() +{ + static struct timeval timestamp = {.tv_sec = 0, .tv_usec = 0}; + const unsigned int CHECK_PERIOD = 20; /* seconds */ + const char *err = "gettimeofday() failed, selinux handle might not get re-initialized"; + + if (_selabel_hnd == NULL) { + _selabel_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0); + if (gettimeofday(×tamp, NULL) < 0) { + lmi_warn(err); + } + } else { + struct timeval now; + if (gettimeofday(&now, NULL) < 0) { + lmi_warn(err); + } + /* reinit handle if it's too old */ + if (now.tv_sec - timestamp.tv_sec >= CHECK_PERIOD) { + selabel_close(_selabel_hnd); + _selabel_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0); + if (gettimeofday(×tamp, NULL) < 0) { + lmi_warn(err); + } + } + } + + return _selabel_hnd; +} +#endif + static void LMI_UnixFileInitialize() { + lmi_init_logging(LMI_UnixFile_ClassName, _cb); } static CMPIStatus LMI_UnixFileCleanup( @@ -32,6 +69,11 @@ static CMPIStatus LMI_UnixFileCleanup( const CMPIContext* cc, CMPIBoolean term) { +#ifdef LOGICALFILE_SELINUX + if (_selabel_hnd != NULL) { + selabel_close(_selabel_hnd); + } +#endif CMReturn(CMPI_RC_OK); } @@ -90,6 +132,25 @@ static CMPIStatus LMI_UnixFileGetInstance( LMI_UnixFile_Set_LinkCount(&lmi_file, sb.st_nlink); /* sticky bit */ LMI_UnixFile_Set_SaveText(&lmi_file, sb.st_mode & S_IFMT & S_ISVTX); +#ifdef LOGICALFILE_SELINUX + /* selinux */ + security_context_t context; + struct selabel_handle *hnd; + if (lgetfilecon(path, &context) < 0) { + CMReturnWithChars(_cb, CMPI_RC_ERR_NOT_FOUND, "Can't get selinux file context"); + } + LMI_UnixFile_Set_SELinuxCurrentContext(&lmi_file, context); + freecon(context); + hnd = get_selabel_handle(); + if (hnd == NULL) { + CMReturnWithChars(_cb, CMPI_RC_ERR_NOT_FOUND, "Can't get selabel handle"); + } + if (selabel_lookup(hnd, &context, path, 0) < 0) { + CMReturnWithChars(_cb, CMPI_RC_ERR_NOT_FOUND, "Can't look up selinux file context"); + } + LMI_UnixFile_Set_SELinuxExpectedContext(&lmi_file, context); + freecon(context); +#endif KReturnInstance(cr, lmi_file); CMReturn(CMPI_RC_OK); |