diff --git a/src/modules/users/MiscJobs.cpp b/src/modules/users/MiscJobs.cpp index 4f9472cc6..04880d1d8 100644 --- a/src/modules/users/MiscJobs.cpp +++ b/src/modules/users/MiscJobs.cpp @@ -12,10 +12,16 @@ #include "Config.h" +#include "GlobalStorage.h" +#include "JobQueue.h" #include "utils/CalamaresUtilsSystem.h" #include "utils/Logger.h" #include "utils/Permissions.h" +#include +#include +#include + SetupSudoJob::SetupSudoJob( const QString& group ) : m_sudoGroup( group ) { @@ -55,3 +61,123 @@ SetupSudoJob::exec() return Calamares::JobResult::ok(); } + +STATICTEST QStringList +groupsInTargetSystem() +{ + Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); + QDir targetRoot( gs->value( "rootMountPoint" ).toString() ); + + QFileInfo groupsFi( targetRoot.absoluteFilePath( "etc/group" ) ); + QFile groupsFile( groupsFi.absoluteFilePath() ); + if ( !groupsFile.open( QIODevice::ReadOnly | QIODevice::Text ) ) + { + return QStringList(); + } + QString groupsData = QString::fromLocal8Bit( groupsFile.readAll() ); + QStringList groupsLines = groupsData.split( '\n' ); + QStringList::iterator it = groupsLines.begin(); + while ( it != groupsLines.end() ) + { + if ( it->startsWith( '#' ) ) + { + it = groupsLines.erase( it ); + continue; + } + int indexOfFirstToDrop = it->indexOf( ':' ); + if ( indexOfFirstToDrop < 1 ) + { + it = groupsLines.erase( it ); + continue; + } + it->truncate( indexOfFirstToDrop ); + ++it; + } + return groupsLines; +} + +/** @brief Create groups in target system as needed + * + * Given a list of groups that already exist, @p availableGroups, + * go through the @p wantedGroups and create each of them. Groups that + * fail, or which should have already been there, are added to + * @p missingGroups by name. + */ +static bool +ensureGroupsExistInTarget( const QList< GroupDescription >& wantedGroups, + const QStringList& availableGroups, + QStringList& missingGroups ) +{ + int failureCount = 0; + + for ( const auto& group : wantedGroups ) + { + int groupaddResult = 0; + if ( group.isValid() && !availableGroups.contains( group.name() ) ) + { + if ( group.mustAlreadyExist() ) + { + // Should have been there already: don't create it + missingGroups.append( group.name() ); + continue; + } + +#ifdef __FreeBSD__ + groupaddResult + = CalamaresUtils::System::instance()->targetEnvCall( { "pw", "groupadd", "-n", group.name() } ); +#else + groupaddResult = CalamaresUtils::System::instance()->targetEnvCall( { "groupadd", group.name() } ); +#endif + if ( groupaddResult ) + { + failureCount++; + missingGroups.append( group.name() + QChar( '*' ) ); + } + } + } + if ( !missingGroups.isEmpty() ) + { + cWarning() << "Missing groups in target system (* for groupadd failure):" << Logger::DebugList( missingGroups ); + } + return failureCount == 0; +} + +SetupGroupsJob::SetupGroupsJob( const Config* config, const QString& autologinGroup ) + : m_autologinGroup( autologinGroup ) + , m_config( config ) +{ +} + +QString +SetupGroupsJob::prettyName() const +{ + return tr( "Preparing groups." ); +} + +Calamares::JobResult +SetupGroupsJob::exec() +{ + const auto& defaultGroups = m_config->defaultGroups(); + QStringList availableGroups = groupsInTargetSystem(); + QStringList missingGroups; + + if ( !ensureGroupsExistInTarget( defaultGroups, availableGroups, missingGroups ) ) + { + return Calamares::JobResult::error( tr( "Could not create groups in target system" ) ); + } + if ( !missingGroups.isEmpty() ) + { + return Calamares::JobResult::error( + tr( "Could not create groups in target system" ), + tr( "These groups are missing in the target system: %1" ).arg( missingGroups.join( ',' ) ) ); + } + + if ( m_config->doAutoLogin() && !m_config->autologinGroup().isEmpty() ) + { + const QString autologinGroup = m_config->autologinGroup(); + (void)ensureGroupsExistInTarget( + QList< GroupDescription >() << GroupDescription( autologinGroup ), availableGroups, missingGroups ); + } + + return Calamares::JobResult::ok(); +} diff --git a/src/modules/users/MiscJobs.h b/src/modules/users/MiscJobs.h index 2f8055e8a..8065079ce 100644 --- a/src/modules/users/MiscJobs.h +++ b/src/modules/users/MiscJobs.h @@ -19,6 +19,8 @@ #include "Job.h" +class Config; + class SetupSudoJob : public Calamares::Job { Q_OBJECT @@ -31,4 +33,18 @@ public: QString m_sudoGroup; }; +class SetupGroupsJob : public Calamares::Job +{ + Q_OBJECT + +public: + SetupGroupsJob( const Config* config, const QString& autologinGroup ); + QString prettyName() const override; + Calamares::JobResult exec() override; + +public: + QString m_autologinGroup; + const Config* m_config; +}; + #endif