#include "tests_common.h"
#include <unistd.h>
+#include <grp.h>
+#include <errno.h>
+#include <vector>
+#include <algorithm>
int DB::Transaction::db_result = PC_OPERATION_SUCCESS;
#endif
}
-void closeFileDsr(int *fd)
-{
- close(*fd);
-}
-
/**
* Dropping root privileges
* returns 0 on success, 1 on error
*/
-int drop_root_privileges(void)
+int drop_root_privileges(uid_t appUid, gid_t appGid)
{
if (getuid() == 0) {
/* process is running as root, drop privileges */
- if (setgid(APP_GID) != 0)
+ if (setgid(appGid) != 0)
return 1;
- if (setuid(APP_UID) != 0)
+ if (setuid(appUid) != 0)
return 1;
}
uid_t uid = getuid();
- if (uid == APP_UID)
+ if (uid == appUid)
return 0;
return 1;
}
-void dropRootPrivileges(const int line)
-{
- int ret = drop_root_privileges();
- RUNNER_ASSERT_MSG(ret == 0, "Error in drop privileges" << ", line: " << line);
-}
-
void setLabelForSelf(const int line, const char *label)
{
int ret = smack_set_label_for_self(label);
RUNNER_ASSERT_MSG(ret == 0, "Error in smack_set_label_for_self(): " << ret << ", line: " << line);
}
-void addSmackRule(const int line, const char *subject, const char *object, const char *access)
+/*
+ * Add a new group to the current process groups.
+ */
+void add_process_group(const char* group_name)
{
- struct smack_accesses *rulesTmp = NULL;
-
- int ret = smack_accesses_new(&rulesTmp);
- RUNNER_ASSERT_MSG(ret == 0, "Error in smack_accesses_new(): " << ret << ", line: " << line);
+ // get group ID by group name
+ group *gr = getgrnam(group_name);
+ RUNNER_ASSERT_ERRNO_MSG(gr != nullptr, "getgrnam failed on '" << group_name << "' group");
+ const gid_t new_group_id = gr->gr_gid;
- AccessesUniquePtr rules(rulesTmp, smack_accesses_free);
+ // get number of groups that the current process belongs to
+ int ngroups = getgroups(0, nullptr);
- ret = smack_accesses_add(rules.get(), subject, object, access);
- RUNNER_ASSERT_MSG(ret == 0, "Error in smack_accesses_add():" << ret << ", line: " << line);
+ //allocate groups table + space for new group entry
+ std::vector<gid_t> groups(ngroups + 1);
+ getgroups(ngroups, groups.data());
- ret = smack_accesses_apply(rules.get());
- RUNNER_ASSERT_MSG(ret == 0, "Error in smack_accesses_apply(): " << ret << ", line: " << line);
+ // check if the process already belongs to the group
+ if (std::find(groups.begin(), groups.end(), new_group_id) != groups.end()) return;
- ret = smack_have_access(subject, object, access);
- RUNNER_ASSERT_MSG(ret == 1, "Error in checking if smack rule exist: " << ret << ", line: " << line);
+ // add new group & apply change
+ groups[ngroups] = new_group_id;
+ int ret = setgroups(groups.size(), groups.data());
+ RUNNER_ASSERT_ERRNO_MSG(ret == 0, "setgroups() failed");
}
-void removeSmackRule(const int line, const char *subject, const char *object, const char *access)
+/*
+ * Remove specific group from the current process groups.
+ */
+void remove_process_group(const char* group_name)
{
- struct smack_accesses *rulesTmp = NULL;
-
- int ret = smack_accesses_new(&rulesTmp);
- RUNNER_ASSERT_MSG(ret == 0, "Error in smack_accesses_new(): " << ret << ", line: " << line);
-
- AccessesUniquePtr rules(rulesTmp, smack_accesses_free);
-
- ret = smack_accesses_add(rules.get(), subject, object, access);
- RUNNER_ASSERT_MSG(ret == 0, "Error in smack_accesses_add(): " << ret << ", line: " << line);
-
- ret = smack_accesses_clear(rules.get());
- RUNNER_ASSERT_MSG(ret == 0, "Error in smack_accesses_clear(): " << ret << ", line: " << line);
+ // get group ID by group name
+ group *gr = getgrnam(group_name);
+ RUNNER_ASSERT_ERRNO_MSG(gr != nullptr, "getgrnam failed on '" << group_name << "' group");
+ const gid_t new_group_id = gr->gr_gid;
+
+ int ngroups = getgroups(0, nullptr);
+ std::vector<gid_t> groups(ngroups);
+ getgroups(ngroups, groups.data());
+
+ // remove group from the list
+ groups.erase(std::remove(groups.begin(), groups.end(), new_group_id), groups.end());
+
+ if (groups.size() != (size_t)ngroups) {
+ // apply change
+ int ret = setgroups(groups.size(), groups.data());
+ RUNNER_ASSERT_ERRNO_MSG(ret == 0, "setgroups() failed");
+ }
+}
- ret = smack_have_access(subject, object, access);
- RUNNER_ASSERT_MSG(ret == 1, "Error in checking if smack rule exist: " << ret << ", line: " << line);
+std::string formatCstr(const char *cstr)
+{
+ if (!cstr)
+ return std::string("nullptr");
+ return std::string("\"") + cstr + "\"";
}