From 3c92ca2b5c1aea283efebd50b27e2a256adf5f7f Mon Sep 17 00:00:00 2001 From: Evan Lucas Date: Mon, 27 Apr 2015 11:24:19 -0500 Subject: [PATCH] src: add ability to get/set effective uid/gid Adds the following to process: - `process.geteuid()` - `process.seteuid(id)` - `process.getegid()` - `process.setegid(id)` PR-URL: https://github.com/iojs/io.js/pull/1536 Reviewed-By: Ben Noordhuis --- doc/api/process.markdown | 68 ++++++++++++++++++++++++++++++++++++++++ src/node.cc | 54 +++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/doc/api/process.markdown b/doc/api/process.markdown index 004958e1887329..179d39b16e2610 100644 --- a/doc/api/process.markdown +++ b/doc/api/process.markdown @@ -455,6 +455,19 @@ This is the numerical group id, not the group name. } +## process.getegid() + +Note: this function is only available on POSIX platforms (i.e. not Windows, +Android) + +Gets the effective group identity of the process. (See getegid(2).) +This is the numerical group id, not the group name. + + if (process.getegid) { + console.log('Current gid: ' + process.getegid()); + } + + ## process.setgid(id) Note: this function is only available on POSIX platforms (i.e. not Windows, @@ -476,6 +489,27 @@ blocks while resolving it to a numerical ID. } +## process.setegid(id) + +Note: this function is only available on POSIX platforms (i.e. not Windows, +Android) + +Sets the effective group identity of the process. (See setegid(2).) +This accepts either a numerical ID or a groupname string. If a groupname +is specified, this method blocks while resolving it to a numerical ID. + + if (process.getegid && process.setegid) { + console.log('Current gid: ' + process.getegid()); + try { + process.setegid(501); + console.log('New gid: ' + process.getegid()); + } + catch (err) { + console.log('Failed to set gid: ' + err); + } + } + + ## process.getuid() Note: this function is only available on POSIX platforms (i.e. not Windows, @@ -489,6 +523,19 @@ This is the numerical userid, not the username. } +## process.geteuid() + +Note: this function is only available on POSIX platforms (i.e. not Windows, +Android) + +Gets the effective user identity of the process. (See geteuid(2).) +This is the numerical userid, not the username. + + if (process.geteuid) { + console.log('Current uid: ' + process.geteuid()); + } + + ## process.setuid(id) Note: this function is only available on POSIX platforms (i.e. not Windows, @@ -510,6 +557,27 @@ blocks while resolving it to a numerical ID. } +## process.seteuid(id) + +Note: this function is only available on POSIX platforms (i.e. not Windows, +Android) + +Sets the effective user identity of the process. (See seteuid(2).) +This accepts either a numerical ID or a username string. If a username +is specified, this method blocks while resolving it to a numerical ID. + + if (process.geteuid && process.seteuid) { + console.log('Current uid: ' + process.geteuid()); + try { + process.seteuid(501); + console.log('New uid: ' + process.geteuid()); + } + catch (err) { + console.log('Failed to set uid: ' + err); + } + } + + ## process.getgroups() Note: this function is only available on POSIX platforms (i.e. not Windows, diff --git a/src/node.cc b/src/node.cc index 67cf140154866f..4cafe96f445dd1 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1750,6 +1750,18 @@ static void GetGid(const FunctionCallbackInfo& args) { } +static void GetEUid(const FunctionCallbackInfo& args) { + // uid_t is an uint32_t on all supported platforms. + args.GetReturnValue().Set(static_cast(geteuid())); +} + + +static void GetEGid(const FunctionCallbackInfo& args) { + // gid_t is an uint32_t on all supported platforms. + args.GetReturnValue().Set(static_cast(getegid())); +} + + static void SetGid(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -1769,6 +1781,25 @@ static void SetGid(const FunctionCallbackInfo& args) { } +static void SetEGid(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + + if (!args[0]->IsUint32() && !args[0]->IsString()) { + return env->ThrowTypeError("setegid argument must be a number or string"); + } + + gid_t gid = gid_by_name(env->isolate(), args[0]); + + if (gid == gid_not_found) { + return env->ThrowError("setegid group id does not exist"); + } + + if (setegid(gid)) { + return env->ThrowErrnoException(errno, "setegid"); + } +} + + static void SetUid(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -1788,6 +1819,25 @@ static void SetUid(const FunctionCallbackInfo& args) { } +static void SetEUid(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + + if (!args[0]->IsUint32() && !args[0]->IsString()) { + return env->ThrowTypeError("seteuid argument must be a number or string"); + } + + uid_t uid = uid_by_name(env->isolate(), args[0]); + + if (uid == uid_not_found) { + return env->ThrowError("seteuid user id does not exist"); + } + + if (seteuid(uid)) { + return env->ThrowErrnoException(errno, "seteuid"); + } +} + + static void GetGroups(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -2821,10 +2871,14 @@ void SetupProcessObject(Environment* env, #if defined(__POSIX__) && !defined(__ANDROID__) env->SetMethod(process, "getuid", GetUid); + env->SetMethod(process, "geteuid", GetEUid); env->SetMethod(process, "setuid", SetUid); + env->SetMethod(process, "seteuid", SetEUid); env->SetMethod(process, "setgid", SetGid); + env->SetMethod(process, "setegid", SetEGid); env->SetMethod(process, "getgid", GetGid); + env->SetMethod(process, "getegid", GetEGid); env->SetMethod(process, "getgroups", GetGroups); env->SetMethod(process, "setgroups", SetGroups);