Merge pull request '1.2-dev merge' (#5) from 1.2-dev into main
Reviewed-on: #5
This commit is contained in:
commit
f00453f703
34 files changed
+438
-214
No files matched your search
@@ -64,12 +64,18 @@ local newGid = resolveGid(groupStr)
|
||||
local function chgrpPath(path)
|
||||
local stat = syscall.stat(path)
|
||||
if not stat then
|
||||
print(name .. ": cannot stat '" .. path .. "': No such file or directory")
|
||||
print(name .. ": cannot stat '" .. path .. "': no such file or directory")
|
||||
return false
|
||||
end
|
||||
local ok, err = pcall(syscall.chown, path, stat.owner, newGid)
|
||||
if not ok then
|
||||
print(name .. ": cannot change group of '" .. path .. "': " .. tostring(err))
|
||||
local msg = tostring(err)
|
||||
if msg:find("EPERM") or msg:find("EACCES") then
|
||||
msg = "operation not permitted (must be root)"
|
||||
elseif msg:find("ENOENT") then
|
||||
msg = "no such file or directory"
|
||||
end
|
||||
print(name .. ": cannot change group of '" .. path .. "': " .. msg)
|
||||
return false
|
||||
end
|
||||
return true
|
||||
|
||||
@@ -220,7 +220,13 @@ local function chmodPath(path)
|
||||
|
||||
local ok, cerr = pcall(syscall.chmod, path, newPerms)
|
||||
if not ok then
|
||||
print(name .. ": cannot change permissions of '" .. path .. "': " .. tostring(cerr))
|
||||
local msg = tostring(cerr)
|
||||
if msg:find("EACCES") or msg:find("EPERM") then
|
||||
msg = "permission denied"
|
||||
elseif msg:find("ENOENT") then
|
||||
msg = "no such file or directory"
|
||||
end
|
||||
print(name .. ": cannot change permissions of '" .. path .. "': " .. msg)
|
||||
return false
|
||||
end
|
||||
return true
|
||||
|
||||
@@ -95,14 +95,20 @@ end
|
||||
local function chownPath(path)
|
||||
local stat = syscall.stat(path)
|
||||
if not stat then
|
||||
print(name .. ": cannot stat '" .. path .. "': No such file or directory")
|
||||
print(name .. ": cannot stat '" .. path .. "': no such file or directory")
|
||||
return false
|
||||
end
|
||||
local uid = newUid ~= nil and newUid or stat.owner
|
||||
local gid = newGid ~= nil and newGid or stat.group
|
||||
local ok, err = pcall(syscall.chown, path, uid, gid)
|
||||
if not ok then
|
||||
print(name .. ": cannot change owner of '" .. path .. "': " .. tostring(err))
|
||||
local msg = tostring(err)
|
||||
if msg:find("EPERM") or msg:find("EACCES") then
|
||||
msg = "operation not permitted (must be root)"
|
||||
elseif msg:find("ENOENT") then
|
||||
msg = "no such file or directory"
|
||||
end
|
||||
print(name .. ": cannot change owner of '" .. path .. "': " .. msg)
|
||||
return false
|
||||
end
|
||||
return true
|
||||
|
||||
@@ -33,7 +33,6 @@ local host_str = syscall.getHost() or "Unknown"
|
||||
local cc_ver = host_str:match("ComputerCraft ([%d%.]+)") or host_str
|
||||
|
||||
local info = {
|
||||
-- {label, value} label=nil means print value as-is (userhost / separator)
|
||||
{nil, userhost},
|
||||
{nil, string.rep("-", #userhost)},
|
||||
{"OS", syscall.version() or "Unknown"},
|
||||
@@ -42,7 +41,7 @@ local info = {
|
||||
{"Uptime", formatUptime(syscall.getUptime() or 0)},
|
||||
{"Tasks", tostring(#(syscall.getTasks() or {}))},
|
||||
{"Shell", syscall.getEnviron("SHELL") or "Unknown"},
|
||||
{"Terminal", "TTY1"},
|
||||
{"Terminal", "tty1"},
|
||||
{"UID", tostring(syscall.getuid())},
|
||||
{"Packages", "n/a (spm)"},
|
||||
}
|
||||
@@ -71,15 +70,12 @@ local lines = math.max(#logo, #info)
|
||||
for i = 1, lines do
|
||||
local logo_str = logo[i] or string.rep(" ", 36)
|
||||
|
||||
-- print logo segment in cyan
|
||||
c(C_LOGO)
|
||||
printInline(logo_str)
|
||||
|
||||
-- print separator pipe
|
||||
c(C_LABEL)
|
||||
printInline("| ")
|
||||
|
||||
-- print info segment
|
||||
local row = info[i]
|
||||
if row then
|
||||
if row[1] == nil and i == 1 then
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--:Minify:--
|
||||
syscall.open("/dev/tty/TTY1","r") --stdin (Device 0)
|
||||
syscall.open("/dev/tty/TTY1","w") --stdout (Device 1)
|
||||
syscall.open("/dev/tty/tty1","r") --stdin (Device 0)
|
||||
syscall.open("/dev/tty/tty1","w") --stdout (Device 1)
|
||||
syscall.open("/dev/null","w") --stderr (device 2)
|
||||
|
||||
local success, errorMsg = xpcall(function()
|
||||
@@ -17,7 +17,13 @@ local commandHistory = {}
|
||||
local terminate = false
|
||||
syscall.setEnviron("SHELL","rtbash")
|
||||
syscall.setEnviron("PATH","/bin/")
|
||||
local _home = syscall.getEnviron("HOME")
|
||||
if _home and _home ~= "" then
|
||||
local ok = pcall(syscall.chdir, _home)
|
||||
if not ok then syscall.chdir("/") end
|
||||
else
|
||||
syscall.chdir("/")
|
||||
end
|
||||
local oldWD = ""
|
||||
|
||||
for i = 1, 16 do
|
||||
@@ -951,8 +957,8 @@ local function runCommand(command)
|
||||
end
|
||||
|
||||
local proc = syscall.spawn(function(...)
|
||||
syscall.open("/dev/tty/TTY1","r")
|
||||
syscall.open("/dev/tty/TTY1","w")
|
||||
syscall.open("/dev/tty/tty1","r")
|
||||
syscall.open("/dev/tty/tty1","w")
|
||||
syscall.open("/dev/null","w")
|
||||
local ok2, msg = pcall(program, ...)
|
||||
if not ok2 then printError(progName, msg) end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--:Minify:--
|
||||
syscall.open("/dev/tty/TTY1","r")
|
||||
syscall.open("/dev/tty/TTY1","w")
|
||||
syscall.open("/dev/tty/tty1","r")
|
||||
syscall.open("/dev/tty/tty1","w")
|
||||
syscall.open("/dev/null","r")
|
||||
syscall.devctl(1,"clear")
|
||||
syscall.devctl(1,"sfgc",1)
|
||||
@@ -57,8 +57,8 @@ while true do
|
||||
printInline("> ")
|
||||
end
|
||||
proc = syscall.spawn(function(...)
|
||||
syscall.open("/dev/tty/TTY1","r")
|
||||
syscall.open("/dev/tty/TTY1","w")
|
||||
syscall.open("/dev/tty/tty1","r")
|
||||
syscall.open("/dev/tty/tty1","w")
|
||||
syscall.open("/dev/null","w")
|
||||
program(...)
|
||||
end, path, nil, {table.unpack(split, 2)})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--:Minify:--
|
||||
syscall.open("/dev/tty/TTY1", "r") --stdin (fd 0)
|
||||
syscall.open("/dev/tty/TTY1", "w") --stdout (fd 1)
|
||||
syscall.open("/dev/tty/tty1", "r") --stdin (fd 0)
|
||||
syscall.open("/dev/tty/tty1", "w") --stdout (fd 1)
|
||||
syscall.open("/dev/null", "w") --stderr (fd 2)
|
||||
|
||||
|
||||
@@ -96,6 +96,9 @@ local function spawnShell(username, uid, shell, homedir)
|
||||
end
|
||||
|
||||
local chdirOk, chdirErr = pcall(syscall.chdir, homedir)
|
||||
if not chdirOk then
|
||||
pcall(syscall.chdir, "/")
|
||||
end
|
||||
|
||||
local ok, err = pcall(syscall.execspawn, shell, username .. ":shell")
|
||||
if not ok then
|
||||
|
||||
@@ -31,7 +31,7 @@ for j = i + 1, #cmdArgs do restArgs[#restArgs + 1] = cmdArgs[j] end
|
||||
local currentUid = syscall.getuid()
|
||||
local currentUser = syscall.getUsername(currentUid) or tostring(currentUid)
|
||||
|
||||
local targetUid = syscall.getuid(targetUser)
|
||||
local targetUid = syscall.getuidbyname(targetUser)
|
||||
if not targetUid then
|
||||
print("sudo: user '" .. targetUser .. "' does not exist")
|
||||
syscall.exit(1)
|
||||
@@ -39,7 +39,7 @@ if not targetUid then
|
||||
end
|
||||
|
||||
if currentUid ~= 0 then
|
||||
printInline("[sudo] password for " .. currentUser .. ": ")
|
||||
printInline("[sudo] password for root: ")
|
||||
local pw = ""
|
||||
while true do
|
||||
local ch = syscall.read(0)
|
||||
@@ -55,7 +55,7 @@ if currentUid ~= 0 then
|
||||
end
|
||||
end
|
||||
|
||||
local ok, err = syscall.elevate(currentUser, pw)
|
||||
local ok, err = syscall.elevate("root", pw)
|
||||
if not ok then
|
||||
sleep(1)
|
||||
print("sudo: Authentication failure")
|
||||
@@ -63,7 +63,7 @@ if currentUid ~= 0 then
|
||||
return
|
||||
end
|
||||
|
||||
if targetUid ~= 0 then
|
||||
if targetUid ~= currentUid then
|
||||
syscall.setuid(targetUid)
|
||||
end
|
||||
else
|
||||
|
||||
@@ -14,6 +14,9 @@ for i,v in pairs(kernel.processes) do
|
||||
end, i)
|
||||
end
|
||||
|
||||
if not fs.exists("/bin/startup") then
|
||||
fs.mkdir("/bin/startup")
|
||||
end
|
||||
local files = fs.list("/bin/startup")
|
||||
if not files then error("Failed to list /bin/startup") end
|
||||
for i,v in ipairs(files) do
|
||||
|
||||
@@ -37,7 +37,7 @@ function peripheral.isPresent(name)
|
||||
end
|
||||
|
||||
function peripheral.getType(peripheral)
|
||||
if type(peripheral) == "string" then -- Peripheral name passed
|
||||
if type(peripheral) == "string" then
|
||||
if native.isPresent(peripheral) then
|
||||
return native.getType(peripheral)
|
||||
end
|
||||
@@ -58,7 +58,7 @@ function peripheral.getType(peripheral)
|
||||
end
|
||||
|
||||
function peripheral.hasType(peripheral, peripheral_type)
|
||||
if type(peripheral) == "string" then -- Peripheral name passed
|
||||
if type(peripheral) == "string" then
|
||||
if native.isPresent(peripheral) then
|
||||
return native.hasType(peripheral, peripheral_type)
|
||||
end
|
||||
|
||||
@@ -184,11 +184,18 @@ end
|
||||
|
||||
kernel.log("Gathering modules")
|
||||
for _, i in ipairs(ifs.list("/lib/modules")) do
|
||||
for _,v in ipairs(ifs.list("/lib/modules/"..i)) do
|
||||
local modlist = ifs.list("/lib/modules/"..i)
|
||||
if not modlist then
|
||||
kernel.log("WARNING: could not list /lib/modules/"..i.." (skipping)", "WARN", 8)
|
||||
else
|
||||
for _,v in ipairs(modlist) do
|
||||
local prior=tonumber(v:sub(1,2))
|
||||
if prior then
|
||||
modules[prior+1][#modules[prior+1]+1]="/lib/modules/"..i.."/"..v
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
kernel.ifs=ifs
|
||||
kernel.apis=apis
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
-- :Minify:--
|
||||
local kernel = ...
|
||||
|
||||
local P = kernel.vfs.P
|
||||
local PERM = kernel.vfs.PERM
|
||||
|
||||
local RW_R_R = P.OWNER_R + P.OWNER_W + P.GROUP_R + P.WORLD_R
|
||||
local RWX_RX_RX = P.OWNER_R + P.OWNER_W + P.OWNER_X
|
||||
+ P.GROUP_R + P.GROUP_X
|
||||
+ P.WORLD_R + P.WORLD_X
|
||||
local RW_R__ = P.OWNER_R + P.OWNER_W + P.GROUP_R
|
||||
local RW____ = P.OWNER_R + P.OWNER_W
|
||||
local RWXRWXRWX = PERM.RWXRWXRWX
|
||||
local SUID_755 = PERM.SUID_755
|
||||
|
||||
local META_VERSION = 0x01
|
||||
local rootDisk = kernel.disks["$"]
|
||||
|
||||
local function makeEntry(name, etype, owner, group, perms, cmeta)
|
||||
cmeta = cmeta or ""
|
||||
local plo = perms % 256
|
||||
local phi = math.floor(perms / 256) % 256
|
||||
return string.char(#name) .. name
|
||||
.. string.char(etype, owner, group, plo, phi)
|
||||
.. string.char(#cmeta) .. cmeta
|
||||
end
|
||||
|
||||
local function writeMeta(dir, entries)
|
||||
local diskDir = dir
|
||||
if diskDir:sub(1,1) == "/" then diskDir = diskDir:sub(2) end
|
||||
local metaPath = (diskDir == "" and ".meta" or diskDir .. "/.meta")
|
||||
|
||||
local data = string.char(META_VERSION)
|
||||
for _, e in ipairs(entries) do
|
||||
data = data .. makeEntry(e[1], e[2] or 0x00, e[3], e[4], e[5], e[6])
|
||||
end
|
||||
|
||||
local ok, err = pcall(function()
|
||||
local f = rootDisk:open(metaPath, "w")
|
||||
f.write(data)
|
||||
f.close()
|
||||
end)
|
||||
if not ok then
|
||||
kernel.log("permissions: failed to write " .. metaPath .. ": " .. tostring(err), "WARN", 8)
|
||||
end
|
||||
end
|
||||
|
||||
local REG = 0x00
|
||||
|
||||
if rootDisk:fileExists(".meta") then
|
||||
kernel.log("Permissions already seeded, skipping.", "INFO")
|
||||
else
|
||||
kernel.log("Seeding filesystem permissions...", "INFO")
|
||||
|
||||
-- /
|
||||
writeMeta("/", {
|
||||
{"bin", REG, 0, 0, RWX_RX_RX},
|
||||
{"boot", REG, 0, 0, RWX_RX_RX},
|
||||
{"dev", REG, 0, 0, RWX_RX_RX},
|
||||
{"etc", REG, 0, 0, RWX_RX_RX},
|
||||
{"home", REG, 0, 0, RWX_RX_RX},
|
||||
{"lib", REG, 0, 0, RWX_RX_RX},
|
||||
{"root", REG, 0, 0, RW____ },
|
||||
{"sbin", REG, 0, 0, RWX_RX_RX},
|
||||
{"tmp", REG, 0, 0, RWXRWXRWX},
|
||||
{"usr", REG, 0, 0, RWX_RX_RX},
|
||||
{"var", REG, 0, 0, RWX_RX_RX},
|
||||
})
|
||||
|
||||
-- /bin
|
||||
writeMeta("/bin", {
|
||||
{"cat", REG, 0, 0, RWX_RX_RX},
|
||||
{"clear", REG, 0, 0, RWX_RX_RX},
|
||||
{"echo", REG, 0, 0, RWX_RX_RX},
|
||||
{"hfetch", REG, 0, 0, RWX_RX_RX},
|
||||
{"hysh", REG, 0, 0, RWX_RX_RX},
|
||||
{"hyshex", REG, 0, 0, RWX_RX_RX},
|
||||
{"install", REG, 0, 0, RWX_RX_RX},
|
||||
{"login", REG, 0, 0, SUID_755 },
|
||||
{"ls", REG, 0, 0, RWX_RX_RX},
|
||||
{"lua", REG, 0, 0, RWX_RX_RX},
|
||||
{"luaold", REG, 0, 0, RWX_RX_RX},
|
||||
{"mkdir", REG, 0, 0, RWX_RX_RX},
|
||||
{"ps", REG, 0, 0, RWX_RX_RX},
|
||||
{"pwd", REG, 0, 0, RWX_RX_RX},
|
||||
{"spm", REG, 0, 0, RWX_RX_RX},
|
||||
{"su", REG, 0, 0, SUID_755 },
|
||||
{"sudo", REG, 0, 0, SUID_755 },
|
||||
{"sysdump", REG, 0, 0, RWX_RX_RX},
|
||||
{"whoami", REG, 0, 0, RWX_RX_RX},
|
||||
{"yes", REG, 0, 0, RWX_RX_RX},
|
||||
{"startup", REG, 0, 0, RWX_RX_RX},
|
||||
{"ln", REG, 0, 0, RWX_RX_RX},
|
||||
{"readlink", REG, 0, 0, RWX_RX_RX},
|
||||
})
|
||||
|
||||
writeMeta("/bin/startup", {
|
||||
{"test.lua", REG, 0, 0, RWX_RX_RX},
|
||||
})
|
||||
|
||||
-- /etc
|
||||
writeMeta("/etc", {
|
||||
{"passwd", REG, 0, 0, RW_R_R},
|
||||
{"shadow", REG, 0, 0, RW____},
|
||||
{"pam.d", REG, 0, 0, RWX_RX_RX},
|
||||
})
|
||||
|
||||
writeMeta("/etc/pam.d", {
|
||||
{"secret", REG, 0, 0, RW____},
|
||||
})
|
||||
|
||||
-- /sbin
|
||||
writeMeta("/sbin", {
|
||||
{"init.lua", REG, 0, 0, RWX_RX_RX},
|
||||
})
|
||||
|
||||
-- /boot
|
||||
writeMeta("/boot", {
|
||||
{"kernel.lua", REG, 0, 0, RW_R_R },
|
||||
{"boot.cfg", REG, 0, 0, RW_R_R },
|
||||
{"safeboot.cfg", REG, 0, 0, RW_R_R },
|
||||
{"fstab", REG, 0, 0, RW_R_R },
|
||||
{"initfs", REG, 0, 0, RW_R_R },
|
||||
{"cct", REG, 0, 0, RWX_RX_RX},
|
||||
{"oc", REG, 0, 0, RWX_RX_RX},
|
||||
})
|
||||
|
||||
-- /lib
|
||||
writeMeta("/lib", {
|
||||
{"sys", REG, 0, 0, RWX_RX_RX},
|
||||
{"modules", REG, 0, 0, RWX_RX_RX},
|
||||
{"crypto", REG, 0, 0, RWX_RX_RX},
|
||||
{"store", REG, 0, 0, RWX_RX_RX},
|
||||
{"snip", REG, 0, 0, RW_R_R },
|
||||
{"io", REG, 0, 0, RW_R_R },
|
||||
{"bit32", REG, 0, 0, RW_R_R },
|
||||
})
|
||||
|
||||
kernel.log("Filesystem permissions seeded.", "INFO")
|
||||
end
|
||||
|
||||
kernel.log("Permission module loaded.", "INFO")
|
||||
+3
-6
@@ -1,4 +1,7 @@
|
||||
-- :Minify:--
|
||||
local kernel = ...
|
||||
kernel.allowGlobalOverwrites = true
|
||||
|
||||
function string.hasSuffix(str, suffix)
|
||||
return string.sub(str, #suffix + 1) == suffix
|
||||
end
|
||||
@@ -68,30 +71,24 @@ end
|
||||
local function serialize(tbl, seen)
|
||||
seen = seen or {}
|
||||
|
||||
-- If we've seen this table before, return a placeholder to prevent infinite loops
|
||||
if seen[tbl] then return '"[Circular Reference]"' end
|
||||
|
||||
-- Mark this table as seen
|
||||
seen[tbl] = true
|
||||
|
||||
local output = "{"
|
||||
local first = true
|
||||
|
||||
for i, v in pairs(tbl) do
|
||||
-- Handle comma placement more cleanly
|
||||
if not first then output = output .. "," end
|
||||
first = false
|
||||
|
||||
-- Serialize Key
|
||||
if type(i) == "string" then
|
||||
output = output .. "[\"" .. i .. "\"]="
|
||||
elseif type(i) == "number" then
|
||||
output = output .. "[" .. tostring(i) .. "]="
|
||||
end
|
||||
|
||||
-- Serialize Value
|
||||
if type(v) == "table" then
|
||||
-- Pass the 'seen' table down to the recursive call
|
||||
output = output .. serialize(v, seen)
|
||||
elseif type(v) == "string" then
|
||||
output = output .. "[=[" .. v .. "]=]"
|
||||
+113
-21
@@ -5,14 +5,14 @@ kernel.vfs = vfs
|
||||
vfs.mounts = {["$"] = "/"}
|
||||
vfs.disks = kernel.disks
|
||||
|
||||
-- Metafile format (version 1)
|
||||
-- File header: 1 byte = version (0x01)
|
||||
-- Metafile format (version 2)
|
||||
-- File header: 1 byte = version (0x02)
|
||||
-- Per-entry:
|
||||
-- 1 byte = name length
|
||||
-- N bytes = name
|
||||
-- 1 byte = entry type (0x00 = regular, 0x01 = symlink)
|
||||
-- 1 byte = owner uid
|
||||
-- 1 byte = group gid
|
||||
-- 2 bytes = owner uid (little-endian uint16)
|
||||
-- 2 bytes = group gid (little-endian uint16)
|
||||
-- 2 bytes = perms (little-endian uint16)
|
||||
-- bit 0 = world-write bit 1 = world-read
|
||||
-- bit 2 = group-write bit 3 = group-read
|
||||
@@ -24,12 +24,16 @@ vfs.disks = kernel.disks
|
||||
-- 1 byte = cmeta length
|
||||
-- N bytes = cmeta (for symlinks: the link target path)
|
||||
--
|
||||
-- Version 1:
|
||||
-- 1 byte name len, N bytes name, 1 byte etype, 1 byte owner,
|
||||
-- 1 byte group, 2 bytes perms (little-endian), 1 byte cmeta len, N bytes cmeta
|
||||
--
|
||||
-- Version 0:
|
||||
-- No file header. Per-entry:
|
||||
-- 1 byte name len, N bytes name, 1 byte owner, 1 byte group,
|
||||
-- 1 byte perms (low 7 bits only), 1 byte cmeta len, N bytes cmeta
|
||||
|
||||
local META_VERSION = 0x01
|
||||
local META_VERSION = 0x02
|
||||
|
||||
local function bit_is_set(num, bit)
|
||||
return math.floor(num / (2 ^ bit)) % 2 == 1
|
||||
@@ -41,8 +45,9 @@ local function parseMetafile(raw)
|
||||
local p = 1
|
||||
|
||||
local version = 0
|
||||
if raw:byte(1) == META_VERSION then
|
||||
version = META_VERSION
|
||||
local firstByte = raw:byte(1)
|
||||
if firstByte == 0x02 or firstByte == 0x01 then
|
||||
version = firstByte
|
||||
p = 2
|
||||
end
|
||||
|
||||
@@ -54,7 +59,13 @@ local function parseMetafile(raw)
|
||||
|
||||
local etype, owner, group, perms, cmeta
|
||||
|
||||
if version == META_VERSION then
|
||||
if version == 0x02 then
|
||||
if p + 6 > #raw then break end
|
||||
etype = raw:byte(p); p = p + 1
|
||||
owner = raw:byte(p) + raw:byte(p+1) * 256; p = p + 2
|
||||
group = raw:byte(p) + raw:byte(p+1) * 256; p = p + 2
|
||||
perms = raw:byte(p) + raw:byte(p+1) * 256; p = p + 2
|
||||
elseif version == 0x01 then
|
||||
if p + 4 > #raw then break end
|
||||
etype = raw:byte(p); p = p + 1
|
||||
owner = raw:byte(p); p = p + 1
|
||||
@@ -87,34 +98,71 @@ local function makeMetafile(meta)
|
||||
for name, m in pairs(meta) do
|
||||
local plo = m.perms % 256
|
||||
local phi = math.floor(m.perms / 256) % 256
|
||||
local olo = (m.owner or 0) % 256
|
||||
local ohi = math.floor((m.owner or 0) / 256) % 256
|
||||
local glo = (m.group or 0) % 256
|
||||
local ghi = math.floor((m.group or 0) / 256) % 256
|
||||
out = out
|
||||
.. string.char(#name) .. name
|
||||
.. string.char(m.etype or 0x00)
|
||||
.. string.char(m.owner, m.group, plo, phi)
|
||||
.. string.char(olo, ohi, glo, ghi, plo, phi)
|
||||
.. string.char(#m.cmeta) .. m.cmeta
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
local SAFE_COMPONENT_PATTERN = "^[A-Za-z0-9_.+%-%@%(%)%[%]]+$"
|
||||
|
||||
local function normalizePath(path)
|
||||
local task = kernel.currentTask
|
||||
local cwd = task.cwd or "/"
|
||||
if path:sub(1,1) ~= "/" then path = cwd .. "/" .. path end
|
||||
local parts = {}
|
||||
for part in path:gmatch("[^/]+") do
|
||||
if part == ".." then
|
||||
if #parts > 0 then table.remove(parts) end
|
||||
elseif part ~= "." and part ~= "" then
|
||||
table.insert(parts, part)
|
||||
|
||||
if path:sub(1, 1) ~= "/" then
|
||||
path = cwd .. "/" .. path
|
||||
end
|
||||
|
||||
local stack = {}
|
||||
local i = 1
|
||||
local len = #path
|
||||
while i <= len do
|
||||
local j = path:find("/", i, true)
|
||||
local comp
|
||||
if j then
|
||||
comp = path:sub(i, j - 1)
|
||||
i = j + 1
|
||||
else
|
||||
comp = path:sub(i)
|
||||
i = len + 1
|
||||
end
|
||||
|
||||
comp = comp:match("^%s*(.-)%s*$")
|
||||
|
||||
if comp == "" or comp == "." then
|
||||
elseif comp == ".." then
|
||||
if #stack > 0 then
|
||||
table.remove(stack)
|
||||
end
|
||||
else
|
||||
comp = comp:lower()
|
||||
if not comp:match(SAFE_COMPONENT_PATTERN) then
|
||||
error("EINVAL: illegal characters in path component: " .. comp, 2)
|
||||
end
|
||||
if comp == ".meta" then
|
||||
error("EINVAL: reserved path component: " .. comp, 2)
|
||||
end
|
||||
table.insert(stack, comp)
|
||||
end
|
||||
end
|
||||
local result = "/" .. table.concat(parts, "/")
|
||||
|
||||
local result = "/" .. table.concat(stack, "/")
|
||||
|
||||
local root = task and task.root
|
||||
if root and root ~= "/" then
|
||||
if result ~= root and result:sub(1, #root + 1) ~= root .. "/" then
|
||||
result = root
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
@@ -146,8 +194,10 @@ local function resolveMount(normalPath)
|
||||
return vfs.disks[mountId], diskPath
|
||||
end
|
||||
|
||||
vfs._parseMetafile = parseMetafile
|
||||
|
||||
local function readMetaEntry(disk, parentDiskPath, filename)
|
||||
if filename == ".meta" then error("Cannot open metafile") end
|
||||
if filename == ".meta" then error("EACCES: Cannot open metafile") end
|
||||
local mp
|
||||
if parentDiskPath == "/" then
|
||||
mp = ".meta"
|
||||
@@ -159,6 +209,14 @@ local function readMetaEntry(disk, parentDiskPath, filename)
|
||||
if not ok or not f then return nil end
|
||||
local raw = f.read(65535)
|
||||
if f.close then f.close() end
|
||||
|
||||
if raw and #raw > 0 and raw:byte(1) ~= META_VERSION then
|
||||
local upgraded = makeMetafile(parseMetafile(raw))
|
||||
local wok, wf = pcall(function() return disk:open(mp, "w") end)
|
||||
if wok and wf then wf.write(upgraded); if wf.close then wf.close() end end
|
||||
raw = upgraded
|
||||
end
|
||||
|
||||
local parsed = parseMetafile(raw)
|
||||
return parsed[filename]
|
||||
end
|
||||
@@ -400,6 +458,8 @@ function vfs.open(path, mode)
|
||||
if not disk then error("NODISK") end
|
||||
|
||||
local meta = getFileMeta(path)
|
||||
local isNew = (mode == "w" or mode == "a") and not disk:fileExists(diskPath)
|
||||
|
||||
checkperms(meta, mode == "r" and "r" or "w")
|
||||
|
||||
local handle
|
||||
@@ -408,6 +468,21 @@ function vfs.open(path, mode)
|
||||
if type(handle) ~= "table" then error("ENFILE") end
|
||||
end
|
||||
|
||||
if isNew then
|
||||
local euid = (task and (task.euid or task.uid)) or kernel.uid
|
||||
local egid = (task and task.gid) or 0
|
||||
local norm = normalizePath(path)
|
||||
local parent = norm:match("^(.*)/[^/]+$") or "/"
|
||||
if parent == "" then parent = "/" end
|
||||
local name = norm:match("[^/]+$")
|
||||
if name then
|
||||
local entry = { etype=0x00, owner=euid, group=egid,
|
||||
perms=vfs.PERM.RW_R_R, cmeta="" }
|
||||
pcall(writeMetaEntry, parent, name, entry, false)
|
||||
meta = entry
|
||||
end
|
||||
end
|
||||
|
||||
local fobj = newFileObj(handle, mode, path, meta, disk:type(diskPath))
|
||||
if mode == "r" and bit_is_set(meta.perms, 6) then
|
||||
fobj.suid_owner = meta.owner
|
||||
@@ -574,15 +649,32 @@ function vfs.listdir(path)
|
||||
end
|
||||
|
||||
function vfs.mkdir(path)
|
||||
local norm = normalizePath(path)
|
||||
local parent = norm:match("^(.*)/[^/]+$") or "/"
|
||||
if parent == "" then parent = "/" end
|
||||
local parentMeta = getFileMeta(parent)
|
||||
checkperms(parentMeta, "w")
|
||||
local disk, diskPath = resolvePath(path)
|
||||
local meta = getFileMeta(path)
|
||||
checkperms(meta, "w")
|
||||
disk:makeDirectory(diskPath)
|
||||
local task = kernel.currentTask
|
||||
local euid = (task and (task.euid or task.uid)) or kernel.uid
|
||||
local egid = (task and task.gid) or 0
|
||||
local name = norm:match("[^/]+$")
|
||||
if name then
|
||||
local entry = { etype=0x00, owner=euid, group=egid,
|
||||
perms=vfs.PERM.RWX_RX, cmeta="" }
|
||||
pcall(writeMetaEntry, parent, name, entry, false)
|
||||
end
|
||||
end
|
||||
|
||||
function vfs.remove(path)
|
||||
local norm = resolveSymlinks(path, true)
|
||||
local parent = norm:match("^(.*)/[^/]+$") or "/"
|
||||
if parent == "" then parent = "/" end
|
||||
local parentMeta = getFileMeta(parent)
|
||||
checkperms(parentMeta, "w")
|
||||
|
||||
local meta = getFileMeta(path, true)
|
||||
checkperms(meta, "w")
|
||||
|
||||
if kernel.unixSockets and kernel.unixSockets[path] then
|
||||
kernel.unixSockets[path] = nil
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+2
-2
@@ -385,11 +385,11 @@ kernel.processes.cctmond = function()
|
||||
end
|
||||
end
|
||||
|
||||
newtty(apis.term, "TTY1", fifo.pop)
|
||||
newtty(apis.term, "tty1", fifo.pop)
|
||||
|
||||
|
||||
for i,v in ipairs({peripheral.find("monitor")}) do
|
||||
v.setTextScale(.5)
|
||||
v.write("Initializing...")
|
||||
newtty(v,"TTY"..tostring(i+1),function () end)
|
||||
newtty(v,"tty"..tostring(i+1),function () end)
|
||||
end
|
||||
+5
-4
@@ -3,6 +3,7 @@ local args = {...}
|
||||
local kernel = args[1]
|
||||
kernel._G = _G
|
||||
|
||||
|
||||
local function readonly(tbl)
|
||||
return setmetatable({}, {
|
||||
__index = function(_, key)
|
||||
@@ -20,7 +21,7 @@ local function readonly(tbl)
|
||||
error("Attempt to modify global variable '" .. k .. "'", 2)
|
||||
end,
|
||||
|
||||
__pairs = function()
|
||||
__pairs = function(self)
|
||||
local function iter(_, key)
|
||||
local nextKey, value = next(tbl, key)
|
||||
if type(value) == "table" then
|
||||
@@ -28,7 +29,7 @@ local function readonly(tbl)
|
||||
end
|
||||
return nextKey, value
|
||||
end
|
||||
return iter, tbl, nil
|
||||
return iter, self, nil
|
||||
end,
|
||||
|
||||
__ipairs = function()
|
||||
@@ -49,8 +50,8 @@ local function readonly(tbl)
|
||||
__metatable = false
|
||||
})
|
||||
end
|
||||
local origLoad = load
|
||||
|
||||
kernel._U = readonly(kernel._G)
|
||||
kernel.allowGlobalOverwrites = true
|
||||
kernel._U._G = kernel._U
|
||||
kernel.allowGlobalOverwrites = false
|
||||
kernel._U.load = function(a,b,c,d) return origLoad(a,b,c,d or kernel._U) end
|
||||
+8
-6
@@ -394,6 +394,8 @@ function auth.newUser(username, password, gid, homedir, shell)
|
||||
|
||||
if kernel.vfs.mkdir and not kernel.vfs.exists(homedir) then
|
||||
kernel.vfs.mkdir(homedir)
|
||||
-- Homedir must be owned by the new user, not root
|
||||
pcall(kernel.vfs.chown, homedir, uid, uid)
|
||||
end
|
||||
|
||||
kernel.log("AUTH: new user '" .. username .. "' uid=" .. tostring(uid))
|
||||
@@ -591,13 +593,13 @@ function auth.elevate(targetUsername, password)
|
||||
|
||||
local task = kernel.currentTask
|
||||
local prevUid = task.uid
|
||||
task.uid = uid
|
||||
task.euid = uid
|
||||
task.gid = tonumber(entry[2]) or uid
|
||||
task.egid = tonumber(entry[2]) or uid
|
||||
kernel.uid = uid
|
||||
task.uid = 0
|
||||
task.euid = 0
|
||||
task.gid = 0
|
||||
task.egid = 0
|
||||
kernel.uid = 0
|
||||
|
||||
kernel.log("AUTH: elevate uid=" .. tostring(prevUid) .. " -> " .. tostring(uid) .. " (" .. targetUsername .. ")")
|
||||
kernel.log("AUTH: elevate uid=" .. tostring(prevUid) .. " -> 0 (via " .. targetUsername .. ")")
|
||||
return true, uid
|
||||
end
|
||||
|
||||
+10
-4
@@ -5,6 +5,8 @@ local sys = {}
|
||||
local nextpid = 2
|
||||
kernel.exitMain = false
|
||||
|
||||
local resumeWithTimeout = coroutine.resumeWithTimeout
|
||||
|
||||
local function bit_is_set(num, bit)
|
||||
return math.floor(num / (2 ^ bit)) % 2 == 1
|
||||
end
|
||||
@@ -206,11 +208,15 @@ function sys.kill(pid)
|
||||
return false, "Task does not exist"
|
||||
elseif task.status == "Z" then
|
||||
return false, "Task is already dead"
|
||||
else
|
||||
end
|
||||
local caller = kernel.currentTask
|
||||
local ceuid = caller and (caller.euid or caller.uid) or kernel.uid
|
||||
if ceuid ~= 0 and task.uid ~= (caller and caller.uid or kernel.uid) then
|
||||
return false, "EPERM"
|
||||
end
|
||||
task.status = "Z"
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function sys.stop(pid)
|
||||
local task = tasks[tostring(pid)]
|
||||
@@ -352,7 +358,7 @@ function kernel.main()
|
||||
if task.sigq and #task.sigq ~= 0 and task.sigh then
|
||||
local coro = coroutine.create(task.sigh)
|
||||
if kernel.config.preempt then
|
||||
coroutine.resumeWithTimeout(coro, task.timeSlice, table.remove(task.sigq, 1))
|
||||
resumeWithTimeout(coro, task.timeSlice, table.remove(task.sigq, 1))
|
||||
else
|
||||
coroutine.resume(coro, table.remove(task.sigq, 1))
|
||||
end
|
||||
@@ -363,7 +369,7 @@ function kernel.main()
|
||||
local ret
|
||||
|
||||
if kernel.config.preempt then
|
||||
ret = { coroutine.resumeWithTimeout(task.coro, task.timeSlice, table.unpack(task.syscallReturn)) }
|
||||
ret = { resumeWithTimeout(task.coro, task.timeSlice, table.unpack(task.syscallReturn)) }
|
||||
else
|
||||
ret = { coroutine.resume(task.coro, table.unpack(task.syscallReturn)) }
|
||||
end
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,233 @@
|
||||
-- :Minify:--
|
||||
local kernel = ...
|
||||
|
||||
local P = kernel.vfs.P
|
||||
local PERM = kernel.vfs.PERM
|
||||
|
||||
local RW_R_R = P.OWNER_R + P.OWNER_W + P.GROUP_R + P.WORLD_R
|
||||
local RWX_RX_RX = P.OWNER_R + P.OWNER_W + P.OWNER_X
|
||||
+ P.GROUP_R + P.GROUP_X
|
||||
+ P.WORLD_R + P.WORLD_X
|
||||
local RW_R__ = P.OWNER_R + P.OWNER_W + P.GROUP_R
|
||||
local RW____ = P.OWNER_R + P.OWNER_W
|
||||
local RWXRWXRWX = PERM.RWXRWXRWX
|
||||
local SUID_755 = PERM.SUID_755
|
||||
|
||||
local META_VERSION = 0x02
|
||||
local rootDisk = kernel.disks["$"]
|
||||
|
||||
local function makeEntry(name, etype, owner, group, perms, cmeta)
|
||||
cmeta = cmeta or ""
|
||||
local plo = perms % 256
|
||||
local phi = math.floor(perms / 256) % 256
|
||||
local olo = (owner or 0) % 256
|
||||
local ohi = math.floor((owner or 0) / 256) % 256
|
||||
local glo = (group or 0) % 256
|
||||
local ghi = math.floor((group or 0) / 256) % 256
|
||||
return string.char(#name) .. name
|
||||
.. string.char(etype, olo, ohi, glo, ghi, plo, phi)
|
||||
.. string.char(#cmeta) .. cmeta
|
||||
end
|
||||
|
||||
local REG = 0x00
|
||||
|
||||
local function mergeMeta(dir, entries)
|
||||
local diskDir = dir
|
||||
if diskDir:sub(1,1) == "/" then diskDir = diskDir:sub(2) end
|
||||
local metaPath = (diskDir == "" and ".meta" or diskDir .. "/.meta")
|
||||
|
||||
local existing = {}
|
||||
local rok, rf = pcall(function() return rootDisk:open(metaPath, "r") end)
|
||||
if rok and rf then
|
||||
local raw = rf.read(65535)
|
||||
if rf.close then rf.close() end
|
||||
existing = (kernel.vfs._parseMetafile and kernel.vfs._parseMetafile(raw)) or {}
|
||||
end
|
||||
|
||||
for _, e in ipairs(entries) do
|
||||
local name = e[1]
|
||||
local etype = e[2] or REG
|
||||
local owner = e[3] or 0
|
||||
local group = e[4] or 0
|
||||
local perms = e[5] or RWX_RX_RX
|
||||
local cmeta = e[6] or ""
|
||||
existing[name] = {
|
||||
etype = etype,
|
||||
owner = owner,
|
||||
group = group,
|
||||
perms = perms,
|
||||
cmeta = cmeta,
|
||||
}
|
||||
end
|
||||
|
||||
local data = string.char(META_VERSION)
|
||||
for name, m in pairs(existing) do
|
||||
data = data .. makeEntry(
|
||||
name,
|
||||
m.etype or REG,
|
||||
m.owner or 0,
|
||||
m.group or 0,
|
||||
m.perms or RWX_RX_RX,
|
||||
m.cmeta or ""
|
||||
)
|
||||
end
|
||||
|
||||
local ok, err = pcall(function()
|
||||
local f = rootDisk:open(metaPath, "w")
|
||||
f.write(data)
|
||||
f.close()
|
||||
end)
|
||||
if not ok then
|
||||
kernel.log("permissions: failed to write " .. metaPath .. ": " .. tostring(err), "WARN", 8)
|
||||
end
|
||||
end
|
||||
|
||||
kernel.log("Seeding filesystem permissions...", "INFO")
|
||||
|
||||
mergeMeta("/", {
|
||||
{"bin", REG, 0, 0, RWX_RX_RX},
|
||||
{"boot", REG, 0, 0, RWX_RX_RX},
|
||||
{"dev", REG, 0, 0, RWX_RX_RX},
|
||||
{"etc", REG, 0, 0, RWX_RX_RX},
|
||||
{"home", REG, 0, 0, RWX_RX_RX},
|
||||
{"lib", REG, 0, 0, RWX_RX_RX},
|
||||
{"root", REG, 0, 0, RW____ },
|
||||
{"sbin", REG, 0, 0, RWX_RX_RX},
|
||||
{"tmp", REG, 0, 0, RWXRWXRWX},
|
||||
{"usr", REG, 0, 0, RWX_RX_RX},
|
||||
{"var", REG, 0, 0, RWX_RX_RX},
|
||||
})
|
||||
|
||||
mergeMeta("/boot", {
|
||||
{"kernel.lua", REG, 0, 0, RW_R_R },
|
||||
{"boot.cfg", REG, 0, 0, RW_R_R },
|
||||
{"safeboot.cfg", REG, 0, 0, RW_R_R },
|
||||
{"fstab", REG, 0, 0, RW_R_R },
|
||||
{"initfs", REG, 0, 0, RW_R_R },
|
||||
{"cct", REG, 0, 0, RWX_RX_RX},
|
||||
{"oc", REG, 0, 0, RWX_RX_RX},
|
||||
})
|
||||
|
||||
mergeMeta("/boot/cct", {
|
||||
{"boot.lua", REG, 0, 0, RW_R_R},
|
||||
{"initdisks", REG, 0, 0, RW_R_R},
|
||||
{"eeprom", REG, 0, 0, RW_R_R},
|
||||
})
|
||||
|
||||
mergeMeta("/boot/oc", {
|
||||
{"boot.lua", REG, 0, 0, RW_R_R},
|
||||
{"initfs.lua",REG, 0, 0, RW_R_R},
|
||||
{"eeprom", REG, 0, 0, RW_R_R},
|
||||
})
|
||||
|
||||
mergeMeta("/sbin", {
|
||||
{"init.lua", REG, 0, 0, RWX_RX_RX},
|
||||
})
|
||||
|
||||
mergeMeta("/bin", {
|
||||
{"cat", REG, 0, 0, RWX_RX_RX},
|
||||
{"chattr", REG, 0, 0, RWX_RX_RX},
|
||||
{"chgrp", REG, 0, 0, RWX_RX_RX},
|
||||
{"chmod", REG, 0, 0, RWX_RX_RX},
|
||||
{"chown", REG, 0, 0, RWX_RX_RX},
|
||||
{"chroot", REG, 0, 0, RWX_RX_RX},
|
||||
{"clear", REG, 0, 0, RWX_RX_RX},
|
||||
{"echo", REG, 0, 0, RWX_RX_RX},
|
||||
{"hfetch", REG, 0, 0, RWX_RX_RX},
|
||||
{"help", REG, 0, 0, RWX_RX_RX},
|
||||
{"hysh", REG, 0, 0, RWX_RX_RX},
|
||||
{"hyshex", REG, 0, 0, RWX_RX_RX},
|
||||
{"id", REG, 0, 0, RWX_RX_RX},
|
||||
{"install", REG, 0, 0, RWX_RX_RX},
|
||||
{"ln", REG, 0, 0, RWX_RX_RX},
|
||||
{"login", REG, 0, 0, SUID_755 },
|
||||
{"loimgcreate", REG, 0, 0, RWX_RX_RX},
|
||||
{"looptest", REG, 0, 0, RWX_RX_RX},
|
||||
{"losetup", REG, 0, 0, RWX_RX_RX},
|
||||
{"ls", REG, 0, 0, RWX_RX_RX},
|
||||
{"lsusers", REG, 0, 0, RWX_RX_RX},
|
||||
{"lua", REG, 0, 0, RWX_RX_RX},
|
||||
{"luaold", REG, 0, 0, RWX_RX_RX},
|
||||
{"micro", REG, 0, 0, RWX_RX_RX},
|
||||
{"mkdir", REG, 0, 0, RWX_RX_RX},
|
||||
{"mount", REG, 0, 0, RWX_RX_RX},
|
||||
{"passwd", REG, 0, 0, RWX_RX_RX},
|
||||
{"ps", REG, 0, 0, RWX_RX_RX},
|
||||
{"pwd", REG, 0, 0, RWX_RX_RX},
|
||||
{"readlink", REG, 0, 0, RWX_RX_RX},
|
||||
{"sed", REG, 0, 0, RWX_RX_RX},
|
||||
{"socktest", REG, 0, 0, RWX_RX_RX},
|
||||
{"spm", REG, 0, 0, RWX_RX_RX},
|
||||
{"startup", REG, 0, 0, RWX_RX_RX},
|
||||
{"su", REG, 0, 0, SUID_755 },
|
||||
{"sudo", REG, 0, 0, SUID_755 },
|
||||
{"sysdump", REG, 0, 0, RWX_RX_RX},
|
||||
{"umount", REG, 0, 0, RWX_RX_RX},
|
||||
{"useradd", REG, 0, 0, RWX_RX_RX},
|
||||
{"userdel", REG, 0, 0, RWX_RX_RX},
|
||||
{"usermod", REG, 0, 0, RWX_RX_RX},
|
||||
{"whoami", REG, 0, 0, RWX_RX_RX},
|
||||
{"yes", REG, 0, 0, RWX_RX_RX},
|
||||
})
|
||||
|
||||
mergeMeta("/bin/startup", {
|
||||
{"test.lua", REG, 0, 0, RWX_RX_RX},
|
||||
})
|
||||
|
||||
mergeMeta("/lib", {
|
||||
{"sys", REG, 0, 0, RWX_RX_RX},
|
||||
{"modules", REG, 0, 0, RWX_RX_RX},
|
||||
{"crypto", REG, 0, 0, RWX_RX_RX},
|
||||
{"store", REG, 0, 0, RWX_RX_RX},
|
||||
{"snip", REG, 0, 0, RW_R_R },
|
||||
{"io", REG, 0, 0, RW_R_R },
|
||||
{"bit32", REG, 0, 0, RW_R_R },
|
||||
})
|
||||
|
||||
mergeMeta("/lib/sys", {
|
||||
{"fs", REG, 0, 0, RW_R_R},
|
||||
{"hpv", REG, 0, 0, RW_R_R},
|
||||
{"ipc", REG, 0, 0, RW_R_R},
|
||||
{"term", REG, 0, 0, RW_R_R},
|
||||
{"init", REG, 0, 0, RW_R_R},
|
||||
})
|
||||
|
||||
mergeMeta("/lib/modules", {
|
||||
{"hyperion", REG, 0, 0, RWX_RX_RX},
|
||||
})
|
||||
|
||||
mergeMeta("/lib/modules/hyperion", {
|
||||
{"01_stdlib.kmod", REG, 0, 0, RW_R_R},
|
||||
{"10_vfs.kmod", REG, 0, 0, RW_R_R},
|
||||
{"11_require.kmod", REG, 0, 0, RW_R_R},
|
||||
{"12_devfs.kmod", REG, 0, 0, RW_R_R},
|
||||
{"12_tmpfs.kmod", REG, 0, 0, RW_R_R},
|
||||
{"13_loopdev.kmod", REG, 0, 0, RW_R_R},
|
||||
{"14_keventd.kmod", REG, 0, 0, RW_R_R},
|
||||
{"19_fstab.kmod", REG, 0, 0, RW_R_R},
|
||||
{"20_signals.kmod", REG, 0, 0, RW_R_R},
|
||||
{"20_socket.kmod", REG, 0, 0, RW_R_R},
|
||||
{"26_tty.kmod", REG, 0, 0, RW_R_R},
|
||||
{"30_userspace.kmod", REG, 0, 0, RW_R_R},
|
||||
{"40_auth.kmod", REG, 0, 0, RW_R_R},
|
||||
{"45_hypervisor.kmod", REG, 0, 0, RW_R_R},
|
||||
{"47_dbg.kmod", REG, 0, 0, RW_R_R},
|
||||
{"50_gpio.kmod", REG, 0, 0, RW_R_R},
|
||||
{"70_stdlibadv.kmod", REG, 0, 0, RW_R_R},
|
||||
{"90_init.kmod", REG, 0, 0, RW_R_R},
|
||||
{"91_login.kmod", REG, 0, 0, RW_R_R},
|
||||
{"92_permissions.kmod", REG, 0, 0, RW_R_R},
|
||||
{"99_final.kmod", REG, 0, 0, RW_R_R},
|
||||
})
|
||||
|
||||
mergeMeta("/etc", {
|
||||
{"passwd", REG, 0, 0, RW_R_R },
|
||||
{"shadow", REG, 0, 0, RW____ },
|
||||
{"pam.d", REG, 0, 0, RWX_RX_RX},
|
||||
})
|
||||
|
||||
mergeMeta("/etc/pam.d", {
|
||||
{"secret", REG, 0, 0, RW____},
|
||||
})
|
||||
|
||||
kernel.log("Filesystem permissions seeded.", "INFO")
|
||||
@@ -0,0 +1,2 @@
|
||||
local kernel = ...
|
||||
kernel.allowGlobalOverwrites = false
|
||||
@@ -203,7 +203,7 @@ def _make_firstboot_kmod(users):
|
||||
|
||||
lines.append("do")
|
||||
lines.append(" local ok, err = pcall(function()")
|
||||
lines.append(" kernel.vfs.remove('/lib/modules/Hyperion/50_firstboot_users.kmod')")
|
||||
lines.append(" kernel.vfs.remove('/lib/modules/hyperion/50_firstboot_users.kmod')")
|
||||
lines.append(" end)")
|
||||
lines.append(" if not ok then")
|
||||
lines.append(" kernel.log('FIRSTBOOT: could not self-delete: ' .. tostring(err), 'WARN')")
|
||||
@@ -215,7 +215,7 @@ def _make_firstboot_kmod(users):
|
||||
|
||||
def inject_makeusers(users, arch):
|
||||
base = BUILD_ROOT / "$" if arch else BUILD_ROOT
|
||||
kmod_path = base / "lib" / "modules" / "Hyperion" / "50_firstboot_users.kmod"
|
||||
kmod_path = base / "lib" / "modules" / "hyperion" / "50_firstboot_users.kmod"
|
||||
kmod_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
kmod_path.write_text(_make_firstboot_kmod(users), encoding="utf-8")
|
||||
print(" Wrote first-boot user setup -> " + str(kmod_path.relative_to(BUILD_ROOT)))
|
||||
|
||||
Reference in new issue
Block a user