File: dh_sysuser

package info (click to toggle)
dh-sysuser 1.6.0
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 124 kB
  • sloc: perl: 437; sh: 42; makefile: 5
file content (210 lines) | stat: -rwxr-xr-x 7,610 bytes parent folder | download
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