diff options
author | isaacs <i@izs.me> | 2011-06-04 23:35:17 +0400 |
---|---|---|
committer | isaacs <i@izs.me> | 2011-06-04 23:35:17 +0400 |
commit | 701a32d6c02c1d615276ff99b2d9f5a2e7530694 (patch) | |
tree | d83b989bfaca1d0862ea49f3a01c3cfd8cf1046f | |
parent | fdfeefbdc150047039ee703e6bafb32478d10658 (diff) |
Close #898 Get and cache the uid/gid values early
-rw-r--r-- | lib/utils/uid-number.js | 14 | ||||
-rw-r--r-- | npm.js | 35 |
2 files changed, 39 insertions, 10 deletions
diff --git a/lib/utils/uid-number.js b/lib/utils/uid-number.js index 27fa9e27b..59952ffd0 100644 --- a/lib/utils/uid-number.js +++ b/lib/utils/uid-number.js @@ -1,11 +1,18 @@ module.exports = uidNumber +// This module calls into bin/npm-get-uid-gid.js, which sets the +// uid and gid to the supplied argument, in order to find out their +// numeric value. This can't be done in the main node process, +// because otherwise npm would be running as that user. + var exec = require("./exec") , path = require("path") , log = require("./log") , constants = require("constants") , npm = require("../../npm") , uidSupport = process.getuid && process.setuid + , uidCache = {} + , gidCache = {} function uidNumber (uid, gid, cb) { if (!uidSupport || npm.config.get("unsafe-perm")) return cb() @@ -15,9 +22,14 @@ function uidNumber (uid, gid, cb) { if (uid == null) uid = process.getuid() if (!isNaN(gid)) gid = +gid if (!isNaN(uid)) uid = +uid + + if (uidCache[uid]) uid = uidCache[uid] + if (gidCache[gid]) gid = gidCache[gid] + if (typeof gid === "number" && typeof uid === "number") { return cb(null, uid, gid) } + var getter = path.join(__dirname, "..", "..", "bin", "npm-get-uid-gid.js") return exec( process.execPath, [getter, uid, gid], process.env, false , null, process.getuid(), process.getgid() @@ -36,6 +48,8 @@ function uidNumber (uid, gid, cb) { } if (isNaN(out.uid) || isNaN(out.gid)) return cb(new Error( "Could not get uid/gid: "+JSON.stringify(out))) + uidCache[uid] = out.uid + uidCache[gid] = out.gid cb(null, out.uid, out.gid) }) } @@ -22,6 +22,7 @@ var EventEmitter = require("events").EventEmitter , which = require("./lib/utils/which") , semver = require("semver") , findPrefix = require("./lib/utils/find-prefix") + , getUid = require("./lib/utils/uid-number") npm.commands = {} npm.ELIFECYCLE = {} @@ -200,16 +201,30 @@ npm.load = function (conf, cb_) { } else { p = npm.config.get("prefix") } - // try to guess at a good node_modules location. - findPrefix(p, function (er, p) { - if (er) return handleError(er) - Object.defineProperty(npm, "prefix", - { get : function () { return p } - , set : function (r) { return p = r } - , enumerable : true - }) - return cb() - }) + + // if we're not in unsafe-perm mode, then figure out who + // to run stuff as. Do this first, to support `npm update npm -g` + if (!npm.config.get("unsafe-perm")) { + getUid( npm.config.get("user"), npm.config.get("group") + , function (er, uid, gid) { + if (er) return log.er(cb, "Could not get uid/gid")(er) + next() + }) + } else next() + + function next () { + // try to guess at a good node_modules location. + findPrefix(p, function (er, p) { + if (er) return handleError(er) + Object.defineProperty(npm, "prefix", + { get : function () { return p } + , set : function (r) { return p = r } + , enumerable : true + }) + return cb() + }) + } + }) }) } |