Fixed series of bugs and optimalised arguments preparation 93/70793/2
authorKonrad Lipinski <konrad.l@samsung.com>
Wed, 13 Apr 2016 08:58:43 +0000 (10:58 +0200)
committerKazimierz Krosman <k.krosman@samsung.com>
Fri, 27 May 2016 09:54:07 +0000 (11:54 +0200)
Fixed kdbus pool memory managment.
Refactored tslog (getenv called only once).
Removed duplicated credential information.
Dropped unused timeouts.
Added lockless calls when logs are disabled.
Removed udesc allocation.
Decreased KDBUS_POOL_SIZE from 16M to 1M.
Minor fixes.

Change-Id: I1e5fda8df4dbd1dd6dfecae60aff6d7d67705a3b

src/dbuspolicy1/libdbuspolicy1.h
src/internal/internal.cpp
src/internal/internal.h
src/internal/libdbuspolicy1-private.hpp
src/internal/timer.hpp [deleted file]
src/internal/tslog.hpp
src/internal/xml_parser.hpp
src/internal/xml_policy.hpp
src/libdbuspolicy1-private.h
src/libdbuspolicy1.c

index 0037fc7..ae9b0c2 100644 (file)
@@ -29,9 +29,6 @@ extern "C" {
 #define SYSTEM_BUS_CONF_FILE_SECONDARY  "/etc/dbus-1/system-local.conf"
 #define SESSION_BUS_CONF_FILE_SECONDARY "/etc/dbus-1/session-local.conf"
 
-#define SYSTEM_BUS   1
-#define SESSION_BUS  2
-
 /** used when check policy for message prepared to send */
 #define DBUSPOLICY_DIRECTION_SENDING 0
 
index 274d321..e26c510 100644 (file)
 extern "C" {
 #endif
 
-static const char* get_bus(int bus_type) {
-    return (bus_type == SYSTEM_BUS) ? "SYSTEM" : "SESSION";
-}
-
 static const char* get_str(const char* const szstr) {
     return (szstr != NULL) ? szstr : "";
 }
 
+static std::string get_strv(const char *s) {
+       unsigned i = 0;
+       if (s) {
+               i = -1;
+               char c;
+               while ((c = s[++i]) && ' ' != c);
+       }
+       return std::string{s, i};
+}
+
 static const char* get_message_type(int type) {
     const char* sztype;
     switch(type) {
@@ -43,14 +49,41 @@ static const char* get_message_type(int type) {
     return sztype;
 }
 
-int __internal_init(unsigned int bus_type, const char* const config_name)
+int __internal_init(bool bus_type, const char* const config_name)
 {
-    _ldp_xml_parser::XmlAsyncParser p;
-    auto err = p.parse_policy(get_bus(bus_type), get_str(config_name));
+    _ldp_xml_parser::XmlParser p;
+    auto err = p.parse_policy(bus_type, get_str(config_name));
     return err.get();
 }
 
-int __internal_can_send(unsigned int bus_type,
+pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+void __internal_init_once()
+{
+       tslog::init();
+}
+
+void __internal_init_flush_logs()
+{
+       if (tslog::enabled()) {
+               pthread_mutex_lock(&g_mutex);
+               std::cout << std::flush;
+               pthread_mutex_unlock(&g_mutex);
+       }
+}
+
+void __internal_enter()
+{
+       if (tslog::enabled())
+               pthread_mutex_lock(&g_mutex);
+}
+void __internal_exit()
+{
+       if (tslog::enabled())
+               pthread_mutex_unlock(&g_mutex);
+}
+
+int __internal_can_send(bool bus_type,
                             const char* const user,
                             const char* const group,
                             const char* const label,
@@ -60,12 +93,12 @@ int __internal_can_send(unsigned int bus_type,
                             const char* const member,
                             int type)
 {
-    _ldp_xml_parser::XmlAsyncParser p;
-    auto err = p.can_send(get_bus(bus_type), get_str(user), get_str(group), get_str(label), get_str(destination), get_str(path), get_str(interface), get_str(member), get_message_type(type));
+    _ldp_xml_parser::XmlParser p;
+    auto err = p.can_send(bus_type, get_str(user), get_str(group), get_str(label), get_strv(destination), get_str(path), get_str(interface), get_str(member), get_message_type(type));
     return err.get();
 }
 
-int __internal_can_recv(unsigned int bus_type,
+int __internal_can_recv(bool bus_type,
                             const char* const user,
                             const char* const group,
                             const char* const label,
@@ -75,18 +108,18 @@ int __internal_can_recv(unsigned int bus_type,
                             const char* const member,
                             int type)
 {
-    _ldp_xml_parser::XmlAsyncParser p;
-    auto err = p.can_recv(get_bus(bus_type), get_str(user), get_str(group), get_str(label), get_str(sender), get_str(path), get_str(interface), get_str(member), get_message_type(type));
+    _ldp_xml_parser::XmlParser p;
+    auto err = p.can_recv(bus_type, get_str(user), get_str(group), get_str(label), get_strv(sender), get_str(path), get_str(interface), get_str(member), get_message_type(type));
     return err.get();
 }
 
-int __internal_can_own(unsigned int bus_type,
+int __internal_can_own(bool bus_type,
                             const char* const user,
                             const char* const group,
                             const char* const service)
 {
-    _ldp_xml_parser::XmlAsyncParser p;
-    auto err = p.can_own(get_bus(bus_type), get_str(user), get_str(group), get_str(service));
+    _ldp_xml_parser::XmlParser p;
+    auto err = p.can_own(bus_type, get_str(user), get_str(group), get_str(service));
     return err.get();
 }
 
index 84a1069..0914abe 100644 (file)
@@ -22,8 +22,13 @@ extern "C" {
 #endif
 
 int __internal_init(unsigned int bus_type, const char* const config_name);
+void __internal_init_once(void);
+extern pthread_mutex_t g_mutex;
+void __internal_init_flush_logs(void);
+void __internal_enter(void);
+void __internal_exit(void);
 
-int __internal_can_send(unsigned int bus_type,
+int __internal_can_send(bool bus_type,
                             const char* const user,
                             const char* const group,
                             const char* const label,
@@ -33,7 +38,7 @@ int __internal_can_send(unsigned int bus_type,
                             const char* const member,
                             int type);
 
-int __internal_can_recv(unsigned int bus_type,
+int __internal_can_recv(bool bus_type,
                             const char* const user,
                             const char* const group,
                             const char* const label,
@@ -43,7 +48,7 @@ int __internal_can_recv(unsigned int bus_type,
                             const char* const member,
                             int type);
 
-int __internal_can_own(unsigned int bus_type,
+int __internal_can_own(bool bus_type,
                             const char* const user,
                             const char* const group,
                             const char* const service);
index 4b467b4..0cef333 100644 (file)
 
 #include <string>
 
+namespace arraySizeDetail {
+       template <class T, size_t S> constexpr size_t size(T const (&)[S]) { return S; }
+       template <class T> constexpr size_t size(std::initializer_list<T> const &l) { return l.size(); }
+}
+#define TABSIZE(...) (::arraySizeDetail::size(__VA_ARGS__))
+
 namespace {
     class ErrCode {
         int m_err;
@@ -26,7 +32,6 @@ namespace {
         ErrCode(int e, const std::string& s) : m_err(e), m_err_str(s) {}
         public:
             ErrCode() : m_err(0), m_err_str("") {}
-            virtual ~ErrCode() {}
 
             static ErrCode ok() {
                 return ErrCode(0, "OK");
@@ -41,10 +46,6 @@ namespace {
                 return ErrCode(-1, what);
             }
 
-            static ErrCode timeout(const std::string& what) {
-                return ErrCode(-99, std::string("Timeout: ") + what);
-            }
-
             int get() const {
                 return m_err;
             }
diff --git a/src/internal/timer.hpp b/src/internal/timer.hpp
deleted file mode 100644 (file)
index 2d856b3..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
-
-#ifndef _TIMER_HPP
-#define _TIMER_HPP
-#include <chrono>
-
-namespace _ldp_timer
-{
-    template<typename BaseTimeUnit = std::chrono::nanoseconds>
-        class Duration : public BaseTimeUnit {
-            public:
-                void setNanoTime(std::chrono::nanoseconds nano) {
-                    BaseTimeUnit d = std::chrono::duration_cast<BaseTimeUnit>(nano);
-                    BaseTimeUnit::operator =(d);
-                }
-
-                double getSeconds() {
-                    typename BaseTimeUnit::period p;
-                    return 1.0 * BaseTimeUnit::count() * p.num/p.den;
-                }
-
-                uint64_t getNativeTime() {
-                    return BaseTimeUnit::count();
-                }
-
-                friend std::ostream& operator<< (std::ostream& os,
-                        const Duration<BaseTimeUnit>& d) {
-                    typename BaseTimeUnit::period p;
-                    std::string unit;
-                    switch(p.den/p.num) {
-                        case 1000000000:    unit = "ns"; break;
-                        case 1000000:       unit = "us"; break;
-                        case 1000:          unit = "ms"; break;
-                        case 1:             unit = "s";  break;
-                    }
-
-                    os << d.count() << " " << unit;
-                    return os;
-                }
-        };
-
-    typedef Duration<std::chrono::nanoseconds> nanosec;
-    typedef Duration<std::chrono::microseconds> microsec;
-    typedef Duration<std::chrono::milliseconds> millisec;
-    typedef Duration<std::chrono::seconds> sec;
-
-    template<typename _T = nanosec>
-        class Timer {
-            typedef std::chrono::steady_clock CLK;
-            CLK::time_point tbegin;
-            _T* const pOT;
-            public:
-            Timer(_T* const pTP)
-                : tbegin(CLK::now()), pOT(pTP) {}
-
-            virtual ~Timer() {
-                if(pOT)
-                    pOT->setNanoTime(CLK::now() - tbegin);
-            }
-        };
-}
-
-#endif // _TIMER_HPP
index 3452dbc..dd57976 100644 (file)
 
 #include <iostream>
 #include <thread>
-#include <mutex>
+#include <pthread.h>
 #include <stdlib.h>
 
-namespace _ldp_tslog
-{
-    typedef std::ostream& (*t_ManFun)(std::ostream&);
-
-    namespace {
-        static constexpr bool LOG_DEFAULT_ENABLE = false;
-        static constexpr bool LOG_DEFAULT_VERBOSE = false;
-        static const std::string LDP_ENV_VERBOSE_NAME = "LDP_VERBOSE";
-        static const std::string LDP_ENV_LOG_NAME = "LDP_LOG";
-
-        const bool get_log_env(const std::string& name) {
-            bool bret;
-            char* ldp_log_mode = getenv(name.c_str());
-            if(ldp_log_mode) {
-                const std::string slog(ldp_log_mode);
-                bret = (slog == "0") ? false : true;
-            } else {
-                bret = (name == LDP_ENV_LOG_NAME) ? LOG_DEFAULT_ENABLE : LOG_DEFAULT_VERBOSE;
-            }
-            return bret;
-        }
-    }
-
-    const bool get_verbose() {
-        return get_log_env(LDP_ENV_VERBOSE_NAME);
-    }
-
-    const bool get_enable() {
-        return get_log_env(LDP_ENV_LOG_NAME);
-    }
-
-    class TsLog
-    {
-        private:
-            static bool m_verbose;
-            static std::mutex m_mtx;
-            std::ostream& m_os;
-            bool m_enable;
+typedef std::ostream& (*t_ManFun)(std::ostream&);
 
-            template<typename T>
-                TsLog& lckLog(const T& t) {
-                    if(m_enable) {
-                        std::unique_lock<std::mutex> lck(m_mtx);
-                        m_os << t;
-                    }
-                    return *this;
-                }
-
-        public:
-            TsLog() = delete;
-
-            explicit TsLog(std::ostream& os, bool enable = true)
-                : m_os(os), m_enable(enable) {}
-
-            virtual ~TsLog() {}
+namespace tslog
+{
+       int8_t g_verbosity; // <0 disable 0 brief >0 verbose
 
-            template<typename T>
-                TsLog& operator<< (const T& t) {
-                    return lckLog<T>(t);
-                }
+       bool get_log_env(char const *name) {
+               char const *ldp_log_mode = getenv(name);
+               return ldp_log_mode && '0' != *ldp_log_mode;
+       }
 
-            TsLog& operator<< (t_ManFun f) {
-                return lckLog<t_ManFun>(f);
-            }
+       void init() {
+               g_verbosity = get_log_env("LDP_LOG") ? get_log_env("LDP_VERBOSE") : -1;
+       }
 
-    };
-    std::mutex TsLog::m_mtx;
+       bool enabled() { return g_verbosity >= 0; }
+       bool verbose() { return g_verbosity > 0; }
 }
 
-namespace {
-    //Thread-safe loggers
-    _ldp_tslog::TsLog tout(std::cout, _ldp_tslog::get_enable());
-    _ldp_tslog::TsLog terr(std::cerr, _ldp_tslog::get_enable());
-
-    namespace verbose {
-        _ldp_tslog::TsLog tout(std::cout, _ldp_tslog::get_enable() && _ldp_tslog::get_verbose());
-        _ldp_tslog::TsLog terr(std::cerr, _ldp_tslog::get_enable() && _ldp_tslog::get_verbose());
-    }
-} //namespace
-
 #endif
index 05df566..61e60e4 100644 (file)
 #ifndef _XML_PARSER_HPP
 #define _XML_PARSER_HPP
 
-#include <map>
-#include <thread>
-#include <future>
+#include <set>
 #include <boost/noncopyable.hpp>
 #include <boost/property_tree/ptree.hpp>
 #include <boost/property_tree/xml_parser.hpp>
-#include <boost/functional/hash.hpp>
 #include <dirent.h>
 #include <libgen.h>
-#include "timer.hpp"
 #include "xml_policy.hpp"
 
 namespace _ldp_xml_parser
 {
-    class XmlAsyncParser : boost::noncopyable
+    class XmlParser : boost::noncopyable
     {
         public:
-            XmlAsyncParser() {
-            }
-
-            virtual ~XmlAsyncParser() {
-            }
-
-            ErrCode parse_policy(const std::string bus,
-                    const std::string fname,
-                    const std::chrono::milliseconds timeout = std::chrono::milliseconds(std::numeric_limits<int32_t>::max())) {
-                set_policy_bus_filename(bus, fname);
-                m_xml_policy.init();
-                ErrCode err = parse(timeout);
+            ErrCode parse_policy(bool bus,
+                    std::string const &fname) {
+                ErrCode err = parse(bus, fname);
                 return err;
             }
 
-            ErrCode can_send(const std::string bus,
+            ErrCode can_send(bool bus,
                     const std::string user,
                     const std::string group,
                     const std::string label,
@@ -62,7 +49,7 @@ namespace _ldp_xml_parser
                 return m_xml_policy.can_send_to(bus, idx_v, label);
             }
 
-            ErrCode can_recv(const std::string bus,
+            ErrCode can_recv(bool bus,
                     const std::string user,
                     const std::string group,
                     const std::string label,
@@ -75,7 +62,7 @@ namespace _ldp_xml_parser
                 return m_xml_policy.can_recv_from(bus, idx_v, label);
             }
 
-            ErrCode can_own(const std::string bus,
+            ErrCode can_own(bool bus,
                     const std::string user,
                     const std::string group,
                     const std::string service) {
@@ -86,173 +73,95 @@ namespace _ldp_xml_parser
 
         private:
             //IO operation
-            std::string m_bus;
-            std::string m_filename;
-            static std::map<std::string, std::size_t> m_hashes;
-            static std::mutex m_io_xml_mtx;
+            static std::set<std::string> m_parsed;
 
             //Data obtained from XML
             static XmlPolicy m_xml_policy;
 
-            //Called by calling user thread
-            void set_policy_bus_filename(const std::string& bus, const std::string& fname) {
-                m_filename = fname;
-                m_bus = bus;
-            }
-
-            const std::string& get_policy_bus() const {
-                return m_bus;
-            }
-
-            const std::string& get_policy_filename() const {
-                return m_filename;
-            }
-
-            ErrCode parse(const std::chrono::milliseconds timeout) {
+            ErrCode parse(bool bus, std::string const &filename) {
                 ErrCode err;
                 std::vector<std::string> incl_files;
 
-                err = parse(get_policy_filename(), incl_files, timeout);
-                if(err.is_ok()) {
+                err = parse(bus, true, filename, incl_files);
+                if (err.is_ok())
                     for(const auto& x : incl_files) {
-                        err = parse(x, incl_files, timeout);
-                        if(err.is_error()) { break; }
+                        err = parse(bus, false, x, incl_files);
+                        if (err.is_error()) break;
                     }
-                }
 
-                if(err.is_ok()) {
-                    m_xml_policy.print_decision_trees();
-                }
+                if(err.is_ok())
+                    m_xml_policy.print_decision_trees(bus);
 
                 return err;
             }
 
-            ErrCode parse(const std::string& filename, std::vector<std::string>& included_files, const std::chrono::milliseconds timeout) {
+            ErrCode parse(bool bus, bool first, const std::string& filename, std::vector<std::string>& included_files) {
                 std::pair<ErrCode, std::string> errparam;
 
-                verbose::tout << "=== XML PARSING BEGIN === : " << filename << std::endl;
+                               if (tslog::verbose())
+                                       std::cout << "=== XML PARSING BEGIN === : " << filename << '\n';
 
-                auto fut = std::async(std::launch::async, &XmlAsyncParser::async_xml_parse, this, filename);
-
-                auto r = fut.wait_for(timeout);
-                if(r == std::future_status::ready) {
-                    errparam = fut.get();
-                    if(errparam.first.get() >= 0) {
-                        get_included_files(filename, errparam.second, included_files);
-                    }
-                } else if(r == std::future_status::timeout) {
-                    errparam.first = ErrCode::timeout("XML parsing timeout");
-                }
+                errparam = xml_parse(bus, filename);
+                               if (first && errparam.first.get() >= 0 && errparam.second != "")
+                                       get_included_files(filename, errparam.second, included_files);
 
-                verbose::tout << "=== XML PARSING END ===" << std::endl << std::endl;
-                tout << "Processing of " << filename << " -> [" << errparam.first.get() << ", " << errparam.first.get_str() << "]" << std::endl;
+                               if (tslog::enabled()) {
+                                       if (tslog::verbose())
+                                               std::cout << "=== XML PARSING END ===\n\n";
+                                       std::cout << "Processing of " << filename << " -> [" << errparam.first.get() << ", " << errparam.first.get_str() << "]\n";
+                               }
                 return errparam.first;
             }
 
             //Get all the .conf files within included subdirectory, POSIX style as boost::filesystem is not header-only
             void get_included_files(const std::string& filename, const std::string& incldir, std::vector<std::string>& files) {
-                if(get_policy_filename() == filename && incldir != "") {
-                    DIR *dir;
-                    struct dirent *ent;
-                    std::string fname;
-                    std::copy(filename.begin(), filename.end(), fname.begin());
-                    std::string dname = dirname(const_cast<char*>(fname.c_str()));
-                    dname += (std::string("/") + incldir);
-                    files.clear();
-                    if((dir = opendir(dname.c_str())) != NULL) {
-                        while((ent = readdir(dir)) != NULL) {
-                            std::string s(ent->d_name);
-                            if(s.find(".conf") != std::string::npos) {
-                                files.push_back(dname + std::string("/") + s);
-                            }
-                        }
-                        closedir(dir);
-
-                        tout << std::endl << "includedir for " << filename << " is " << incldir << ", " << files.size() << " included files found:" << std::endl;
-                        if(_ldp_tslog::get_enable()) { std::copy(files.begin(), files.end(), std::ostream_iterator<std::string>(std::cout, "\n")); }
-                        tout << std::endl;
-                    } else {
-                        terr << "could not open directory " << dname << std::endl;
-                    }
-                }
-            }
-
-            //All 'async_*' methods are executed in library's internal worker threads
-            std::pair<ErrCode, std::string> async_xml_parse(const std::string& filename) {
+                               DIR *dir;
+                               struct dirent *ent;
+                               std::string fname;
+                               std::copy(filename.begin(), filename.end(), fname.begin());
+                               std::string dname = dirname(const_cast<char*>(fname.c_str()));
+                               dname += (std::string("/") + incldir);
+                               files.clear();
+                               if((dir = opendir(dname.c_str())) != NULL) {
+                                       while((ent = readdir(dir)) != NULL) {
+                                               std::string s(ent->d_name);
+                                               if(s.find(".conf") != std::string::npos) {
+                                                       files.push_back(dname + std::string("/") + s);
+                                               }
+                                       }
+                                       closedir(dir);
+
+                                       if (tslog::enabled()) {
+                                               std::cout << "\nincludedir for " << filename << " is " << incldir << ", " << files.size() << " included files found:\n";
+                                               std::copy(files.begin(), files.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
+                                               std::cout << '\n';
+                                       }
+                               } else if (tslog::enabled())
+                                       std::cout << "could not open directory " << dname << '\n';
+            }
+
+            std::pair<ErrCode, std::string> xml_parse(bool bus, const std::string& filename) {
                 std::pair<ErrCode, std::string> ret;
-                _ldp_timer::microsec latency;
 
-                try {
-                    boost::property_tree::ptree pt;
+                               if (m_parsed.insert(filename).second)
+                                       try {
+                                               boost::property_tree::ptree pt;
+                                               read_xml(filename, pt);
+                                               if (!pt.empty()) {
+                                                       m_xml_policy.update(bus, pt);
+                                                       ret.second = pt.get("busconfig.includedir", "");
+                                               }
+                                       } catch(const boost::property_tree::xml_parser::xml_parser_error& ex) {
+                                               ret.first = ErrCode::error(ex.what());
+                                       } catch(const boost::property_tree::ptree_error& ex) {
+                                               ret.first = ErrCode::error(ex.what());
+                                       } catch(...) {
+                                               ret.first = ErrCode::error(filename + std::string(": unknown error while parsing XML"));
+                                       }
 
-                    //XML file IO critical section
-                    {
-                        std::unique_lock<std::mutex> lck(m_io_xml_mtx);
-                        _ldp_timer::Timer<_ldp_timer::microsec> t(&latency);
-
-                        std::size_t hash;
-                        if(async_xml_parsing_needed(filename, hash)) {
-                            read_xml(filename, pt);
-                            async_xml_hash_update(filename, hash);
-                        }
-                    }
-
-                    m_xml_policy.update(get_policy_bus(), pt);
-
-                    ret.second = pt.get("busconfig.includedir", "");
-
-                    ret.first = ErrCode::ok();
-                } catch(const boost::property_tree::xml_parser::xml_parser_error& ex) {
-                    ret.first = ErrCode::error(ex.what());
-                } catch(const boost::property_tree::ptree_error& ex) {
-                    ret.first = ErrCode::error(ex.what());
-                } catch(...) {
-                    ret.first = ErrCode::error(filename + std::string(": unknown error while parsing XML"));
-                }
-
-                tout << "XML processing latency: " << latency << std::endl;
-                return ret;
-            }
-
-            std::size_t async_xml_hash(const std::string& filename) {
-                std::size_t seed = 0;
-                std::ifstream ifs(filename);
-                for(std::string line; getline(ifs, line); ) {
-                    boost::hash_combine(seed, line);
-                }
-                ifs.close();
-
-                return seed;
-            }
-
-            void async_xml_hash_update(const std::string& filename, const std::size_t hash) {
-                auto r = m_hashes.insert(std::pair<std::string, std::size_t>(filename, hash));
-                if(r.second == false) {
-                    auto it = r.first;
-                    it->second = hash;
-                }
-            }
-
-            bool async_xml_parsing_needed(const std::string& filename, std::size_t& hash) {
-                bool ret = false;
-                hash = async_xml_hash(filename);
-                auto it = m_hashes.find(filename);
-                if(it != m_hashes.end()) {
-                    if(hash == it->second) {
-                        ret = false;
-                    } else {
-                        ret = true;
-                    }
-                } else {
-                    ret = true;
-                }
                 return ret;
             }
-
     };
-    std::map<std::string, std::size_t> XmlAsyncParser::m_hashes;
-    std::mutex XmlAsyncParser::m_io_xml_mtx;
-    XmlPolicy XmlAsyncParser::m_xml_policy;
 } //namespace
 
 #endif
index 63fe956..48fa7f9 100644 (file)
 #include <boost/noncopyable.hpp>
 #include <boost/tokenizer.hpp>
 #include <boost/property_tree/ptree.hpp>
+#include <map>
 #include "libdbuspolicy1-private.hpp"
-#include "timer.hpp"
 #include "tslog.hpp"
 #include "cynara.hpp"
 
+enum class TreeType : uint8_t {
+       SEND,
+       RECV,
+       OWN
+};
+
 namespace _ldp_xml_parser
 {
     namespace {
@@ -56,7 +62,6 @@ namespace _ldp_xml_parser
                 static const size_t IDX_OWN_LENGTH = IDX_SERVICE + 1;
                 static const size_t IDX_DEFAULT = IDX_GROUP + 1;
 
-                std::string m_bus;
                 std::vector<std::string> m_path_content;
                 std::string m_privilege;
                 bool m_bsend;
@@ -66,9 +71,8 @@ namespace _ldp_xml_parser
                 bool m_ballow;
                 static size_t m_weight;
 
-                Key(const std::string& bus)
-                    : m_bus(bus),
-                    m_path_content(std::vector<std::string>(IDX_TOTAL_LENGTH, ANY)),
+                Key(bool bus)
+                    : m_path_content(std::vector<std::string>(IDX_TOTAL_LENGTH, ANY)),
                     m_bsend(false),
                     m_brecv(false),
                     m_bown(false),
@@ -85,9 +89,8 @@ namespace _ldp_xml_parser
                 const std::string get_path() const {
                     std::string path = "R";
                     auto it_cend = m_bown ? m_path_content.cbegin() + IDX_OWN_LENGTH : m_path_content.cend();
-                    for(auto it = m_path_content.cbegin(); it != it_cend; ++it) {
-                        path += (std::string(1, Key::DELIM) + *it);
-                    }
+                    for(auto it = m_path_content.cbegin(); it != it_cend; ++it)
+                        (path += Key::DELIM) += *it;
                     return path;
                 }
         };
@@ -121,11 +124,10 @@ namespace _ldp_xml_parser
             }
 
             friend std::ostream& operator<<(std::ostream& os, const Leaf& lf) {
-                if(lf.m_check) {
+                if(lf.m_check)
                     os << "check," << lf.m_privilege << "," << lf.m_weight;
-                } else {
+                else
                     os << (lf.m_decision ? "true" : "false") << "," << lf.m_weight;
-                }
                 return os;
             }
 
@@ -138,24 +140,20 @@ namespace _ldp_xml_parser
                 for(auto it = tokens.begin(); it != tokens.end(); ++it) {
                     const auto it_last = std::next(tokens.begin(), size - 1);
                     if(it == tokens.begin()) {
-                        if(size > 2) {
+                        if(size > 2)
                             lf.m_check = (*it == "check") ? true : false;
-                        } else {
+                        else
                             lf.m_decision = (*it == "true") ? true : false;
-                        }
-                    } else if(it == it_last) {
+                    } else if(it == it_last)
                         lf.m_weight = std::stoul(*it);
-                    } else {
-                        if(size > 2) {
-                            lf.m_privilege = *it;
-                        }
-                    }
+                    else if(size > 2)
+                                               lf.m_privilege = *it;
                 }
                 return is;
             }
         };
 
-        static const std::string get_context_str(const CtxType& ctx_type) {
+        static char const *get_context_str(const CtxType& ctx_type) {
             switch(ctx_type) {
                 case CtxType::DEFAULT: return "(default)"; break;
                 case CtxType::SPECIFIC: return "(specific)"; break;
@@ -165,34 +163,24 @@ namespace _ldp_xml_parser
         }
 
         static const std::string get_field_str(const std::string& field) {
-            return (field == "") ? Key::ANY : field;
+            return field == "" ? Key::ANY : field;
         }
 
         //Data obtained from XML parsing - decision trees
-        typedef std::map<std::string, boost::property_tree::ptree> Trees_t;
-        std::map<std::string, Trees_t> m_dec_trees;
-        std::mutex m_xml_policy_mtx;
-
-        boost::property_tree::ptree* get_decision_tree(const std::string& bus, const std::string& tree_type) {
-            boost::property_tree::ptree* p_tree = NULL;
-
-            auto it1 = m_dec_trees.find(bus);
-            if(it1 != m_dec_trees.end()) {
-                auto it2 = it1->second.find(tree_type);
-                if(it2 != it1->second.end()) {
-                    p_tree = &it2->second;
-                }
-            }
-            return p_tree;
+        boost::property_tree::ptree m_dec_trees[2][3];
+
+        boost::property_tree::ptree &get_decision_tree(bool bus, TreeType tree_type) {
+            return m_dec_trees[bus][static_cast<unsigned>(tree_type)];
         }
 
-        boost::property_tree::ptree* get_decision_tree(const Key& key) {
-            std::string tree_type;
-            if(key.m_bsend) { tree_type = "SEND"; }
-            else if(key.m_brecv) { tree_type = "RECV"; }
-            else if(key.m_bown) { tree_type = "OWN"; }
+        boost::property_tree::ptree* get_decision_tree(bool bus, const Key& key) {
+            TreeType tree_type;
+            if(key.m_bsend) tree_type = TreeType::SEND;
+            else if(key.m_brecv) tree_type = TreeType::RECV;
+            else if(key.m_bown) tree_type = TreeType::OWN;
+                       else return NULL;
 
-            return get_decision_tree(key.m_bus, tree_type);
+            return &get_decision_tree(bus, tree_type);
         }
 
         void print_decision_tree(const boost::property_tree::ptree& pt, int level = 0) {
@@ -202,31 +190,30 @@ namespace _ldp_xml_parser
             }
         }
 
-        void print_decision_key(const Key& key) {
-            if(_ldp_tslog::get_verbose()) {
-                std::string s = key.m_bus + " ";
-                if(key.m_bsend && !key.m_brecv) { s += "--> #"; }
-                if(!key.m_bsend && key.m_brecv) { s += "<-- #"; }
-                if(!key.m_bsend && !key.m_brecv && key.m_bown) { s += "OWN #"; }
+        void print_decision_key(bool bus, const Key& key) {
+            if (tslog::verbose()) {
+                std::string s = bus + " ";
+                if(key.m_bsend && !key.m_brecv) s += "--> #";
+                if(!key.m_bsend && key.m_brecv) s += "<-- #";
+                if(!key.m_bsend && !key.m_brecv && key.m_bown) s += "OWN #";
                 std::string prv = key.m_bcheck ? key.m_privilege : "";
-                verbose::tout << s
+                std::cout << s
                     << (key.m_bcheck ? "check " : std::to_string(key.m_ballow))
                     << prv
                     << " : "
                     << key.get_path()
                     << "    (weight: "
                     << key.m_weight
-                    << ")"
-                    << std::endl;
+                    << ")\n";
             }
         }
 
-        void update_decision_tree(const Key& key) {
+        void update_decision_tree(bool bus, const Key& key) {
             if(!key.get_path().empty()) {
-                print_decision_key(key);
+                print_decision_key(bus, key);
 
                 //update
-                boost::property_tree::ptree* const p_tree = get_decision_tree(key);
+                boost::property_tree::ptree* const p_tree = get_decision_tree(bus, key);
                 if(p_tree) {
                     boost::property_tree::ptree::path_type tpath(key.get_path(), Key::DELIM);
                     p_tree->put(tpath, Leaf(key.m_ballow, key.m_bcheck, key.m_privilege, key.m_weight));
@@ -260,7 +247,7 @@ namespace _ldp_xml_parser
                 ++key.m_weight;
             } else {
                 if(attr) {
-                    std::string data_str = (v.second.data() == "*") ? Key::ANY : v.second.data();
+                    std::string data_str = v.second.data() == "*" ? Key::ANY : v.second.data();
                     if(v.first == "context") {
                         if(data_str == "mandatory") {
                             key.m_path_content[Key::IDX_USER] = Key::MRY;
@@ -272,20 +259,16 @@ namespace _ldp_xml_parser
                             current_ctx = CtxType::DEFAULT;
                         }
                     } else if(v.first == "user") {
-                        if(current_ctx == CtxType::SPECIFIC) {
+                        if(current_ctx == CtxType::SPECIFIC)
                             key.m_path_content[Key::IDX_USER] = data_str;
-                        }
                     } else if(v.first == "group") {
-                        if(current_ctx == CtxType::SPECIFIC) {
+                        if(current_ctx == CtxType::SPECIFIC)
                             key.m_path_content[Key::IDX_GROUP] = data_str;
-                        }
                     } else {
-                        if(field_has(v, "send_")) {
+                        if(field_has(v, "send_"))
                             key.m_bsend = true;
-                        }
-                        if(field_has(v, "receive_")) {
+                        if(field_has(v, "receive_"))
                             key.m_brecv = true;
-                        }
                         if(v.first == "own") {
                             key.m_bown = true;
                             key.m_path_content[Key::IDX_SERVICE] = data_str;
@@ -294,27 +277,20 @@ namespace _ldp_xml_parser
                             key.m_bown = true;
                             key.m_path_content[Key::IDX_SERVICE] = data_str + "*";
                         }
-                        if(field_has(v, "_destination")) {
+                        if(field_has(v, "_destination"))
                             key.m_path_content[Key::IDX_DEST] = data_str;
-                        }
-                        if(field_has(v, "_sender")) {
+                        if(field_has(v, "_sender"))
                             key.m_path_content[Key::IDX_SENDER] = data_str;
-                        }
-                        if(field_has(v, "_path")) {
+                        if(field_has(v, "_path"))
                             key.m_path_content[Key::IDX_PATH] = data_str;
-                        }
-                        if(field_has(v, "_interface")) {
+                        if(field_has(v, "_interface"))
                             key.m_path_content[Key::IDX_IFACE] = data_str;
-                        }
-                        if(field_has(v, "_member")) {
+                        if(field_has(v, "_member"))
                             key.m_path_content[Key::IDX_MEMBER] = data_str;
-                        }
-                        if(field_has(v, "_type")) {
+                        if(field_has(v, "_type"))
                             key.m_path_content[Key::IDX_TYPE] = data_str;
-                        }
-                        if(v.first == "privilege") {
+                        if(v.first == "privilege")
                             key.m_privilege = data_str;
-                        }
 
                         key.m_bcheck = bcheck;
                         key.m_ballow = allden;
@@ -328,14 +304,15 @@ namespace _ldp_xml_parser
         }
 
         void print_field(const boost::property_tree::ptree::value_type& v, int level) {
-            verbose::tout    << ((level > 0) ? std::string((level - 1) * 8, ' ') + std::string(8, '.') : "")
-                << v.first
-                << " : "
-                << v.second.data()
-                << std::endl;
+                       std::cout << ((level > 0) ? std::string((level - 1) * 8, ' ') + std::string(8, '.') : "")
+                               << v.first
+                               << " : "
+                               << v.second.data()
+                               << '\n';
         }
 
-        void xml_traversal(const boost::property_tree::ptree& pt,
+        void xml_traversal(bool bus,
+                               const boost::property_tree::ptree& pt,
                 Key& key,
                 CtxType& current_ctx,
                 bool allden = false,
@@ -349,20 +326,18 @@ namespace _ldp_xml_parser
                     if(v.first == "<xmlcomment>") { continue; }
 
                     update_decision_path(v, key, current_ctx, allden, bcheck, attr);
-                    //print_field(v, level);
-                    xml_traversal(v.second, key, current_ctx, allden, bcheck, attr, level + 1);
+                    //if (tslog::verbose()) print_field(v, level);
+                    xml_traversal(bus, v.second, key, current_ctx, allden, bcheck, attr, level + 1);
                 }
 
-                if(!pt.empty() && attr && level > 1) {
-                    update_decision_tree(key);
-                }
-            } else {
-                terr << "XML traversal max level reached: " << level << std::endl;
-            }
+                if(!pt.empty() && attr && level > 1)
+                    update_decision_tree(bus, key);
+            } else if (tslog::enabled())
+                std::cout << "XML traversal max level reached: " << level << '\n';
         }
 
         void print_indexing_path(size_t idx, const std::string& path, const Leaf& leaf = Leaf(), bool empty = true) {
-            if(_ldp_tslog::get_verbose()) {
+            if (tslog::verbose()) {
                 std::string s;
                 if(!empty) {
                     s = "    : <";
@@ -373,72 +348,59 @@ namespace _ldp_xml_parser
                     s += std::string(">");
                 }
 
-                verbose::tout << "path #"
-                    << idx
-                    << " : "
-                    << path
-                    << s
-                    << std::endl;
+                               std::cout << "path #"
+                                       << idx
+                                       << " : "
+                                       << path
+                                       << s
+                                       << '\n';
             }
         }
 
         void prepare_indexing_path(const std::vector<std::string>& idx_v,
-                const size_t pattern,
+                size_t pattern,
                 const size_t usrgrp_obfuscate_order,
                 const bool obfuscate_params,
                 const CtxType& ctx_type,
                 std::string& path) {
 
-            const size_t offset = Key::IDX_DEFAULT;
+            constexpr size_t offset = Key::IDX_DEFAULT;
             path = "R";
 
             if(ctx_type == CtxType::SPECIFIC) {
-                switch(usrgrp_obfuscate_order) {
-                    case 0:
-                        path += (std::string(1, Key::DELIM) + get_field_str(idx_v[Key::IDX_USER]));
-                        path += (std::string(1, Key::DELIM) + Key::ANY);
-                    break;
-                    case 1:
-                        path += (std::string(1, Key::DELIM) + Key::ANY);
-                        path += (std::string(1, Key::DELIM) + get_field_str(idx_v[Key::IDX_GROUP]));
-                    break;
-                    case 2:
-                        path += (std::string(1, Key::DELIM) + get_field_str(idx_v[Key::IDX_USER]));
-                        path += (std::string(1, Key::DELIM) + get_field_str(idx_v[Key::IDX_GROUP]));
-                    break;
-                    case 3:
-                    default:
-                        path += (std::string(1, Key::DELIM) + Key::ANY);
-                        path += (std::string(1, Key::DELIM) + Key::ANY);
-                    break;
-                }
-            } else {
-                for(size_t i = 0; i < offset; ++i) {
-                    const std::string as = (ctx_type == CtxType::MANDATORY) ? Key::MRY : Key::DEF;
-                    path += (std::string(1, Key::DELIM) + as);
-                }
-            }
+                               path += Key::DELIM;
+                               if (usrgrp_obfuscate_order & 1) // 1 3
+                                       path += Key::ANY;
+                               else
+                                       path += get_field_str(idx_v[Key::IDX_USER]);
+                               path += Key::DELIM;
+                               if ((usrgrp_obfuscate_order+1) & 2) // 1 2
+                                       path += get_field_str(idx_v[Key::IDX_GROUP]);
+                               else
+                                       path += Key::ANY;
+            } else
+                for(size_t i = 0; i < offset; ++i)
+                    (path += Key::DELIM) += ctx_type == CtxType::MANDATORY ? Key::MRY : Key::DEF;
 
-            const size_t m = 1;
             const size_t n = idx_v.size() - offset;
-            for(size_t i = 0; i < n; ++i) {
-                std::string s = get_field_str(idx_v[i + offset]);
+            for (size_t i = 0; i < n; ++i) {
                 path += Key::DELIM;
-                if(obfuscate_params && (pattern & (m << i))) {
-                    path += Key::ANY;
-                } else {
-                    path += s;
-                }
+                               if (obfuscate_params && pattern & 1)
+                                       path += Key::ANY;
+                               else
+                                       path += get_field_str(idx_v[i + offset]);
+                               pattern >>= 1;
             }
         }
 
         ErrCode service_leaf_found(const Leaf& leaf, const std::string& label, const std::vector<std::string>& idx_v) {
             ErrCode err;
             if(leaf.get_check()) {
-                verbose::tout << __func__
-                    << ": cynara check needed for privilege " << leaf.get_privilege()
-                    << ", weight " << leaf.get_weight()
-                    << std::endl;
+                               if (tslog::verbose())
+                                       std::cout << __func__
+                                               << ": cynara check needed for privilege " << leaf.get_privilege()
+                                               << ", weight " << leaf.get_weight()
+                                               << '\n';
 
                 //cynara check
                 try {
@@ -487,14 +449,16 @@ namespace _ldp_xml_parser
                         if(!found) { err = ErrCode::error("No path"); }
                     } catch(...) {
                         print_indexing_path(p, path);
-                        verbose::tout << "Unknown exception while indexing decision tree!" << std::endl;
+                                               if (tslog::verbose())
+                                                       std::cout << "Unknown exception while indexing decision tree!\n";
                         if(!found) { err = ErrCode::error("Unknown err, no path"); }
                     }
                 }
 
                 if(found) {
                     err = service_leaf_found(leaf_found, label, idx_v);
-                    verbose::tout << __func__ << ": returning decision #" << err.get() << " " << err.get_str() << ", weight " << leaf_found.get_weight() << std::endl;
+                                       if (tslog::verbose())
+                                               std::cout << __func__ << ": returning decision #" << err.get() << " " << err.get_str() << ", weight " << leaf_found.get_weight() << '\n';
                     break;
                 }
             }
@@ -509,85 +473,63 @@ namespace _ldp_xml_parser
             const CtxType& ctx_type) {
             ErrCode err;
 
-            tout << "context: " << get_context_str(ctx_type) << ",  indexing arguments: ";
-            if(_ldp_tslog::get_enable()) { std::copy(idx_v.begin(), idx_v.end(), std::ostream_iterator<std::string>(std::cout, ", ")); }
-            tout << std::endl;
+                       if (tslog::enabled()) {
+                               std::cout << "context: " << get_context_str(ctx_type) << ",  indexing arguments: ";
+                               std::copy(idx_v.begin(), idx_v.end(), std::ostream_iterator<std::string>(std::cout, ", "));
+                               std::cout << '\n';
+                       }
 
             //Examine policy data and make decision
-            _ldp_timer::microsec latency;
-            {
-                _ldp_timer::Timer<_ldp_timer::microsec> t(&latency);
-                err = index_decision_tree(pt, idx_v, label, obfuscate_params, ctx_type);
-            }
+                       err = index_decision_tree(pt, idx_v, label, obfuscate_params, ctx_type);
 
-            tout << __func__ << ": #" << err.get() << " " << err.get_str() << " " << get_context_str(ctx_type) << std::endl;
-            tout << "tree indexing latency: " << latency << std::endl;
+                       if (tslog::enabled())
+                               std::cout << __func__ << ": #" << err.get() << " " << err.get_str() << " " << get_context_str(ctx_type) << '\n';
             return err;
         }
 
-        ErrCode can_do_action(const std::string& bus,
-                const std::string& tree_type,
+        ErrCode can_do_action(bool bus,
+                TreeType tree_type,
                 const std::vector<std::string>& idx_v,
                 const std::string& label = "",
                 const bool analyze_prefix = false) {
-            std::unique_lock<std::mutex> lck(m_xml_policy_mtx);
             ErrCode err;
-            boost::property_tree::ptree* const p_tree = get_decision_tree(bus, tree_type);
-            if(p_tree) {
-                err = index_decision_tree_lat(*p_tree, idx_v, label, !analyze_prefix, CtxType::MANDATORY);
-                if(!err.is_ok()) {
-                    err = index_decision_tree_lat(*p_tree, idx_v, label, !analyze_prefix, CtxType::SPECIFIC);
-                    if(!err.is_ok()) {
-                        err = index_decision_tree_lat(*p_tree, idx_v, label, !analyze_prefix, CtxType::DEFAULT);
-                    }
-                }
-            } else {
-                err = ErrCode::error("Get decision tree returned NULL ptr");
-            }
-            tout << __func__ << ": #" << err.get()  << " " << err.get_str() << std::endl;
+            boost::property_tree::ptree const &p_tree = get_decision_tree(bus, tree_type);
+                       err = index_decision_tree_lat(p_tree, idx_v, label, !analyze_prefix, CtxType::MANDATORY);
+                       if(!err.is_ok()) {
+                               err = index_decision_tree_lat(p_tree, idx_v, label, !analyze_prefix, CtxType::SPECIFIC);
+                               if(!err.is_ok())
+                                       err = index_decision_tree_lat(p_tree, idx_v, label, !analyze_prefix, CtxType::DEFAULT);
+                       }
+                       if (tslog::enabled())
+                               std::cout << __func__ << ": #" << err.get()  << " " << err.get_str() << '\n';
             return err;
         }
 
         public:
         XmlPolicy() {
-            Trees_t t;
-            t.emplace("SEND", typename Trees_t::mapped_type());
-            t.emplace("RECV", typename Trees_t::mapped_type());
-            t.emplace("OWN", typename Trees_t::mapped_type());
-            m_dec_trees.emplace("SYSTEM", t);
-            m_dec_trees.emplace("SESSION", t);
-        }
-
-        virtual ~XmlPolicy() {}
-
-        void init() {
-            std::unique_lock<std::mutex> lck(m_xml_policy_mtx);
             Key::m_weight = 0;
         }
 
-        void update(const std::string& bus, const boost::property_tree::ptree& pt) {
-            if(!pt.empty()) {
-                std::unique_lock<std::mutex> lck(m_xml_policy_mtx);
-                const auto& children = pt.get_child(ROOT_FIELD);
-                for(const auto& x : children) {
-                    if(x.first == ROOT_POLICY) {
-                        Key key(bus);
-                        CtxType current_ctx = CtxType::SPECIFIC;
-                        xml_traversal(x.second, key, current_ctx);
-                    }
-                }
-            }
+        void update(bool bus, const boost::property_tree::ptree& pt) {
+                       const auto& children = pt.get_child(ROOT_FIELD);
+                       for(const auto& x : children) {
+                               if(x.first == ROOT_POLICY) {
+                                       Key key(bus);
+                                       CtxType current_ctx = CtxType::SPECIFIC;
+                                       xml_traversal(bus, x.second, key, current_ctx);
+                               }
+                       }
         }
 
-        ErrCode can_send_to(const std::string bus, const std::vector<std::string>& idx_v, const std::string label) {
-            return can_do_action(bus, "SEND", idx_v, label);
+        ErrCode can_send_to(bool bus, const std::vector<std::string>& idx_v, const std::string label) {
+            return can_do_action(bus, TreeType::SEND, idx_v, label);
         }
 
-        ErrCode can_recv_from(const std::string bus, const std::vector<std::string>& idx_v, const std::string label) {
-            return can_do_action(bus, "RECV", idx_v, label);
+        ErrCode can_recv_from(bool bus, const std::vector<std::string>& idx_v, const std::string label) {
+            return can_do_action(bus, TreeType::RECV, idx_v, label);
         }
 
-        ErrCode can_own_what(const std::string bus, const std::vector<std::string>& idx_v) {
+        ErrCode can_own_what(bool bus, const std::vector<std::string>& idx_v) {
             ErrCode err;
 
             //Evaluate own_prefix
@@ -596,34 +538,29 @@ namespace _ldp_xml_parser
             const size_t srv_size = srv.size();
             for(size_t n = 1; n <= srv_size; ++n) {
                 const std::string sub = srv.substr(0, n) + "*";
-                verbose::tout << "own_prefix: " << sub << std::endl;
+                               if (tslog::enabled())
+                                       std::cout << "own_prefix: " << sub << '\n';
                 iv.pop_back();
                 iv.push_back(sub);
-                err = can_do_action(bus, "OWN", iv, "", true);
-                if(err.is_ok()) {
+                err = can_do_action(bus, TreeType::OWN, iv, "", true);
+                if(err.is_ok())
                     break;
-                }
             }
 
             //Evaluate own
-            if(err.is_error()) {
-                err = can_do_action(bus, "OWN", idx_v);
-            }
+            if(err.is_error())
+                err = can_do_action(bus, TreeType::OWN, idx_v);
 
             return err;
         }
 
-        void print_decision_trees() {
-            if(_ldp_tslog::get_verbose()) {
-                std::unique_lock<std::mutex> lck(m_xml_policy_mtx);
-
-                for(const auto& x : m_dec_trees) {
-                    for(const auto& y : x.second) {
-                        verbose::tout << x.first << " " << y.first << " " << (y.second.empty() ? "(empty)" : "") << std::endl;
+        void print_decision_trees(bool bus) {
+            if (tslog::verbose())
+                               for (unsigned i = 0; i < TABSIZE(m_dec_trees[bus]); ++i)
+                    for(auto const& y : m_dec_trees[bus][i]) {
+                        std::cout << i << " " << y.first << " " << (y.second.empty() ? "(empty)" : "") << '\n';
                         print_decision_tree(y.second);
                     }
-                }
-            }
         }
 
     }; //XmlPolicy
index 58e27bd..24c3d02 100644 (file)
@@ -26,4 +26,7 @@
 
 #define DBUSPOLICY1_EXPORT __attribute__ ((visibility("default")))
 
+typedef uint8_t dbus_name_len;
+#define MAX_DBUS_NAME_LEN 255
+
 #endif
index 68f13a9..0ff7d6b 100644 (file)
@@ -31,6 +31,7 @@
 #include <pwd.h>
 #include <grp.h>
 #include <limits.h>
+#include <pthread.h>
 
 #include <dbuspolicy1/libdbuspolicy1.h>
 #include "libdbuspolicy1-private.h"
 
 #define KDBUS_PATH_PREFIX "/sys/fs/kdbus/"
 #define KDBUS_SYSTEM_BUS_PATH "/sys/fs/kdbus/0-system/bus"
+#define KDBUS_POOL_SIZE (1024UL * 1024UL)
 
-#define KDBUS_POOL_SIZE (16 * 1024UL * 1024UL)
+#define SYSTEM_BUS   0
+#define SESSION_BUS  1
 
 #define ALIGN8(l) (((l) + 7) & ~7)
+#define ALIGNDN8(l) ((l) & ~7)
 #define UID_INVALID ((uid_t) -1)
 #define GID_INVALID ((gid_t) -1)
 
-#define FOREACH_STRV(i,l, s, os)\
-for(\
-({\
-i=0;\
-l = strlen(s);\
-name = malloc(sizeof(char*)*(l+1));\
-strncpy(os, s, sizeof(char*)*(l+1)-1);\
-});\
-i < l;\
-i++)
-
-#define GET_NEXT_STR(i,s,os)\
-        os = s+i;\
-        for(;s[i] && s[i] != ' ';i++);\
-        s[i] = 0;
-
+static char const *foreach_strv_advance(char const *str) {
+       char c;
+       while ((c = *str++))
+               if (' ' == c)
+                       return str;
+       return NULL;
+}
 
+/* iterate over STR; iterate once with "" if !STR or !*STR */
+#define FOREACH_STRV_DEFAULT(ITERLVALPTR,STR) for (\
+       ITERLVALPTR = (!STR || !*STR) ? "" : STR;\
+       ITERLVALPTR;\
+       ITERLVALPTR = foreach_strv_advance(ITERLVALPTR)\
+)
 
 /** A process ID */
 typedef unsigned long dbus_pid_t;
@@ -70,159 +71,64 @@ typedef unsigned long dbus_uid_t;
 /** A group ID */
 typedef unsigned long dbus_gid_t;
 
-struct kcreds {
-    uid_t uid;
-    gid_t gid;
-    char* label;
-    char** names;
-};
-
 struct kconn {
     int fd;
     uint64_t id;
     char *pool;
-};
+} g_conn[2];
+
 struct udesc {
-    unsigned int bus_type;
     char user[256];
     dbus_uid_t uid;
     char group[256];
     dbus_gid_t gid;
     char label[256];
-    struct kconn* conn;
-};
-
+} g_udesc;
 
 static int kdbus_open_bus(const char *path)
 {
     return open(path, O_RDWR|O_NOCTTY|O_LARGEFILE|O_CLOEXEC);
 }
 
-static int kdbus_hello(struct kconn *kc, uint64_t hello_flags, uint64_t attach_flags_send, uint64_t attach_flags_recv)
+static int kdbus_hello(bool bus_type, uint64_t hello_flags, uint64_t attach_flags_send, uint64_t attach_flags_recv)
 {
-    struct kdbus_cmd_hello kcmd_hello;
-    int r;
+    struct kdbus_cmd_hello cmd;
+       int fd = g_conn[bus_type].fd;
 
-    memset(&kcmd_hello, 0, sizeof(kcmd_hello));
-    kcmd_hello.flags = hello_flags;
-    kcmd_hello.attach_flags_send = attach_flags_send;
-    kcmd_hello.attach_flags_recv = attach_flags_recv;
-    kcmd_hello.size = sizeof(kcmd_hello);
-    kcmd_hello.pool_size = KDBUS_POOL_SIZE;
+    cmd.size = sizeof(cmd);
+    cmd.flags = hello_flags;
+    cmd.attach_flags_send = attach_flags_send;
+    cmd.attach_flags_recv = attach_flags_recv;
+    cmd.pool_size = KDBUS_POOL_SIZE;
 
-    r = ioctl(kc->fd, KDBUS_CMD_HELLO, &kcmd_hello);
-    if (r < 0)
+    if (ioctl(fd, KDBUS_CMD_HELLO, &cmd) < 0)
         return -errno;
 
-    kc->id = (uint64_t)kcmd_hello.id;
-    kc->pool = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, kc->fd, 0);
-    if (kc->pool == MAP_FAILED)
+    g_conn[bus_type].id = cmd.id;
+    if (MAP_FAILED == (g_conn[bus_type].pool = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, fd, 0)))
         return -errno;
 
     return 0;
 }
 
-static int kdbus_is_unique_id(const char* name)
+static bool kdbus_is_unique_id(const char* name)
 {
-    return (strlen(name)>3 && name[0]==':' && isdigit(name[1]) && name[2]=='.');
+    return ':' == name[0];
 }
 
-static int kdbus_get_creds_from_name(struct kconn* kc, struct kcreds* kcr, const char* name)
+static uint64_t kdbus_unique_id(char const *name)
 {
-    unsigned long long int unique_id;
-    struct kdbus_cmd_info* cmd;
-    struct kdbus_info* conn_info;
-    struct kdbus_item *item;
-    char** tmp_names;
-    int j, r, l, counter;
-    unsigned int size;
-
-    counter = 0;
-    kcr->names = calloc(counter+1, sizeof(char *));
-
-    kcr->uid = UID_INVALID;
-    kcr->gid = GID_INVALID;
-    kcr->label = NULL;
-
-    if (kdbus_is_unique_id(name)) {
-        l = sizeof(unique_id);
-        unique_id = strtoull(name+3, NULL, 10);
-        size = sizeof(struct kdbus_cmd_info);
-        cmd = aligned_alloc(8, size);
-        memset(cmd, 0, sizeof(struct kdbus_cmd_info));
-        cmd->id = unique_id;
-        cmd->size = size;
-        cmd->attach_flags  = KDBUS_ATTACH_CREDS | KDBUS_ATTACH_SECLABEL | KDBUS_ATTACH_NAMES;
-    } else {
-        l = strlen(name) + 1;
-        size = offsetof(struct kdbus_cmd_info, items) + ALIGN8((l) + offsetof(struct kdbus_item, data));
-        cmd = aligned_alloc(8, size);
-        memset(cmd, 0, sizeof(struct kdbus_cmd_info));
-        cmd->items[0].size =  l + offsetof(struct kdbus_item, data);
-        cmd->items[0].type = KDBUS_ITEM_NAME;
-        memcpy(cmd->items[0].str, name, l);
-        cmd->size = size;
-        cmd->attach_flags  = KDBUS_ATTACH_CREDS | KDBUS_ATTACH_SECLABEL | KDBUS_ATTACH_NAMES;
-    }
-
-    r = ioctl(kc->fd, KDBUS_CMD_CONN_INFO, cmd);
-    if (r < 0)
-        return -errno;
-
-    conn_info = (struct kdbus_info *) ((uint8_t *) kc->pool + cmd->offset);
-
-    for(item = conn_info->items;
-        ((uint8_t *)(item) < (uint8_t *)(conn_info) + (conn_info)->size) &&
-        ((uint8_t *) item >= (uint8_t *) conn_info);
-        item = ((typeof(item))(((uint8_t *)item) + ALIGN8((item)->size))) )
-        {
-            switch (item->type)
-            {
-                case KDBUS_ITEM_CREDS:
-                    if (item->creds.euid != UID_INVALID)
-                    {
-                         kcr->uid = (uid_t) item->creds.euid;
-                    }
-                    if (item->creds.egid != GID_INVALID)
-                    {
-                        kcr->gid = (gid_t) item->creds.egid;
-                    }
-                break;
-            case KDBUS_ITEM_SECLABEL:
-                kcr->label = strdup(item->str);
-            break;
-            case KDBUS_ITEM_OWNED_NAME:
-                counter++;
-                tmp_names = calloc(counter+1, sizeof(char*));
-                for (j = 0;kcr->names[j]; j++)
-                {
-                    tmp_names[j] = kcr->names[j];
-                }
-                tmp_names[j] = strdup(item->name.name);
-                free(kcr->names);
-                kcr->names = tmp_names;
-            break;
-        }
-    }
-
-    return 0;
-}
-
-static void kcreds_free(struct kcreds* kcr)
-{
-    int i = 0;
-    if (kcr == NULL)
-        return;
-
-    free(kcr->label);
-    for (i=0; kcr->names[i];i++)
-        free(kcr->names[i]);
-    free(kcr->names[i]);
-    free(kcr->names);
-    free(kcr);
+       uint64_t res;
+       unsigned i = 2;
+       int c;
+       while (!(c = name[++i] - '0'));
+       res = c;
+       while ((c = (int)(name[++i]) - '0') > 0)
+               res = res*10 + c;
+       return res;
 }
 
-static int dbuspolicy_init_udesc(struct kconn* kc, unsigned int bus_type, struct udesc* p_udesc)
+static bool dbuspolicy_init_once(void)
 {
      struct passwd pwent;
      struct passwd *pwd;
@@ -239,30 +145,28 @@ static int dbuspolicy_init_udesc(struct kconn* kc, unsigned int bus_type, struct
 
      close(attr_fd);
 
-     if (r < 0 || r >= (long int)sizeof(p_udesc->label)) /* read */
-         return -1;
-
-     snprintf(p_udesc->label, r + 1 /* additional byte for \0 */, "%s", buf);
+     if (r < 0 || r >= (long int)sizeof(g_udesc.label)) /* read */
+         return true;
 
-     p_udesc->uid = getuid();
-     p_udesc->gid = getgid();
+     snprintf(g_udesc.label, r + 1 /* additional byte for \0 */, "%s", buf);
+     if (getpwuid_r(g_udesc.uid, &pwent, buf, sizeof(buf), &pwd))
+         return true;
 
-     if (getpwuid_r(p_udesc->uid, &pwent, buf, sizeof(buf), &pwd))
-         return -1;
-
-     if (getgrgid_r(p_udesc->gid, &grent, buf, sizeof(buf), &gg))
-         return -1;
+     if (getgrgid_r(g_udesc.gid, &grent, buf, sizeof(buf), &gg))
+         return true;
 
      if (!pwd || !gg)
           return -1;
 
-     snprintf(p_udesc->user, sizeof(p_udesc->user), "%s", pwd->pw_name);
-     snprintf(p_udesc->group, sizeof(p_udesc->group), "%s", gg->gr_name);
+     snprintf(g_udesc.user, sizeof(g_udesc.user), "%s", pwd->pw_name);
+     snprintf(g_udesc.group, sizeof(g_udesc.group), "%s", gg->gr_name);
 
-     p_udesc->bus_type = bus_type;
-     p_udesc->conn = kc;
+     g_udesc.uid = getuid();
+     g_udesc.gid = getgid();
 
-     return 0;
+       __internal_init_once();
+
+     return false;
 }
 
 static int bus_path_resolve(const char *bus_path, char *resolved_path, unsigned resolved_path_size, unsigned int *bus_type)
@@ -296,62 +200,62 @@ static int bus_path_resolve(const char *bus_path, char *resolved_path, unsigned
      return 0;
 }
 
+static bool init_once_done = false;
+
 DBUSPOLICY1_EXPORT void* dbuspolicy1_init(const char *bus_path)
 {
-     uint64_t hello_flags = 0;
-     uint64_t attach_flags_send =  _KDBUS_ATTACH_ANY;
-     uint64_t attach_flags_recv =  _KDBUS_ATTACH_ALL;
-     struct kconn* kc = NULL;
-     struct udesc* p_udesc = NULL;
-     unsigned int bus_type = -1;
-     char resolved_path[PATH_MAX] = { 0 };
-
-     if (bus_path_resolve(bus_path, resolved_path, sizeof(resolved_path), &bus_type) < 0)
-         goto err;
-
-     kc = (struct kconn*) calloc(1, sizeof(struct kconn));
-     if (!kc)
-         goto err;
-
-     if ((kc->fd = kdbus_open_bus(resolved_path)) < 0)
-         goto err;
-
-     if (kdbus_hello(kc, hello_flags, attach_flags_send, attach_flags_recv) < 0)
-         goto err;
-
-     if (__internal_init(bus_type, (bus_type == SYSTEM_BUS) ? SYSTEM_BUS_CONF_FILE_PRIMARY : SESSION_BUS_CONF_FILE_PRIMARY) < 0
-        && __internal_init(bus_type, (bus_type == SYSTEM_BUS) ? SYSTEM_BUS_CONF_FILE_SECONDARY : SESSION_BUS_CONF_FILE_SECONDARY) < 0)
-         goto err;
-
-     p_udesc = (struct udesc*)malloc(sizeof(struct udesc));
-     if (!p_udesc)
-         goto err;
-
-     if (dbuspolicy_init_udesc(kc, bus_type, p_udesc) < 0)
-         goto err;
-
-     return p_udesc;
-
+       unsigned int bus_type = -1;
+       char resolved_path[PATH_MAX] = { 0 };
+       int rp, rs;
+       bool rb;
+
+       _Static_assert(SYSTEM_BUS == 0, "SYSTEM_BUS not 0");
+       _Static_assert(SESSION_BUS == 1, "SESSION_BUS not 0");
+
+       if (bus_path_resolve(bus_path, resolved_path, sizeof(resolved_path), &bus_type) < 0)
+               return NULL;
+
+       if (bus_type)
+               bus_type = SESSION_BUS;
+
+       rb = false;
+       pthread_mutex_lock(&g_mutex);
+       if (!init_once_done) {
+               init_once_done = true;
+               rb = dbuspolicy_init_once();
+       }
+       pthread_mutex_unlock(&g_mutex);
+       if (rb)
+               goto err_close;
+
+       if ((g_conn[bus_type].fd = kdbus_open_bus(resolved_path)) < 0)
+               goto err;
+
+       if (kdbus_hello(bus_type, 0, _KDBUS_ATTACH_ALL, 0) < 0)
+               goto err_close;
+
+       rp = __internal_init(bus_type, (bus_type == SYSTEM_BUS) ? SYSTEM_BUS_CONF_FILE_PRIMARY : SESSION_BUS_CONF_FILE_PRIMARY);
+       rs = __internal_init(bus_type, (bus_type == SYSTEM_BUS) ? SYSTEM_BUS_CONF_FILE_SECONDARY : SESSION_BUS_CONF_FILE_SECONDARY);
+       __internal_init_flush_logs();
+       if ((rp & rs) < 0) /* when both negative */
+               goto err_close;
+
+       return &g_conn[bus_type];
+
+err_close:
+       close(g_conn[bus_type].fd);
 err:
-     if (kc && kc->fd != -1)
-         close(kc->fd);
-     free(kc);
-     free(p_udesc);
-
-     return NULL;
+       return NULL;
 }
 
 DBUSPOLICY1_EXPORT void dbuspolicy1_free(void* configuration)
 {
-    struct udesc* p_udesc = (struct udesc*)configuration;
-    if(p_udesc) {
-       close(p_udesc->conn->fd);
-        free(p_udesc->conn);
-        free(p_udesc);
-        p_udesc = NULL;
-    }
+    if (configuration)
+               close(((typeof(&g_conn[0]))configuration)->fd);
 }
 
+static bool configuration_bus_type(struct kconn const *configuration) { return configuration != g_conn; }
+
 /**
  * dbuspolicy1_can_send
  * @param: <>
@@ -370,62 +274,103 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration,
         int               reply_serial,
         int               requested_reply)
 {
-    struct udesc* const p_udesc = (struct udesc*)configuration;
-    int i, rs, rr, l,  r = 0;
-    struct kcreds* p_creds = NULL;
-    char gid[25], uid[25];
-    char* name = NULL;
-    char  empty_names = 1;
-
-    rs = 0;
-    rr = 1;
-
-    if (message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL || (destination != NULL && *destination != '\0') ) {
-        p_creds = calloc(1, sizeof(struct kcreds));
-        r = kdbus_get_creds_from_name(p_udesc->conn, p_creds, destination);
-        if(r < 0) {
-            kcreds_free(p_creds);
-            return 0;
-        }
-
-        snprintf(uid, 24, "%lu", (unsigned long int)p_creds->uid);
-        snprintf(gid, 24, "%lu", (unsigned long int)p_creds->gid);
-        if (!p_creds->names[0])
-            empty_names = 0;
-
-        for (i=0;p_creds->names[i];i++)
-        {
-            rs = __internal_can_send(p_udesc->bus_type, p_udesc->user, p_udesc->group, p_udesc->label, p_creds->names[i], path, interface, member, message_type);
-            if (rs > 0)
-                break;
-        }
-    }
+       char const *label = NULL;
+       int r;
+       uid_t uid_n = UID_INVALID;
+       gid_t gid_n = GID_INVALID;
+       bool free_offset = false;
+       bool empty_names = true;
+       bool bus_type = configuration_bus_type(configuration);
+       union {
+               struct kdbus_cmd_info cmd_info;
+               struct kdbus_cmd_free cmd_free;
+               uint8_t _buffer_[sizeof(struct kdbus_cmd_info) + offsetof(struct kdbus_item, data) + ALIGN8(MAX_DBUS_NAME_LEN+1)];
+       } cmd;
+
+       __internal_enter();
+
+    if (DBUSPOLICY_MESSAGE_TYPE_SIGNAL != message_type || (destination && *destination)) {
+               struct kdbus_info *conn_info;
+               struct kdbus_item *item;
+               uintptr_t items_end;
+
+               cmd.cmd_info.flags = 0;
+               cmd.cmd_info.attach_flags = KDBUS_ATTACH_CREDS | KDBUS_ATTACH_NAMES | (DBUSPOLICY_MESSAGE_TYPE_SIGNAL != message_type ? KDBUS_ATTACH_SECLABEL : 0);
+
+               if (kdbus_is_unique_id(destination)) {
+                       cmd.cmd_info.size = sizeof(cmd.cmd_info);
+                       cmd.cmd_info.id = kdbus_unique_id(destination);
+               } else {
+                       int l = strlen(destination);
+                       cmd.cmd_info.size = sizeof(struct kdbus_cmd_info) + offsetof(struct kdbus_item, data) + ALIGN8(l+1);
+                       cmd.cmd_info.id = 0;
+                       cmd.cmd_info.items->size =  offsetof(struct kdbus_item, data) + l+1;
+                       cmd.cmd_info.items->type = KDBUS_ITEM_NAME;
+                       *(uint64_t*)ALIGNDN8((uintptr_t)cmd.cmd_info.items->str + l) = 0; /* trailing zero + padding */
+                       memcpy(cmd.cmd_info.items->str, destination, l);
+               }
+
+               r = ioctl(g_conn[bus_type].fd, KDBUS_CMD_CONN_INFO, &cmd.cmd_info);
+               if (r < 0) {
+                       r = -errno;
+                       goto end;
+               }
+
+               cmd.cmd_free.size = sizeof(cmd.cmd_free);
+               /* flags already 0 */
+               _Static_assert(sizeof(cmd.cmd_info.flags) == sizeof(cmd.cmd_free.flags), "cmd_info/cmd_free: flag sizeof differs");
+               _Static_assert(offsetof(typeof(cmd.cmd_info), flags) == offsetof(typeof(cmd.cmd_free), flags), "cmd_info/cmd_free: flag offsetof differs");
+               cmd.cmd_free.offset = cmd.cmd_info.offset;
+
+               free_offset = true;
+
+               conn_info = (struct kdbus_info *) ((uint8_t *) g_conn[bus_type].pool + cmd.cmd_info.offset);
+               items_end = (uintptr_t)conn_info + (unsigned)conn_info->size;
+
+               _Static_assert((unsigned)KDBUS_ITEM_CREDS == KDBUS_ITEM_CREDS, "KDBUS_ITEM_CREDS not preserved when cast to unsigned");
+               _Static_assert((unsigned)KDBUS_ITEM_SECLABEL == KDBUS_ITEM_SECLABEL, "KDBUS_ITEM_SECLABEL not preserved when cast to unsigned");
+               _Static_assert((unsigned)KDBUS_ITEM_OWNED_NAME == KDBUS_ITEM_OWNED_NAME, "KDBUS_ITEM_OWNED_NAME not preserved when cast to unsigned");
+
+               for (item = conn_info->items; (uintptr_t)item < items_end; item = (typeof(item))ALIGN8((uintptr_t)item + (unsigned)item->size))
+                       switch ((unsigned)item->type)
+                       {
+                               case KDBUS_ITEM_CREDS:
+                                       uid_n = item->creds.euid;
+                                       gid_n = item->creds.egid;
+                                       break;
+                               case KDBUS_ITEM_SECLABEL:
+                                       label = item->str;
+                                       break;
+                               case KDBUS_ITEM_OWNED_NAME:
+                                       empty_names = false;
+                                       if (r <= 0)
+                                               r = __internal_can_send(bus_type, g_udesc.user, g_udesc.group, g_udesc.label, item->name.name, path, interface, member, message_type);
+                                       break;
+                       }
+       }
 
     if (empty_names)
-        rs = __internal_can_send(p_udesc->bus_type, p_udesc->user, p_udesc->group, p_udesc->label, destination, path, interface, member, message_type);
-
-    if (message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL) {
-        rr = 0;
-
-        if (!sender || !(*sender))
-            rr = __internal_can_recv(p_udesc->bus_type, uid, gid, p_creds->label, sender, path, interface, member, message_type);
-        else
-            FOREACH_STRV(i, l, sender, name) {
-                char* source;
-                GET_NEXT_STR(i, name, source);
-                rr = __internal_can_recv(p_udesc->bus_type, uid, gid, p_creds->label, source, path, interface, member, message_type);
-                if (rr > 0)
-                    break;
-            }
+        r = __internal_can_send(bus_type, g_udesc.user, g_udesc.group, g_udesc.label, destination, path, interface, member, message_type);
+
+       if (r > 0 && message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL) {
+               char gid[25], uid[25];
+               char const *ptr;
+               snprintf(uid, sizeof(uid), "%lu", (unsigned long)uid_n);
+               snprintf(gid, sizeof(gid), "%lu", (unsigned long)gid_n);
+
+        FOREACH_STRV_DEFAULT(ptr, sender)
+                       if (0 < (r = __internal_can_recv(bus_type, uid, gid, label, ptr, path, interface, member, message_type)))
+                               break;
     }
 
-    free(name);
-    kcreds_free(p_creds);
+       if (free_offset)
+               ioctl(g_conn[bus_type].fd, KDBUS_CMD_FREE, &cmd.cmd_free);
 
-    if(rs > 0 && rr > 0) { r = 1; }
-    if(rs < 0 || rr < 0) { r = -1; }
+end:
+       __internal_exit();
     return r;
 }
+
 /**
  * dbuspolicy1_can_send
  * @param: <>
@@ -447,55 +392,29 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration,
         int               reply_serial,
         int               requested_reply)
 {
-    struct udesc* const p_udesc = (struct udesc*)configuration;
-    int i, rs, rr, l, r = 0;
-    struct kcreds* p_creds = NULL;
+       char const *ptr;
+    int r;
     char gid[25], uid[25];
-    char* name = NULL;
-
-    rs = 0;
-    rr = 1;
-
-    snprintf(uid, 24, "%lu", (unsigned long int)sender_uid);
-    snprintf(gid, 24, "%lu", (unsigned long int)sender_gid);
-
-    if (!destination || !(*destination))
-         rs = __internal_can_send(p_udesc->bus_type, uid, gid, sender_label, destination, path, interface, member, message_type);
-    else
-        FOREACH_STRV(i, l, destination, name) {
-            char* dest;
-            GET_NEXT_STR(i, name, dest);
-
-            rs = __internal_can_send(p_udesc->bus_type, uid, gid, sender_label, dest, path, interface, member, message_type);
-            if (rs > 0)
-                break;
-        }
-    free(name);
-    name = NULL;
-
-    if(message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL) {
-        rr = 0;
-
-        if (!sender || !(*sender))
-            rr = __internal_can_recv(p_udesc->bus_type, p_udesc->user, p_udesc->group, p_udesc->label, sender, path, interface, member, message_type);
-        else
-            FOREACH_STRV(i, l, sender, name) {
-                char* source;
-                GET_NEXT_STR(i, name, source);
-                rr = __internal_can_recv(p_udesc->bus_type, p_udesc->user, p_udesc->group, p_udesc->label, source, path, interface, member, message_type);
-                if(rr > 0)
-                    break;
-            }
-        free(name);
-    }
-    kcreds_free(p_creds);
+       bool bus_type = configuration_bus_type(configuration);
+
+    snprintf(uid, sizeof(uid), "%lu", (unsigned long)sender_uid);
+    snprintf(gid, sizeof(gid), "%lu", (unsigned long)sender_gid);
+
+       __internal_enter();
 
-    if(rs > 0 && rr > 0) { r = 1; }
-    if(rs < 0 || rr < 0) { r = -1; }
+    FOREACH_STRV_DEFAULT(ptr, destination)
+               if (0 < (r = __internal_can_send(bus_type, uid, gid, sender_label, ptr, path, interface, member, message_type)))
+                       break;
+
+       if (r > 0 && message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL)
+        FOREACH_STRV_DEFAULT(ptr, sender)
+                       if (0 < (r = __internal_can_recv(bus_type, g_udesc.user, g_udesc.group, g_udesc.label, ptr, path, interface, member, message_type)))
+                               break;
+
+       __internal_exit();
     return r;
 }
 
-
 /**
  * dbuspolicy1_can_send
  * @param: <>
@@ -505,6 +424,10 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration,
  **/
 DBUSPOLICY1_EXPORT int dbuspolicy1_can_own(void* configuration, const char* const service)
 {
-    struct udesc* const p_udesc = (struct udesc*)configuration;
-    return  __internal_can_own(p_udesc->bus_type, p_udesc->user, p_udesc->group, service);
+       int r;
+       bool bus_type = configuration_bus_type(configuration);
+       __internal_enter();
+    r = __internal_can_own(bus_type, g_udesc.user, g_udesc.group, service);
+       __internal_exit();
+       return r;
 }