]> git.ipfire.org Git - thirdparty/snapper.git/commitdiff
- also handle primary group of user when checking permissions (see gh#openSUSE/snappe... 103/head
authorArvin Schnell <aschnell@suse.de>
Thu, 31 Jul 2014 13:54:34 +0000 (15:54 +0200)
committerArvin Schnell <aschnell@suse.de>
Thu, 31 Jul 2014 13:54:34 +0000 (15:54 +0200)
package/snapper.changes
server/Client.cc
server/MetaSnapper.cc
server/MetaSnapper.h
snapper/AppUtil.cc
snapper/AppUtil.h

index ab4d781c833da2eecfed8d0c9aa48b06edb8b69c..08af4cd7be79e34cd6e3296e07f3d6430e77aee8 100644 (file)
@@ -1,3 +1,9 @@
+-------------------------------------------------------------------
+Thu Jul 31 15:38:16 CEST 2014 - aschnell@suse.de
+
+- also handle primary group of user when checking permissions
+  (see gh#openSUSE/snapper#100)
+
 -------------------------------------------------------------------
 Fri Jul 25 12:38:33 CEST 2014 - aschnell@suse.de
 
index 52c2b21d46406a85fed63a600a9e469168f75169..d5ee82054a97e92888633d5cb0e8b1ea14b575c1 100644 (file)
@@ -382,12 +382,33 @@ Client::check_permission(DBus::Connection& conn, DBus::Message& msg,
                         const MetaSnapper& meta_snapper) const
 {
     unsigned long uid = conn.get_unix_userid(msg);
+
+    // Check if the uid of the dbus-user is root.
     if (uid == 0)
        return;
 
-    if (find(meta_snapper.uids.begin(), meta_snapper.uids.end(), uid) != meta_snapper.uids.end())
+    // Check if the uid of the dbus-user is included in the allowed uids.
+    if (contains(meta_snapper.uids, uid))
        return;
 
+    string username;
+    gid_t gid;
+
+    if (get_uid_username_gid(uid, username, gid))
+    {
+       // Check if the primary gid of the dbus-user is included in the allowed gids.
+       if (contains(meta_snapper.gids, gid))
+           return;
+
+       vector<gid_t> gids = getgrouplist(username.c_str(), gid);
+
+       // Check if any (primary or secondary) gid of the dbus-user is included in the allowed
+       // gids.
+       for (vector<gid_t>::const_iterator it = gids.begin(); it != gids.end(); ++it)
+           if (contains(meta_snapper.gids, *it))
+               return;
+    }
+
     throw Permissions();
 }
 
index 31686965d6a902e6fd8c20d4370a7802f6d0722d..941c18ffa8b05880bcee4997200af60dd8389fb0 100644 (file)
@@ -147,19 +147,24 @@ MetaSnapper::set_permissions()
        }
     }
 
+    sort(uids.begin(), uids.end());
+    uids.erase(unique(uids.begin(), uids.end()), uids.end());
+
+    gids.clear();
+
     vector<string> groups;
     if (config_info.getValue(KEY_ALLOW_GROUPS, groups))
     {
        for (vector<string>::const_iterator it = groups.begin(); it != groups.end(); ++it)
        {
-           vector<uid_t> tmp;
-           if (get_group_uids(it->c_str(), tmp))
-               uids.insert(uids.end(), tmp.begin(), tmp.end());
+           gid_t tmp;
+           if (get_group_gid(it->c_str(), tmp))
+               gids.push_back(tmp);
        }
     }
 
-    sort(uids.begin(), uids.end());
-    uids.erase(unique(uids.begin(), uids.end()), uids.end());
+    sort(gids.begin(), gids.end());
+    gids.erase(unique(gids.begin(), gids.end()), gids.end());
 }
 
 
index 4afda9e791da8a40fd1cd5c95d36fcd79435e4ec..e570a5d28d96906ad97ef8e6a1ebb3d532d440ca 100644 (file)
@@ -95,6 +95,7 @@ public:
     void setConfigInfo(const map<string, string>& raw);
 
     vector<uid_t> uids;
