summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRoman Rakus <rrakus@redhat.com>2013-06-26 16:39:57 +0200
committerRoman Rakus <rrakus@redhat.com>2013-07-01 11:32:25 +0200
commit17155ddc8f2d7168a8f6f6fa24439342758d3125 (patch)
treeb917be9030dd0d64be5d701b20d4d410da3350ce /src
parent9382852767bcd560fa14e9cdbbbc8764fdf4dd91 (diff)
downloadopenlmi-providers-17155ddc8f2d7168a8f6f6fa24439342758d3125.tar.gz
openlmi-providers-17155ddc8f2d7168a8f6f6fa24439342758d3125.tar.xz
openlmi-providers-17155ddc8f2d7168a8f6f6fa24439342758d3125.zip
Account: Indications for creation and deletion
Signed-off-by: Roman Rakus <rrakus@redhat.com>
Diffstat (limited to 'src')
-rw-r--r--src/account/CMakeLists.txt13
-rw-r--r--src/account/LMI_AccountInstanceCreationIndicationProvider.c134
-rw-r--r--src/account/LMI_AccountInstanceDeletionIndicationProvider.c137
-rw-r--r--src/account/indication_common.c183
-rw-r--r--src/account/indication_common.h23
5 files changed, 482 insertions, 8 deletions
diff --git a/src/account/CMakeLists.txt b/src/account/CMakeLists.txt
index 38ecd02..a8f8553 100644
--- a/src/account/CMakeLists.txt
+++ b/src/account/CMakeLists.txt
@@ -7,6 +7,7 @@ set(ACCOUNT_SCRIPT cmpiLMI_${PROVIDER_NAME}-cimprovagt)
set(provider_SRCS
aux_lu.c
account_globals.c
+ indication_common.c
)
if (NOT DEFINED CRYPT_ALGS)
@@ -15,7 +16,7 @@ if (NOT DEFINED CRYPT_ALGS)
endif (NOT DEFINED CRYPT_ALGS)
message ("Using crypto algorithms: ${CRYPT_ALGS}")
-add_definitions(-DCRYPT_ALGS=${CRYPT_ALGS})
+add_definitions(-DCRYPT_ALGS=${CRYPT_ALGS} -DINOTIFY_THREAD_SAFE)
konkretcmpi_generate(${MOF}
CIM_PROVIDERS
@@ -31,15 +32,11 @@ add_library(${LIBRARY_NAME} SHARED
# Require GLib-2.0 and libuser
pkg_check_modules(GLIB REQUIRED glib-2.0)
pkg_check_modules(LIBUSER REQUIRED libuser)
+pkg_check_modules(IM REQUIRED openlmiindmanager)
-include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMPI_INCLUDE_DIR} ${GLIB_INCLUDE_DIRS})
+include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMPI_INCLUDE_DIR} ${GLIB_INCLUDE_DIRS} ${LIBUSER_INCLUDE_DIRS} ${IM_INCLUDE_DIRS})
-target_link_libraries(${LIBRARY_NAME} openlmicommon ${KONKRETCMPI_LIBRARIES} ${GLIB_LIBRARIES})
-
-
-include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMPI_INCLUDE_DIR} ${LIBUSER_INCLUDE_DIRS})
-
-target_link_libraries(${LIBRARY_NAME} openlmicommon ${KONKRETCMPI_LIBRARIES} ${LIBUSER_LIBRARIES})
+target_link_libraries(${LIBRARY_NAME} openlmicommon ${KONKRETCMPI_LIBRARIES} ${GLIB_LIBRARIES} ${LIBUSER_LIBRARIES} ${IM_LIBRARIES})
# Create registration file
cim_registration(${PROVIDER_NAME} ${LIBRARY_NAME} ${MOF} share/openlmi-providers)
diff --git a/src/account/LMI_AccountInstanceCreationIndicationProvider.c b/src/account/LMI_AccountInstanceCreationIndicationProvider.c
new file mode 100644
index 0000000..bbf69a6
--- /dev/null
+++ b/src/account/LMI_AccountInstanceCreationIndicationProvider.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2013 Red Hat, Inc. All rights reserved.
+ *
+ * This library 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.
+ *
+ * This library 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Roman Rakus <rrakus@redhat.com>
+ */
+
+#include <konkret/konkret.h>
+#include "LMI_AccountInstanceCreationIndication.h"
+
+#include <ind_manager.h>
+#include "indication_common.h"
+
+#include "macros.h"
+
+static const CMPIBroker* _cb = NULL;
+
+static IMManager *im = NULL;
+static IMError im_err = IM_ERR_OK;
+
+static void LMI_AccountInstanceCreationIndicationInitialize()
+{
+ im = im_create_manager(NULL, filter_checker, true, watcher,
+ IM_IND_CREATION, _cb, &im_err);
+}
+
+static CMPIStatus LMI_AccountInstanceCreationIndicationIndicationCleanup(
+ CMPIIndicationMI* mi,
+ const CMPIContext* cc,
+ CMPIBoolean term)
+{
+ if (!im_destroy_manager(im, cc, &im_err)) CMReturn(CMPI_RC_ERR_FAILED);
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_AccountInstanceCreationIndicationAuthorizeFilter(
+ CMPIIndicationMI* mi,
+ const CMPIContext* cc,
+ const CMPISelectExp* se,
+ const char* ns,
+ const CMPIObjectPath* op,
+ const char* user)
+{
+ if (!im_verify_filter(im, se, cc, &im_err) ) {
+ CMReturn(CMPI_RC_ERR_INVALID_QUERY);
+ }
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_AccountInstanceCreationIndicationMustPoll(
+ CMPIIndicationMI* mi,
+ const CMPIContext* cc,
+ const CMPISelectExp* se,
+ const char* ns,
+ const CMPIObjectPath* op)
+{
+ CMReturn(CMPI_RC_ERR_NOT_SUPPORTED);
+}
+
+static CMPIStatus LMI_AccountInstanceCreationIndicationActivateFilter(
+ CMPIIndicationMI* mi,
+ const CMPIContext* cc,
+ const CMPISelectExp* se,
+ const char* ns,
+ const CMPIObjectPath* op,
+ CMPIBoolean firstActivation)
+{
+ if (!im_verify_filter(im, se, cc, &im_err)) {
+ CMReturn(CMPI_RC_ERR_INVALID_QUERY);
+ }
+ if (!im_add_filter(im, (CMPISelectExp*)se, cc, &im_err)) {
+ CMReturn(CMPI_RC_ERR_FAILED);
+ }
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_AccountInstanceCreationIndicationDeActivateFilter(
+ CMPIIndicationMI* mi,
+ const CMPIContext* cc,
+ const CMPISelectExp* se,
+ const char* ns,
+ const CMPIObjectPath* op,
+ CMPIBoolean lastActivation)
+{
+ if (!im_remove_filter(im, se, cc, &im_err)) {
+ CMReturn(CMPI_RC_ERR_FAILED);
+ }
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_AccountInstanceCreationIndicationEnableIndications(
+ CMPIIndicationMI* mi,
+ const CMPIContext* cc)
+{
+ if (!im_start_ind(im, cc, &im_err)) {
+ CMReturn(CMPI_RC_ERR_FAILED);
+ }
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_AccountInstanceCreationIndicationDisableIndications(
+ CMPIIndicationMI* mi,
+ const CMPIContext* cc)
+{
+ if (!im_stop_ind(im, cc, &im_err)) {
+ CMReturn(CMPI_RC_ERR_FAILED);
+ }
+ CMReturn(CMPI_RC_OK);
+}
+
+CMIndicationMIStub(
+ LMI_AccountInstanceCreationIndication,
+ LMI_AccountInstanceCreationIndication,
+ _cb,
+ LMI_AccountInstanceCreationIndicationInitialize())
+
+KONKRET_REGISTRATION(
+ "root/cimv2",
+ "LMI_AccountInstanceCreationIndication",
+ "LMI_AccountInstanceCreationIndication",
+ "indication")
diff --git a/src/account/LMI_AccountInstanceDeletionIndicationProvider.c b/src/account/LMI_AccountInstanceDeletionIndicationProvider.c
new file mode 100644
index 0000000..029fc65
--- /dev/null
+++ b/src/account/LMI_AccountInstanceDeletionIndicationProvider.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2013 Red Hat, Inc. All rights reserved.
+ *
+ * This library 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.
+ *
+ * This library 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Roman Rakus <rrakus@redhat.com>
+ */
+
+#include <konkret/konkret.h>
+#include "LMI_AccountInstanceDeletionIndication.h"
+
+#include <sys/inotify.h>
+#include <unistd.h>
+
+#include <ind_manager.h>
+#include "indication_common.h"
+
+#include "macros.h"
+
+static const CMPIBroker* _cb = NULL;
+
+static IMManager *im = NULL;
+static IMError im_err = IM_ERR_OK;
+
+static void LMI_AccountInstanceDeletionIndicationInitialize()
+{
+ im = im_create_manager(NULL, filter_checker, true, watcher,
+ IM_IND_DELETION, _cb, &im_err);
+}
+
+static CMPIStatus LMI_AccountInstanceDeletionIndicationIndicationCleanup(
+ CMPIIndicationMI* mi,
+ const CMPIContext* cc,
+ CMPIBoolean term)
+{
+ if (!im_destroy_manager(im, cc, &im_err)) CMReturn(CMPI_RC_ERR_FAILED);
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_AccountInstanceDeletionIndicationAuthorizeFilter(
+ CMPIIndicationMI* mi,
+ const CMPIContext* cc,
+ const CMPISelectExp* se,
+ const char* ns,
+ const CMPIObjectPath* op,
+ const char* user)
+{
+ if (!im_verify_filter(im, se, cc, &im_err) ) {
+ CMReturn(CMPI_RC_ERR_INVALID_QUERY);
+ }
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_AccountInstanceDeletionIndicationMustPoll(
+ CMPIIndicationMI* mi,
+ const CMPIContext* cc,
+ const CMPISelectExp* se,
+ const char* ns,
+ const CMPIObjectPath* op)
+{
+ CMReturn(CMPI_RC_ERR_NOT_SUPPORTED);
+}
+
+static CMPIStatus LMI_AccountInstanceDeletionIndicationActivateFilter(
+ CMPIIndicationMI* mi,
+ const CMPIContext* cc,
+ const CMPISelectExp* se,
+ const char* ns,
+ const CMPIObjectPath* op,
+ CMPIBoolean firstActivation)
+{
+ if (!im_verify_filter(im, se, cc, &im_err)) {
+ CMReturn(CMPI_RC_ERR_INVALID_QUERY);
+ }
+ if (!im_add_filter(im, (CMPISelectExp*)se, cc, &im_err)) {
+ CMReturn(CMPI_RC_ERR_FAILED);
+ }
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_AccountInstanceDeletionIndicationDeActivateFilter(
+ CMPIIndicationMI* mi,
+ const CMPIContext* cc,
+ const CMPISelectExp* se,
+ const char* ns,
+ const CMPIObjectPath* op,
+ CMPIBoolean lastActivation)
+{
+ if (!im_remove_filter(im, se, cc, &im_err)) {
+ CMReturn(CMPI_RC_ERR_FAILED);
+ }
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_AccountInstanceDeletionIndicationEnableIndications(
+ CMPIIndicationMI* mi,
+ const CMPIContext* cc)
+{
+ if (!im_start_ind(im, cc, &im_err)) {
+ CMReturn(CMPI_RC_ERR_FAILED);
+ }
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_AccountInstanceDeletionIndicationDisableIndications(
+ CMPIIndicationMI* mi,
+ const CMPIContext* cc)
+{
+ if (!im_stop_ind(im, cc, &im_err)) {
+ CMReturn(CMPI_RC_ERR_FAILED);
+ }
+ CMReturn(CMPI_RC_OK);
+}
+
+CMIndicationMIStub(
+ LMI_AccountInstanceDeletionIndication,
+ LMI_AccountInstanceDeletionIndication,
+ _cb,
+ LMI_AccountInstanceDeletionIndicationInitialize())
+
+KONKRET_REGISTRATION(
+ "root/cimv2",
+ "LMI_AccountInstanceDeletionIndication",
+ "LMI_AccountInstanceDeletionIndication",
+ "indication")
diff --git a/src/account/indication_common.c b/src/account/indication_common.c
new file mode 100644
index 0000000..7c61ba0
--- /dev/null
+++ b/src/account/indication_common.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2013 Red Hat, Inc. All rights reserved.
+ *
+ * This library 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.
+ *
+ * This library 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Roman Rakus <rrakus@redhat.com>
+ */
+
+/*
+ * Common functions for indications used in Account provider
+ */
+
+#include <cmpimacs.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/inotify.h>
+#include <limits.h>
+
+#include "indication_common.h"
+
+
+#include "LMI_Account.h"
+#include "LMI_Group.h"
+#include "LMI_Identity.h"
+static const char* allowed_classes[] = {
+ LMI_Account_ClassName,
+ LMI_Group_ClassName,
+ LMI_Identity_ClassName,
+ NULL };
+
+#define EVENT_SIZE (sizeof(struct inotify_event))
+#define BUF_LEN (10 * EVENT_SIZE + NAME_MAX + 1)
+#define PASSWD_FILE "/etc/passwd"
+#define GROUP_FILE "/etc/group"
+
+
+bool filter_checker(const CMPISelectExp *filter)
+{
+ /*
+ * Support only simple conditions and only on allowed_classes
+ * and type of `sourceinstance ISA allowed_class'
+ */
+ CMPIStatus st;
+ CMPISelectCond *sec = CMGetDoc(filter, &st);
+ if (!sec) return false;
+ CMPICount count = CMGetSubCondCountAndType(sec, NULL, &st);
+ if (count != 1) return false;
+ CMPISubCond *sub = CMGetSubCondAt(sec, 0, &st);
+ if (!sub) return false;
+ count = CMGetPredicateCount(sub, &st);
+ if (count != 1) return false;
+ CMPIPredicate *pred = CMGetPredicateAt(sub, 0, &st);
+ if (!pred) return false;
+ CMPIType type;
+ CMPIPredOp op;
+ CMPIString *lhs = NULL;
+ CMPIString *rhs = NULL;
+ st = CMGetPredicateData(pred, &type, &op, &lhs, &rhs);
+ if (st.rc != CMPI_RC_OK || op != CMPI_PredOp_Isa) return false;
+ const char *rhs_str = CMGetCharsPtr(rhs, &st);
+ if (!rhs_str) return false;
+ unsigned i = 0;
+ while (allowed_classes[i]) {
+ if (strcasecmp(rhs_str, allowed_classes[i++]) == 0) return true;
+ }
+ return false;
+}
+
+/*
+ * Returns last modification time for specified file name
+ */
+static struct timespec get_last_mod(const char* file)
+{
+ struct stat buf = {0};
+ stat (file, &buf);
+ return buf.st_mtim;
+}
+
+/*
+ * Compares 2 timespecs
+ * return value is same like in strcmp
+ */
+static int timecmp(struct timespec a, struct timespec b)
+{
+ if (a.tv_sec == b.tv_sec) {
+ if (a.tv_nsec == b.tv_nsec) {
+ return 0;
+ } else {
+ return (a.tv_nsec > b.tv_nsec ? 1 : -1);
+ }
+ } else {
+ return (a.tv_sec > b.tv_sec ? 1 : -1);
+ }
+}
+
+#define ADD_WATCH(fd, wd, file)\
+ (wd) = inotify_add_watch((fd), (file), IN_CLOSE_WRITE | IN_MODIFY |\
+ IN_DELETE | IN_DELETE_SELF);\
+ if ((wd) < 0) {\
+ close((fd));\
+ return false;\
+ }\
+
+bool watcher(void *data)
+{
+ struct timespec last_pwd = get_last_mod(PASSWD_FILE);
+ struct timespec last_grp = get_last_mod(GROUP_FILE);
+ int fd = inotify_init();
+
+ if (fd < 0) {
+ return false;
+ }
+ char buffer[BUF_LEN];
+
+ int wd_pwd, wd_grp;
+ ADD_WATCH(fd, wd_pwd, PASSWD_FILE);
+ ADD_WATCH(fd, wd_grp, GROUP_FILE);
+ if (wd_pwd < 0 || wd_grp < 0) {
+ close(fd);
+ return false;
+ }
+
+ do {
+ int len = 0, i = 0;
+ if ((len = read(fd, buffer, BUF_LEN)) < 0) {
+ close(fd);
+ return false;
+ }
+ while (i < len) {
+ struct inotify_event *event = (struct inotify_event *) &buffer[i];
+ switch (event->mask) {
+ case IN_MODIFY:
+ case IN_CLOSE_WRITE:
+ case IN_DELETE:
+ case IN_DELETE_SELF:
+ if (event->wd == wd_grp) {
+ if (timecmp(last_grp, get_last_mod(GROUP_FILE)) == -1) {
+ goto out;
+ }
+ } else {
+ if (timecmp(last_pwd, get_last_mod(PASSWD_FILE)) == -1) {
+ goto out;
+ }
+ }
+ break;
+ case IN_IGNORED:
+ if (event->wd == wd_grp) {
+ ADD_WATCH(fd, wd_grp, GROUP_FILE);
+ if (timecmp(last_grp, get_last_mod(GROUP_FILE)) == -1) {
+ goto out;
+ }
+ } else {
+ ADD_WATCH(fd, wd_pwd, PASSWD_FILE);
+ if (timecmp(last_pwd, get_last_mod(PASSWD_FILE)) == -1) {
+ goto out;
+ }
+ }
+ break;
+ i += EVENT_SIZE + event->len;
+ }
+ }
+ } while (1);
+
+out:
+ inotify_rm_watch(fd, wd_pwd);
+ inotify_rm_watch(fd, wd_grp);
+ close(fd);
+ return true;
+}
diff --git a/src/account/indication_common.h b/src/account/indication_common.h
new file mode 100644
index 0000000..d57fefa
--- /dev/null
+++ b/src/account/indication_common.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2013 Red Hat, Inc. All rights reserved.
+ *
+ * This library 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.
+ *
+ * This library 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Roman Rakus <rrakus@redhat.com>
+ */
+
+
+bool filter_checker(const CMPISelectExp *filter);
+bool watcher(void *data);