summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2023-03-14 14:52:59 +0200
committerPanu Matilainen <pmatilai@redhat.com>2023-03-30 13:59:28 +0300
commitc7fd9fed9951dc884c345eb9280987389b291c41 (patch)
tree9ab1def4247d7bf1edf13480117ba9c7c23322fa
parent15b7025c0059a41afda7493ae2ef61ac3878f3af (diff)
downloadrpm-c7fd9fed9951dc884c345eb9280987389b291c41.tar.gz
Generate user() and group() provides from packaged sysusers.d files
Encode the actual sysusers.d line as base64 in the EVR string to be passed to systemd-sysusers (or a compatibility script) by rpm during installation. The source string is \0 padded as needed to avoid base64's '=' padding in the output as this is not a welcome character in EVR strings. For example: u dnsmasq - "Dnsmasq DHCP and DNS server" /var/lib/dnsmasq user(dnsmasq) = dSBkbnNtYXNxIC0gIkRuc21hc3EgREhDUCBhbmQgRE5TIHNlcnZlciIgL3Zhci9saWIvZG5zbWFzcQAA group(dnsmasq) The EVR string is omitted from the group as that gets created as a side-effect of the user creation and does not require calling systemd-sysusers.
-rw-r--r--fileattrs/CMakeLists.txt2
-rw-r--r--fileattrs/sysusers.attr18
-rw-r--r--macros.in37
3 files changed, 56 insertions, 1 deletions
diff --git a/fileattrs/CMakeLists.txt b/fileattrs/CMakeLists.txt
index 7260fe1a2..63caeea03 100644
--- a/fileattrs/CMakeLists.txt
+++ b/fileattrs/CMakeLists.txt
@@ -1,6 +1,6 @@
install(FILES
debuginfo.attr desktop.attr elf.attr font.attr metainfo.attr
perl.attr perllib.attr pkgconfig.attr ocaml.attr
- rpm_macro.attr script.attr usergroup.attr
+ rpm_macro.attr script.attr sysusers.attr usergroup.attr
DESTINATION ${RPM_CONFIGDIR}/fileattrs
)
diff --git a/fileattrs/sysusers.attr b/fileattrs/sysusers.attr
new file mode 100644
index 000000000..f7a3e838d
--- /dev/null
+++ b/fileattrs/sysusers.attr
@@ -0,0 +1,18 @@
+%__sysusers_path ^%{_sysusersdir}/.*\\.conf$
+
+# Create user(name) and group(name) provides for sysusers.
+# For the primary item, encode the whole sysusers entry in base64, to be
+# fed into systemd-sysusers or something else that can handle it.
+# For groups created as a side-effect, only provide the group.
+%__sysusers_provides() %{lua:
+ for line in io.lines(macros["1"]) do
+ fields = {}
+ for w in line:gmatch("%S+") do
+ table.insert(fields, w)
+ end
+ if #fields >= 2 then
+ table.insert(fields, 1, '-b')
+ print(macros.add_sysuser(fields))
+ end
+ end
+}
diff --git a/macros.in b/macros.in
index 46de05dbe..b3460b03b 100644
--- a/macros.in
+++ b/macros.in
@@ -952,6 +952,7 @@ Supplements: (%{name} = %{version}-%{release} and langpacks-%{1})\
%_includedir %{_prefix}/include
%_infodir %{_datadir}/info
%_mandir %{_datadir}/man
+%_sysusersdir %{_prefix}/lib/sysusers.d
#==============================================================================
# ---- config.guess platform macros.
@@ -1300,5 +1301,41 @@ end
%{expand:%__scm_setup_%{__scm} %{!-v:-q}}\
%{!-N:%autopatch %{-v} %{-p:-p%{-p*}}}
+# Add a sysuser user/group to a package. Takes a sysusers.d(5) line as
+# arguments, eg `%add_sysuser g mygroup 515`.
+# -b option omits the "Provides: " to support formatting the entry outside
+# spec context.
+%add_sysuser(-) %{lua:
+ if arg[1] == '-b' then
+ prefix = ''
+ table.remove(arg, 1)
+ else
+ prefix = 'Provides: '
+ end
+ if #arg < 2 then
+ error('not enough arguments')
+ end
+ if arg[1] == 'g' then
+ type = 'group'
+ elseif arg[1] == 'u' then
+ type = 'user'
+ else
+ error('invalid sysuser type: '..arg[1])
+ end
+ name = arg[2]
+ line = table.concat(arg, ' ')
+ -- \0-pad source string to avoid '=' in the output
+ llen = line:len()
+ ulen = math.ceil(4 * (llen / 3))
+ plen = 4 * math.ceil(llen / 3)
+ pad = string.rep('\\0', plen-ulen)
+ enc = rpm.b64encode(line..pad, 0);
+
+ print(string.format('%s%s(%s) = %s\\n', prefix, type, name, enc))
+ if type == 'user' then
+ print(string.format('%s%s(%s)\\n', prefix, 'group', name))
+ end
+}
+
# \endverbatim
#*/