[Pkg-shadow-devel] [Git][debian/adduser][master] 8 commits: introduce new systemcall_useradd
Marc Haber (@zugschlus)
gitlab at salsa.debian.org
Wed Feb 19 17:41:07 GMT 2025
Marc Haber pushed to branch master at Debian / adduser
Commits:
cb02adde by Marc Haber at 2025-02-19T16:40:34+01:00
introduce new systemcall_useradd
- - - - -
d1d011ef by Marc Haber at 2025-02-19T16:40:57+01:00
fix variable names in systemcall and systemcall_or_warn
Git-Dch: ignore
- - - - -
cc406d31 by Marc Haber at 2025-02-19T18:09:15+01:00
use systemcall_useradd
Git-Dch: ignore
- - - - -
a436c8f4 by Marc Haber at 2025-02-19T18:09:17+01:00
use systemcall instead of &systemcall
Git-Dch: ignore
- - - - -
2d904580 by Marc Haber at 2025-02-19T18:09:17+01:00
use systemcall instead of @systemcall
Git-Dch: ignore
- - - - -
561b7c9b by Marc Haber at 2025-02-19T18:09:17+01:00
re-work call of passwd and exit code evaluation
Git-Dch: ignore
- - - - -
168d0a5d by Marc Haber at 2025-02-19T18:09:17+01:00
fixup! introduce new systemcall_useradd
- - - - -
f9a73dfc by Marc Haber at 2025-02-19T18:09:45+01:00
eliminate more of & function calls
Git-Dch: ignore
- - - - -
3 changed files:
- AdduserCommon.pm
- adduser
- deluser
Changes:
=====================================
AdduserCommon.pm
=====================================
@@ -77,6 +77,7 @@ use constant {
'get_group_members',
'read_config',
'read_pool',
+ 'systemcall_useradd',
'systemcall',
'systemcall_or_warn',
'systemcall_silent',
@@ -305,15 +306,46 @@ sub get_group_members
return @members;
}
+sub systemcall_useradd {
+ my $name_check_level = shift;
+ my $command = join(' ', @_);
+ my $ret;
+ log_debug( "executing systemcall_useradd (%s): %s", $name_check_level, $command );
+ $ret = system(@_);
+ if ($ret != 0) {
+ my $exitcode = $ret>>8;
+ if ($exitcode != 0) {
+ if ($exitcode == 19 ) {
+ # we should never get here. It is our expectation that we catch
+ # an invalid user name before useradd gets to reject it. So
+ # we consider getting here a bug in our regexps. We can safely
+ # bomb out here.
+ if( $name_check_level == 2 ) {
+ log_warn( mtx("`%s' refused the given user name, but --allow-all-names is given. Continueing."), $command );
+ return( RET_INVALID_NAME_FROM_USERADD );
+ } else {
+ log_err( mtx("`%s' refused the given user name. This is a bug in adduser. Please file a bug report."), $command );
+ exit( RET_INVALID_NAME_FROM_USERADD );
+ };
+ } else {
+ log_fatal( mtx("`%s' returned error code %d. Exiting."), $command, $exitcode );
+ exit( RET_SYSTEMCALL_ERROR );
+ }
+ }
+ log_fatal( mtx("`%s' exited from signal %d. Exiting."), $command, $ret&127 );
+ exit( RET_SYSTEMCALL_SIGNAL );
+ }
+}
+
sub systemcall {
- my $c = join(' ', @_);
+ my $command = join(' ', @_);
log_debug( "executing systemcall: %s", $command );
if (system(@_)) {
if ($?>>8) {
- log_fatal( mtx("`%s' returned error code %d. Exiting."), $c, $?>>8 );
+ log_fatal( mtx("`%s' returned error code %d. Exiting."), $command, $?>>8 );
exit( RET_SYSTEMCALL_ERROR );
}
- log_fatal( mtx("`%s' exited from signal %d. Exiting."), $c, $?&127 );
+ log_fatal( mtx("`%s' exited from signal %d. Exiting."), $command, $?&127 );
exit( RET_SYSTEMCALL_SIGNAL );
}
}
@@ -322,16 +354,17 @@ sub systemcall_or_warn {
my $command = join(' ', @_);
log_debug( "executing systemcall_or_warn: %s", $command );
system(@_);
+ my $ret = $?;
- if ($? == -1) {
+ if ($ret == -1) {
log_warn( mtx("`%s' failed to execute. %s. Continuing."), $command, $! );
} elsif ($? & 127) {
- log_warn( mtx("`%s' killed by signal %d. Continuing."), $command, ($? & 127) );
+ log_warn( mtx("`%s' killed by signal %d. Continuing."), $command, ($ret & 127) );
} elsif ($? >> 8) {
- log_warn( mtx("`%s' failed with status %d. Continuing."), $command, ($? >> 8) );
+ log_warn( mtx("`%s' failed with status %d. Continuing."), $command, ($ret >> 8) );
}
- return $?;
+ return $ret;
}
sub systemcall_silent {
=====================================
adduser
=====================================
@@ -128,6 +128,7 @@ my %uid_pool;
my %gid_pool;
my %reserved_uid_pool;
my %reserved_gid_pool;
+my $returnvalue = RET_OK;
our @names;
@@ -458,10 +459,13 @@ if ($action eq "addsysgroup") {
log_info( mtx("Adding group `%s' (GID %d) ..."), $new_name, $gid_option);
- my $groupadd = &which('groupadd');
- &systemcall($groupadd, '-g', $gid_option, $new_name);
+ my $groupadd = which('groupadd');
+ $ret = systemcall_useradd($name_check_level, $groupadd, '-g', $gid_option, $new_name);
+ if( $ret == RET_INVALID_NAME_FROM_USERADD ) {
+ $returnvalue = RET_INVALID_NAME_FROM_USERADD;
+ }
release_lock(0);
- exit( RET_OK );
+ exit( $returnvalue );
}
@@ -500,10 +504,13 @@ if ($action eq "addgroup") {
}
log_info( mtx("Adding group `%s' (GID %d) ..."), $new_name, $gid_option);
- my $groupadd = &which('groupadd');
- &systemcall($groupadd, '-g', $gid_option, $new_name);
+ my $groupadd = which('groupadd');
+ my $ret = systemcall_useradd($name_check_level, $groupadd, '-g', $gid_option, $new_name);
+ if( $ret == RET_INVALID_NAME_FROM_USERADD ) {
+ $returnvalue = RET_INVALID_NAME_FROM_USERADD;
+ }
release_lock(0);
- exit( RET_OK );
+ exit( $returnvalue );
}
@@ -529,10 +536,10 @@ if ($action eq 'addusertogroup') {
log_info( mtx("Adding user `%s' to group `%s' ..."), $existing_user, $existing_group );
acquire_lock();
- &systemcall('/usr/sbin/usermod', '-a', '-G', $existing_group, $existing_user);
+ systemcall('/usr/sbin/usermod', '-a', '-G', $existing_group, $existing_user);
release_lock();
- exit( RET_OK );
+ exit( $returnvalue );
}
################
@@ -615,8 +622,11 @@ if ($action eq "addsysuser") {
if ($make_group_also && !egetgrnam($new_name)) {
log_info( mtx("Adding new group `%s' (GID %d) ..."), $new_name, $gid_option );
$undogroup = $new_name;
- my $groupadd = &which('groupadd');
- &systemcall($groupadd, '-g', $gid_option, $new_name);
+ my $groupadd = which('groupadd');
+ my $ret = systemcall_useradd($name_check_level, $groupadd, '-g', $gid_option, $new_name);
+ if( $ret == RET_INVALID_NAME_FROM_USERADD ) {
+ $returnvalue = RET_INVALID_NAME_FROM_USERADD;
+ }
}
log_info( mtx("Adding new user `%s' (UID %d) with group `%s' ..."),
@@ -627,7 +637,10 @@ if ($action eq "addsysuser") {
$shell = $special_shell || $uid_pool{$new_name}{'shell'} || '/usr/sbin/nologin';
$undouser = $new_name;
- &systemcall('/usr/sbin/useradd', '-r',
+ my $useradd = which('useradd');
+ my $ret = systemcall_useradd($name_check_level,
+ $useradd,
+ '-r',
'-K', sprintf('SYS_UID_MIN=%d', $new_firstuid || $config{'first_system_uid'}),
'-K', sprintf('SYS_UID_MAX=%d', $new_lastuid || $config{'last_system_uid'}),
'-d', $home_dir,
@@ -635,20 +648,22 @@ if ($action eq "addsysuser") {
'-s', $shell,
'-u', $new_uid,
$new_name);
- ##+# TODO: Catch exit code 19 "invalid user name"
+ if( $ret == RET_INVALID_NAME_FROM_USERADD ) {
+ $returnvalue = RET_INVALID_NAME_FROM_USERADD;
+ }
release_lock(0);
if (defined($new_comment)) {
- &ch_comment($new_comment);
+ ch_comment($new_comment);
} elsif ($uid_pool{$new_name}{'comment'}) {
- &ch_comment($uid_pool{$new_name}{'comment'});
+ ch_comment($uid_pool{$new_name}{'comment'});
}
$primary_gid = $gid_option;
create_homedir(0);
- exit( RET_OK );
+ exit( $returnvalue );
}
@@ -835,16 +850,20 @@ if ($action eq "adduser") {
log_debug ("make_group_also %s", $make_group_also );
if ($make_group_also) {
$undogroup = $new_name;
- my $groupadd = &which('groupadd');
+ my $groupadd = which('groupadd');
+ my $ret;
if( defined( $primary_gid ) ) {
log_info( mtx("Adding new group `%s' (%d) ..."), $new_name, $primary_gid);
- &systemcall($groupadd, '-g', $primary_gid, $new_name);
+ $ret = systemcall_useradd($name_check_level, $groupadd, '-g', $primary_gid, $new_name);
} else {
log_info( mtx("Adding new group `%s' (new group ID) ..."), $new_name);
- &systemcall($groupadd, $new_name);
+ $ret = systemcall_useradd($name_check_level, $groupadd, $new_name);
$primary_gid = egetgrnam($new_name);
log_info( mtx("new group '%s' created with GID %d"), $new_name, $primary_gid );
}
+ if( $ret == RET_INVALID_NAME_FROM_USERADD ) {
+ $returnvalue = RET_INVALID_NAME_FROM_USERADD;
+ }
}
{
@@ -860,10 +879,17 @@ if ($action eq "adduser") {
}
log_debug( "creating new user %s with home_dir %s and shell %s", $new_name, $home_dir, $shell );
$undouser = $new_name;
- my $useradd = &which('useradd');
- &systemcall($useradd, '-d', $home_dir, '-g', $primary_gid, '-s',
- $shell, '-u', $new_uid, $new_name);
- ##+# TODO: Catch exit code 19 "invalid user name"
+ my $useradd = which('useradd');
+ my $ret = systemcall_useradd($name_check_level,
+ $useradd,
+ '-d', $home_dir,
+ '-g', $primary_gid,
+ '-s', $shell,
+ '-u', $new_uid,
+ $new_name);
+ if( $ret == RET_INVALID_NAME_FROM_USERADD ) {
+ $returnvalue = RET_INVALID_NAME_FROM_USERADD;
+ }
create_homedir (1); # copy skeleton data
@@ -872,20 +898,30 @@ if ($action eq "adduser") {
my $noexpr = langinfo(NOEXPR());
if ($ask_passwd) {
PASSWD: for (;;) {
- my $passwd = &which('passwd');
- # do _not_ use systemcall() here, since systemcall() dies on
- # non-zero exit code and we need to do special handling here!
- system($passwd, $new_name);
- my $ok = $?>>8;
+ my $passwd = which('passwd');
+ my $ok = systemcall_or_warn($passwd, $new_name);
+ $ok = $ok >> 8;
+ log_debug( "systemcall_or_warn %s %s return value %s", $passwd, $new_name, $ok);
if ($ok != 0) {
my $answer;
# hm, error, should we break now?
- log_warn( mtx("Permission denied")) if ($ok == 1);
- log_warn( mtx("invalid combination of options")) if ($ok == 2);
- log_warn( mtx("unexpected failure, nothing done")) if ($ok == 3);
- log_warn( mtx("unexpected failure, passwd file missing")) if ($ok == 4);
- log_warn( mtx("passwd file busy, try again")) if ($ok == 5);
- log_warn( mtx("invalid argument to option")) if ($ok == 6);
+ if ($ok == 1) {
+ log_warn( mtx("Permission denied"));
+ } elsif ($ok == 2) {
+ log_warn( mtx("invalid combination of options"));
+ } elsif ($ok == 3) {
+ log_warn( mtx("unexpected failure, nothing done"));
+ } elsif ($ok == 4) {
+ log_warn( mtx("unexpected failure, passwd file missing"));
+ } elsif ($ok == 5) {
+ log_warn( mtx("passwd file busy, try again"));
+ } elsif ($ok == 6) {
+ log_warn( mtx("invalid argument to option"));
+ } elsif ($ok == 10) {
+ log_warn( mtx("wrong password given or password retyped incorrectly"));
+ } else {
+ log_warn( mtx("unexpected return code %s given from passwd"), $ok );
+ }
# Translators: [y/N] has to be replaced by values defined in your
# locale. You can see by running "locale noexpr" which regular
@@ -904,15 +940,15 @@ if ($action eq "adduser") {
}
if (defined($new_comment)) {
- &ch_comment($new_comment);
+ ch_comment($new_comment);
} elsif ($uid_pool{$new_name}{'comment'}) {
- &ch_comment($uid_pool{$new_name}{'comment'});
+ ch_comment($uid_pool{$new_name}{'comment'});
} else {
my $noexpr = langinfo(NOEXPR());
my $yesexpr = langinfo(YESEXPR());
CHFN: for (;;) {
my $chfn = &which('chfn');
- &systemcall($chfn, $new_name);
+ systemcall($chfn, $new_name);
# Translators: [y/N] has to be replaced by values defined in your
# locale. You can see by running "locale yesexpr" which regular
# expression will be checked to find positive answer.
@@ -947,7 +983,7 @@ if ($action eq "adduser") {
log_info( mtx("Adding user `%s' to group `%s' ..."), $new_name, $newgrp );
my $gpasswd = &which('gpasswd');
- &systemcall($gpasswd, '-M',
+ systemcall($gpasswd, '-M',
join(',', get_group_members($newgrp), $new_name),
$newgrp);
}
@@ -957,14 +993,14 @@ if ($action eq "adduser") {
if ($config{"quotauser"}) {
log_info( mtx("Setting quota for user `%s' to values of user `%s' ..."), $new_name, $config{quotauser} );
my $edquota = &which('edquota');
- &systemcall($edquota, '-p', $config{quotauser}, $new_name);
+ systemcall($edquota, '-p', $config{quotauser}, $new_name);
}
- &systemcall('/usr/local/sbin/adduser.local', $new_name, $new_uid,
+ systemcall('/usr/local/sbin/adduser.local', $new_name, $new_uid,
$primary_gid, $home_dir) if (-x "/usr/local/sbin/adduser.local");
release_lock(0);
- exit( RET_OK );
+ exit( $returnvalue );
}
#
@@ -1424,15 +1460,15 @@ sub ch_comment {
my($comment_name,$comment_room,$comment_work,$comment_home,$comment_other)
= split(/,/,$comment);
- &systemcall($chfn, '-f', $comment_name, '-r', $comment_room, $new_name);
- &systemcall($chfn,'-w',$comment_work,$new_name)
+ systemcall($chfn, '-f', $comment_name, '-r', $comment_room, $new_name);
+ systemcall($chfn,'-w',$comment_work,$new_name)
if(defined($comment_work));
- &systemcall($chfn,'-h',$comment_home,$new_name)
+ systemcall($chfn,'-h',$comment_home,$new_name)
if(defined($comment_home));
- &systemcall($chfn,'-o',$comment_other,$new_name)
+ systemcall($chfn,'-o',$comment_other,$new_name)
if(defined($comment_other));
} else {
- &systemcall($chfn, '-f', $comment, $new_name);
+ systemcall($chfn, '-f', $comment, $new_name);
}
}
@@ -1449,15 +1485,15 @@ sub user_is_member {
sub cleanup {
if ($undohome) {
log_info( mtx("Removing directory `%s' ..."), $undohome);
- &systemcall('rm', '-rf', $undohome);
+ systemcall('rm', '-rf', $undohome);
}
if ($undouser) {
log_info( mtx("Removing user `%s' ..."), $undouser);
- &systemcall('userdel', $undouser);
+ systemcall('userdel', $undouser);
}
if ($undogroup) {
log_info( mtx("Removing group `%s' ..."), $undogroup);
- &systemcall('groupdel', $undogroup);
+ systemcall('groupdel', $undogroup);
}
exit( RET_ADDUSER_ABORTED );
}
=====================================
deluser
=====================================
@@ -376,7 +376,7 @@ if($action eq "deluser") {
$backup_name .= $config{'backup_suffix'};
$backup_name = sanitize_string( $backup_name, simplepathre );
log_debug( "backup_name = %s", $backup_name );
- &systemcall($tar, "--directory", "/", "--auto-compress", "-cf", $backup_name, "--files-from", $filesfilename);
+ systemcall($tar, "--directory", "/", "--auto-compress", "-cf", $backup_name, "--files-from", $filesfilename);
chmod 0600, $backup_name;
my $rootid = 0;
chown $rootid, $rootid, $backup_name;
@@ -395,8 +395,8 @@ if($action eq "deluser") {
if (-x '/usr/bin/crontab') {
log_info( mtx("Removing crontab ...") );
- if (&systemcall_silent('/usr/bin/crontab', '-u', $user, '-l') == 0) {
- &systemcall_or_warn('/usr/bin/crontab', '-u', $user, '-r');
+ if (systemcall_silent('/usr/bin/crontab', '-u', $user, '-l') == 0) {
+ systemcall_or_warn('/usr/bin/crontab', '-u', $user, '-r');
}
} else {
log_warn( mtx("`%s' not executed. Skipping crontab removal. Package `cron' required."),
@@ -405,10 +405,10 @@ if($action eq "deluser") {
log_info( mtx("Removing user `%s' ..."), $user);
acquire_lock();
- &systemcall('/usr/sbin/userdel', $user);
+ systemcall('/usr/sbin/userdel', $user);
release_lock();
- &systemcall('/usr/local/sbin/deluser.local', $user, $pw_uid,
+ systemcall('/usr/local/sbin/deluser.local', $user, $pw_uid,
$pw_gid, $pw_homedir) if (-x "/usr/local/sbin/deluser.local");
exit( RET_OK );
@@ -448,7 +448,7 @@ if ($action eq 'delgroup') {
log_info( mtx("Removing group `%s' ..."), $group );
my $groupdel = &which('groupdel');
acquire_lock();
- &systemcall($groupdel,$group);
+ systemcall($groupdel,$group);
release_lock();
exit 0;
}
@@ -490,7 +490,7 @@ if($action eq 'deluserfromgroup')
log_info( mtx("Removing user `%s' from group `%s' ..."), $user, $group );
acquire_lock();
- &systemcall('/usr/bin/gpasswd', '-M', join(',', @members), $group);
+ systemcall('/usr/bin/gpasswd', '-M', join(',', @members), $group);
release_lock();
}
@@ -561,7 +561,7 @@ sub check_backup_suffix {
}
my $filename = '/tmp/deluser-check.tar';
my $testfile = 'usr/sbin/deluser';
- &systemcall_silent_error($tar, '--auto-compress', '--directory', '/', '-cf', $filename.$suffix, $testfile);
+ systemcall_silent_error($tar, '--auto-compress', '--directory', '/', '-cf', $filename.$suffix, $testfile);
if ($?) {
# compressor recognized, not available
@@ -569,7 +569,7 @@ sub check_backup_suffix {
$suffix = '.gz';
} else {
# no error, check if compressed
- &systemcall_silent($tar, '--directory', '/', '-cf', $filename, $testfile);
+ systemcall_silent($tar, '--directory', '/', '-cf', $filename, $testfile);
my @zstat = stat($filename.$suffix);
my @ustat = stat($filename);
View it on GitLab: https://salsa.debian.org/debian/adduser/-/compare/1aae1ef35eba09c04237868ada66594a8e557773...f9a73dfc70a4779c6ccd8db13bb07f0e720690de
--
View it on GitLab: https://salsa.debian.org/debian/adduser/-/compare/1aae1ef35eba09c04237868ada66594a8e557773...f9a73dfc70a4779c6ccd8db13bb07f0e720690de
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-shadow-devel/attachments/20250219/bc846c25/attachment-0001.htm>
More information about the Pkg-shadow-devel
mailing list