summaryrefslogtreecommitdiffstats
path: root/src/indmanager/ind_manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/indmanager/ind_manager.c')
-rw-r--r--src/indmanager/ind_manager.c72
1 files changed, 66 insertions, 6 deletions
diff --git a/src/indmanager/ind_manager.c b/src/indmanager/ind_manager.c
index 446137d..cae141b 100644
--- a/src/indmanager/ind_manager.c
+++ b/src/indmanager/ind_manager.c
@@ -795,10 +795,6 @@ IMManager* im_create_manager(IMInstGather gather, IMFilterChecker f_checker,
*err = IM_ERR_GATHER;
return NULL;
}
- if (!f_checker) {
- *err = IM_ERR_FILTER_CHECKER;
- return NULL;
- }
if (!watcher) {
*err = IM_ERR_WATCHER;
return NULL;
@@ -866,6 +862,50 @@ bool im_destroy_manager(IMManager *manager, const CMPIContext *ctx,
return true;
}
+static bool default_ind_filter_cb(IMManager *manager, const CMPISelectExp *filter)
+{
+ /* Looks for a class to be subscribed and matches it against a list of
+ * allowed classes. Filter query may contain more conditions, only those
+ * with a ISA operator are looked for.
+ */
+ CMPIStatus st;
+ unsigned int i;
+
+ 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 == 0)
+ return false;
+
+ for (i = 0; i < count; i++) {
+ CMPIType type;
+ CMPIPredOp op;
+ CMPIString *lhs = NULL;
+ CMPIString *rhs = NULL;
+ CMPIPredicate *pred = CMGetPredicateAt(sub, i, &st);
+ if (!pred)
+ return false;
+ st = CMGetPredicateData(pred, &type, &op, &lhs, &rhs);
+ if (st.rc != CMPI_RC_OK || op != CMPI_PredOp_Isa)
+ continue;
+ const char *rhs_str = CMGetCharsPtr(rhs, &st);
+ if (!rhs_str)
+ continue;
+ while (manager->f_allowed_classes[i]) {
+ if (strcasecmp(rhs_str, manager->f_allowed_classes[i++]) == 0)
+ return true;
+ }
+ }
+ return false;
+}
+
bool im_verify_filter(IMManager *manager, const CMPISelectExp *filter,
const CMPIContext *ctx, IMError *err)
{
@@ -880,9 +920,18 @@ bool im_verify_filter(IMManager *manager, const CMPISelectExp *filter,
*err = IM_ERR_FILTER;
return NULL;
}
+ if (!filter && !manager->f_allowed_classes) {
+ *err = IM_ERR_FILTER_CHECKER;
+ return NULL;
+ }
manager->ctx_main = ctx;
- DEBUG("Verifying filter. Manager = %p, filter checker = %p", manager, manager->f_checker);
- return manager->f_checker(filter);
+ if (manager->f_checker) {
+ DEBUG("Verifying filter. Manager = %p, filter checker = %p", manager, manager->f_checker);
+ return manager->f_checker(filter);
+ } else {
+ DEBUG("Verifying filter. Manager = %p, using default filter checker", manager);
+ return default_ind_filter_cb(manager, filter);
+ }
}
/*
@@ -1009,6 +1058,17 @@ bool im_add_filter(IMManager *manager, CMPISelectExp *filter,
return true;
}
+bool im_register_filter_classes(IMManager *manager,
+ const char** allowed_classes, IMError *err)
+{
+ if (!manager) {
+ *err = IM_ERR_MANAGER;
+ return false;
+ }
+ manager->f_allowed_classes = allowed_classes;
+ return true;
+}
+
/*
* Decrease reference count for polled enumerations. If count is 0, remove
* the whole enumerations.