su to root

This commit is contained in:
Lisa Milne 2023-12-16 22:31:45 +10:00
parent b14fc8e13b
commit 99a58594d3
4 changed files with 259 additions and 34 deletions

View file

@ -54,7 +54,7 @@ Options:
`);
}
function writeNodeData(st,fd) {
function writeNodeData(st,fn) {
if (long) {
var pw = stdlib.getpwuid(st.st_uid);
var gr = stdlib.getgrgid(st.st_gid);
@ -80,9 +80,14 @@ Options:
}
var ms = clite.strmode(st.st_mode);
if (st.type == stdio.types.FT_LINK) {
var lp = stdio.readAll(fd);
if (!lp)
lp = '?';
var lp = '?';
var fd = stdio.open(fn,stdio.flags.O_RDONLY|stdio.flags.O_NOFOLLOW|stdio.flags.O_SYNC);
if (fd) {
lp = stdio.readAll(fd);
stdio.close(fd);
if (!lp)
lp = '?';
}
stdio.printf('%s%12s%12s%14s%12s -> %s\n',ms,uname,gname,d,st.name,lp);
}else{
stdio.printf('%s%12s%12s%14s%12s\n',ms,uname,gname,d,st.name);
@ -149,19 +154,12 @@ Options:
while ((e = stdio.read(fd)) != null) {
if (e[0] == '.' && !all)
continue;
var efd = stdio.open(dir+'/'+e,stdio.flags.O_RDONLY|stdio.flags.O_NOFOLLOW|stdio.flags.O_SYNC);
if (!efd) {
stdio.fprintf(io.stderr,'cannot read contents: %s\n',dir);
break;
}
var est = stdio.fstatat(efd,stdio.flags.AT_SYMLINK_NOFOLLOW);
var est = stdio.lstat(dir+'/'+e,stdio.flags.AT_SYMLINK_NOFOLLOW);
if (!est) {
stdio.close(efd);
stdio.fprintf(io.stderr,'cannot read content: %s\n',dir);
break;
}
writeNodeData(est,efd);
stdio.close(efd);
writeNodeData(est,dir+'/'+e);
}
stdio.close(fd);
if (!one && !long)
@ -2172,6 +2170,149 @@ Options:
return main(args);
});
clite.commands.load('su',function(args,env,io) {
var stdio = io.include('stdio');
var stdlib = io.include('stdlib');
var auth = io.include('auth');
var pw = null;
var preserve = true;
var shell = null;
function help() {
stdio.printf(`
su - switch users
Usage: su [OPTION]
Options:
-? Print this help information
-l Simulate a full login
-m Preserve the environment
-s <sh> Use the shell at <sh>
`);
}
function changeUser() {
if (!stdlib.setgid(pw.pw_gid)) {
stdio.write(io.stderr,'internal error\n');
io.exit(1);
return;
}
if (!stdlib.setuid(pw.pw_uid)) {
stdio.write(io.stderr,'internal error\n');
io.exit(1);
return;
}
var e = null;
if (preserve) {
e = structuredClone(env);
}else{
e = {};
e.USER = pw.pw_name;
e.PWD = pw.pw_dir;
e.HOME = pw.pw_dir;
e.SHELL = pw.pw_shell;
}
if (shell == null)
shell = e.SHELL;
var args = [shell];
var r = stdlib.exec(shell,args,e,io);
if (r == 0)
return;
stdio.write(io.stderr,'internal error\n');
io.exit(1);
}
function doLogin(str) {
if (!auth.checkpassuid(pw.pw_uid,str)) {
stdio.printf('authentication error\n');
io.exit(1);
return;
}
changeUser();
}
function main(args) {
var user = 'root';
var shellnext = false;
for (var i=1; i<args.length; i++) {
if (shellnext == true) {
shell = args[i];
shellnext = false;
}else if (args[i] == '-') {
preserve = false;
}else if (args[i][0] == '-') {
for (var j=1; j<args[i].length; j++) {
switch (args[i][j]) {
case '?':
help();
return 0;
break;
case 'l':
preserve = false;
break;
case 'm':
preserve = true;
break;
case 's':
shellnext = true;
break;
default:
stdio.fprintf(io.stderr,'unknown argument: -%c\n',args[i][j]);
}
}
}else{
user = args[i];
}
}
if (shellnext) {
stdio.write(io.stderr,'invalid arguments\n');
return 1;
}
if (!user) {
stdio.write(io.stderr,'no user specified\n');
return 1;
}
pw = stdlib.getpwnam(user);
if (!pw) {
stdio.fprintf(io.stderr,'invalid user: %s\n',user);
return 1;
}
if (!stdio.isatty(io.stdin)) {
stdio.write(io.stderr,'internal error\n');
return 1;
}
if (stdlib.getuid() != 0) {
stdio.write(io.stdout,'password: ');
if (!stdio.read(io.stdin,doLogin)) {
stdio.write(io.stderr,'authentication error\n');
return 1;
}
return null;
}
changeUser();
return null;
}
return main(args);
},true);
if (window.location.protocol == 'file:')
clite.commands.load('exp',function(args,env,io) {
var stdio = io.include('stdio');
@ -2183,7 +2324,7 @@ clite.commands.load('exp',function(args,env,io) {
stdio.printf('gmtime gives: %d %d %d %d %d %d %d %d %d\n',tm.tm_sec,tm.tm_min,tm.tm_hour,tm.tm_mday,tm.tm_mon,tm.tm_year,tm.tm_wday,tm.tm_yday,tm.tm_isdst);
stdio.printf('%s\n',time.ctime(t));
stdio.printf('Hello world\n');
stdio.printf('uid:%d\n',stdlib.getuid());
stdio.printf('%d %d\n',stdlib.getuid(),stdlib.getgid());
stdio.printf('%#15x:%15o:%15.5f:%0$15.5f:%%:\n',10,12,8.123456789);
function rcb(data) {
stdio.write(io.stdout,data);

View file

@ -1,6 +1,6 @@
var clite = {
state:{
version:'0.5.3',
version:'0.6.0',
isinit:false,
runlevel:1,
bios:null,
@ -349,13 +349,17 @@ cat /etc/greeting
function loadCommands(nextfn) {
clite.commands = {
data:null,
load:function(name,fn) {
load:function(name,fn,setug) {
vfsapi.mkFile(0,'/bin/'+name);
var f = vfsapi.getNode(0,'/bin/'+name);
if (!f)
return;
f.mode = clite.lib.modestr('-rwxr-xr-x');
f.data.content = fn;
if (typeof setug === 'boolean' && setug == true) {
f.mode |= clite.io.modes.S_ISUID;
f.mode |= clite.io.modes.S_ISGID;
}
vfsapi.mkFile(0,'/usr/src/'+name+'.js');
f = vfsapi.getNode(0,'/usr/src/'+name+'.js');
if (!f)
@ -641,8 +645,10 @@ clite.proc = {
if (typeof fn !== 'function')
return 0;
var proc = Object.create({
uid:0, // the user id this process is running as
gid:0, // the group id this process is running as
ruid:0, // the real user id - owner of the process
rgid:0, // the real group id - owner of the process
uid:0, // the (effective) user id this process is running as
gid:0, // the (effective) group id this process is running as
gpid:mapCPID(cpid), // the group pid (parent process id) of this process
pid:data.nextid++, // the pid (process id) of this process
ctty:0, // the id of the controlling tty for this process
@ -653,6 +659,8 @@ clite.proc = {
if (parent) {
proc.uid = parent.uid;
proc.gid = parent.gid;
proc.ruid = parent.ruid;
proc.rgid = parent.rgid;
proc.ctty = parent.ctty;
}
data.procs.push(proc);
@ -661,11 +669,10 @@ clite.proc = {
n.data.content = 'pid: '+proc.pid+'\n';
return proc.pid;
}
clite.proc.update = function(cl) {
var i = getProcIndex(-1);
if (i<0)
clite.proc.update = function(pid,cl) {
var proc = getProc(pid);
if (!proc)
return false;
var proc = data.procs[i];
var n = vfsapi.getNode(0,'/proc/'+proc.pid);
if (!n)
return false;
@ -755,6 +762,18 @@ clite.proc = {
return 0;
return proc.gid;
}
clite.proc.getRUID = function(pid) {
var proc = getProc(pid);
if (!proc)
return 0;
return proc.ruid;
}
clite.proc.getRGID = function(pid) {
var proc = getProc(pid);
if (!proc)
return 0;
return proc.rgid;
}
clite.proc.setUID = function(pid,uid,force) {
var proc = getProc(pid);
if (!proc)
@ -772,11 +791,34 @@ clite.proc = {
return false;
if (!clite.user.getGRData(gid))
return false;
if (!force && gid == 0)
if (!force && gid == 0 && clite.proc.getUID(pid) != 0)
return false;
proc.gid = gid;
return true;
}
clite.proc.setRUID = 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.gpid = addGroup(pid);
proc.ruid = uid;
return true;
}
clite.proc.setRGID = function(pid,gid,force) {
var proc = getProc(pid);
if (!proc)
return false;
if (!clite.user.getGRData(gid))
return false;
if (!force && gid == 0 && proc.uid != 0)
return false;
proc.rgid = gid;
return true;
}
clite.proc.getTTY = function(pid) {
var proc = getProc(pid);
if (!proc)
@ -787,8 +829,10 @@ clite.proc = {
var proc = getProc(pid);
if (!proc)
return false;
proc.ruid = uid;
proc.uid = uid;
proc.gid = clite.user.getGID(uid);
proc.rgid = clite.user.getGID(uid);
proc.gid = proc.rgid;
return true;
}
clite.proc.init = null;
@ -1143,7 +1187,7 @@ cat -l /usr/share/introduction
return false;
var ps = pass+':'+udata.name;
var cp = clite.lib.hash(ps);
var cp = clite.lib.hash(ps).toString(16);
udata.pass = cp;
saveUsers();
@ -1156,9 +1200,9 @@ cat -l /usr/share/introduction
return false;
var ps = pass+':'+udata.name;
var cp = clite.lib.hash(ps);
var cp = clite.lib.hash(ps).toString(16);
if (ps == udata.pass)
if (cp == udata.pass)
return true;
return false;
}
@ -2857,6 +2901,8 @@ clite.lib = {
},
checkNodeReadable:function(node,pid) {
var uid = clite.proc.getUID(pid);
if (uid == 0)
return true;
if ((node.mode&clite.io.modes.S_IROTH) == clite.io.modes.S_IROTH)
return true;
if (clite.user.checkGID(uid,node.gid) && (node.mode&clite.io.modes.S_IRGRP) == clite.io.modes.S_IRGRP)
@ -2867,6 +2913,8 @@ clite.lib = {
},
checkNodeWritable:function(node,pid) {
var uid = clite.proc.getUID(pid);
if (uid == 0)
return true;
if (node.uid == uid && (node.mode&clite.io.modes.S_IWUSR) == clite.io.modes.S_IWUSR)
return true;
// check for directory sticky bit on parent
@ -3153,8 +3201,30 @@ clite.lib = {
if (!clite.proc.setUID(io.pid,fd.node.uid,true))
return -8;
}
io.include = function(name) {
var file = '';
clite.libs.index.forEach(function(e) {
if (e.header == name)
file = e.file;
});
if (file == '')
return null;
clite.proc.update(args.join(' '));
var fd = clite.io.open(0,'/lib/'+file+'.so',clite.io.flags.O_RDONLY);
if (!fd)
return null;
var lib = null;
try{
lib = fd.node.data.content(io,env);
}catch(err) {}
clite.io.close(0,fd);
if (lib)
return lib;
return null;
}
clite.proc.update(io.pid,args.join(' '));
var r = clite.core.execSafe(function() {
var rr = fd.node.data.content(args,env,io);

View file

@ -52,13 +52,20 @@ return Object.create({
// returns the current user id
getuid:function() {
return clite.proc.getRUID(io.pid);
},
geteuid:function() {
return clite.proc.getUID(io.pid);
},
setuid:function(uid) {
return clite.proc.setUID(io.pid,uid,false);
if (!clite.proc.setUID(io.pid,uid,false))
return false;
return clite.proc.setRUID(io.pid,uid,false);
},
setreuid:function(ruid,euid) {
return clite.proc.setGID(io.pid,euid,false);
if (!clite.proc.setUID(io.pid,euid,false))
return false;
return clite.proc.setRUID(io.pid,ruid,false);
},
// gets the passwd file data for a user based on their uid
@ -85,13 +92,20 @@ return Object.create({
// returns the current group id
getgid:function() {
return clite.proc.getRGID(io.pid);
},
getegid:function() {
return clite.proc.getGID(io.pid);
},
setgid:function(gid) {
return clite.proc.setGID(io.pid,gid,false);
if (!clite.proc.setGID(io.pid,gid,false))
return false;
return clite.proc.setRGID(io.pid,gid,false);
},
setregid:function(rgid,egid) {
return clite.proc.setGID(io.pid,egid,false);
if (!clite.proc.setGID(io.pid,egid,false))
return false;
return clite.proc.setRGID(io.pid,rgid,false);
},
endgrent:function() {},
getgrent:function() {

View file

@ -65,7 +65,7 @@ return Object.create({
},
stat:function(path) {
var fd = clite.io.open(io.pid,path,clite.io.flags.O_RDONLY|clite.io.flags.O_NONBLOCK);
var fd = clite.io.open(0,path,clite.io.flags.O_RDONLY|clite.io.flags.O_NONBLOCK);
if (!fd)
return null;
var st = clite.io.fstatat(io.pid,fd,0);
@ -74,7 +74,7 @@ return Object.create({
},
lstat:function(path) {
var fd = clite.io.open(io.pid,path,clite.io.flags.O_RDONLY|clite.io.flags.O_NOFOLLOW|clite.io.flags.O_NONBLOCK);
var fd = clite.io.open(0,path,clite.io.flags.O_RDONLY|clite.io.flags.O_NOFOLLOW|clite.io.flags.O_NONBLOCK);
if (!fd)
return null;
var st = clite.io.fstatat(io.pid,fd,clite.io.flags.AT_SYMLINK_NOFOLLOW);