The branch main has been updated by dtxdf:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=9a829e865697e623a046800545be7781a117125e

commit 9a829e865697e623a046800545be7781a117125e
Author:     Jesús Daniel Colmenares Oviedo <dt...@freebsd.org>
AuthorDate: 2025-09-11 16:54:24 +0000
Commit:     Jesús Daniel Colmenares Oviedo <dt...@freebsd.org>
CommitDate: 2025-09-11 17:06:03 +0000

    nuageinit: Add doas support
    
    * Set mode of etc directory to 0755.
    * Use user.localbase sysctl instead of /usr/local.
    * Add test case for doas.
    * Set ${LOCALBASE} instead of /usr/local in nuageinit(7) man page.
    
    Reviewed by:            bapt@
    Approved by:            bapt@
    Differential Revision:  https://reviews.freebsd.org/D52437
---
 libexec/nuageinit/nuage.lua          | 62 +++++++++++++++++++++++++++++++++++-
 libexec/nuageinit/nuageinit          |  3 ++
 libexec/nuageinit/nuageinit.7        |  9 +++++-
 libexec/nuageinit/tests/nuageinit.sh | 12 ++++++-
 4 files changed, 83 insertions(+), 3 deletions(-)

diff --git a/libexec/nuageinit/nuage.lua b/libexec/nuageinit/nuage.lua
index 22140dd06fe5..587e4c9c2cd4 100644
--- a/libexec/nuageinit/nuage.lua
+++ b/libexec/nuageinit/nuage.lua
@@ -7,6 +7,17 @@ local unistd = require("posix.unistd")
 local sys_stat = require("posix.sys.stat")
 local lfs = require("lfs")
 
+local function getlocalbase()
+       local f = io.popen("sysctl -in user.localbase 2> /dev/null")
+       local localbase = f:read("*l")
+       f:close()
+       if localbase == nil or localbase:len() == 0 then
+               -- fallback
+               localbase = "/usr/local"
+       end
+       return localbase
+end
+
 local function decode_base64(input)
        local b = 
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
        input = string.gsub(input, '[^'..b..'=]', '')
@@ -276,11 +287,59 @@ local function addsshkey(homedir, key)
        end
 end
 
+local function adddoas(pwd)
+       local chmodetcdir = false
+       local chmoddoasconf = false
+       local root = os.getenv("NUAGE_FAKE_ROOTDIR")
+       local localbase = getlocalbase()
+       local etcdir = localbase .. "/etc"
+       if root then
+               etcdir= root .. etcdir
+       end
+       local doasconf = etcdir .. "/doas.conf"
+       local doasconf_attr = lfs.attributes(doasconf)
+       if doasconf_attr == nil then
+               chmoddoasconf = true
+               local dirattrs = lfs.attributes(etcdir)
+               if dirattrs == nil then
+                       local r, err = mkdir_p(etcdir)
+                       if not r then
+                               return nil, err .. " (creating " .. etcdir .. 
")"
+                       end
+                       chmodetcdir = true
+               end
+       end
+       local f = io.open(doasconf, "a")
+       if not f then
+               warnmsg("impossible to open " .. doasconf)
+               return
+       end
+       if type(pwd.doas) == "string" then
+               local rule = pwd.doas
+               rule = rule:gsub("%%u", pwd.name)
+               f:write(rule .. "\n")
+       elseif type(pwd.doas) == "table" then
+               for _, str in ipairs(pwd.doas) do
+                       local rule = str
+                       rule = rule:gsub("%%u", pwd.name)
+                       f:write(rule .. "\n")
+               end
+       end
+       f:close()
+       if chmoddoasconf then
+               chmod(doasconf, "0640")
+       end
+       if chmodetcdir then
+               chmod(etcdir, "0755")
+       end
+end
+
 local function addsudo(pwd)
        local chmodsudoersd = false
        local chmodsudoers = false
        local root = os.getenv("NUAGE_FAKE_ROOTDIR")
-       local sudoers_dir = "/usr/local/etc/sudoers.d"
+       local localbase = getlocalbase()
+       local sudoers_dir = localbase .. "/etc/sudoers.d"
        if root then
                sudoers_dir= root .. sudoers_dir
        end
