summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA. Wilcox <AWilcox@Wilcox-Tech.com>2019-10-18 18:31:19 -0500
committerA. Wilcox <AWilcox@Wilcox-Tech.com>2019-10-18 18:31:19 -0500
commit799b2fc3939bf4e30ed404a67aa7697ae352f5fe (patch)
tree06ca7e1282503580f557d4b2b41a0897d32aa91c
parente4cd6fffb79807fa1d184bc8d108a91aea8af649 (diff)
downloadhorizon-799b2fc3939bf4e30ed404a67aa7697ae352f5fe.tar.gz
horizon-799b2fc3939bf4e30ed404a67aa7697ae352f5fe.tar.bz2
horizon-799b2fc3939bf4e30ed404a67aa7697ae352f5fe.tar.xz
horizon-799b2fc3939bf4e30ed404a67aa7697ae352f5fe.zip
hscript: Add stub User* classes
-rw-r--r--hscript/script.cc107
-rw-r--r--hscript/user.cc88
-rw-r--r--hscript/user.hh81
3 files changed, 269 insertions, 7 deletions
diff --git a/hscript/script.cc b/hscript/script.cc
index 83957f8..1cc6f5d 100644
--- a/hscript/script.cc
+++ b/hscript/script.cc
@@ -67,6 +67,15 @@ const std::map<std::string, key_parse_fn> valid_keys = {
namespace Horizon {
+/*! Describes a user account. */
+struct UserDetail {
+ std::unique_ptr<Horizon::Keys::Username> name;
+ std::unique_ptr<Horizon::Keys::UserAlias> alias;
+ std::unique_ptr<Horizon::Keys::UserPassphrase> passphrase;
+ std::unique_ptr<Horizon::Keys::UserIcon> icon;
+ std::vector< std::unique_ptr<Horizon::Keys::UserGroups> > groups;
+};
+
struct Script::ScriptPrivate {
/*! Determines whether or not to enable networking. */
std::unique_ptr<Horizon::Keys::Network> network;
@@ -86,6 +95,9 @@ struct Script::ScriptPrivate {
/*! APK repositories */
std::vector< std::unique_ptr<Horizon::Keys::Repository> > repos;
+ /*! User account information */
+ std::map< std::string, std::unique_ptr<UserDetail> > accounts;
+
/*! Disk identification keys */
std::vector< std::unique_ptr<Horizon::Keys::DiskId> > diskids;
@@ -104,29 +116,35 @@ struct Script::ScriptPrivate {
err_str += " at installfile:" + std::to_string(OBJ->lineno());\
if(errors) *errors += 1;\
output_error("installfile:" + std::to_string(lineno),\
- "duplicate value for key '" + KEY + "'", err_str);
+ "duplicate value for key '" + std::string(KEY) + "'",\
+ err_str);
using namespace Horizon::Keys;
if(key_name == "network") {
+
if(this->network) {
- DUPLICATE_ERROR(this->network, std::string("network"),
+ DUPLICATE_ERROR(this->network, "network",
this->network->test() ? "true" : "false")
return false;
}
std::unique_ptr<Network> net(dynamic_cast<Network *>(obj));
this->network = std::move(net);
return true;
+
} else if(key_name == "hostname") {
+
if(this->hostname) {
- DUPLICATE_ERROR(this->hostname, std::string("hostname"),
+ DUPLICATE_ERROR(this->hostname, "hostname",
this->hostname->value())
return false;
}
std::unique_ptr<Hostname> name(dynamic_cast<Hostname *>(obj));
this->hostname = std::move(name);
return true;
+
} else if(key_name == "pkginstall") {
+
PkgInstall *install = dynamic_cast<PkgInstall *>(obj);
for(auto &pkg : install->packages()) {
if(opts.test(StrictMode) && packages.find(pkg) != packages.end()) {
@@ -140,7 +158,9 @@ struct Script::ScriptPrivate {
}
delete install;
return true;
+
} else if(key_name == "rootpw") {
+
if(this->rootpw) {
DUPLICATE_ERROR(this->rootpw, std::string("rootpw"),
"an encrypted passphrase")
@@ -151,29 +171,110 @@ struct Script::ScriptPrivate {
);
this->rootpw = std::move(name);
return true;
+
} else if(key_name == "mount") {
+
std::unique_ptr<Mount> mount(dynamic_cast<Mount *>(obj));
this->mounts.push_back(std::move(mount));
return true;
+
} else if(key_name == "netaddress") {
+
std::unique_ptr<NetAddress> addr(dynamic_cast<NetAddress *>(obj));
this->addresses.push_back(std::move(addr));
return true;
+
} else if(key_name == "netssid") {
+
std::unique_ptr<NetSSID> ssid(dynamic_cast<NetSSID *>(obj));
this->ssids.push_back(std::move(ssid));
return true;
+
} else if(key_name == "repository") {
+
std::unique_ptr<Repository> repo(dynamic_cast<Repository *>(obj));
this->repos.push_back(std::move(repo));
return true;
+
} else if(key_name == "diskid") {
+
std::unique_ptr<DiskId> diskid(dynamic_cast<DiskId *>(obj));
this->diskids.push_back(std::move(diskid));
return true;
+
+ } else if(key_name == "username") {
+
+ if(accounts.size() >= 255) {
+ output_error("installfile:" + std::to_string(lineno),
+ "username: too many users",
+ "you may only specify 255 users");
+ return false;
+ }
+ std::unique_ptr<Username> name(dynamic_cast<Username *>(obj));
+ if(accounts.find(name->value()) != accounts.end()) {
+ DUPLICATE_ERROR((*accounts.find(name->value())).second->name,
+ "username", "assigned")
+ return false;
+ }
+ std::unique_ptr<UserDetail> detail(new UserDetail);
+ detail->name = std::move(name);
+ accounts.insert(std::make_pair(name->value(), std::move(detail)));
+ return true;
+
+#define GET_USER_DETAIL(OBJ, KEY) \
+ if(accounts.find(OBJ->username()) == accounts.end()) {\
+ output_error("installfile:" + std::to_string(lineno),\
+ std::string(KEY) + ": account name " + OBJ->username() +\
+ " is unknown");\
+ return false;\
+ }\
+ UserDetail *detail = (*accounts.find(OBJ->username())).second.get();
+
+ } else if(key_name == "useralias") {
+
+ std::unique_ptr<UserAlias> alias(dynamic_cast<UserAlias *>(obj));
+ GET_USER_DETAIL(alias, "useralias")
+ if(detail->alias) {
+ DUPLICATE_ERROR(detail->alias, "useralias", detail->alias->alias())
+ return false;
+ }
+ detail->alias = std::move(alias);
+ return true;
+
+ } else if(key_name == "userpw") {
+
+ std::unique_ptr<UserPassphrase> pw(dynamic_cast<UserPassphrase *>(obj));
+ GET_USER_DETAIL(pw, "userpw")
+ if(detail->passphrase) {
+ DUPLICATE_ERROR(detail->passphrase, "userpw",
+ "an encrypted passphrase")
+ return false;
+ }
+ detail->passphrase = std::move(pw);
+ return true;
+
+ } else if(key_name == "usericon") {
+
+ std::unique_ptr<UserIcon> icon(dynamic_cast<UserIcon *>(obj));
+ GET_USER_DETAIL(icon, "usericon")
+ if(detail->icon) {
+ DUPLICATE_ERROR(detail->icon, "usericon", detail->icon->icon())
+ return false;
+ }
+ detail->icon = std::move(icon);
+ return true;
+
+ } else if(key_name == "usergroups") {
+
+ std::unique_ptr<UserGroups> grp(dynamic_cast<UserGroups *>(obj));
+ GET_USER_DETAIL(grp, "usergroups")
+ detail->groups.push_back(std::move(grp));
+ return true;
+
} else {
return false;
}
+
#undef DUPLICATE_ERROR
}
};
diff --git a/hscript/user.cc b/hscript/user.cc
index 4d00cb2..92fed4e 100644
--- a/hscript/user.cc
+++ b/hscript/user.cc
@@ -13,6 +13,7 @@
#include <assert.h>
#include <cstring>
#include <fstream>
+#include <set>
#include <sstream>
#include <time.h>
#include "user.hh"
@@ -20,6 +21,23 @@
using namespace Horizon::Keys;
+const static std::set<std::string> system_names = {
+ "root", "bin", "daemon", "adm", "lp", "sync", "shutdown", "halt", "mail",
+ "news", "uucp", "operator", "man", "postmaster", "cron", "ftp", "sshd",
+ "at", "squid", "xfs", "games", "postgres", "cyrus", "vpopmail", "utmp",
+ "catchlog", "alias", "qmaild", "qmailp", "qmailq", "qmailr", "qmails",
+ "qmaill", "ntp", "smmsp", "guest", "nobody"
+};
+
+const static std::set<std::string> system_groups = {
+ "root", "bin", "daemon", "sys", "adm", "tty", "disk", "lp", "mem", "kmem",
+ "wheel", "floppy", "mail", "news", "uucp", "man", "cron", "console",
+ "audio", "cdrom", "dialout", "ftp", "sshd", "input", "at", "tape", "video",
+ "netdev", "readproc", "squid", "xfs", "kvm", "games", "shadow", "postgres",
+ "cdrw", "usb", "vpopmail", "users", "catchlog", "ntp", "nofiles", "qmail",
+ "qmaill", "smmsp", "locate", "abuild", "utmp", "ping", "nogroup", "nobody"
+};
+
Key *RootPassphrase::parseFromData(const std::string &data, int lineno,
int *errors, int *warnings) {
if(data.size() < 5 || data[0] != '$' || (data[1] != '2' && data[1] != '6')
@@ -85,3 +103,73 @@ bool RootPassphrase::execute(ScriptOptions options) const {
return true;
/* LCOV_EXCL_STOP */
}
+
+
+Key *Username::parseFromData(const std::string &data, int lineno, int *errors,
+ int *warnings) {
+ return nullptr;
+}
+
+bool Username::validate(ScriptOptions) const {
+ return false;
+}
+
+bool Username::execute(ScriptOptions) const {
+ return false;
+}
+
+
+Key *UserAlias::parseFromData(const std::string &data, int lineno, int *errors,
+ int *warnings) {
+ return nullptr;
+}
+
+bool UserAlias::validate(ScriptOptions) const {
+ return false;
+}
+
+bool UserAlias::execute(ScriptOptions) const {
+ return false;
+}
+
+
+Key *UserPassphrase::parseFromData(const std::string &data, int lineno,
+ int *errors, int *warnings) {
+ return nullptr;
+}
+
+bool UserPassphrase::validate(ScriptOptions) const {
+ return false;
+}
+
+bool UserPassphrase::execute(ScriptOptions) const {
+ return false;
+}
+
+
+Key *UserIcon::parseFromData(const std::string &data, int lineno, int *errors,
+ int *warnings) {
+ return nullptr;
+}
+
+bool UserIcon::validate(ScriptOptions) const {
+ return false;
+}
+
+bool UserIcon::execute(ScriptOptions) const {
+ return false;
+}
+
+
+Key *UserGroups::parseFromData(const std::string &data, int lineno,
+ int *errors, int *warnings) {
+ return nullptr;
+}
+
+bool UserGroups::validate(ScriptOptions) const {
+ return false;
+}
+
+bool UserGroups::execute(ScriptOptions) const {
+ return false;
+}
diff --git a/hscript/user.hh b/hscript/user.hh
index 3f4d23b..b8d5386 100644
--- a/hscript/user.hh
+++ b/hscript/user.hh
@@ -13,6 +13,8 @@
#ifndef __HSCRIPT_USER_HH_
#define __HSCRIPT_USER_HH_
+#include <set>
+#include <string>
#include "key.hh"
namespace Horizon {
@@ -20,28 +22,99 @@ namespace Keys {
class RootPassphrase : public StringKey {
private:
- RootPassphrase(int _line, const std::string my_pw) :
+ RootPassphrase(int _line, const std::string &my_pw) :
StringKey(_line, my_pw) {}
public:
- static Key *parseFromData(const std::string &data, int lineno, int *errors,
- int *warnings);
+ static Key *parseFromData(const std::string &, int, int*, int*);
bool validate(ScriptOptions) const override;
bool execute(ScriptOptions) const override;
};
class Username : public StringKey {
+private:
+ Username(int _line, const std::string &name) :
+ StringKey(_line, name) {}
+public:
+ static Key *parseFromData(const std::string &, int, int*, int*);
+ bool validate(ScriptOptions) const override;
+ bool execute(ScriptOptions) const override;
};
class UserAlias : public Key {
+private:
+ const std::string _username;
+ const std::string _alias;
+
+ UserAlias(int _line, const std::string &_n, const std::string &_a) :
+ Key(_line), _username(_n), _alias(_a) {}
+public:
+ static Key *parseFromData(const std::string &, int, int*, int*);
+
+ /*! Retrieve the username for this alias. */
+ const std::string &username() const { return this->_username; }
+ /*! Retrieve the alias for the account. */
+ const std::string &alias() const { return this->_alias; }
+
+ bool validate(ScriptOptions) const override;
+ bool execute(ScriptOptions) const override;
};
-class UserPassphrase : public StringKey {
+class UserPassphrase : public Key {
+private:
+ const std::string _username;
+ const std::string _passphrase;
+
+ UserPassphrase(int _line, const std::string &_n, const std::string &_p) :
+ Key(_line), _username(_n), _passphrase(_p) {}
+public:
+ static Key *parseFromData(const std::string &, int, int*, int*);
+
+ /*! Retrieve the username for this passphrase. */
+ const std::string &username() const { return this->_username; }
+ /*! Retrieve the passphrase for the account. */
+ const std::string &passphrase() const { return this->_passphrase; }
+
+ bool validate(ScriptOptions) const override;
+ bool execute(ScriptOptions) const override;
};
class UserIcon : public Key {
+private:
+ const std::string _username;
+ const std::string _icon_path;
+
+ UserIcon(int _line, const std::string &_n, const std::string &_i) :
+ Key(_line), _username(_n), _icon_path(_i) {}
+public:
+ static Key *parseFromData(const std::string &, int, int*, int*);
+
+ /*! Retrieve the username for this icon. */
+ const std::string &username() const { return this->_username; }
+ /*! Retrieve the icon path for the account. */
+ const std::string &icon() const { return this->_icon_path; }
+
+ bool validate(ScriptOptions) const override;
+ bool execute(ScriptOptions) const override;
};
class UserGroups : public Key {
+private:
+ const std::string _username;
+ const std::set<std::string> _groups;
+
+ UserGroups(int _line, const std::string &_n,
+ const std::set<std::string> &_g) :
+ Key(_line), _username(_n), _groups(_g) {}
+public:
+ static Key *parseFromData(const std::string &, int, int*, int*);
+
+ /*! Retrieve the username for this group set. */
+ const std::string &username() const { return this->_username; }
+ /*! Retrieve the groups for the account. */
+ const std::set<std::string> &groups() const { return this->_groups; }
+
+ bool validate(ScriptOptions) const override;
+ bool execute(ScriptOptions) const override;
};
}