#include <unistd.h>
#include <memory>
+#include <string>
+#include <vector>
#include "caps.h"
#include "config.h"
return val;
}
-/* findSpecDestination mutates spec (source:dest) to have a null byte instead
- * of ':' in between source and dest, then returns a pointer to the dest
- * string. */
-static char* cmdlineSplitStrByColon(char* spec) {
- if (spec == NULL) {
- return NULL;
+static std::string argByColon(const char* str, size_t pos) {
+ if (!str) {
+ return "";
}
-
- char* dest = spec;
- while (*dest != ':' && *dest != '\0') {
- dest++;
- }
-
- switch (*dest) {
- case ':':
- *dest = '\0';
- return dest + 1;
- case '\0':
- return NULL;
- default:
- LOG_F("Impossible condition in cmdlineSplitStrByColon()");
- return NULL;
+ std::vector<std::string> vec;
+ util::strSplit(str, &vec, ':');
+ if (pos > vec.size()) {
+ return "";
}
+ return vec[pos];
}
std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
nsjconf->envs.push_back(optarg);
break;
case 'u': {
- char* i_id = optarg;
- char* o_id = cmdlineSplitStrByColon(i_id);
- char* cnt = cmdlineSplitStrByColon(o_id);
- size_t count =
- (cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0);
- if (user::parseId(nsjconf.get(), i_id, o_id, count, false /* is_gid */,
- false /* is_newidmap */) == false) {
+ std::string i_id = argByColon(optarg, 0);
+ std::string o_id = argByColon(optarg, 1);
+ std::string cnt = argByColon(optarg, 2);
+ size_t count = std::strtoul(cnt.c_str(), nullptr, 0);
+ if (!user::parseId(nsjconf.get(), i_id, o_id, count, /* is_gid= */ false,
+ /* is_newidmap= */ false)) {
return nullptr;
}
} break;
case 'g': {
- char* i_id = optarg;
- char* o_id = cmdlineSplitStrByColon(i_id);
- char* cnt = cmdlineSplitStrByColon(o_id);
- size_t count =
- (cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0);
- if (user::parseId(nsjconf.get(), i_id, o_id, count, true /* is_gid */,
- false /* is_newidmap */) == false) {
+ std::string i_id = argByColon(optarg, 0);
+ std::string o_id = argByColon(optarg, 1);
+ std::string cnt = argByColon(optarg, 2);
+ size_t count = std::strtoul(cnt.c_str(), nullptr, 0);
+ if (!user::parseId(nsjconf.get(), i_id, o_id, count, /* is_gid= */ true,
+ /* is_newidmap= */ false)) {
return nullptr;
}
} break;
case 'U': {
- char* i_id = optarg;
- char* o_id = cmdlineSplitStrByColon(i_id);
- char* cnt = cmdlineSplitStrByColon(o_id);
- size_t count =
- (cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0);
- if (user::parseId(nsjconf.get(), i_id, o_id, count, false /* is_gid */,
- true /* is_newidmap */) == false) {
+ std::string i_id = argByColon(optarg, 0);
+ std::string o_id = argByColon(optarg, 1);
+ std::string cnt = argByColon(optarg, 2);
+ size_t count = std::strtoul(cnt.c_str(), nullptr, 0);
+ if (!user::parseId(nsjconf.get(), i_id, o_id, count, /* is_gid= */ false,
+ /* is_newidmap= */ true)) {
return nullptr;
}
} break;
case 'G': {
- char* i_id = optarg;
- char* o_id = cmdlineSplitStrByColon(i_id);
- char* cnt = cmdlineSplitStrByColon(o_id);
- size_t count =
- (cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0);
- if (user::parseId(nsjconf.get(), i_id, o_id, count, true /* is_gid */,
- true /* is_newidmap */) == false) {
+ std::string i_id = argByColon(optarg, 0);
+ std::string o_id = argByColon(optarg, 1);
+ std::string cnt = argByColon(optarg, 2);
+ size_t count = std::strtoul(cnt.c_str(), nullptr, 0);
+ if (!user::parseId(nsjconf.get(), i_id, o_id, count, /* is_gid= */ true,
+ /* is_newidmap= */ true)) {
return nullptr;
}
} break;
case 'R': {
- const char* dst = cmdlineSplitStrByColon(optarg);
- dst = dst ? dst : optarg;
- if (!mnt::addMountPtTail(nsjconf.get(), /* src= */ optarg, dst,
- /* fs_type= */ "",
- /* options= */ "", MS_BIND | MS_REC | MS_PRIVATE | MS_RDONLY,
+ std::string src = argByColon(optarg, 0);
+ std::string dst = argByColon(optarg, 1);
+ if (dst.empty()) {
+ dst = src;
+ }
+ if (!mnt::addMountPtTail(nsjconf.get(), src.c_str(), dst.c_str(),
+ /* fs_type= */ "", /* options= */ "",
+ MS_BIND | MS_REC | MS_PRIVATE | MS_RDONLY,
/* isDir= */ mnt::NS_DIR_MAYBE, /* mandatory= */ true, NULL, NULL,
NULL, 0, /* is_symlink= */ false)) {
return nullptr;
}
}; break;
case 'B': {
- const char* dst = cmdlineSplitStrByColon(optarg);
- dst = dst ? dst : optarg;
- if (!mnt::addMountPtTail(nsjconf.get(), /* src= */ optarg, dst,
- /* fs_type= */ "",
- /* options= */ "", MS_BIND | MS_REC | MS_PRIVATE,
+ std::string src = argByColon(optarg, 0);
+ std::string dst = argByColon(optarg, 1);
+ if (dst.empty()) {
+ dst = src;
+ }
+ if (!mnt::addMountPtTail(nsjconf.get(), src.c_str(), dst.c_str(),
+ /* fs_type= */ "", /* options= */ "", MS_BIND | MS_REC | MS_PRIVATE,
/* isDir= */ mnt::NS_DIR_MAYBE, /* mandatory= */ true, NULL, NULL,
NULL, 0, /* is_symlink= */ false)) {
return nullptr;
namespace config {
-#define VAL_IF_SET_OR_NULL(njc, val) (njc.has_##val() ? njc.val().c_str() : NULL)
-
static uint64_t configRLimit(
int res, const nsjail::RLimit& rl, const uint64_t val, unsigned long mul = 1UL) {
if (rl == nsjail::RLimit::VALUE) {
nsjconf->clone_newcgroup = njc.clone_newcgroup();
for (ssize_t i = 0; i < njc.uidmap_size(); i++) {
- if (!user::parseId(nsjconf, VAL_IF_SET_OR_NULL(njc.uidmap(i), inside_id),
- VAL_IF_SET_OR_NULL(njc.uidmap(i), outside_id), njc.uidmap(i).count(),
- false /* is_gid */, njc.uidmap(i).use_newidmap())) {
+ if (!user::parseId(nsjconf, njc.uidmap(i).inside_id(), njc.uidmap(i).outside_id(),
+ njc.uidmap(i).count(), false /* is_gid */, njc.uidmap(i).use_newidmap())) {
return false;
}
}
for (ssize_t i = 0; i < njc.gidmap_size(); i++) {
- if (!user::parseId(nsjconf, VAL_IF_SET_OR_NULL(njc.gidmap(i), inside_id),
- VAL_IF_SET_OR_NULL(njc.gidmap(i), outside_id), njc.gidmap(i).count(),
- true /* is_gid */, njc.gidmap(i).use_newidmap())) {
+ if (!user::parseId(nsjconf, njc.gidmap(i).inside_id(), njc.gidmap(i).outside_id(),
+ njc.gidmap(i).count(), true /* is_gid */, njc.gidmap(i).use_newidmap())) {
return false;
}
}
return true;
}
-static uid_t parseUid(const char* id) {
- if (id == NULL || strlen(id) == 0) {
+static uid_t parseUid(const std::string& id) {
+ if (id.empty()) {
return getuid();
}
- struct passwd* pw = getpwnam(id);
+ struct passwd* pw = getpwnam(id.c_str());
if (pw != NULL) {
return pw->pw_uid;
}
- if (util::isANumber(id)) {
- return (uid_t)strtoull(id, NULL, 0);
+ if (util::isANumber(id.c_str())) {
+ return (uid_t)strtoull(id.c_str(), NULL, 0);
}
return (uid_t)-1;
}
-static gid_t parseGid(const char* id) {
- if (id == NULL || strlen(id) == 0) {
+static gid_t parseGid(const std::string& id) {
+ if (id.empty()) {
return getgid();
}
- struct group* gr = getgrnam(id);
+ struct group* gr = getgrnam(id.c_str());
if (gr != NULL) {
return gr->gr_gid;
}
- if (util::isANumber(id)) {
- return (gid_t)strtoull(id, NULL, 0);
+ if (util::isANumber(id.c_str())) {
+ return (gid_t)strtoull(id.c_str(), NULL, 0);
}
return (gid_t)-1;
}
-bool parseId(nsjconf_t* nsjconf, const char* i_id, const char* o_id, size_t cnt, bool is_gid,
- bool is_newidmap) {
+bool parseId(nsjconf_t* nsjconf, const std::string& i_id, const std::string& o_id, size_t cnt,
+ bool is_gid, bool is_newidmap) {
+ if (cnt < 1) {
+ cnt = 1;
+ }
+
uid_t inside_id;
uid_t outside_id;
if (is_gid) {
inside_id = parseGid(i_id);
if (inside_id == (uid_t)-1) {
- LOG_W("Cannot parse '%s' as GID", i_id);
+ LOG_W("Cannot parse '%s' as GID", i_id.c_str());
return false;
}
outside_id = parseGid(o_id);
if (outside_id == (uid_t)-1) {
- LOG_W("Cannot parse '%s' as GID", o_id);
+ LOG_W("Cannot parse '%s' as GID", o_id.c_str());
return false;
}
} else {
inside_id = parseUid(i_id);
if (inside_id == (uid_t)-1) {
- LOG_W("Cannot parse '%s' as UID", i_id);
+ LOG_W("Cannot parse '%s' as UID", i_id.c_str());
return false;
}
outside_id = parseUid(o_id);
if (outside_id == (uid_t)-1) {
- LOG_W("Cannot parse '%s' as UID", o_id);
+ LOG_W("Cannot parse '%s' as UID", o_id.c_str());
return false;
}
}