Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 83c7fdcc authored by Tom Cherry's avatar Tom Cherry Committed by android-build-merger
Browse files

Merge "init: implement getpwnam for host init verifier"

am: 1c15b02b

Change-Id: Id268013a2a115124eea67d253c2e4808e1a2d1f9
parents 758102af 1c15b02b
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -250,7 +250,10 @@ cc_binary {
    proto: {
        type: "lite",
    },
    generated_headers: ["generated_stub_builtin_function_map"],
    generated_headers: [
        "generated_stub_builtin_function_map",
        "generated_android_ids"
    ],
    target: {
        android: {
            enabled: false,
+70 −10
Original line number Diff line number Diff line
@@ -14,12 +14,17 @@
// limitations under the License.
//

#include <errno.h>
#include <pwd.h>
#include <stdio.h>

#include <iostream>
#include <string>
#include <vector>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/strings.h>

#include "action.h"
@@ -31,21 +36,74 @@
#include "result.h"
#include "service.h"

#define EXCLUDE_FS_CONFIG_STRUCTURES
#include "generated_android_ids.h"

using namespace std::literals;

using android::base::ParseInt;
using android::base::ReadFileToString;
using android::base::Split;

// The host passwd file won't have the Android entries, so we fake success here.
static std::string out_dir;

static std::vector<std::pair<std::string, int>> GetVendorPasswd() {
    std::string passwd;
    if (!ReadFileToString(out_dir + "/vendor/etc/passwd", &passwd)) {
        return {};
    }

    std::vector<std::pair<std::string, int>> result;
    auto passwd_lines = Split(passwd, "\n");
    for (const auto& line : passwd_lines) {
        auto split_line = Split(line, ":");
        if (split_line.size() < 3) {
            continue;
        }
        int uid = 0;
        if (!ParseInt(split_line[2], &uid)) {
            continue;
        }
        result.emplace_back(split_line[0], uid);
    }
    return result;
}

passwd* getpwnam(const char* login) {  // NOLINT: implementing bad function.
    char dummy_buf[] = "dummy";
    static passwd dummy_passwd = {
        .pw_name = dummy_buf,
        .pw_dir = dummy_buf,
        .pw_shell = dummy_buf,
        .pw_uid = 123,
        .pw_gid = 123,
    // This isn't thread safe, but that's okay for our purposes.
    static char static_name[32] = "";
    static char static_dir[32] = "/";
    static char static_shell[32] = "/system/bin/sh";
    static passwd static_passwd = {
        .pw_name = static_name,
        .pw_dir = static_dir,
        .pw_shell = static_shell,
        .pw_uid = 0,
        .pw_gid = 0,
    };
    return &dummy_passwd;

    for (size_t n = 0; n < android_id_count; ++n) {
        if (!strcmp(android_ids[n].name, login)) {
            snprintf(static_name, sizeof(static_name), "%s", android_ids[n].name);
            static_passwd.pw_uid = android_ids[n].aid;
            static_passwd.pw_gid = android_ids[n].aid;
            return &static_passwd;
        }
    }

    static const auto vendor_passwd = GetVendorPasswd();

    for (const auto& [name, uid] : vendor_passwd) {
        if (name == login) {
            snprintf(static_name, sizeof(static_name), "%s", name.c_str());
            static_passwd.pw_uid = uid;
            static_passwd.pw_gid = uid;
            return &static_passwd;
        }
    }

    errno = ENOENT;
    return nullptr;
}

namespace android {
@@ -65,6 +123,8 @@ int main(int argc, char** argv) {
        return -1;
    }

    out_dir = argv[1];

    auto properties = Split(argv[2], ",");
    for (const auto& property : properties) {
        auto split_property = Split(property, "=");
@@ -81,7 +141,7 @@ int main(int argc, char** argv) {
    Parser parser;
    parser.AddSectionParser("service", std::make_unique<ServiceParser>(&sl, nullptr));
    parser.AddSectionParser("on", std::make_unique<ActionParser>(&am, nullptr));
    parser.AddSectionParser("import", std::make_unique<HostImportParser>(argv[1], &parser));
    parser.AddSectionParser("import", std::make_unique<HostImportParser>(out_dir, &parser));

    if (!parser.ParseConfig(argv[1] + "/root/init.rc"s)) {
        LOG(ERROR) << "Failed to find root init.rc script";