1 -- SPDX-License-Identifier: BSD-2-Clause
3 -- Copyright(c) 2022 Baptiste Daroussin <bapt@FreeBSD.org>
5 local pu = require("posix.unistd")
7 local function warnmsg(str)
8 io.stderr:write(str.."\n")
11 local function errmsg(str)
12 io.stderr:write(str.."\n")
16 local function dirname(oldpath)
20 local path = oldpath:gsub("[^/]+/*$", "")
27 local function mkdir_p(path)
28 if lfs.attributes(path, "mode") ~= nil then
31 local r,err = mkdir_p(dirname(path))
33 return nil,err.." (creating "..path..")"
35 return lfs.mkdir(path)
38 local function sethostname(hostname)
39 if hostname == nil then return end
40 local root = os.getenv("NUAGE_FAKE_ROOTDIR")
44 local hostnamepath = root .. "/etc/rc.conf.d/hostname"
46 mkdir_p(dirname(hostnamepath))
47 local f,err = io.open(hostnamepath, "w")
49 warnmsg("Impossible to open "..hostnamepath .. ":" ..err)
52 f:write("hostname=\""..hostname.."\"\n")
56 local function splitlist(list)
58 if type(list) == "string" then
59 for str in list:gmatch("([^, ]+)") do
62 elseif type(list) == "table" then
65 warnmsg("Invalid type ".. type(list) ..", expecting table or string")
70 local function adduser(pwd)
71 if (type(pwd) ~= "table") then
72 warnmsg("Argument should be a table")
75 local f = io.popen("getent passwd "..pwd.name)
76 local pwdstr = f:read("*a")
78 if pwdstr:len() ~= 0 then
79 return pwdstr:match("%a+:.+:%d+:%d+:.*:(.*):.*")
82 pwd.gecos = pwd.name .. " User"
85 pwd.home = "/home/" .. pwd.name
89 local list = splitlist(pwd.groups)
90 extraargs = " -G ".. table.concat(list, ',')
92 -- pw will automatically create a group named after the username
93 -- do not add a -g option in this case
94 if pwd.primary_group and pwd.primary_group ~= pwd.name then
95 extraargs = extraargs .. " -g " .. pwd.primary_group
97 if not pwd.no_create_home then
98 extraargs = extraargs .. " -m "
100 if not pwd.shell then
101 pwd.shell = "/bin/sh"
106 precmd = "echo "..pwd.passwd .. "| "
108 elseif pwd.plain_text_passwd then
109 precmd = "echo "..pwd.plain_text_passwd .. "| "
112 local root = os.getenv("NUAGE_FAKE_ROOTDIR")
113 local cmd = precmd .. "pw "
115 cmd = cmd .. "-R " .. root .. " "
117 cmd = cmd .. "useradd -n ".. pwd.name .. " -M 0755 -w none "
118 cmd = cmd .. extraargs .. " -c '".. pwd.gecos
119 cmd = cmd .. "' -d '" .. pwd.home .. "' -s "..pwd.shell .. postcmd
121 local r = os.execute(cmd)
123 warnmsg("nuageinit: fail to add user "..pwd.name);
130 cmd = cmd .. "-R " .. root .. " "
132 cmd = cmd .. "lock " .. pwd.name
138 local function addgroup(grp)
139 if (type(grp) ~= "table") then
140 warnmsg("Argument should be a table")
143 local f = io.popen("getent group "..grp.name)
144 local grpstr = f:read("*a")
146 if grpstr:len() ~= 0 then
151 local list = splitlist(grp.members)
152 extraargs = " -M " .. table.concat(list, ',')
154 local root = os.getenv("NUAGE_FAKE_ROOTDIR")
157 cmd = cmd .. "-R " .. root .. " "
159 cmd = cmd .. "groupadd -n ".. grp.name .. extraargs
160 local r = os.execute(cmd)
162 warnmsg("nuageinit: fail to add group ".. grp.name);
169 local function addsshkey(homedir, key)
170 local chownak = false
171 local chowndotssh = false
172 local ak_path = homedir .. "/.ssh/authorized_keys"
173 local dotssh_path = homedir .. "/.ssh"
174 local dirattrs = lfs.attributes(ak_path)
175 if dirattrs == nil then
177 dirattrs = lfs.attributes(dotssh_path)
178 if dirattrs == nil then
179 if not lfs.mkdir(dotssh_path) then
180 warnmsg("nuageinit: impossible to create ".. dotssh_path)
184 dirattrs = lfs.attributes(homedir)
188 local f = io.open(ak_path, "a")
190 warnmsg("nuageinit: impossible to open "..ak_path)
196 pu.chown(ak_path, dirattrs.uid, dirattrs.gid)
199 pu.chown(dotssh_path, dirattrs.uid, dirattrs.gid)
206 sethostname = sethostname,
209 addsshkey = addsshkey,