summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bootstrapper.cc11
-rw-r--r--src/env.cc2
-rw-r--r--src/node.cc59
-rw-r--r--src/node_binding.cc1
-rw-r--r--src/node_credentials.cc395
-rw-r--r--src/node_internals.h17
-rw-r--r--src/node_main.cc6
-rw-r--r--src/node_process.cc332
-rw-r--r--src/node_util.cc14
9 files changed, 419 insertions, 418 deletions
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 2c8212177b..0a1cfed210 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -147,17 +147,6 @@ void SetupBootstrapObject(Environment* env,
BOOTSTRAP_METHOD(_rawDebug, RawDebug);
BOOTSTRAP_METHOD(_umask, Umask);
-#if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__)
- if (env->is_main_thread()) {
- BOOTSTRAP_METHOD(_initgroups, InitGroups);
- BOOTSTRAP_METHOD(_setegid, SetEGid);
- BOOTSTRAP_METHOD(_seteuid, SetEUid);
- BOOTSTRAP_METHOD(_setgid, SetGid);
- BOOTSTRAP_METHOD(_setuid, SetUid);
- BOOTSTRAP_METHOD(_setgroups, SetGroups);
- }
-#endif // __POSIX__ && !defined(__ANDROID__) && !defined(__CloudABI__)
-
Local<String> should_abort_on_uncaught_toggle =
FIXED_ONE_BYTE_STRING(env->isolate(), "_shouldAbortOnUncaughtToggle");
CHECK(bootstrapper->Set(env->context(),
diff --git a/src/env.cc b/src/env.cc
index ed6717d684..1e65dfdac8 100644
--- a/src/env.cc
+++ b/src/env.cc
@@ -225,7 +225,7 @@ Environment::Environment(IsolateData* isolate_data,
should_abort_on_uncaught_toggle_[0] = 1;
std::string debug_cats;
- SafeGetenv("NODE_DEBUG_NATIVE", &debug_cats);
+ credentials::SafeGetenv("NODE_DEBUG_NATIVE", &debug_cats);
set_debug_categories(debug_cats, true);
isolate()->GetHeapProfiler()->AddBuildEmbedderGraphCallback(
diff --git a/src/node.cc b/src/node.cc
index d830b846c9..58722f23b3 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -100,12 +100,7 @@ typedef int mode_t;
#else
#include <pthread.h>
#include <sys/resource.h> // getrlimit, setrlimit
-#include <unistd.h> // setuid, getuid
-#endif
-
-#if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__)
-#include <pwd.h> // getpwnam()
-#include <grp.h> // getgrnam()
+#include <unistd.h> // STDIN_FILENO, STDERR_FILENO
#endif
namespace node {
@@ -153,8 +148,6 @@ unsigned int reverted = 0;
bool v8_initialized = false;
-bool linux_at_secure = false;
-
// process-relative uptime base, initialized at start-up
double prog_start_time;
@@ -501,27 +494,6 @@ const char* signo_string(int signo) {
}
}
-// Look up environment variable unless running as setuid root.
-bool SafeGetenv(const char* key, std::string* text) {
-#if !defined(__CloudABI__) && !defined(_WIN32)
- if (linux_at_secure || getuid() != geteuid() || getgid() != getegid())
- goto fail;
-#endif
-
- {
- Mutex::ScopedLock lock(environ_mutex);
- if (const char* value = getenv(key)) {
- *text = value;
- return true;
- }
- }
-
-fail:
- text->clear();
- return false;
-}
-
-
void* ArrayBufferAllocator::Allocate(size_t size) {
if (zero_fill_field_ || per_process_opts->zero_fill_all_buffers)
return UncheckedCalloc(size);
@@ -1157,14 +1129,6 @@ void SetupProcessObject(Environment* env,
env->SetMethod(process, "dlopen", binding::DLOpen);
env->SetMethod(process, "reallyExit", Exit);
env->SetMethodNoSideEffect(process, "uptime", Uptime);
-
-#if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__)
- env->SetMethodNoSideEffect(process, "getuid", GetUid);
- env->SetMethodNoSideEffect(process, "geteuid", GetEUid);
- env->SetMethodNoSideEffect(process, "getgid", GetGid);
- env->SetMethodNoSideEffect(process, "getegid", GetEGid);
- env->SetMethodNoSideEffect(process, "getgroups", GetGroups);
-#endif // __POSIX__ && !defined(__ANDROID__) && !defined(__CloudABI__)
}
@@ -1625,37 +1589,40 @@ void Init(std::vector<std::string>* argv,
{
std::string text;
default_env_options->pending_deprecation =
- SafeGetenv("NODE_PENDING_DEPRECATION", &text) && text[0] == '1';
+ credentials::SafeGetenv("NODE_PENDING_DEPRECATION", &text) &&
+ text[0] == '1';
}
// Allow for environment set preserving symlinks.
{
std::string text;
default_env_options->preserve_symlinks =
- SafeGetenv("NODE_PRESERVE_SYMLINKS", &text) && text[0] == '1';
+ credentials::SafeGetenv("NODE_PRESERVE_SYMLINKS", &text) &&
+ text[0] == '1';
}
{
std::string text;
default_env_options->preserve_symlinks_main =
- SafeGetenv("NODE_PRESERVE_SYMLINKS_MAIN", &text) && text[0] == '1';
+ credentials::SafeGetenv("NODE_PRESERVE_SYMLINKS_MAIN", &text) &&
+ text[0] == '1';
}
if (default_env_options->redirect_warnings.empty()) {
- SafeGetenv("NODE_REDIRECT_WARNINGS",
- &default_env_options->redirect_warnings);
+ credentials::SafeGetenv("NODE_REDIRECT_WARNINGS",
+ &default_env_options->redirect_warnings);
}
#if HAVE_OPENSSL
std::string* openssl_config = &per_process_opts->openssl_config;
if (openssl_config->empty()) {
- SafeGetenv("OPENSSL_CONF", openssl_config);
+ credentials::SafeGetenv("OPENSSL_CONF", openssl_config);
}
#endif
#if !defined(NODE_WITHOUT_NODE_OPTIONS)
std::string node_options;
- if (SafeGetenv("NODE_OPTIONS", &node_options)) {
+ if (credentials::SafeGetenv("NODE_OPTIONS", &node_options)) {
std::vector<std::string> env_argv;
// [0] is expected to be the program name, fill it in from the real argv.
env_argv.push_back(argv->at(0));
@@ -1687,7 +1654,7 @@ void Init(std::vector<std::string>* argv,
#if defined(NODE_HAVE_I18N_SUPPORT)
// If the parameter isn't given, use the env variable.
if (per_process_opts->icu_data_dir.empty())
- SafeGetenv("NODE_ICU_DATA", &per_process_opts->icu_data_dir);
+ credentials::SafeGetenv("NODE_ICU_DATA", &per_process_opts->icu_data_dir);
// Initialize ICU.
// If icu_data_dir is empty here, it will load the 'minimal' data.
if (!i18n::InitializeICUDirectory(per_process_opts->icu_data_dir)) {
@@ -2095,7 +2062,7 @@ int Start(int argc, char** argv) {
#if HAVE_OPENSSL
{
std::string extra_ca_certs;
- if (SafeGetenv("NODE_EXTRA_CA_CERTS", &extra_ca_certs))
+ if (credentials::SafeGetenv("NODE_EXTRA_CA_CERTS", &extra_ca_certs))
crypto::UseExtraCaCerts(extra_ca_certs);
}
#ifdef NODE_FIPS_MODE
diff --git a/src/node_binding.cc b/src/node_binding.cc
index 4a47c744c2..1e78f7c17f 100644
--- a/src/node_binding.cc
+++ b/src/node_binding.cc
@@ -30,6 +30,7 @@
V(cares_wrap) \
V(config) \
V(contextify) \
+ V(credentials) \
V(domain) \
V(fs) \
V(fs_event_wrap) \
diff --git a/src/node_credentials.cc b/src/node_credentials.cc
new file mode 100644
index 0000000000..0f202dfb75
--- /dev/null
+++ b/src/node_credentials.cc
@@ -0,0 +1,395 @@
+#include "node_internals.h"
+
+#ifdef NODE_IMPLEMENTS_POSIX_CREDENTIALS
+#include <grp.h> // getgrnam()
+#include <pwd.h> // getpwnam()
+#endif // NODE_IMPLEMENTS_POSIX_CREDENTIALS
+
+#if !defined(_MSC_VER)
+#include <unistd.h> // setuid, getuid
+#endif
+
+namespace node {
+
+using v8::Array;
+using v8::Context;
+using v8::Function;
+using v8::FunctionCallbackInfo;
+using v8::Integer;
+using v8::Isolate;
+using v8::Local;
+using v8::Object;
+using v8::String;
+using v8::Uint32;
+using v8::Value;
+
+namespace per_process {
+bool linux_at_secure = false;
+} // namespace per_process
+
+namespace credentials {
+
+// Look up environment variable unless running as setuid root.
+bool SafeGetenv(const char* key, std::string* text) {
+#if !defined(__CloudABI__) && !defined(_WIN32)
+ if (per_process::linux_at_secure || getuid() != geteuid() ||
+ getgid() != getegid())
+ goto fail;
+#endif
+
+ {
+ Mutex::ScopedLock lock(environ_mutex);
+ if (const char* value = getenv(key)) {
+ *text = value;
+ return true;
+ }
+ }
+
+fail:
+ text->clear();
+ return false;
+}
+
+static void SafeGetenv(const FunctionCallbackInfo<Value>& args) {
+ CHECK(args[0]->IsString());
+ Isolate* isolate = args.GetIsolate();
+ Utf8Value strenvtag(isolate, args[0]);
+ std::string text;
+ if (!SafeGetenv(*strenvtag, &text)) return;
+ Local<Value> result =
+ ToV8Value(isolate->GetCurrentContext(), text).ToLocalChecked();
+ args.GetReturnValue().Set(result);
+}
+
+#ifdef NODE_IMPLEMENTS_POSIX_CREDENTIALS
+
+static const uid_t uid_not_found = static_cast<uid_t>(-1);
+static const gid_t gid_not_found = static_cast<gid_t>(-1);
+
+static uid_t uid_by_name(const char* name) {
+ struct passwd pwd;
+ struct passwd* pp;
+ char buf[8192];
+
+ errno = 0;
+ pp = nullptr;
+
+ if (getpwnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr)
+ return pp->pw_uid;
+
+ return uid_not_found;
+}
+
+static char* name_by_uid(uid_t uid) {
+ struct passwd pwd;
+ struct passwd* pp;
+ char buf[8192];
+ int rc;
+
+ errno = 0;
+ pp = nullptr;
+
+ if ((rc = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
+ pp != nullptr) {
+ return strdup(pp->pw_name);
+ }
+
+ if (rc == 0) errno = ENOENT;
+
+ return nullptr;
+}
+
+static gid_t gid_by_name(const char* name) {
+ struct group pwd;
+ struct group* pp;
+ char buf[8192];
+
+ errno = 0;
+ pp = nullptr;
+
+ if (getgrnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr)
+ return pp->gr_gid;
+
+ return gid_not_found;
+}
+
+#if 0 // For future use.
+static const char* name_by_gid(gid_t gid) {
+ struct group pwd;
+ struct group* pp;
+ char buf[8192];
+ int rc;
+
+ errno = 0;
+ pp = nullptr;
+
+ if ((rc = getgrgid_r(gid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
+ pp != nullptr) {
+ return strdup(pp->gr_name);
+ }
+
+ if (rc == 0)
+ errno = ENOENT;
+
+ return nullptr;
+}
+#endif
+
+static uid_t uid_by_name(Isolate* isolate, Local<Value> value) {
+ if (value->IsUint32()) {
+ return static_cast<uid_t>(value.As<Uint32>()->Value());
+ } else {
+ Utf8Value name(isolate, value);
+ return uid_by_name(*name);
+ }
+}
+
+static gid_t gid_by_name(Isolate* isolate, Local<Value> value) {
+ if (value->IsUint32()) {
+ return static_cast<gid_t>(value.As<Uint32>()->Value());
+ } else {
+ Utf8Value name(isolate, value);
+ return gid_by_name(*name);
+ }
+}
+
+static void GetUid(const FunctionCallbackInfo<Value>& args) {
+ // uid_t is an uint32_t on all supported platforms.
+ args.GetReturnValue().Set(static_cast<uint32_t>(getuid()));
+}
+
+static void GetGid(const FunctionCallbackInfo<Value>& args) {
+ // gid_t is an uint32_t on all supported platforms.
+ args.GetReturnValue().Set(static_cast<uint32_t>(getgid()));
+}
+
+static void GetEUid(const FunctionCallbackInfo<Value>& args) {
+ // uid_t is an uint32_t on all supported platforms.
+ args.GetReturnValue().Set(static_cast<uint32_t>(geteuid()));
+}
+
+static void GetEGid(const FunctionCallbackInfo<Value>& args) {
+ // gid_t is an uint32_t on all supported platforms.
+ args.GetReturnValue().Set(static_cast<uint32_t>(getegid()));
+}
+
+static void SetGid(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+ CHECK(env->is_main_thread());
+
+ CHECK_EQ(args.Length(), 1);
+ CHECK(args[0]->IsUint32() || args[0]->IsString());
+
+ gid_t gid = gid_by_name(env->isolate(), args[0]);
+
+ if (gid == gid_not_found) {
+ // Tells JS to throw ERR_INVALID_CREDENTIAL
+ args.GetReturnValue().Set(1);
+ } else if (setgid(gid)) {
+ env->ThrowErrnoException(errno, "setgid");
+ } else {
+ args.GetReturnValue().Set(0);
+ }
+}
+
+static void SetEGid(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+ CHECK(env->is_main_thread());
+
+ CHECK_EQ(args.Length(), 1);
+ CHECK(args[0]->IsUint32() || args[0]->IsString());
+
+ gid_t gid = gid_by_name(env->isolate(), args[0]);
+
+ if (gid == gid_not_found) {
+ // Tells JS to throw ERR_INVALID_CREDENTIAL
+ args.GetReturnValue().Set(1);
+ } else if (setegid(gid)) {
+ env->ThrowErrnoException(errno, "setegid");
+ } else {
+ args.GetReturnValue().Set(0);
+ }
+}
+
+static void SetUid(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+ CHECK(env->is_main_thread());
+
+ CHECK_EQ(args.Length(), 1);
+ CHECK(args[0]->IsUint32() || args[0]->IsString());
+
+ uid_t uid = uid_by_name(env->isolate(), args[0]);
+
+ if (uid == uid_not_found) {
+ // Tells JS to throw ERR_INVALID_CREDENTIAL
+ args.GetReturnValue().Set(1);
+ } else if (setuid(uid)) {
+ env->ThrowErrnoException(errno, "setuid");
+ } else {
+ args.GetReturnValue().Set(0);
+ }
+}
+
+static void SetEUid(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+ CHECK(env->is_main_thread());
+
+ CHECK_EQ(args.Length(), 1);
+ CHECK(args[0]->IsUint32() || args[0]->IsString());
+
+ uid_t uid = uid_by_name(env->isolate(), args[0]);
+
+ if (uid == uid_not_found) {
+ // Tells JS to throw ERR_INVALID_CREDENTIAL
+ args.GetReturnValue().Set(1);
+ } else if (seteuid(uid)) {
+ env->ThrowErrnoException(errno, "seteuid");
+ } else {
+ args.GetReturnValue().Set(0);
+ }
+}
+
+static void GetGroups(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+
+ int ngroups = getgroups(0, nullptr);
+
+ if (ngroups == -1) return env->ThrowErrnoException(errno, "getgroups");
+
+ gid_t* groups = new gid_t[ngroups];
+
+ ngroups = getgroups(ngroups, groups);
+
+ if (ngroups == -1) {
+ delete[] groups;
+ return env->ThrowErrnoException(errno, "getgroups");
+ }
+
+ Local<Array> groups_list = Array::New(env->isolate(), ngroups);
+ bool seen_egid = false;
+ gid_t egid = getegid();
+
+ for (int i = 0; i < ngroups; i++) {
+ groups_list->Set(env->context(), i, Integer::New(env->isolate(), groups[i]))
+ .FromJust();
+ if (groups[i] == egid) seen_egid = true;
+ }
+
+ delete[] groups;
+
+ if (seen_egid == false)
+ groups_list
+ ->Set(env->context(), ngroups, Integer::New(env->isolate(), egid))
+ .FromJust();
+
+ args.GetReturnValue().Set(groups_list);
+}
+
+static void SetGroups(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+
+ CHECK_EQ(args.Length(), 1);
+ CHECK(args[0]->IsArray());
+
+ Local<Array> groups_list = args[0].As<Array>();
+ size_t size = groups_list->Length();
+ gid_t* groups = new gid_t[size];
+
+ for (size_t i = 0; i < size; i++) {
+ gid_t gid = gid_by_name(
+ env->isolate(), groups_list->Get(env->context(), i).ToLocalChecked());
+
+ if (gid == gid_not_found) {
+ delete[] groups;
+ // Tells JS to throw ERR_INVALID_CREDENTIAL
+ args.GetReturnValue().Set(static_cast<uint32_t>(i + 1));
+ return;
+ }
+
+ groups[i] = gid;
+ }
+
+ int rc = setgroups(size, groups);
+ delete[] groups;
+
+ if (rc == -1) return env->ThrowErrnoException(errno, "setgroups");
+
+ args.GetReturnValue().Set(0);
+}
+
+static void InitGroups(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+
+ CHECK_EQ(args.Length(), 2);
+ CHECK(args[0]->IsUint32() || args[0]->IsString());
+ CHECK(args[1]->IsUint32() || args[1]->IsString());
+
+ Utf8Value arg0(env->isolate(), args[0]);
+ gid_t extra_group;
+ bool must_free;
+ char* user;
+
+ if (args[0]->IsUint32()) {
+ user = name_by_uid(args[0].As<Uint32>()->Value());
+ must_free = true;
+ } else {
+ user = *arg0;
+ must_free = false;
+ }
+
+ if (user == nullptr) {
+ // Tells JS to throw ERR_INVALID_CREDENTIAL
+ return args.GetReturnValue().Set(1);
+ }
+
+ extra_group = gid_by_name(env->isolate(), args[1]);
+
+ if (extra_group == gid_not_found) {
+ if (must_free) free(user);
+ // Tells JS to throw ERR_INVALID_CREDENTIAL
+ return args.GetReturnValue().Set(2);
+ }
+
+ int rc = initgroups(user, extra_group);
+
+ if (must_free) free(user);
+
+ if (rc) return env->ThrowErrnoException(errno, "initgroups");
+
+ args.GetReturnValue().Set(0);
+}
+
+#endif // NODE_IMPLEMENTS_POSIX_CREDENTIALS
+
+static void Initialize(Local<Object> target,
+ Local<Value> unused,
+ Local<Context> context,
+ void* priv) {
+ Environment* env = Environment::GetCurrent(context);
+ Isolate* isolate = env->isolate();
+
+ env->SetMethod(target, "safeGetenv", SafeGetenv);
+
+#ifdef NODE_IMPLEMENTS_POSIX_CREDENTIALS
+ READONLY_TRUE_PROPERTY(target, "implementsPosixCredentials");
+ env->SetMethodNoSideEffect(target, "getuid", GetUid);
+ env->SetMethodNoSideEffect(target, "geteuid", GetEUid);
+ env->SetMethodNoSideEffect(target, "getgid", GetGid);
+ env->SetMethodNoSideEffect(target, "getegid", GetEGid);
+ env->SetMethodNoSideEffect(target, "getgroups", GetGroups);
+
+ if (env->is_main_thread()) {
+ env->SetMethod(target, "initgroups", InitGroups);
+ env->SetMethod(target, "setegid", SetEGid);
+ env->SetMethod(target, "seteuid", SetEUid);
+ env->SetMethod(target, "setgid", SetGid);
+ env->SetMethod(target, "setuid", SetUid);
+ env->SetMethod(target, "setgroups", SetGroups);
+ }
+#endif // NODE_IMPLEMENTS_POSIX_CREDENTIALS
+}
+
+} // namespace credentials
+} // namespace node
+
+NODE_MODULE_CONTEXT_AWARE_INTERNAL(credentials, node::credentials::Initialize)
diff --git a/src/node_internals.h b/src/node_internals.h
index d9a72a10a4..2c6aad5b96 100644
--- a/src/node_internals.h
+++ b/src/node_internals.h
@@ -126,7 +126,6 @@ void RegisterSignalHandler(int signal,
bool reset_handler = false);
#endif
-bool SafeGetenv(const char* key, std::string* text);
v8::Local<v8::Object> CreateEnvVarProxy(v8::Local<v8::Context> context,
v8::Isolate* isolate,
v8::Local<v8::Value> data);
@@ -734,19 +733,13 @@ void ProcessTitleSetter(v8::Local<v8::Name> property,
const v8::PropertyCallbackInfo<void>& info);
#if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__)
-void SetGid(const v8::FunctionCallbackInfo<v8::Value>& args);
-void SetEGid(const v8::FunctionCallbackInfo<v8::Value>& args);
-void SetUid(const v8::FunctionCallbackInfo<v8::Value>& args);
-void SetEUid(const v8::FunctionCallbackInfo<v8::Value>& args);
-void SetGroups(const v8::FunctionCallbackInfo<v8::Value>& args);
-void InitGroups(const v8::FunctionCallbackInfo<v8::Value>& args);
-void GetUid(const v8::FunctionCallbackInfo<v8::Value>& args);
-void GetGid(const v8::FunctionCallbackInfo<v8::Value>& args);
-void GetEUid(const v8::FunctionCallbackInfo<v8::Value>& args);
-void GetEGid(const v8::FunctionCallbackInfo<v8::Value>& args);
-void GetGroups(const v8::FunctionCallbackInfo<v8::Value>& args);
+#define NODE_IMPLEMENTS_POSIX_CREDENTIALS 1
#endif // __POSIX__ && !defined(__ANDROID__) && !defined(__CloudABI__)
+namespace credentials {
+bool SafeGetenv(const char* key, std::string* text);
+} // namespace credentials
+
void DefineZlibConstants(v8::Local<v8::Object> target);
} // namespace node
diff --git a/src/node_main.cc b/src/node_main.cc
index bea1af7bdd..7107aea8c1 100644
--- a/src/node_main.cc
+++ b/src/node_main.cc
@@ -88,7 +88,9 @@ extern char** environ;
#endif
namespace node {
- extern bool linux_at_secure;
+namespace per_process {
+extern bool linux_at_secure;
+} // namespace per_process
} // namespace node
int main(int argc, char* argv[]) {
@@ -112,7 +114,7 @@ int main(int argc, char* argv[]) {
Elf_auxv_t* auxv = reinterpret_cast<Elf_auxv_t*>(envp);
for (; auxv->a_type != AT_NULL; auxv++) {
if (auxv->a_type == AT_SECURE) {
- node::linux_at_secure = auxv->a_un.a_val;
+ node::per_process::linux_at_secure = auxv->a_un.a_val;
break;
}
}
diff --git a/src/node_process.cc b/src/node_process.cc
index ccd8ce2fd9..b9376953e2 100644
--- a/src/node_process.cc
+++ b/src/node_process.cc
@@ -24,12 +24,6 @@ typedef int mode_t;
#include <pthread.h>
#include <sys/resource.h> // getrlimit, setrlimit
#include <termios.h> // tcgetattr, tcsetattr
-#include <unistd.h> // setuid, getuid
-#endif
-
-#if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__)
-#include <pwd.h> // getpwnam()
-#include <grp.h> // getgrnam()
#endif
namespace node {
@@ -42,7 +36,6 @@ using v8::Float64Array;
using v8::Function;
using v8::FunctionCallbackInfo;
using v8::HeapStatistics;
-using v8::Integer;
using v8::Isolate;
using v8::Local;
using v8::Name;
@@ -254,331 +247,6 @@ void Uptime(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(uptime / 1000);
}
-
-#if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__)
-
-static const uid_t uid_not_found = static_cast<uid_t>(-1);
-static const gid_t gid_not_found = static_cast<gid_t>(-1);
-
-
-static uid_t uid_by_name(const char* name) {
- struct passwd pwd;
- struct passwd* pp;
- char buf[8192];
-
- errno = 0;
- pp = nullptr;
-
- if (getpwnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr)
- return pp->pw_uid;
-
- return uid_not_found;
-}
-
-
-static char* name_by_uid(uid_t uid) {
- struct passwd pwd;
- struct passwd* pp;
- char buf[8192];
- int rc;
-
- errno = 0;
- pp = nullptr;
-
- if ((rc = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
- pp != nullptr) {
- return strdup(pp->pw_name);
- }
-
- if (rc == 0)
- errno = ENOENT;
-
- return nullptr;
-}
-
-
-static gid_t gid_by_name(const char* name) {
- struct group pwd;
- struct group* pp;
- char buf[8192];
-
- errno = 0;
- pp = nullptr;
-
- if (getgrnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr)
- return pp->gr_gid;
-
- return gid_not_found;
-}
-
-
-#if 0 // For future use.
-static const char* name_by_gid(gid_t gid) {
- struct group pwd;
- struct group* pp;
- char buf[8192];
- int rc;
-
- errno = 0;
- pp = nullptr;
-
- if ((rc = getgrgid_r(gid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
- pp != nullptr) {
- return strdup(pp->gr_name);
- }
-
- if (rc == 0)
- errno = ENOENT;
-
- return nullptr;
-}
-#endif
-
-
-static uid_t uid_by_name(Isolate* isolate, Local<Value> value) {
- if (value->IsUint32()) {
- return static_cast<uid_t>(value.As<Uint32>()->Value());
- } else {
- Utf8Value name(isolate, value);
- return uid_by_name(*name);
- }
-}
-
-
-static gid_t gid_by_name(Isolate* isolate, Local<Value> value) {
- if (value->IsUint32()) {
- return static_cast<gid_t>(value.As<Uint32>()->Value());
- } else {
- Utf8Value name(isolate, value);
- return gid_by_name(*name);
- }
-}
-
-void GetUid(const FunctionCallbackInfo<Value>& args) {
- // uid_t is an uint32_t on all supported platforms.
- args.GetReturnValue().Set(static_cast<uint32_t>(getuid()));
-}
-
-
-void GetGid(const FunctionCallbackInfo<Value>& args) {
- // gid_t is an uint32_t on all supported platforms.
- args.GetReturnValue().Set(static_cast<uint32_t>(getgid()));
-}
-
-
-void GetEUid(const FunctionCallbackInfo<Value>& args) {
- // uid_t is an uint32_t on all supported platforms.
- args.GetReturnValue().Set(static_cast<uint32_t>(geteuid()));
-}
-
-
-void GetEGid(const FunctionCallbackInfo<Value>& args) {
- // gid_t is an uint32_t on all supported platforms.
- args.GetReturnValue().Set(static_cast<uint32_t>(getegid()));
-}
-
-
-void SetGid(const FunctionCallbackInfo<Value>& args) {
- Environment* env = Environment::GetCurrent(args);
- CHECK(env->is_main_thread());
-
- CHECK_EQ(args.Length(), 1);
- CHECK(args[0]->IsUint32() || args[0]->IsString());
-
- gid_t gid = gid_by_name(env->isolate(), args[0]);
-
- if (gid == gid_not_found) {
- // Tells JS to throw ERR_INVALID_CREDENTIAL
- args.GetReturnValue().Set(1);
- } else if (setgid(gid)) {
- env->ThrowErrnoException(errno, "setgid");
- } else {
- args.GetReturnValue().Set(0);
- }
-}
-
-
-void SetEGid(const FunctionCallbackInfo<Value>& args) {
- Environment* env = Environment::GetCurrent(args);
- CHECK(env->is_main_thread());
-
- CHECK_EQ(args.Length(), 1);
- CHECK(args[0]->IsUint32() || args[0]->IsString());
-
- gid_t gid = gid_by_name(env->isolate(), args[0]);
-
- if (gid == gid_not_found) {
- // Tells JS to throw ERR_INVALID_CREDENTIAL
- args.GetReturnValue().Set(1);
- } else if (setegid(gid)) {
- env->ThrowErrnoException(errno, "setegid");
- } else {
- args.GetReturnValue().Set(0);
- }
-}
-
-
-void SetUid(const FunctionCallbackInfo<Value>& args) {
- Environment* env = Environment::GetCurrent(args);
- CHECK(env->is_main_thread());
-
- CHECK_EQ(args.Length(), 1);
- CHECK(args[0]->IsUint32() || args[0]->IsString());
-
- uid_t uid = uid_by_name(env->isolate(), args[0]);
-
- if (uid == uid_not_found) {
- // Tells JS to throw ERR_INVALID_CREDENTIAL
- args.GetReturnValue().Set(1);
- } else if (setuid(uid)) {
- env->ThrowErrnoException(errno, "setuid");
- } else {
- args.GetReturnValue().Set(0);
- }
-}
-
-
-void SetEUid(const FunctionCallbackInfo<Value>& args) {
- Environment* env = Environment::GetCurrent(args);
- CHECK(env->is_main_thread());
-
- CHECK_EQ(args.Length(), 1);
- CHECK(args[0]->IsUint32() || args[0]->IsString());
-
- uid_t uid = uid_by_name(env->isolate(), args[0]);
-
- if (uid == uid_not_found) {
- // Tells JS to throw ERR_INVALID_CREDENTIAL
- args.GetReturnValue().Set(1);
- } else if (seteuid(uid)) {
- env->ThrowErrnoException(errno, "seteuid");
- } else {
- args.GetReturnValue().Set(0);
- }
-}
-
-
-void GetGroups(const FunctionCallbackInfo<Value>& args) {
- Environment* env = Environment::GetCurrent(args);
-
- int ngroups = getgroups(0, nullptr);
-
- if (ngroups == -1)
- return env->ThrowErrnoException(errno, "getgroups");
-
- gid_t* groups = new gid_t[ngroups];
-
- ngroups = getgroups(ngroups, groups);
-
- if (ngroups == -1) {
- delete[] groups;
- return env->ThrowErrnoException(errno, "getgroups");
- }
-
- Local<Array> groups_list = Array::New(env->isolate(), ngroups);
- bool seen_egid = false;
- gid_t egid = getegid();
-
- for (int i = 0; i < ngroups; i++) {
- groups_list->Set(env->context(),
- i, Integer::New(env->isolate(), groups[i])).FromJust();
- if (groups[i] == egid)
- seen_egid = true;
- }
-
- delete[] groups;
-
- if (seen_egid == false)
- groups_list->Set(env->context(),
- ngroups,
- Integer::New(env->isolate(), egid)).FromJust();
-
- args.GetReturnValue().Set(groups_list);
-}
-
-
-void SetGroups(const FunctionCallbackInfo<Value>& args) {
- Environment* env = Environment::GetCurrent(args);
-
- CHECK_EQ(args.Length(), 1);
- CHECK(args[0]->IsArray());
-
- Local<Array> groups_list = args[0].As<Array>();
- size_t size = groups_list->Length();
- gid_t* groups = new gid_t[size];
-
- for (size_t i = 0; i < size; i++) {
- gid_t gid = gid_by_name(env->isolate(),
- groups_list->Get(env->context(),
- i).ToLocalChecked());
-
- if (gid == gid_not_found) {
- delete[] groups;
- // Tells JS to throw ERR_INVALID_CREDENTIAL
- args.GetReturnValue().Set(static_cast<uint32_t>(i + 1));
- return;
- }
-
- groups[i] = gid;
- }
-
- int rc = setgroups(size, groups);
- delete[] groups;
-
- if (rc == -1)
- return env->ThrowErrnoException(errno, "setgroups");
-
- args.GetReturnValue().Set(0);
-}
-
-
-void InitGroups(const FunctionCallbackInfo<Value>& args) {
- Environment* env = Environment::GetCurrent(args);
-
- CHECK_EQ(args.Length(), 2);
- CHECK(args[0]->IsUint32() || args[0]->IsString());
- CHECK(args[1]->IsUint32() || args[1]->IsString());
-
- Utf8Value arg0(env->isolate(), args[0]);
- gid_t extra_group;
- bool must_free;
- char* user;
-
- if (args[0]->IsUint32()) {
- user = name_by_uid(args[0].As<Uint32>()->Value());
- must_free = true;
- } else {
- user = *arg0;
- must_free = false;
- }
-
- if (user == nullptr) {
- // Tells JS to throw ERR_INVALID_CREDENTIAL
- return args.GetReturnValue().Set(1);
- }
-
- extra_group = gid_by_name(env->isolate(), args[1]);
-
- if (extra_group == gid_not_found) {
- if (must_free)
- free(user);
- // Tells JS to throw ERR_INVALID_CREDENTIAL
- return args.GetReturnValue().Set(2);
- }
-
- int rc = initgroups(user, extra_group);
-
- if (must_free)
- free(user);
-
- if (rc)
- return env->ThrowErrnoException(errno, "initgroups");
-
- args.GetReturnValue().Set(0);
-}
-
-#endif // __POSIX__ && !defined(__ANDROID__) && !defined(__CloudABI__)
-
void ProcessTitleGetter(Local<Name> property,
const PropertyCallbackInfo<Value>& info) {
char buffer[512];
diff --git a/src/node_util.cc b/src/node_util.cc
index f6ebee895f..f7412d92bc 100644
--- a/src/node_util.cc
+++ b/src/node_util.cc
@@ -15,7 +15,6 @@ using v8::Integer;
using v8::Isolate;
using v8::KeyCollectionMode;
using v8::Local;
-using v8::NewStringType;
using v8::Object;
using v8::ONLY_CONFIGURABLE;
using v8::ONLY_ENUMERABLE;
@@ -172,17 +171,6 @@ void WatchdogHasPendingSigint(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(ret);
}
-void SafeGetenv(const FunctionCallbackInfo<Value>& args) {
- CHECK(args[0]->IsString());
- Utf8Value strenvtag(args.GetIsolate(), args[0]);
- std::string text;
- if (!node::SafeGetenv(*strenvtag, &text)) return;
- args.GetReturnValue()
- .Set(String::NewFromUtf8(
- args.GetIsolate(), text.c_str(),
- NewStringType::kNormal).ToLocalChecked());
-}
-
void EnqueueMicrotask(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
Isolate* isolate = env->isolate();
@@ -232,8 +220,6 @@ void Initialize(Local<Object> target,
env->SetMethodNoSideEffect(target, "watchdogHasPendingSigint",
WatchdogHasPendingSigint);
- env->SetMethod(target, "safeGetenv", SafeGetenv);
-
env->SetMethod(target, "enqueueMicrotask", EnqueueMicrotask);
Local<Object> constants = Object::New(env->isolate());