[Pkg-shadow-devel] [Git][debian/adduser][adduser-encrypt-home] 9 commits: sanitize log output
Marc Haber (@zugschlus)
gitlab at salsa.debian.org
Mon Jun 1 14:04:18 BST 2026
Marc Haber pushed to branch adduser-encrypt-home at Debian / adduser
Commits:
2230a04e by Marc Haber at 2026-06-01T14:56:45+02:00
sanitize log output
Some UTF-8 chars break log output in testing
- - - - -
d27407e3 by Marc Haber at 2026-06-01T14:56:45+02:00
have which return undef if the program is not found
This should not change anything since this code path was
previously unused.
- - - - -
aaf0a620 by Marc Haber at 2026-06-01T14:57:54+02:00
change logic and return values
0 means okay, != 0 means something wrong (meaningful return value)
Improve error message.
That also means that the callers must turn their logic around.
- - - - -
22a745ef by Marc Haber at 2026-06-01T14:57:56+02:00
better output in skel.t
Git-Dch: ignore
- - - - -
0c2ac9bc by Dustin Kirkland at 2026-06-01T14:58:19+02:00
Add support for encrypting home directories
* adduser: Add --encrypt-home option, which calls ecryptfs-setup-private
for the hard work.
* doc/adduser.8: document the --encrypt-home option
* debian/control: suggest ecryptfs-utils >= 67-1
* deluser: remove all of /var/lib/ecryptfs/$user with --remove-home
- - - - -
81291b8a by Mateus Rodrigues de Morais at 2026-06-01T14:58:20+02:00
Add encrypted home tests with isolation-machine restriction
- - - - -
15757249 by Marc Haber at 2026-06-01T14:58:20+02:00
also execute ecryptfs test without ecryptfs-utils installed
Git-Dch: ignore
- - - - -
56b1ab4c by Marc Haber at 2026-06-01T14:58:20+02:00
hike up module version number to 3.157
Git-Dch: ignore
- - - - -
cf1bbcd9 by Marc Haber at 2026-06-01T14:58:20+02:00
add encrypt_home_no_package
We test whether adduser --encrypt-home fails correctly when
the ecryptfs package is not installed.
- - - - -
13 changed files:
- AdduserCommon.pm
- AdduserCreateHomedir.pm
- AdduserLogging.pm
- AdduserRetvalues.pm
- AdduserStatefile.pm
- adduser
- debian/control
- debian/tests/control
- + debian/tests/ecryptfs-no-package/encrypt_home_no_package.t
- + debian/tests/ecryptfs/encrypt_home.t
- debian/tests/f/skel.t
- deluser
- doc/adduser.8
Changes:
=====================================
AdduserCommon.pm
=====================================
@@ -1,4 +1,4 @@
-package Debian::AdduserCommon 3.139;
+package Debian::AdduserCommon 3.157;
use 5.36.0;
use utf8;
@@ -29,12 +29,12 @@ use parent qw(Exporter);
use Fcntl qw(:flock SEEK_END);
my $codeset;
-use Debian::AdduserLogging 3.139;
-use Debian::AdduserRetvalues 3.139;
-use Debian::AdduserStatefile 3.139;
+use Debian::AdduserLogging 3.157;
+use Debian::AdduserRetvalues 3.157;
+use Debian::AdduserStatefile 3.157;
BEGIN {
- if ( Debian::AdduserLogging->VERSION != version->declare('3.139') ||
- Debian::AdduserRetvalues->VERSION != version->declare('3.139') ) {
+ if ( Debian::AdduserLogging->VERSION != version->declare('3.157') ||
+ Debian::AdduserRetvalues->VERSION != version->declare('3.157') ) {
die "wrong module version in adduser, check your packaging or path";
}
local $ENV{PERL_DL_NONLAZY}=1;
@@ -482,7 +482,7 @@ sub which {
log_fatal( mtx("Could not find program named `%s' in \$PATH."), $progname );
exit( RET_EXEC_NOT_FOUND );
}
- return 0;
+ return undef;
}
=====================================
AdduserCreateHomedir.pm
=====================================
@@ -1,10 +1,12 @@
-package Debian::AdduserCreateHomedir 3.139;
+package Debian::AdduserCreateHomedir 3.157;
use 5.36.0;
use utf8;
use strict;
use warnings;
-use Debian::AdduserLogging 3.139;
+use Debian::AdduserLogging 3.157;
+use Debian::AdduserCommon 3.157;
+use Debian::AdduserRetvalues 3.157;
# Adduser module to create home dir and to copy skel
#
@@ -22,24 +24,35 @@ use vars qw(@EXPORT $VAR1);
sub create_homedir {
my %params = @_;
+ my $new_name = $params{new_name};
my $home_dir = $params{home_dir};
my $new_uid = $params{uid};
my $primary_gid = $params{gid};
my $copy_skeleton = $params{copy_skeleton};
my $system_user = $params{system_user};
my $no_create_home = $params{no_create_home};
+ my $encrypt_home = $params{encrypt_home};
my $config = $params{config};
log_trace("create_homedir(home_dir=%s, new_uid=%s, primary_gid=%s, copy_skeleton=%s, system_user=%s, no_create_home=%s", $home_dir, $new_uid, $primary_gid, $copy_skeleton, $system_user, $no_create_home);
+ my $ecryptfs_setup_private;
+ if (defined($encrypt_home)) {
+ $ecryptfs_setup_private = &which('ecryptfs-setup-private', 1);
+ unless (defined $ecryptfs_setup_private) {
+ log_fatal("encrypt_home set but ecryptfs-setup-private not found. Package missing?");
+ return( RET_EXEC_NOT_FOUND );
+ }
+ }
+
if ($home_dir =~ /^\/+nonexistent(\/|$)/) {
log_info(mtx("Not creating `%s'."), $home_dir);
- return 1;
+ return 0;
}
if ($no_create_home) {
log_info(mtx("Not creating home directory `%s' as requested."), $home_dir);
- return 1;
+ return 0;
}
if (-e $home_dir) {
@@ -50,19 +63,19 @@ sub create_homedir {
log_warn(mtx("Warning: The home directory `%s' does not belong to the user you are currently creating."), $home_dir);
}
}
- return 1;
+ return 0;
}
log_info(mtx("Creating home directory `%s' ..."), $home_dir);
mktree($home_dir) or do {
log_err(gtx("Couldn't create home directory `%s': %s."), $home_dir, $!);
- return 0;
+ return RET_INVALID_HOME_DIRECTORY;
};
chown($new_uid, $primary_gid, $home_dir) or do {
log_err("chown %s:%s %s: %s", $new_uid, $primary_gid, $home_dir, $!);
- return 0;
+ return RET_WRONG_OBJECT_PROPERTIES;
};
# Determine if setgid bit should be applied
@@ -81,9 +94,14 @@ sub create_homedir {
chmod($dir_mode, $home_dir) or do {
log_err("chmod %s %s: %s", $dir_mode, $home_dir, $!);
- return 0;
+ return RET_WRONG_OBJECT_PROPERTIES;
};
+ if (defined($encrypt_home)) {
+ log_info( mtx("Setting up encryption ...\n"));
+ &systemcall($ecryptfs_setup_private, '-b', '-u', $new_name);
+ }
+
if ($config->{skel} && $copy_skeleton) {
log_info(mtx("Copying files from `%s' ..."), $config->{skel});
copy_skel(
@@ -93,10 +111,14 @@ sub create_homedir {
$primary_gid,
$setgid,
$config->{skel_ignore_regex}
- ) or return 0;
+ ) and return RET_FILE_ERROR;
}
- return 1;
+ if (defined($encrypt_home)) {
+ &systemcall("/bin/umount", $home_dir);
+ }
+
+ return RET_OK;
}
sub mktree {
@@ -145,14 +167,14 @@ sub recurse_copy {
# Untaint source path (allow any bytes except / or null)
$src =~ m{^(/[^/\0]+(?:/[^/\0]+)*)$} or do {
log_err("Invalid source path: %s", $src);
- return 0;
+ return RET_INVALID_HOME_DIRECTORY;
};
$src = $1;
log_trace("Processing directory: %s", $src);
opendir(my $dh, $src) or do {
log_err("opendir %s: %s", $src, $!);
- return 0;
+ return RET_SYSTEMCALL_ERROR;
};
my @entries = grep { $_ ne '.' && $_ ne '..' && (!$ignore_re || !/$ignore_re/) } readdir($dh);
@@ -175,7 +197,7 @@ sub recurse_copy {
# Untaint destination path
$dst_path =~ m{^(/[^/\0]+(?:/[^/\0]+)*)$} or do {
log_err("Invalid destination path: %s", $dst_path);
- return 0;
+ return RET_INVALID_HOME_DIRECTORY;
};
$dst_path = $1;
log_trace("src_path=%s dst_path=%s", $src_path, $dst_path);
@@ -184,11 +206,11 @@ sub recurse_copy {
# Symlink
my $target = readlink($src_path) or do {
log_err("readlink %s: %s", $src_path, $!);
- return 0;
+ return RET_SYSTEMCALL_ERROR
};
$target =~ m{^([^/\0]+(?:/[^/\0]+)*)$} or do {
log_err("Unsafe symlink: %s", $target);
- return 0;
+ return RET_WRONG_OBJECT_PROPERTIES;
};
my ($cu, $cg) = ($>, $));
($>, $)) = ($uid, $gid);
@@ -196,8 +218,8 @@ sub recurse_copy {
my $err = $!;
($>, $)) = ($cu, $cg);
if (!$ok) {
- log_err("symlink %s: %s", $dst_path, $err);
- return 0;
+ log_err("error creating symlink %s: %s", $dst_path, $err);
+ return RET_SYSTEMCALL_ERROR;
}
log_trace("Created symlink: %s -> %s", $dst_path, $target);
@@ -205,32 +227,32 @@ sub recurse_copy {
# Directory
if (!-d $dst_path) {
mkdir($dst_path, 0700) or do {
- log_err("mkdir %s: %s", $dst_path, $!);
- return 0;
+ log_err("error in mkdir %s: %s", $dst_path, $!);
+ return RET_INVALID_HOME_DIRECTORY;
};
log_trace("Created directory: %s", $dst_path);
}
set_perms($src_path, $dst_path, $uid, $gid, $sgid) or return 0;
- recurse_copy($src_base, $dst_base, $rel ? "$rel/$entry" : $entry, $uid, $gid, $sgid, $ignore_re) or return 0;
+ recurse_copy($src_base, $dst_base, $rel ? "$rel/$entry" : $entry, $uid, $gid, $sgid, $ignore_re) and return 0;
} elsif (-f $src_path) {
# Regular file
open(my $in, '<', $src_path) or do {
- log_err("open %s: %s", $src_path, $!);
- return 0;
+ log_err("error read-opening %s: %s", $src_path, $!);
+ return RET_FILE_ERROR;
};
open(my $out, '>', $dst_path) or do {
close($in);
- log_err("open %s: %s", $dst_path, $!);
- return 0;
+ log_err("error write-opening %s: %s", $dst_path, $!);
+ return RET_FILE_ERROR;
};
binmode($in);
binmode($out);
print $out $_ while <$in>;
close($in);
close($out) or do {
- log_err("close %s: %s", $dst_path, $!);
- return 0;
+ log_err("error closing %s: %s", $dst_path, $!);
+ return RET_FILE_ERROR;
};
set_perms($src_path, $dst_path, $uid, $gid, 0) or return 0;
log_trace("Copied file: %s", $dst_path);
@@ -238,7 +260,7 @@ sub recurse_copy {
}
log_trace("Finished processing directory: %s", $src);
- return 1;
+ return RET_OK;
}
=====================================
AdduserLogging.pm
=====================================
@@ -1,4 +1,4 @@
-package Debian::AdduserLogging 3.139;
+package Debian::AdduserLogging 3.157;
use 5.36.0;
use utf8;
@@ -200,6 +200,12 @@ sub logf {
$outstring = sprintf( $fmt, @dta );
$loutstring = sprintf( gettext($fmt), @dta );
}
+ # sanitize string and indicate when sanitized.
+ # some utf-8 chars interfere with test output
+ my $changed = ($outstring =~ s/[^ -~]/_/g);
+ $outstring = "[sanitized] $outstring" if $changed;
+ $changed = ($loutstring =~ s/[^ -~]/_/g);
+ $loutstring = "[sanitized] $loutstring" if $changed;
logtrace("outstring %s", $outstring);
logtrace("loutstring %s", $loutstring);
logtrace("msglevel %s (%d), stdoutmsglevel %s (%d), stderrmsglevel %s (%d), logmsglevel %s (%d)", $msglevel, numeric_msglevel($msglevel), $stdoutmsglevel, numeric_msglevel($stdoutmsglevel), $stderrmsglevel, numeric_msglevel($stderrmsglevel), $logmsglevel, numeric_msglevel($logmsglevel));
=====================================
AdduserRetvalues.pm
=====================================
@@ -1,4 +1,4 @@
-package Debian::AdduserRetvalues 3.139;
+package Debian::AdduserRetvalues 3.157;
use 5.36.0;
use utf8;
=====================================
AdduserStatefile.pm
=====================================
@@ -1,4 +1,4 @@
-package Debian::AdduserStatefile 3.139;
+package Debian::AdduserStatefile 3.157;
use 5.36.0;
use utf8;
=====================================
adduser
=====================================
@@ -31,15 +31,15 @@ use utf8;
use Getopt::Long;
-use Debian::AdduserCommon 3.139;
-use Debian::AdduserLogging 3.139;
-use Debian::AdduserRetvalues 3.139;
-use Debian::AdduserStatefile 3.139;
-use Debian::AdduserCreateHomedir 3.139;
+use Debian::AdduserCommon 3.157;
+use Debian::AdduserLogging 3.157;
+use Debian::AdduserRetvalues 3.157;
+use Debian::AdduserStatefile 3.157;
+use Debian::AdduserCreateHomedir 3.157;
BEGIN {
- if ( Debian::AdduserCommon->VERSION != version->declare('3.139') ||
- Debian::AdduserLogging->VERSION != version->declare('3.139') ||
- Debian::AdduserRetvalues->VERSION != version->declare('3.139') ) {
+ if ( Debian::AdduserCommon->VERSION != version->declare('3.157') ||
+ Debian::AdduserLogging->VERSION != version->declare('3.157') ||
+ Debian::AdduserRetvalues->VERSION != version->declare('3.157') ) {
die "wrong module version in adduser, check your packaging or path";
}
}
@@ -113,6 +113,8 @@ my $ask_passwd = 1; # ask for a passwd?
my $disabled_login = 0; # leave the new account disabled?
our @configfiles;
+our @defaults = undef;
+our $encrypt_home = undef;
our $found_group_opt = undef;
our $found_sys_opt = undef;
our $found_unlock_opt = undef;
@@ -146,7 +148,6 @@ my $first_uid = undef;
my $last_uid = undef;
my $first_gid = undef;
my $last_gid = undef;
-my $dir_mode = undef;
my $perm = undef;
my %uid_pool;
my %gid_pool;
@@ -171,6 +172,7 @@ GetOptions(
'logmsglevel=s' => \$logmsglevel,
'disabled-login' => sub { $disabled_login = 1; $ask_passwd = 0 },
'disabled-password' => sub { $ask_passwd = 0 },
+ 'encrypt-home' => \$encrypt_home,
'firstgid=i' => \$new_firstgid,
'firstuid=i' => \$new_firstuid,
'force-badname' => sub { $name_check_level = 1 unless $name_check_level },
@@ -719,16 +721,18 @@ if ($action eq "addsysuser") {
}
$primary_gid = $gid_option;
+ $undohome = $home_dir;
create_homedir(
home_dir => $home_dir,
+ new_name => $new_name,
uid => $new_uid,
gid => $gid_option,
copy_skeleton => 0,
system_user => 1,
no_create_home => $no_create_home,
- dir_mode => $dir_mode,
+ encrypt_home => $encrypt_home,
config => \%config,
- ) or cleanup();
+ ) and cleanup();
exit( $returnvalue );
}
@@ -969,14 +973,15 @@ if ($action eq "adduser") {
create_homedir(
home_dir => $home_dir,
+ new_name => $new_name,
uid => $new_uid,
gid => $primary_gid,
copy_skeleton => $no_copy_skel ? 0 : 1,
system_user => 0,
no_create_home => $no_create_home,
- dir_mode => $dir_mode,
+ encrypt_home => $encrypt_home,
config => \%config,
- ) or cleanup();
+ ) and cleanup();
# useradd without -p has left the account disabled (password string is '!')
if ($ask_passwd) {
@@ -1508,24 +1513,6 @@ sub usage_error {
exit( RET_INVALID_CALL );
}
-# get_dir_mode: return the appropriate permissions mode for a home directory
-# parameters:
-# none
-# return value:
-# a valid octal mode
-sub get_dir_mode
- {
- my $mode = $found_sys_opt
- ? $config{"sys_dir_mode"}
- : $config{"dir_mode"};
-
- if(!defined($mode) || ! ($mode =~ /[0-7]{3}/ || $mode =~ /[0-7]{4}/)) {
- $mode = ($found_sys_opt) ? "755" : "0700";
- }
-
- return oct($mode);
- }
-
# Local Variables:
# mode:cperl
# cperl-indent-level:4
=====================================
debian/control
=====================================
@@ -14,7 +14,7 @@ Architecture: all
Multi-Arch: foreign
Pre-Depends: ${misc:Pre-Depends}
Depends: passwd (>= 1:4.19.0-4), ${misc:Depends}
-Suggests: liblocale-gettext-perl, perl, cron, quota
+Suggests: liblocale-gettext-perl, perl, cron, quota, ecryptfs-utils (>= 67-1)
Description: add and remove users and groups
This package includes the 'adduser' and 'deluser' commands for creating
and removing users.
=====================================
debian/tests/control
=====================================
@@ -3,6 +3,16 @@ Depends: adduser, cron, perl, login
Restrictions: needs-root
Features: test-name=package-test-suite
+Test-Command: /usr/bin/prove -p -v debian/tests/ecryptfs
+Depends: cron, ecryptfs-utils, kmod, perl
+Restrictions: allow-stderr isolation-machine needs-root
+Features: test-name=ecryptfs-with-pkg
+
+Test-Command: /usr/bin/prove -p -v debian/tests/ecryptfs-no-package
+Depends: cron, kmod, perl
+Restrictions: allow-stderr isolation-machine needs-root
+Features: test-name=ecryptfs-without-pkg
+
Test-Command: cd testsuite/ && ./runsuite.sh
Depends: adduser, cron, perl, login
Restrictions: allow-stderr breaks-testbed needs-root
=====================================
debian/tests/ecryptfs-no-package/encrypt_home_no_package.t
=====================================
@@ -0,0 +1,23 @@
+#! /usr/bin/perl -Idebian/tests/lib
+
+use diagnostics;
+use strict;
+use warnings;
+
+use AdduserTestsCommon;
+
+# enable ecryptfs kernel module
+system('/sbin/modprobe', 'ecryptfs');
+
+my $test_user="foocrypt";
+
+assert_user_does_not_exist($test_user);
+
+assert_command_failure('/usr/sbin/adduser', '--encrypt-home', $test_user);
+
+system("getent passwd $test_user");
+system("ls -l /home /home/$test_user");
+
+assert_user_does_not_exist($test_user);
+
+assert_path_does_not_exist("/home/$test_user");
=====================================
debian/tests/ecryptfs/encrypt_home.t
=====================================
@@ -0,0 +1,31 @@
+#! /usr/bin/perl -Idebian/tests/lib
+
+use diagnostics;
+use strict;
+use warnings;
+
+use AdduserTestsCommon;
+
+# enable ecryptfs kernel module
+system('/sbin/modprobe', 'ecryptfs');
+
+my $test_user="foocrypt";
+
+assert_user_does_not_exist($test_user);
+
+assert_command_success('/usr/sbin/adduser', '--encrypt-home', $test_user);
+
+assert_user_exists($test_user);
+assert_group_exists($test_user);
+assert_group_membership_exists($test_user, $test_user);
+
+# test for ecryptfs files stored in $HOME
+assert_path_exists("/home/$test_user/.ecryptfs");
+assert_path_exists("/home/$test_user/.Private");
+# and not stored in $HOME
+assert_path_exists("/home/.ecryptfs/$test_user");
+
+assert_command_success('/usr/sbin/deluser', '--remove-home', $test_user);
+assert_user_does_not_exist($test_user);
+assert_path_does_not_exist("/home/$test_user");
+assert_path_does_not_exist("/home/.ecryptfs/$test_user");
\ No newline at end of file
=====================================
debian/tests/f/skel.t
=====================================
@@ -45,9 +45,13 @@ my $skel_list = `find /etc/skel/ -mindepth 1 -printf "%f %l %m %s\n" | sort`;
my $home_list = `find /home/$name/ -mindepth 1 -printf "%f %l %m %s\n" | sort`;
ok($? == 0, "find /home/$name successful");
if( !ok($home_list eq $skel_list, 'files copied to home directory correct') ) {
+ print("locale\n");
+ system("locale");
print("skel_list: $skel_list\n");
- print("home_list $home_list\n");
+ print("home_list: $home_list\n");
+ print("ls /etc/skel\n");
system("ls -al /etc/skel");
+ print("ls /home/$name\n");
system("ls -al /home/$name");
}
=====================================
deluser
=====================================
@@ -25,14 +25,14 @@ use utf8;
use Getopt::Long;
-use Debian::AdduserCommon 3.139;
-use Debian::AdduserLogging 3.139;
-use Debian::AdduserRetvalues 3.139;
-use Debian::AdduserStatefile 3.139;
+use Debian::AdduserCommon 3.157;
+use Debian::AdduserLogging 3.157;
+use Debian::AdduserRetvalues 3.157;
+use Debian::AdduserStatefile 3.157;
BEGIN {
- if ( Debian::AdduserCommon->VERSION != version->declare('3.139') ||
- Debian::AdduserLogging->VERSION != version->declare('3.139') ||
- Debian::AdduserRetvalues->VERSION != version->declare('3.139') ) {
+ if ( Debian::AdduserCommon->VERSION != version->declare('3.157') ||
+ Debian::AdduserLogging->VERSION != version->declare('3.157') ||
+ Debian::AdduserRetvalues->VERSION != version->declare('3.157') ) {
die "wrong module version in adduser, check your packaging or path";
}
}
@@ -387,8 +387,28 @@ if($action eq "deluser") {
if(-d $name);
} # sub home_match
+ # collect ecryptfs config files not stored in $HOME
+ sub ecryptfs_match {
+ # untaint the name without changing it
+ $File::Find::name =~ /(.*)/s; # captures the full string
+ $name = $1;
+ if ( $name !~ m[^/var/lib/ecryptfs/\Q$user] && $name !~ m[^/home/\.ecryptfs/\Q$user]) {
+ $File::Find::prune=1;
+ return;
+ }
+ push(@files, $name)
+ if(-f $name || -l $name);
+ push(@dirs, $name)
+ if(-d $name);
+ } # sub ecryptfs_match
+
File::Find::find({wanted => \&home_match, untaint => 1, no_chdir => 1}, $pw_homedir)
if(-d "$pw_homedir");
+ if(-d "/var/lib/ecryptfs/$user") {
+ File::Find::find({wanted => \&ecryptfs_match, untaint => 1, no_chdir => 1}, "/var/lib/ecryptfs/$user");
+ } elsif (-d "/home/.ecryptfs/$user") {
+ File::Find::find({wanted => \&ecryptfs_match, untaint => 1, no_chdir => 1}, "/home/.ecryptfs/$user");
+ }
push(@files, "/var/mail/$user")
if(-e "/var/mail/$user");
}
=====================================
doc/adduser.8
=====================================
@@ -26,6 +26,7 @@ adduser, addgroup \- add or manipulate users or groups
.OP \-\-debug
.OP \-\-disabled\-login
.OP \-\-disabled\-password
+.OP \-\-encrypt\-home
.OP \-\-firstgid id
.OP \-\-firstuid id
.OP \-\-gid id
@@ -226,6 +227,11 @@ might be pre-determined with the \fBUID_POOL\fP and \fBGID_POOL\fP option,
documented in
.BR adduser.conf (5).
+To set up an encrypted home directory for the new user, add the
+.B \-\-encrypt\-home
+option. For more information, refer to the \-b option of
+.B ecryptfs-setup-private(1).
+
.SS "Add a system user"
If called with one non-option argument and the \fB\-\-system\fP option,
\fBadduser\fP will add a
View it on GitLab: https://salsa.debian.org/debian/adduser/-/compare/29ac4c535be9a92143933e2290f3bd0742c4e27a...cf1bbcd9d0f5739f0c49d296f2a400cd8f3b31f4
--
View it on GitLab: https://salsa.debian.org/debian/adduser/-/compare/29ac4c535be9a92143933e2290f3bd0742c4e27a...cf1bbcd9d0f5739f0c49d296f2a400cd8f3b31f4
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-shadow-devel/attachments/20260601/7979193b/attachment-0001.htm>
More information about the Pkg-shadow-devel
mailing list