blob: 1b4716fd1349536863c379b8c8891aa82142683c [file] [log] [blame]
Tom Cherryde6bd502018-02-13 16:50:08 -08001//
2// Copyright (C) 2018 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
Tom Cherry31525f52018-05-09 18:33:31 -070017#include <errno.h>
Tom Cherryde6bd502018-02-13 16:50:08 -080018#include <pwd.h>
Tom Cherry31525f52018-05-09 18:33:31 -070019#include <stdio.h>
Tom Cherry863d8082018-06-12 14:40:38 -070020#include <stdlib.h>
Tom Cherryde6bd502018-02-13 16:50:08 -080021
Tom Cherry194b5d12018-05-09 17:38:30 -070022#include <iostream>
23#include <string>
Tom Cherry31525f52018-05-09 18:33:31 -070024#include <vector>
Tom Cherry194b5d12018-05-09 17:38:30 -070025
Tom Cherry31525f52018-05-09 18:33:31 -070026#include <android-base/file.h>
Tom Cherryde6bd502018-02-13 16:50:08 -080027#include <android-base/logging.h>
Tom Cherry31525f52018-05-09 18:33:31 -070028#include <android-base/parseint.h>
Tom Cherry194b5d12018-05-09 17:38:30 -070029#include <android-base/strings.h>
Tom Cherryde6bd502018-02-13 16:50:08 -080030
31#include "action.h"
32#include "action_manager.h"
33#include "action_parser.h"
Tom Cherry194b5d12018-05-09 17:38:30 -070034#include "host_import_parser.h"
35#include "host_init_stubs.h"
Tom Cherryde6bd502018-02-13 16:50:08 -080036#include "parser.h"
37#include "result.h"
38#include "service.h"
Tom Cherry2aeb1ad2019-06-26 10:46:20 -070039#include "service_list.h"
40#include "service_parser.h"
Tom Cherryde6bd502018-02-13 16:50:08 -080041
Tom Cherry31525f52018-05-09 18:33:31 -070042#define EXCLUDE_FS_CONFIG_STRUCTURES
43#include "generated_android_ids.h"
44
Tom Cherry194b5d12018-05-09 17:38:30 -070045using namespace std::literals;
46
Tom Cherry31525f52018-05-09 18:33:31 -070047using android::base::ParseInt;
48using android::base::ReadFileToString;
Tom Cherry194b5d12018-05-09 17:38:30 -070049using android::base::Split;
50
Tom Cherry863d8082018-06-12 14:40:38 -070051static std::string passwd_file;
Tom Cherry31525f52018-05-09 18:33:31 -070052
53static std::vector<std::pair<std::string, int>> GetVendorPasswd() {
54 std::string passwd;
Tom Cherry863d8082018-06-12 14:40:38 -070055 if (!ReadFileToString(passwd_file, &passwd)) {
Tom Cherry31525f52018-05-09 18:33:31 -070056 return {};
57 }
58
59 std::vector<std::pair<std::string, int>> result;
60 auto passwd_lines = Split(passwd, "\n");
61 for (const auto& line : passwd_lines) {
62 auto split_line = Split(line, ":");
63 if (split_line.size() < 3) {
64 continue;
65 }
66 int uid = 0;
67 if (!ParseInt(split_line[2], &uid)) {
68 continue;
69 }
70 result.emplace_back(split_line[0], uid);
71 }
72 return result;
73}
74
Tom Cherryde6bd502018-02-13 16:50:08 -080075passwd* getpwnam(const char* login) { // NOLINT: implementing bad function.
Tom Cherry31525f52018-05-09 18:33:31 -070076 // This isn't thread safe, but that's okay for our purposes.
77 static char static_name[32] = "";
78 static char static_dir[32] = "/";
79 static char static_shell[32] = "/system/bin/sh";
80 static passwd static_passwd = {
81 .pw_name = static_name,
82 .pw_dir = static_dir,
83 .pw_shell = static_shell,
84 .pw_uid = 0,
85 .pw_gid = 0,
Tom Cherryde6bd502018-02-13 16:50:08 -080086 };
Tom Cherry31525f52018-05-09 18:33:31 -070087
88 for (size_t n = 0; n < android_id_count; ++n) {
89 if (!strcmp(android_ids[n].name, login)) {
90 snprintf(static_name, sizeof(static_name), "%s", android_ids[n].name);
91 static_passwd.pw_uid = android_ids[n].aid;
92 static_passwd.pw_gid = android_ids[n].aid;
93 return &static_passwd;
94 }
95 }
96
97 static const auto vendor_passwd = GetVendorPasswd();
98
99 for (const auto& [name, uid] : vendor_passwd) {
100 if (name == login) {
101 snprintf(static_name, sizeof(static_name), "%s", name.c_str());
102 static_passwd.pw_uid = uid;
103 static_passwd.pw_gid = uid;
104 return &static_passwd;
105 }
106 }
107
Tom Cherry290427b2018-06-14 13:40:20 -0700108 unsigned int oem_uid;
109 if (sscanf(login, "oem_%u", &oem_uid) == 1) {
110 snprintf(static_name, sizeof(static_name), "%s", login);
111 static_passwd.pw_uid = oem_uid;
112 static_passwd.pw_gid = oem_uid;
113 return &static_passwd;
114 }
115
Tom Cherry31525f52018-05-09 18:33:31 -0700116 errno = ENOENT;
117 return nullptr;
Tom Cherryde6bd502018-02-13 16:50:08 -0800118}
119
120namespace android {
121namespace init {
122
Tom Cherrybbcbc2f2019-06-10 11:08:01 -0700123static Result<void> do_stub(const BuiltinArguments& args) {
124 return {};
Tom Cherryde6bd502018-02-13 16:50:08 -0800125}
126
127#include "generated_stub_builtin_function_map.h"
128
129int main(int argc, char** argv) {
Elliott Hughes1be0d142018-05-23 09:16:46 -0700130 android::base::InitLogging(argv, &android::base::StdioLogger);
Tom Cherry194b5d12018-05-09 17:38:30 -0700131 android::base::SetMinimumLogSeverity(android::base::ERROR);
Tom Cherry863d8082018-06-12 14:40:38 -0700132
133 if (argc != 2 && argc != 3) {
134 LOG(ERROR) << "Usage: " << argv[0] << " <init rc file> [passwd file]";
135 return EXIT_FAILURE;
Tom Cherryde6bd502018-02-13 16:50:08 -0800136 }
Tom Cherry194b5d12018-05-09 17:38:30 -0700137
Tom Cherry863d8082018-06-12 14:40:38 -0700138 if (argc == 3) {
139 passwd_file = argv[2];
Tom Cherry194b5d12018-05-09 17:38:30 -0700140 }
141
Tom Cherryde6bd502018-02-13 16:50:08 -0800142 const BuiltinFunctionMap function_map;
143 Action::set_function_map(&function_map);
144 ActionManager& am = ActionManager::GetInstance();
145 ServiceList& sl = ServiceList::GetInstance();
146 Parser parser;
147 parser.AddSectionParser("service", std::make_unique<ServiceParser>(&sl, nullptr));
148 parser.AddSectionParser("on", std::make_unique<ActionParser>(&am, nullptr));
Tom Cherry863d8082018-06-12 14:40:38 -0700149 parser.AddSectionParser("import", std::make_unique<HostImportParser>());
Tom Cherryde6bd502018-02-13 16:50:08 -0800150
Tom Cherryd72432d2018-06-19 15:18:40 -0700151 if (!parser.ParseConfigFileInsecure(argv[1])) {
Tom Cherry863d8082018-06-12 14:40:38 -0700152 LOG(ERROR) << "Failed to open init rc script '" << argv[1] << "'";
153 return EXIT_FAILURE;
Tom Cherryde6bd502018-02-13 16:50:08 -0800154 }
Tom Cherry194b5d12018-05-09 17:38:30 -0700155 if (parser.parse_error_count() > 0) {
Tom Cherry863d8082018-06-12 14:40:38 -0700156 LOG(ERROR) << "Failed to parse init script '" << argv[1] << "' with "
157 << parser.parse_error_count() << " errors";
158 return EXIT_FAILURE;
Tom Cherryde6bd502018-02-13 16:50:08 -0800159 }
Tom Cherry863d8082018-06-12 14:40:38 -0700160 return EXIT_SUCCESS;
Tom Cherryde6bd502018-02-13 16:50:08 -0800161}
162
163} // namespace init
164} // namespace android
165
166int main(int argc, char** argv) {
Tom Cherry863d8082018-06-12 14:40:38 -0700167 return android::init::main(argc, argv);
Tom Cherryde6bd502018-02-13 16:50:08 -0800168}