1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
|
#!/usr/bin/perl
# dh_sysuser --- debhelper to create system users
# Copyright (C) 2016—2019 Dmitry Bogatov <kaction@sagulo>
# Copyright (C) 2020-2024 Lorenzo Puliti <plorenzo@disroot.org>
# Author: Dmitry Bogatov <kaction@sagulo>
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
use 5.014;
use strict;
use Debian::Debhelper::Dh_Lib;
use File::Find;
use File::stat;
use feature 'signatures';
use feature 'switch';
no warnings 'experimental::signatures';
no warnings 'experimental::smartmatch';
our $VERSION = "1.6.0";
init();
sub parse_options($conf, $options, $user) {
foreach my $opt (split(/,/, $options)) {
for ($opt) {
if (/^home=(.*)$/) { $conf->{home} = $1; }
elsif (/^home$/) {
my $normal = $user;
$normal =~ s/^_+//; # strip leading
$normal =~ s/_+$//; # and trailing underscore
$normal =~ s/^[Dd]ebian-//; # and discouraged debian- prefix
$conf->{home} = "/var/lib/$normal";
}
elsif (/^defaults$/) { "do nothing"; }
else { error("unknown option `$opt'"); }
}
}
}
foreach my $pkg (@{$dh{DOPACKAGES}}) {
my $tmp = tmpdir($pkg);
my $sysusersdir = "$tmp/usr/lib/sysusers.d";
my $minsysusers = pkgfile($pkg, 'minsysusers');
if ($minsysusers eq '') {
# start DEPRECATED section, remove this after trixie release
my @entries = ();
if (@ARGV) {
while (@ARGV) {
(my $user, my $opt) = splice(@ARGV, 0, 2);
push @entries, [$user, $opt];
}
} elsif (my $cfg = pkgfile($pkg, 'sysuser')) {
@entries = filedoublearray($cfg);
};
next unless @entries;
foreach my $entry (@entries) {
warning("using legacy and deprecated sysuser format, please switch to the new");
warning("minsysusers format or use debhelper's dh_installsysusers instead");
warning("support for the legacy sysuser format is scheduled for removal after trixie release");
(my $user, my $opts) = @$entry;
$opts ||= 'defaults';
my %conf = (home => '/nonexistent');
parse_options(\%conf, $opts, $user);
foreach my $script (qw/postrm postinst/) {
autoscript($pkg, $script, "$script-sysuser",
sub { s/%HOME%/$conf{home}/;
s/%PACKAGE%/$pkg/;
s/%USERNAME%/$user/;});
}
#systemd sysusers.d compat layer
#my $tmp = tmpdir($pkg);
#my $sysusersdir = "$tmp/usr/lib/sysusers.d";
my $sysusersdconf = "$sysusersdir/$pkg.conf";
install_dir($sysusersdir);
open(my $fh, '>>', $sysusersdconf) or die $!;
print $fh "u $user - \"created by dh_sysuser for $pkg \" $conf{home}\n";
close $fh;
}
# 1.3.3 is the first version compatible with current (1.4.1) version
# >=1.4.0 would be better but since recent versions of the package
# imposed <<.1.4.0, a dependency on a more relaxed version is needed
addsubstvar($pkg, 'misc:Depends', 'sysuser-helper', '>= 1.3.3');
#end DEPRECATED section
} else {
install_dir($sysusersdir);
install_file($minsysusers, "$sysusersdir/$pkg.conf");
autoscript($pkg, 'postinst', 'postinst-minsysusers', sub { s/#CONFILE_SYSUSERS#/$pkg.conf/;});
#1.6= first version with minsysusers format
addsubstvar($pkg, 'misc:Depends', 'sysuser-helper', '>= 1.6');
}
}
# PROMISE: DH NOOP WITHOUT pkgfile(sysuser) pkgfile(minsysusers)
=head1 NAME
dh_sysuser - manage system users required for package operation
=head1 SYNOPSIS
B<dh_sysuser> [S<I<debhelper options>>] [I<username> I<options>] ...
=head1 DESCRIPTION
B<dh_sysuser> is an alternative to the more popular dh_installsysusers
addon; dh_sysuser is a debhelper addon providing a simple way to create
system users required for package operation (for example, to run a service
with dropped privileges).
Compared to dh_installsysusers, B<dh_sysuser> injects a different dependency
that plays nice with alternative init systems, non-linux ports or initless systems.
Packages builded with dh_sysuser will still work fine under systemd at the cost of
an additional dependency (sysuser-helper).
B<dh_sysuser> should not be used when the upstream source provides
a sysusers.d conf file already installed in /usr/lib/sysusers.d/; for such cases
please use dh_installsysusers.
The user creation itself is delegated to a systemd-sysusers provider, with
a fallback to the minsysusers(8) utility for systems where a systemd-sysuser
provider is not available.
=over
=item *
The primary group of the new user is created with the same name as the
user. The new users will not be a member of any other group except the
primary one.
=item *
New users have the F</etc/shadow> password field set to '!', making it
impossible to log in.
=item *
By default new users have the shell set to F</usr/sbin/nologin>. It is still possible
to get a new user's shell with I<su -s>.
=item *
The default home directory is set to /; if a different home is chosen, the home directory
is created (see below), its permissions are adjusted according to the B<SYS_DIR_MODE>
variable in F</etc/adduser.conf>. By default, this results in the mode 0755 for the home
directory.Files from F</etc/skel> are I<NOT> copied.
B<WARNING:> The data stored in new user's home directory are world-readable.
If you (as package maintainer) need full control over home directory permissions,
please file a bug.
=item *
It's possible to override the default setting for user's home and shell, add
a GECOS comment and set the user's UID. Please see sysusers.d(5) format.
=back
B<dh_sysuser> looks for a F<debian/I<package>.F<minsysusers>> file,
if one exists, and installs it as F</usr/lib/sysusers.d/package.conf>; then
it adds a postinstall snippet code to make sure that the user is created at
package postinstall.
The F<debian/I<package>.F<minsysusers>> file is expected to follow
the sysusers.d(5) conf file specification.
=over
=back
=head2 CRUFT OF SYSTEM USERS
Creating a system user (or a user in general) is easy, but safely removing one
is hard. Former version of this package used to remove users on purge when
home was set to /nonexistent or was empty; however a user may be allowed to
write files outside his home, and since UIDs are reusable, this may represent a
security risk.
With the current version of this package users are never removed automatically.
=head1 EXAMPLES
With the following F<debian/I<package>.F<minsysusers>> control file, you get
respectively:
u foo - "foo user" /nonexistent -
g bar -
m baz gname
a system user B<foo> with a gecos comment "foo user" and home set to
/nonexistent: the B<foo> group will be also created;
a system group B<bar>;
add gname group as supplementary group of baz user.
=head1 SEE ALSO
useradd(8), groupadd(8), usermod(8)
=cut
|