Implement czechlight authentication

I'm using fgetpwent_r/fgetspent_r for listing users, because all the
other functions aren't thread safe. It also makes it easier to test the
functions.

Change-Id: Ie3fba46d53ada8edf8b39be4f06bf49cef15963e
diff --git a/tests/test_sysrepo_helpers.h b/tests/test_sysrepo_helpers.h
index 54d2d71..8478f17 100644
--- a/tests/test_sysrepo_helpers.h
+++ b/tests/test_sysrepo_helpers.h
@@ -27,6 +27,34 @@
     return res;
 }
 
+/** @short Execute an RPC or action, return result, compacting the XPath. The rpcPath and input gets concatenated. */
+auto rpcFromSysrepo(const std::shared_ptr<sysrepo::Session>& session, const std::string& rpcPath, std::map<std::string, std::string> input)
+{
+    spdlog::get("main")->info("rpcFromSysrepo {}", rpcPath);
+    auto inputNode = std::make_shared<libyang::Data_Node>(session->get_context(), rpcPath.c_str(), nullptr, LYD_ANYDATA_CONSTSTRING, 0);
+    for (const auto& [k, v] : input) {
+        inputNode->new_path(session->get_context(), (rpcPath + "/" + k).c_str(), v.c_str(), LYD_ANYDATA_CONSTSTRING, 0);
+    }
+
+    auto output = session->rpc_send(inputNode);
+    REQUIRE(!!output);
+
+    // Sysrepo returns a top-level node. I need the node that contains the action and iterate over that instead of the
+    // top-level node.
+    auto actualOutput = output->find_path(rpcPath.c_str())->data().front();
+
+    std::map<std::string, std::string> res;
+    for (const auto& node : actualOutput->tree_dfs()) {
+        if (node->schema()->nodetype() == LYS_LEAF) {
+            auto leaf = std::make_shared<libyang::Data_Node_Leaf_List>(node);
+            auto path = node->path();
+            const auto briefXPath = path.substr(rpcPath.size());
+            res.emplace(briefXPath, leaf->value_str());
+        }
+    }
+    return res;
+}
+
 /** @short Return a subtree from specified sysrepo's datastore, compacting the XPath*/
 auto dataFromSysrepo(const std::shared_ptr<sysrepo::Session>& session, const std::string& xpath, sr_datastore_t datastore)
 {