From cb4a4879e00deb6f5527d5b193a1d647a28a1cb4 Mon Sep 17 00:00:00 2001 From: Gar Date: Tue, 5 Apr 2022 12:47:11 -0700 Subject: [PATCH] fix: put infer-owner back in (#12) @npmcli/exec is not out or ready and we need to get the cli updated to use this again --- lib/index.js | 5 +++++ package.json | 3 +++ test/promise-spawn.js | 31 +++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/lib/index.js b/lib/index.js index 9381157..84ddc83 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,4 +1,5 @@ const { spawn } = require('child_process') +const inferOwner = require('infer-owner') const isPipe = (stdio = 'pipe', fd) => stdio === 'pipe' || stdio === null ? true @@ -8,9 +9,13 @@ const isPipe = (stdio = 'pipe', fd) => // 'extra' object is for decorating the error a bit more const promiseSpawn = (cmd, args, opts = {}, extra = {}) => { const cwd = opts.cwd || process.cwd() + const isRoot = process.getuid && process.getuid() === 0 + const { uid, gid } = isRoot ? inferOwner.sync(cwd) : {} return promiseSpawnUid(cmd, args, { ...opts, cwd, + uid, + gid, }, extra) } diff --git a/package.json b/package.json index 0ff9eea..ce6a807 100644 --- a/package.json +++ b/package.json @@ -41,5 +41,8 @@ "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", "version": "3.2.2" + }, + "dependencies": { + "infer-owner": "^1.0.4" } } diff --git a/test/promise-spawn.js b/test/promise-spawn.js index 7b9a6fb..3658077 100644 --- a/test/promise-spawn.js +++ b/test/promise-spawn.js @@ -1,6 +1,7 @@ const t = require('tap') const Minipass = require('minipass') const EE = require('events') +const fs = require('fs') const isPipe = (stdio = 'pipe', fd) => stdio === 'pipe' || stdio === null ? true @@ -214,3 +215,33 @@ t.test('expose process', t => { t.end() setTimeout(() => p.process.exit(0)) }) + +t.test('infer ownership', t => { + const { lstatSync } = fs + t.teardown(() => fs.lstatSync = lstatSync) + fs.lstatSync = (path) => ({ uid: 420, gid: 69 }) + const getuid = process.getuid + t.teardown(() => process.getuid = getuid) + + t.test('as non-root, do not change uid/gid, regardless of arguments', t => { + process.getuid = () => 1234 + return t.resolveMatch(promiseSpawn('whoami', [], { uid: 4321, gid: 9876 }), { + code: 0, + signal: null, + stdout: Buffer.from('UID undefined\nGID undefined\n'), + stderr: Buffer.alloc(0), + }) + }) + + t.test('as root, change uid/gid to folder, regardless of arguments', t => { + process.getuid = () => 0 + return t.resolveMatch(promiseSpawn('whoami', [], { uid: 4321, gid: 9876 }), { + code: 0, + signal: null, + stdout: Buffer.from('UID 420\nGID 69\n'), + stderr: Buffer.alloc(0), + }) + }) + + t.end() +})