+    vector<gid_t> gids;
 
     Snapper* getSnapper();
 
index b7d3a4cd9663dc780533d84cba1277c48db07245..681f332bac8168ccd32281de89808b75ab1c3b88 100644 (file)
@@ -281,7 +281,7 @@ namespace snapper
 
 
     bool
-    get_user_uid(const char* username, uid_t& uid)
+    get_uid_username_gid(uid_t uid, string& username, gid_t& gid)
     {
        struct passwd pwd;
        struct passwd* result;
@@ -289,45 +289,36 @@ namespace snapper
        long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
        char buf[bufsize];
 
-       if (getpwnam_r(username, &pwd, buf, bufsize, &result) != 0 || result != &pwd)
-       {
-           y2war("couldn't find username '" << username << "'");
+       if (getpwuid_r(uid, &pwd, buf, bufsize, &result) != 0 || result != &pwd)
            return false;
-       }
 
        memset(pwd.pw_passwd, 0, strlen(pwd.pw_passwd));
 
-       uid = pwd.pw_uid;
+       username = pwd.pw_name;
+       gid = pwd.pw_gid;
 
        return true;
     }
 
 
     bool
-    get_group_uids(const char* groupname, vector<uid_t>& uids)
+    get_user_uid(const char* username, uid_t& uid)
     {
-       struct group grp;
-       struct group* result;
+       struct passwd pwd;
+       struct passwd* result;
 
-       long bufsize = sysconf(_SC_GETGR_R_SIZE_MAX);
+       long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
        char buf[bufsize];
 
-       if (getgrnam_r(groupname, &grp, buf, bufsize, &result) != 0 || result != &grp)
+       if (getpwnam_r(username, &pwd, buf, bufsize, &result) != 0 || result != &pwd)
        {
-           y2war("couldn't find groupname '" << groupname << "'");
+           y2war("couldn't find username '" << username << "'");
            return false;
        }
 
-       memset(grp.gr_passwd, 0, strlen(grp.gr_passwd));
-
-       uids.clear();
+       memset(pwd.pw_passwd, 0, strlen(pwd.pw_passwd));
 
-       for (char** p = grp.gr_mem; *p != NULL; ++p)
-       {
-           uid_t uid;
-           if (get_user_uid(*p, uid))
-               uids.push_back(uid);
-       }
+       uid = pwd.pw_uid;
 
        return true;
     }
@@ -356,6 +347,27 @@ namespace snapper
     }
 
 
+    vector<gid_t>
+    getgrouplist(const char* username, gid_t gid)
+    {
+       int n = 16;
+       gid_t* buf = (gid_t*) malloc(sizeof(gid_t) * n);
+
+       if (::getgrouplist(username, gid, buf, &n) == -1)
+       {
+           buf = (gid_t*) realloc(buf, sizeof(gid_t) * n);
+           ::getgrouplist(username, gid, buf, &n);
+       }
+
+       vector<gid_t> gids(&buf[0], &buf[n]);
+       sort(gids.begin(), gids.end());
+
+       free(buf);
+
+       return gids;
+    }
+
+
     StopWatch::StopWatch()
     {
        gettimeofday(&start_tv, NULL);
index 05609925eed1a3019c60b85605c19292621d806d..1afb9c94fcb6bd233f3ed4b78540c5ea283edc94 100644 (file)
@@ -86,10 +86,10 @@ namespace snapper
     time_t scan_datetime(const string& str, bool utc);
 
     string username(uid_t uid);
-
+    bool get_uid_username_gid(uid_t uid, string& username, gid_t& gid);
     bool get_user_uid(const char* username, uid_t& uid);
     bool get_group_gid(const char* groupname, gid_t& gid);
-    bool get_group_uids(const char* groupname, vector<uid_t>& uids);
+    vector<gid_t> getgrouplist(const char* username, gid_t gid);
 
 
     class StopWatch