Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2011-06-04 23:35:17 +0400
committerisaacs <i@izs.me>2011-06-04 23:35:17 +0400
commit701a32d6c02c1d615276ff99b2d9f5a2e7530694 (patch)
treed83b989bfaca1d0862ea49f3a01c3cfd8cf1046f
parentfdfeefbdc150047039ee703e6bafb32478d10658 (diff)
Close #898 Get and cache the uid/gid values early
-rw-r--r--lib/utils/uid-number.js14
-rw-r--r--npm.js35
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)
})
}
diff --git a/npm.js b/npm.js
index 88ee93555..917efd06b 100644
--- a/npm.js
+++ b/npm.js
@@ -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()
+ })
+ }
+
})
})
}