diff --git a/clite/commands.js b/clite/commands.js index c5411ae..194ed29 100644 --- a/clite/commands.js +++ b/clite/commands.js @@ -1744,10 +1744,17 @@ Options: // -primary_operator primary_operand if (uargs.length == 2) { switch (uargs[0]) { - case '-b': // test for a block file (don't exist, always false) + case '-b': // test for a block file + var p = clite.resolvePath(uargs[1]); + var st = stdio.stat(p); + if (!st || (st.st_mode&stdio.modes.S_IFBLK) != stdio.modes.S_IFBLK) { + if (negate) + return 0; + return 1; + } if (negate) - return 0; - return 1; + return 1; + return 0; break; case '-c': var p = clite.resolvePath(uargs[1]); @@ -1797,10 +1804,17 @@ Options: return 1; return 0; break; - case '-g': // test for set-groud-id (doesn't exist, always false) + case '-g': // test for set-groud-id + var p = clite.resolvePath(uargs[1]); + var st = stdio.stat(p); + if (!st || (st.st_mode&stdio.modes.S_ISGID) != stdio.modes.S_ISGID) { + if (negate) + return 0; + return 1; + } if (negate) - return 0; - return 1; + return 1; + return 0; break; case '-h': case '-L': @@ -1825,10 +1839,17 @@ Options: return 1; return 0; break; - case '-p': // test for FIFO/pipe (doesn't exist, always false) + case '-p': // test for FIFO/pipe + var p = clite.resolvePath(uargs[1]); + var st = stdio.stat(p); + if (!st || (st.st_mode&stdio.modes.S_IFIFO) != stdio.modes.S_IFIFO) { + if (negate) + return 0; + return 1; + } if (negate) - return 0; - return 1; + return 1; + return 0; break; case '-r': var p = clite.resolvePath(uargs[1]); @@ -1846,10 +1867,17 @@ Options: return 1; return 0; break; - case '-S': // test for socket (doesn't exist, always false) + case '-S': // test for socket + var p = clite.resolvePath(uargs[1]); + var st = stdio.stat(p); + if (!st || (st.st_mode&stdio.modes.S_IFSOCK) != stdio.modes.S_IFSOCK) { + if (negate) + return 0; + return 1; + } if (negate) - return 0; - return 1; + return 1; + return 0; break; case '-s': var p = clite.resolvePath(uargs[1]); @@ -1898,10 +1926,17 @@ Options: return 0; return 1; break; - case '-u': // test for set-user-id (doesn't exist, always false) + case '-u': // test for set-user-id + var p = clite.resolvePath(uargs[1]); + var st = stdio.stat(p); + if (!st || (st.st_mode&stdio.modes.S_ISUID) != stdio.modes.S_ISUID) { + if (negate) + return 0; + return 1; + } if (negate) - return 0; - return 1; + return 1; + return 0; break; case '-w': var p = clite.resolvePath(uargs[1]); diff --git a/clite/core.js b/clite/core.js index c3e98c5..d0dccc3 100644 --- a/clite/core.js +++ b/clite/core.js @@ -744,6 +744,28 @@ clite.proc = { return 0; return proc.gid; } + clite.proc.setUID = function(pid,uid,force) { + var proc = getProc(pid); + if (!proc) + return false; + if (!clite.user.getPWData(uid)) + return false; + if (!force && proc.uid != 0) + return false; + proc.uid = uid; + return true; + } + clite.proc.setGID = function(pid,gid,force) { + var proc = getProc(pid); + if (!proc) + return false; + if (!clite.user.getGRData(gid)) + return false; + if (!force && gid == 0) + return false; + proc.gid = gid; + return true; + } clite.proc.getTTY = function(pid) { var proc = getProc(pid); if (!proc) @@ -1394,7 +1416,7 @@ clite.io = { if (typeof mode != 'number') return false; var uid = clite.proc.getUID(pid); - if (fd.node.uid != uid) + if (fd.node.uid != uid && uid != 0) return false; mode &= ~clite.io.modes.S_IFMT; @@ -2942,6 +2964,16 @@ clite.lib = { return -4; } + if ((fd.node.mode&clite.io.modes.S_ISGID) == clite.io.modes.S_ISGID) { + if (!clite.proc.setGID(io.pid,fd.node.gid,true)) + return -7; + } + + if ((fd.node.mode&clite.io.modes.S_ISUID) == clite.io.modes.S_ISUID) { + if (!clite.proc.setUID(io.pid,fd.node.uid,true)) + return -8; + } + clite.proc.update(args.join(' ')); var r = clite.core.execSafe(function() { diff --git a/clite/libstd.js b/clite/libstd.js index edf6f24..a7f1293 100644 --- a/clite/libstd.js +++ b/clite/libstd.js @@ -47,6 +47,9 @@ return Object.create({ getuid:function() { return clite.proc.getUID(io.pid); }, + setuid:function(id) { + return clite.proc.setUID(io.pid,id,false); + }, // gets the passwd file data for a user based on their uid getpwuid:function(uid) { @@ -64,6 +67,9 @@ return Object.create({ getgid:function() { return clite.proc.getGID(io.pid); }, + setgid:function(id) { + return clite.proc.setGID(io.pid,id,false); + }, // gets teh group file data for a group based on their gid getgrgid:function(gid) { diff --git a/clite/shell.js b/clite/shell.js index 61b36ca..21ee312 100644 --- a/clite/shell.js +++ b/clite/shell.js @@ -421,6 +421,12 @@ clite.commands.load('sh',function(args,env,io) { return; } + if (r == -7 || r == -8) { + stdio.fprintf(io.stderr,'Shell: failed to set uid/gid for: %s\n',exec.active.args[0]); + io.exit(-3); + return; + } + if (r<0) { stdio.fprintf(io.stderr,'Shell: could not exec file: %s\n',exec.active.args[0]); io.exit(-3);