diff --git a/src/modules/users/Config.cpp b/src/modules/users/Config.cpp index b19d29e6a..371d98932 100644 --- a/src/modules/users/Config.cpp +++ b/src/modules/users/Config.cpp @@ -840,6 +840,9 @@ Config::setConfigurationMap( const QVariantMap& configurationMap ) setAutoLoginGroup( either< QString, const QString& >( CalamaresUtils::getString, configurationMap, "autologinGroup", "autoLoginGroup", QString() ) ); setSudoersGroup( CalamaresUtils::getString( configurationMap, "sudoersGroup" ) ); + m_sudoStyle = CalamaresUtils::getBool( configurationMap, "sudoersConfigureWithGroup", false ) + ? SudoStyle::UserAndGroup + : SudoStyle::UserOnly; m_hostNameActions = getHostNameActions( configurationMap ); @@ -904,7 +907,7 @@ Config::createJobs() const if ( !m_sudoersGroup.isEmpty() ) { - j = new SetupSudoJob( m_sudoersGroup ); + j = new SetupSudoJob( m_sudoersGroup, m_sudoStyle ); jobs.append( Calamares::job_ptr( j ) ); } diff --git a/src/modules/users/Config.h b/src/modules/users/Config.h index d9fce4f60..e37ee77d5 100644 --- a/src/modules/users/Config.h +++ b/src/modules/users/Config.h @@ -186,8 +186,15 @@ public: /// The group of which auto-login users must be a member QString autoLoginGroup() const { return m_autoLoginGroup; } + + enum class SudoStyle + { + UserOnly, + UserAndGroup + }; /// The group of which users who can "sudo" must be a member QString sudoersGroup() const { return m_sudoersGroup; } + SudoStyle sudoStyle() const { return m_sudoStyle; } /// The full (GECOS) name of the user QString fullName() const { return m_fullName; } @@ -307,6 +314,7 @@ private: QString m_userShell; QString m_autoLoginGroup; QString m_sudoersGroup; + SudoStyle m_sudoStyle = SudoStyle::UserOnly; QString m_fullName; QString m_loginName; QString m_hostName; diff --git a/src/modules/users/MiscJobs.cpp b/src/modules/users/MiscJobs.cpp index 34fb08863..5cba202e0 100644 --- a/src/modules/users/MiscJobs.cpp +++ b/src/modules/users/MiscJobs.cpp @@ -22,8 +22,9 @@ #include #include -SetupSudoJob::SetupSudoJob( const QString& group ) +SetupSudoJob::SetupSudoJob( const QString& group, Config::SudoStyle style ) : m_sudoGroup( group ) + , m_sudoStyle( style ) { } @@ -33,6 +34,22 @@ SetupSudoJob::prettyName() const return tr( "Configure
sudo
users." ); } +static QString +designatorForStyle( Config::SudoStyle style ) +{ + switch ( style ) + { + case Config::SudoStyle::UserOnly: + return QStringLiteral( "(ALL)" ); + break; + case Config::SudoStyle::UserAndGroup: + return QStringLiteral( "(ALL:ALL)" ); + break; + } + __builtin_unreachable(); + return QString(); +} + Calamares::JobResult SetupSudoJob::exec() { @@ -42,7 +59,9 @@ SetupSudoJob::exec() return Calamares::JobResult::ok(); } - QString sudoersLine = QString( "%%1 ALL=(ALL) ALL\n" ).arg( m_sudoGroup ); + // One % for the sudo format, keep it outside of the string to avoid accidental replacement + QString sudoersLine + = QChar( '%' ) + QString( "%1 ALL=%2 ALL\n" ).arg( m_sudoGroup, designatorForStyle( m_sudoStyle ) ); auto fileResult = CalamaresUtils::System::instance()->createTargetFile( QStringLiteral( "/etc/sudoers.d/10-installer" ), sudoersLine.toUtf8().constData(), diff --git a/src/modules/users/MiscJobs.h b/src/modules/users/MiscJobs.h index fe4ff87c0..57272aa95 100644 --- a/src/modules/users/MiscJobs.h +++ b/src/modules/users/MiscJobs.h @@ -17,20 +17,21 @@ #ifndef USERS_MISCJOBS_H #define USERS_MISCJOBS_H -#include "Job.h" +#include "Config.h" -class Config; +#include "Job.h" class SetupSudoJob : public Calamares::Job { Q_OBJECT public: - SetupSudoJob( const QString& group ); + SetupSudoJob( const QString& group, Config::SudoStyle style ); QString prettyName() const override; Calamares::JobResult exec() override; public: QString m_sudoGroup; + Config::SudoStyle m_sudoStyle; }; class SetupGroupsJob : public Calamares::Job diff --git a/src/modules/users/users.conf b/src/modules/users/users.conf index a196e57d3..9f932c0a1 100644 --- a/src/modules/users/users.conf +++ b/src/modules/users/users.conf @@ -63,6 +63,10 @@ doAutologin: true # the setting will be duplicated in the `/etc/sudoers.d/10-installer` file, # potentially confusing users. sudoersGroup: wheel +# If set to `false` (the default), writes a sudoers file with `(ALL)` +# so that the command can be run as any user. If set to `true`, writes +# `(ALL:ALL)` so that any user and any group can be chosen. +sudoersConfigureWithGroup: false # Setting this to false, causes the root account to be disabled. # When disabled, hides the "Use the same password for administrator" diff --git a/src/modules/users/users.schema.yaml b/src/modules/users/users.schema.yaml index b96b2abd8..3b49061bc 100644 --- a/src/modules/users/users.schema.yaml +++ b/src/modules/users/users.schema.yaml @@ -23,6 +23,7 @@ properties: required: [ name ] autologinGroup: { type: string } sudoersGroup: { type: string } + sudoersConfigureWithGroup: { type: boolean, default: false } # Skip login (depends on displaymanager support) doAutologin: { type: boolean, default: true } # Root password separate from user password?