From fd6322f2dd7406ba45a543e460bda859273d9105 Mon Sep 17 00:00:00 2001 From: Aram Drambyan Date: Tue, 4 Jun 2024 16:32:53 +0400 Subject: [PATCH 1/3] adding support for supplementary groups for Linux --- README.md | 2 +- src/interfaces.ts | 1 + src/native.d.ts | 2 +- src/unix/pty.cc | 28 +++++++++++++++++++++++++--- src/unixTerminal.ts | 4 +++- 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index fb858b70f..122564709 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ const ptyProcess = pty.spawn(shell, [], { env: process.env }); -ptyProcess.onData((data) => { +ptyProcess.on('data', (data) => { process.stdout.write(data); }); diff --git a/src/interfaces.ts b/src/interfaces.ts index c05031f81..6d780ddad 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -115,6 +115,7 @@ interface IBasePtyForkOptions { export interface IPtyForkOptions extends IBasePtyForkOptions { uid?: number; gid?: number; + suppGids?: number[]; } export interface IWindowsPtyForkOptions extends IBasePtyForkOptions { diff --git a/src/native.d.ts b/src/native.d.ts index 2ba107699..75dd6df6c 100644 --- a/src/native.d.ts +++ b/src/native.d.ts @@ -19,7 +19,7 @@ interface IWinptyNative { } interface IUnixNative { - fork(file: string, args: string[], parsedEnv: string[], cwd: string, cols: number, rows: number, uid: number, gid: number, useUtf8: boolean, helperPath: string, onExitCallback: (code: number, signal: number) => void): IUnixProcess; + fork(file: string, args: string[], parsedEnv: string[], cwd: string, cols: number, rows: number, uid: number, gid: number, useUtf8: boolean, helperPath: string, onExitCallback: (code: number, signal: number) => void, suppGids: number[]): IUnixProcess; open(cols: number, rows: number): IUnixOpenProcess; process(fd: number, pty?: string): string; resize(fd: number, cols: number, rows: number): void; diff --git a/src/unix/pty.cc b/src/unix/pty.cc index de50353f9..b3717b6db 100644 --- a/src/unix/pty.cc +++ b/src/unix/pty.cc @@ -65,6 +65,11 @@ #include #endif +/* for setgroups */ +#if defined(__linux__) +#include +#endif + /* NSIG - macro for highest signal + 1, should be defined */ #ifndef NSIG #define NSIG 32 @@ -258,7 +263,7 @@ Napi::Value PtyFork(const Napi::CallbackInfo& info) { Napi::Env napiEnv(info.Env()); Napi::HandleScope scope(napiEnv); - if (info.Length() != 11 || + if (info.Length() != 12 || !info[0].IsString() || !info[1].IsArray() || !info[2].IsArray() || @@ -269,8 +274,9 @@ Napi::Value PtyFork(const Napi::CallbackInfo& info) { !info[7].IsNumber() || !info[8].IsBoolean() || !info[9].IsString() || - !info[10].IsFunction()) { - throw Napi::Error::New(napiEnv, "Usage: pty.fork(file, args, env, cwd, cols, rows, uid, gid, utf8, helperPath, onexit)"); + !info[10].IsFunction() || + !info[11].IsArray()) { + throw Napi::Error::New(napiEnv, "Usage: pty.fork(file, args, env, cwd, cols, rows, uid, gid, utf8, helperPath, onexit, suppGids)"); } // file @@ -419,6 +425,22 @@ Napi::Value PtyFork(const Napi::CallbackInfo& info) { } if (uid != -1 && gid != -1) { + // supplementary group IDs + Napi::Array suppGids_ = info[11].As(); + if (suppGids_.Length() > 0) { + int gidsLength = suppGids_.Length() + 1; + std::unique_ptr gidsPtr(new gid_t[gidsLength]); + for (int i = 0; i < gidsLength - 1; ++i) { + gidsPtr[i] = suppGids_.Get(i).As().Uint32Value(); + } + gidsPtr[gidsLength - 1] = gid; + + if(setgroups(gidsLength, gidsPtr.get()) == -1) { + perror("setgroups(2) failed."); + _exit(1); + } + } + if (setgid(gid) == -1) { perror("setgid(2) failed."); _exit(1); diff --git a/src/unixTerminal.ts b/src/unixTerminal.ts index b745d762d..776b57f60 100644 --- a/src/unixTerminal.ts +++ b/src/unixTerminal.ts @@ -111,8 +111,10 @@ export class UnixTerminal extends Terminal { this.emit('exit', code, signal); }; + const suppGids = opt.suppGids || []; + // fork - const term = pty.fork(file, args, parsedEnv, cwd, this._cols, this._rows, uid, gid, (encoding === 'utf8'), helperPath, onexit); + const term = pty.fork(file, args, parsedEnv, cwd, this._cols, this._rows, uid, gid, (encoding === 'utf8'), helperPath, onexit, suppGids); this._socket = new tty.ReadStream(term.fd); if (encoding !== null) { From 436194ed9d70901130e8864e4488133a4fc6a29f Mon Sep 17 00:00:00 2001 From: Aram Drambyan Date: Tue, 4 Jun 2024 16:42:35 +0400 Subject: [PATCH 2/3] updaing typings --- typings/node-pty.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/typings/node-pty.d.ts b/typings/node-pty.d.ts index 5fd7b237e..396e806e2 100644 --- a/typings/node-pty.d.ts +++ b/typings/node-pty.d.ts @@ -83,6 +83,7 @@ declare module 'node-pty' { */ uid?: number; gid?: number; + suppGids?: number[]; } export interface IWindowsPtyForkOptions extends IBasePtyForkOptions { From b74370cc56f6c8b4673a70adc219a8c4db7e6021 Mon Sep 17 00:00:00 2001 From: Aram Drambyan Date: Sat, 8 Jun 2024 15:19:59 +0400 Subject: [PATCH 3/3] reverting README change --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 122564709..fb858b70f 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ const ptyProcess = pty.spawn(shell, [], { env: process.env }); -ptyProcess.on('data', (data) => { +ptyProcess.onData((data) => { process.stdout.write(data); });