diff options
author | Roman Rakus <rrakus@redhat.com> | 2013-06-26 16:39:57 +0200 |
---|---|---|
committer | Roman Rakus <rrakus@redhat.com> | 2013-07-01 11:32:25 +0200 |
commit | 17155ddc8f2d7168a8f6f6fa24439342758d3125 (patch) | |
tree | b917be9030dd0d64be5d701b20d4d410da3350ce /src | |
parent | 9382852767bcd560fa14e9cdbbbc8764fdf4dd91 (diff) | |
download | openlmi-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.txt | 13 | ||||
-rw-r--r-- | src/account/LMI_AccountInstanceCreationIndicationProvider.c | 134 | ||||
-rw-r--r-- | src/account/LMI_AccountInstanceDeletionIndicationProvider.c | 137 | ||||
-rw-r--r-- | src/account/indication_common.c | 183 | ||||
-rw-r--r-- | src/account/indication_common.h | 23 |
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); |