[Pkg-shadow-devel] [Git][debian/adduser][feature-refactor-existing] refactor existing_*_ok
Marc Haber (@zugschlus)
gitlab at salsa.debian.org
Sat Sep 13 15:06:32 BST 2025
Marc Haber pushed to branch feature-refactor-existing at Debian / adduser
Commits:
db48e31e by Matt Barry at 2025-09-13T16:05:36+02:00
refactor existing_*_ok
replace with new existing_(user|group)_status, which return a bitmask
value corresponding to these constants:
EXISTING_NOT_FOUND EXISTING_FOUND EXISTING_SYSTEM EXISTING_ID_MISMATCH
(and EXISTING_LOCKED, which is unused in this branch)
- - - - -
2 changed files:
- AdduserCommon.pm
- adduser
Changes:
=====================================
AdduserCommon.pm
=====================================
@@ -94,6 +94,15 @@ use constant {
def_min_regex => qr(^[^-+~:,\s/][^:,\s/]*$)aa,
};
+# constants used in existing_*_status
+use constant {
+ EXISTING_NOT_FOUND => 0,
+ EXISTING_FOUND => 1,
+ EXISTING_SYSTEM => 2,
+ EXISTING_ID_MISMATCH => 4,
+ EXISTING_LOCKED => 8,
+};
+
@EXPORT = (
'get_group_members',
'read_config',
@@ -122,6 +131,13 @@ use constant {
'def_sys_name_regex',
'def_ieee_name_regex',
'def_min_regex',
+ 'EXISTING_NOT_FOUND',
+ 'EXISTING_FOUND',
+ 'EXISTING_SYSTEM',
+ 'EXISTING_ID_MISMATCH',
+ 'EXISTING_LOCKED',
+ 'existing_user_status',
+ 'existing_group_status',
);
sub sanitize_string {
@@ -567,6 +583,58 @@ END {
release_lock(1);
}
+# existing_user_status: check if there is already a user present
+# on the system which satisfies the requirements
+# parameter:
+# new_name: the name of the user to check
+# new_uid : the UID of the user
+# return value:
+# bitwise combination of these constants:
+# EXISTING_NOT_FOUND => 0
+# EXISTING_FOUND => 1
+# EXISTING_SYSTEM => 2
+# EXISTING_ID_MISMATCH => 4
+# EXISTING_LOCKED => 8
+# e.g. if the requested account name exists as a locked system user,
+# return 8|2|1 == 11
+sub existing_user_status {
+ my ($config, $new_name,$new_uid) = @_;
+ my ($dummy1,$pw,$uid);
+ my $ret = EXISTING_NOT_FOUND;
+ log_trace( "existing_user_status called with new_name %s, new_uid %s", $new_name, $new_uid );
+ if (($dummy1,$pw,$uid) = egetpwnam($new_name)) {
+ $ret |= EXISTING_FOUND;
+ $ret |= EXISTING_ID_MISMATCH if (defined($new_uid) && $uid != $new_uid);
+ $ret |= EXISTING_SYSTEM if \
+ ($uid >= $config->{"first_system_uid"} && $uid <= $config->{"last_system_uid"});
+ $ret |= EXISTING_LOCKED if (substr($pw,0,1) eq "!"); # TODO: also check expiry?
+ }
+ return $ret;
+}
+
+# existing_group_status: check if there is already a group which satisfies the requirements
+# parameter:
+# new_name: the name of the group
+# new_gid : the GID of the group
+# return value:
+# bitwise combination of these constants:
+# EXISTING_NOT_FOUND => 0
+# EXISTING_FOUND => 1
+# EXISTING_SYSTEM => 2
+# EXISTING_ID_MISMATCH => 4
+sub existing_group_status {
+ my ($config, $new_name,$new_gid) = @_;
+ my ($dummy1,$dummy2,$gid);
+ my $ret = EXISTING_NOT_FOUND;
+ if (($dummy1,$dummy2,$gid) = egetgrnam($new_name)) {
+ $ret |= EXISTING_FOUND;
+ $ret |= EXISTING_ID_MISMATCH if (defined($new_gid) && $gid != $new_gid);
+ $ret |= EXISTING_SYSTEM if \
+ ($gid >= $config->{"first_system_gid"} && $gid <= $config->{"last_system_gid"});
+ }
+ return $ret;
+}
+
1;
# Local Variables:
=====================================
adduser
=====================================
@@ -88,14 +88,6 @@ BEGIN {
}
}
-use constant {
- EXISTING_NOT_FOUND => 0,
- EXISTING_FOUND => 1,
- EXISTING_SYSTEM => 2,
- EXISTING_ID_MISMATCH => 4,
- EXISTING_LOCKED => 8,
-};
-
my $yesexpr = langinfo(YESEXPR());
my $charset = langinfo($codeset);
if ($encode_loaded) {
@@ -103,7 +95,7 @@ if ($encode_loaded) {
binmode(STDERR, ":encoding($charset)");
}
-my %config; # configuration hash
+my %config = ();
my $nogroup_id = egetgrnam("nogroup") || 65534;
$0 =~ s+.*/++;
@@ -332,6 +324,15 @@ if ($found_group_opt) {
}
}
+# $new_firstuid = $new_firstuid || $config{"first_uid"} || 1000;
+# $new_lastuid = $new_lastuid || $config{"last_uid"} || 59999;
+# $new_firstgid = $new_firstgid || $config{"first_gid"} || 1000;
+# $new_lastgid = $new_lastgid || $config{"last_gid"} || 59999;
+# $new_firstuid = $new_firstuid || $config{"first_uid"} || 1000;
+# $new_lastuid = $new_lastuid || $config{"last_uid"} || 59999;
+# $new_firstgid = $new_firstgid || $config{"first_gid"} || 1000;
+# $new_lastgid = $new_lastgid || $config{"last_gid"} || 59999;
+
# read the uid and gid pool
if ($config{"uid_pool"}) {
@@ -385,7 +386,7 @@ if( defined $new_firstuid ) {
}
if( defined $new_lastuid ) {
- log_trace("sanitize new_lastgud");
+ log_trace("sanitize new_lastuid");
$new_lastuid = sanitize_string($new_lastuid, numberre);
}
@@ -438,13 +439,21 @@ if ($action eq "addsysgroup") {
acquire_lock();
# Check if requested group already exists and we can exit safely
- my $asgret = existing_group_status($new_name, $gid_option);
+ my $asgret = existing_group_status(\%config, $new_name, $gid_option);
log_trace( "existing_group_status( %s, %s ) returns %s", $new_name, $gid_option, $asgret );
+ if ($asgret == (EXISTING_FOUND|EXISTING_SYSTEM)) {
+ log_warn( mtx("The group `%s' already exists as a system group. Exiting."), $new_name );
+ exit( RET_OK );
+ }
if ($asgret & EXISTING_ID_MISMATCH) {
log_err( mtx("The group `%s' already exists, but has a different GID. Exiting."), $new_name );
exit( RET_WRONG_OBJECT_PROPERTIES );
}
+ if ($asgret & EXISTING_FOUND) {
+ log_err( mtx("The group `%s' already exists and is not a system group. Exiting."), $new_name );
+ exit( RET_WRONG_OBJECT_PROPERTIES );
+ }
if ($asgret & EXISTING_FOUND) {
log_trace( "existing_found" );
if ($asgret & (EXISTING_SYSTEM)) {
@@ -565,8 +574,9 @@ if ($action eq 'addusertogroup') {
if ($action eq "addsysuser") {
acquire_lock();
- my $ret = existing_user_status($new_name, $new_uid);
- if (($ret & EXISTING_FOUND) && !($ret & EXISTING_SYSTEM)) {
+ log_trace( "addsysuser %s, uid %s", $new_name, $new_uid );
+ my $ret = existing_user_status(\%config, $new_name, $new_uid);
+ if ($ret == (EXISTING_FOUND|EXISTING_SYSTEM)) {
# a user with this name already exists; it's a problem when it's not a system user
log_fatal( mtx("The user `%s' already exists, but is not a system user. Exiting."), $new_name );
exit( RET_WRONG_OBJECT_PROPERTIES );
@@ -1138,66 +1148,6 @@ sub mktree {
return 1;
}
-# existing_user_status: check if there is already a user present
-# on the system which satisfies the requirements
-# parameter:
-# new_name: the name of the user to check
-# new_uid : the UID of the user
-# return value:
-# bitwise combination of these constants:
-# EXISTING_NOT_FOUND => 0
-# EXISTING_FOUND => 1
-# EXISTING_SYSTEM => 2
-# EXISTING_ID_MISMATCH => 4
-# EXISTING_LOCKED => 8
-# e.g. if the requested account name exists as a locked system user,
-# return 8|2|1 == 11
-sub existing_user_status {
- my ($new_name,$new_uid) = @_;
- my ($pw,$uid);
- my $ret = EXISTING_NOT_FOUND;
- log_trace( "existing_user_status called with new_name %s, new_uid %s", $new_name, $new_uid );
- if ((undef,$pw,$uid) = egetpwnam($new_name)) {
- log_trace("egetpwnam %s returned successfully, uid = %s", $new_name, $uid);
- $ret |= EXISTING_FOUND;
- $ret |= EXISTING_ID_MISMATCH if (defined($new_uid) && $uid != $new_uid);
- $ret |= EXISTING_SYSTEM if
- ($uid >= $config{"first_system_uid"} && $uid <= $config{"last_system_uid"});
- } elsif ($new_uid && getpwuid($new_uid)) {
- $ret |= EXISTING_ID_MISMATCH;
- }
- log_trace( "existing_user_status( %s, %s ) returns %s", $new_name, $new_uid, $ret );
- return $ret;
-}
-
-# existing_group_status: check if there is already a group which satisfies the requirements
-# parameter:
-# new_name: the name of the group
-# new_gid : the GID of the group
-# return value:
-# bitwise combination of these constants:
-# EXISTING_NOT_FOUND => 0
-# EXISTING_FOUND => 1
-# EXISTING_SYSTEM => 2
-# EXISTING_ID_MISMATCH => 4
-sub existing_group_status {
- my ($new_name,$new_gid) = @_;
- my $gid;
- my $ret = EXISTING_NOT_FOUND;
- log_trace( "existing_group_status called with new_name %s, new_gid %s", $new_name, $new_gid );
- if ((undef,undef,$gid) = egetgrnam($new_name)) {
- log_trace("egetgrnam %s returned successfully, gid = %s", $new_name, $gid);
- $ret |= EXISTING_FOUND;
- $ret |= EXISTING_ID_MISMATCH if (defined($new_gid) && $gid != $new_gid);
- $ret |= EXISTING_SYSTEM if
- ($gid >= $config{"first_system_gid"} && $gid <= $config{"last_system_gid"});
- } elsif ($new_gid && getgrgid($new_gid)) {
- $ret |= EXISTING_ID_MISMATCH;
- }
- log_trace( "existing_group_status( %s, %s ) returns %s", $new_name, $new_gid, $ret );
- return $ret;
-}
-
# check_user_group: ???
# parameters:
# system: 0 if the user is not a system user, 1 otherwise
@@ -1207,27 +1157,25 @@ sub existing_group_status {
sub check_user_group {
my ($system) = @_;
log_debug( "check_user_group %s called, make_group_also %s", $system, $make_group_also );
-
- my $ustat = existing_user_status($new_name, $new_uid);
- if ($system) {
- if (($ustat & EXISTING_FOUND) && !($ustat & EXISTING_SYSTEM)) {
- log_fatal( mtx("The user `%s' already exists, and is not a system user."), $new_name);
- exit( RET_WRONG_OBJECT_PROPERTIES );
+ if( !$system || !existing_user_status(\%config, $new_name, $new_uid) ) {
+ if( defined egetpwnam($new_name) ) {
+ if( $system ) {
+ log_fatal( mtx("The user `%s' already exists, and is not a system user."), $new_name);
+ exit( RET_WRONG_OBJECT_PROPERTIES );
+ } else {
+ log_fatal( mtx("The user `%s' already exists."), $new_name);
+ exit( RET_OBJECT_EXISTS );
+ }
}
- # if ($new_uid && !($ustat & EXISTING_SYSTEM)) {
- # log_fatal( mtx("The uid `%s' is invalid for system users."), $new_name);
- # exit( RET_OBJECT_EXISTS );
- # }
- } else {
- if ($ustat & EXISTING_FOUND) {
- log_fatal( mtx("The user `%s' already exists."), $new_name);
- exit( RET_OBJECT_EXISTS );
+ if (defined($new_uid) && getpwuid($new_uid)) {
+ log_fatal( mtx("The UID %d is already in use."), $new_uid);
+ exit( RET_ID_IN_USE );
}
}
if ($make_group_also) {
log_trace( "make_group_also 1, new_name %s, new_uid %s", $new_name, $new_uid );
- if( !$system || !existing_group_status($new_name, $new_uid) ) {
+ if( !$system || !existing_group_status(\%config, $new_name, $new_uid) ) {
if (defined egetgrnam($new_name)) {
log_fatal( mtx("The group `%s' already exists."),$new_name );
exit( RET_OBJECT_EXISTS );
View it on GitLab: https://salsa.debian.org/debian/adduser/-/commit/db48e31edb331de8ffecf6c00bc6d85cf14dc750
--
View it on GitLab: https://salsa.debian.org/debian/adduser/-/commit/db48e31edb331de8ffecf6c00bc6d85cf14dc750
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/20250913/6f0e5f76/attachment-0001.htm>
More information about the Pkg-shadow-devel
mailing list