@@ -584,6 +643,7 @@ local n = {
        update_packages = update_packages,
        upgrade_packages = upgrade_packages,
        addsudo = addsudo,
+       adddoas = adddoas,
        addfile = addfile
 }
 
diff --git a/libexec/nuageinit/nuageinit b/libexec/nuageinit/nuageinit
index 52bfc4d9f69f..f457438c7e89 100755
--- a/libexec/nuageinit/nuageinit
+++ b/libexec/nuageinit/nuageinit
@@ -139,6 +139,9 @@ local function users(obj)
                        if u.sudo then
                                nuage.addsudo(u)
                        end
+                       if u.doas then
+                               nuage.adddoas(u)
+                       end
                else
                        nuage.warn("invalid type : " .. type(u) .. " for users 
entry number " .. n)
                end
diff --git a/libexec/nuageinit/nuageinit.7 b/libexec/nuageinit/nuageinit.7
index 84990c93e545..c90fde5f406d 100644
--- a/libexec/nuageinit/nuageinit.7
+++ b/libexec/nuageinit/nuageinit.7
@@ -307,7 +307,14 @@ Ignored if an encrypted password is already provided.
 Boolean to determine if the user account should be locked.
 .It Ic sudo
 A string or an array of strings which should be appended to
-.Pa /usr/local/etc/sudoers.d/90-nuageinit-users
+.Pa ${LOCALBASE}/etc/sudoers.d/90-nuageinit-users
+.It Ic doas
+A string or an array of strings which should be appended to
+.Pa ${LOCALBASE}/etc/doas.conf
+.Pp
+Instead of hardcoding the username, you can use
+.Sy %u Ns ,
+which will be replaced by the current username.
 .El
 .Pp
 A special case exist: if the entry is a simple string with the value
diff --git a/libexec/nuageinit/tests/nuageinit.sh 
b/libexec/nuageinit/tests/nuageinit.sh
index 98593f7d75b0..761eab64f766 100644
--- a/libexec/nuageinit/tests/nuageinit.sh
+++ b/libexec/nuageinit/tests/nuageinit.sh
@@ -119,12 +119,16 @@ users:
     gecos: Foo B. Bar
     primary_group: foobar
     sudo: ALL=(ALL) NOPASSWD:ALL
+    doas: permit persist %u as root
     groups: users
     passwd: 
$6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/
   - name: bla
     sudo:
     - "ALL=(ALL) NOPASSWD:/usr/sbin/pw"
     - "ALL=(ALL) ALL"
+    doas:
+    - "deny %u as foobar"
+    - "permit persist %u as root cmd whoami"
 EOF
        atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
        atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
@@ -147,7 +151,13 @@ EOF
        sed -i "" "s/freebsd:.*:1001/freebsd:freebsd:1001/" 
"${PWD}"/etc/master.passwd
        atf_check -o file:expectedpasswd cat "${PWD}"/etc/master.passwd
        atf_check -o file:expectedgroup cat "${PWD}"/etc/group
-       atf_check -o inline:"foobar ALL=(ALL) NOPASSWD:ALL\nbla ALL=(ALL) 
NOPASSWD:/usr/sbin/pw\nbla ALL=(ALL) ALL\n" cat 
${PWD}/usr/local/etc/sudoers.d/90-nuageinit-users
+       localbase=`sysctl -ni user.localbase 2> /dev/null`
+       if [ -z "${localbase}" ]; then
+               # fallback
+               localbase="/usr/local"
+       fi
+       atf_check -o inline:"foobar ALL=(ALL) NOPASSWD:ALL\nbla ALL=(ALL) 
NOPASSWD:/usr/sbin/pw\nbla ALL=(ALL) ALL\n" cat 
"${PWD}/${localbase}/etc/sudoers.d/90-nuageinit-users"
+       atf_check -o inline:"permit persist foobar as root\ndeny bla as 
foobar\npermit persist bla as root cmd whoami\n" cat 
"${PWD}/${localbase}/etc/doas.conf"
 }
 
 nocloud_network_head()

Reply via email to