diff options
Diffstat (limited to 'src/indmanager/ind_manager.c')
-rw-r--r-- | src/indmanager/ind_manager.c | 72 |
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. |