diff --git a/src/util.cc b/src/util.cc index 9227e3e..b76a5a5 100644 --- a/src/util.cc +++ b/src/util.cc @@ -18,6 +18,8 @@ #include"util.h" #include #include +#include +#include #include #include #include @@ -721,3 +723,32 @@ string strdatetime(struct tm *datetime) strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M", datetime); return string(buf); } + +AccessCheck checkIfExistsAndSameGroup(string device) +{ + struct stat sb; + + int ok = stat(device.c_str(), &sb); + + // The file did not exist. + if (ok) return AccessCheck::NotThere; + + gid_t groups[256]; + int ngroups = 256; + + struct passwd *p = getpwuid(getuid()); + + int rc = getgrouplist(p->pw_name, p->pw_gid, groups, &ngroups); + if (rc < 0) { + error("(wmbusmeters) cannot handle users with more than 256 groups\n"); + } + struct group *g = getgrgid(sb.st_gid); + + for (int i=0; igr_gid) { + return AccessCheck::OK; + } + } + + return AccessCheck::NotSameGroup; +} diff --git a/src/util.h b/src/util.h index 71f7057..3022fd2 100644 --- a/src/util.h +++ b/src/util.h @@ -103,5 +103,9 @@ void eatWhitespace(std::vector &v, std::vector::iterator &i, bool *e std::string eatToSkipWhitespace(std::vector &v, std::vector::iterator &i, int c, size_t max, bool *eof, bool *err); // Remove leading and trailing white space void trimWhitespace(std::string *s); +// Returns true if device exists and this programs user, belongs +// to the same group that the device belongs to. +enum class AccessCheck { NotThere, NotSameGroup, OK }; +AccessCheck checkIfExistsAndSameGroup(std::string device); #endif diff --git a/src/wmbus.cc b/src/wmbus.cc index 5c0f09f..1359d93 100644 --- a/src/wmbus.cc +++ b/src/wmbus.cc @@ -16,7 +16,6 @@ */ #include"wmbus.h" -#include #include #include #include @@ -273,24 +272,6 @@ bool detectIM871A(string device, SerialCommunicationManager *handler); bool detectAMB8465(string device, SerialCommunicationManager *handler); bool detectRTLSDR(string device, SerialCommunicationManager *handler); -bool existsButWrongGroup(string device) -{ - struct stat sb; - - int ok = stat(device.c_str(), &sb); - - // The file did not exist. - if (ok) return false; - - struct group *g = getgrgid(sb.st_gid); - if (g && getegid() != g->gr_gid) - { - // Our group is not the same as the device. - return true; - } - return false; -} - pair detectMBusDevice(string device, SerialCommunicationManager *handler) { // If auto, then assume that uev has been configured with @@ -307,22 +288,37 @@ pair detectMBusDevice(string device, SerialCommunicationM if (detectIM871A("/dev/im871a", handler)) { return { DEVICE_IM871A, "/dev/im871a" }; - } else if (existsButWrongGroup("/dev/im871a")) { - error("You are not in the same group as the device /dev/im871a\n"); + } + else + { + AccessCheck ac = checkIfExistsAndSameGroup("/dev/im871a"); + if (ac == AccessCheck::NotSameGroup) { + error("You are not in the same group as the device /dev/im871a\n"); + } } if (detectAMB8465("/dev/amb8465", handler)) { return { DEVICE_AMB8465, "/dev/amb8465" }; - } else if (existsButWrongGroup("/dev/amb8465")) { - error("You are not in the same group as the device /dev/amb8465\n"); + } + else + { + AccessCheck ac = checkIfExistsAndSameGroup("/dev/amb8465"); + if (ac == AccessCheck::NotSameGroup) { + error("You are not in the same group as the device /dev/amb8465\n"); + } } if (detectRTLSDR("/dev/rtlsdr", handler)) { return { DEVICE_RTLWMBUS, "rtlwmbus" }; - } else if (existsButWrongGroup("/dev/rtlsdr")) { - error("You are not in the same group as the device /dev/rtlsdr\n"); + } + else + { + AccessCheck ac = checkIfExistsAndSameGroup("/dev/amb8465"); + if (ac == AccessCheck::NotSameGroup) { + error("You are not in the same group as the device /dev/rtlsdr\n"); + } } return { DEVICE_UNKNOWN, "" }; @@ -355,9 +351,6 @@ pair detectMBusDevice(string device, SerialCommunicationM { return { DEVICE_IM871A, device }; } - if (existsButWrongGroup(device)) { - error("You are not in the same group as the device %s\n", device.c_str()); - } return { DEVICE_UNKNOWN, "" }; } diff --git a/src/wmbus_rtlwmbus.cc b/src/wmbus_rtlwmbus.cc index e405a89..65d3ed4 100644 --- a/src/wmbus_rtlwmbus.cc +++ b/src/wmbus_rtlwmbus.cc @@ -196,16 +196,6 @@ FrameStatus WMBusRTLWMBUS::checkRTLWMBUSFrame(vector &data, bool detectRTLSDR(string device, SerialCommunicationManager *manager) { // No more advanced test than that the /dev/rtlsdr link exists. - struct stat sb; - int rc = stat(device.c_str(), &sb); - if (rc) return false; - - struct group *g = getgrgid(sb.st_gid); - if (g && getegid() != g->gr_gid) - { - // Our group is not the same as the device. - return false; - } - - return true; + AccessCheck ac = checkIfExistsAndSameGroup(device); + return ac == AccessCheck::OK; }