+-------------------------------------------------------------------
+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
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();
}
}
}
+ 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());
}
void setConfigInfo(const map<string, string>& raw);
vector<uid_t> uids;
+ vector<gid_t> gids;
Snapper* getSnapper();
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;
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;
}
}
+ 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);
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