source: calamares/trunk/fuentes/src/modules/users/CreateUserJob.cpp @ 7538

Last change on this file since 7538 was 7538, checked in by kbut, 17 months ago

sync with github

File size: 6.3 KB
Line 
1/* === This file is part of Calamares - <https://github.com/calamares> ===
2 *
3 *   Copyright 2014-2016, Teo Mrnjavac <teo@kde.org>
4 *   Copyright 2018, Adriaan de Groot <groot@kde.org>
5 *
6 *   Calamares is free software: you can redistribute it and/or modify
7 *   it under the terms of the GNU General Public License as published by
8 *   the Free Software Foundation, either version 3 of the License, or
9 *   (at your option) any later version.
10 *
11 *   Calamares is distributed in the hope that it will be useful,
12 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *   GNU General Public License for more details.
15 *
16 *   You should have received a copy of the GNU General Public License
17 *   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <CreateUserJob.h>
21
22#include "JobQueue.h"
23#include "GlobalStorage.h"
24#include "utils/Logger.h"
25#include "utils/CalamaresUtilsSystem.h"
26
27#include <QDateTime>
28#include <QDir>
29#include <QFile>
30#include <QFileInfo>
31#include <QProcess>
32#include <QTextStream>
33
34
35CreateUserJob::CreateUserJob( const QString& userName,
36                              const QString& fullName,
37                              bool autologin,
38                              const QStringList& defaultGroups )
39    : Calamares::Job()
40    , m_userName( userName )
41    , m_fullName( fullName )
42    , m_autologin( autologin )
43    , m_defaultGroups( defaultGroups )
44{
45}
46
47
48QString
49CreateUserJob::prettyName() const
50{
51    return tr( "Create user %1" ).arg( m_userName );
52}
53
54
55QString
56CreateUserJob::prettyDescription() const
57{
58    return tr( "Create user <strong>%1</strong>." ).arg( m_userName );
59}
60
61
62QString
63CreateUserJob::prettyStatusMessage() const
64{
65    return tr( "Creating user %1." ).arg( m_userName );
66}
67
68
69Calamares::JobResult
70CreateUserJob::exec()
71{
72    Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
73    QDir destDir( gs->value( "rootMountPoint" ).toString() );
74
75    if ( gs->contains( "sudoersGroup" ) &&
76         !gs->value( "sudoersGroup" ).toString().isEmpty() )
77    {
78        QFileInfo sudoersFi( destDir.absoluteFilePath( "etc/sudoers.d/10-installer" ) );
79
80        if ( !sudoersFi.absoluteDir().exists() )
81            return Calamares::JobResult::error( tr( "Sudoers dir is not writable." ) );
82
83        QFile sudoersFile( sudoersFi.absoluteFilePath() );
84        if (!sudoersFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
85            return Calamares::JobResult::error( tr( "Cannot create sudoers file for writing." ) );
86
87        QString sudoersGroup = gs->value( "sudoersGroup" ).toString();
88
89        QTextStream sudoersOut( &sudoersFile );
90        sudoersOut << QString( "%%1 ALL=(ALL) ALL\n" ).arg( sudoersGroup );
91
92        if ( QProcess::execute( "chmod", { "440", sudoersFi.absoluteFilePath() } ) )
93            return Calamares::JobResult::error( tr( "Cannot chmod sudoers file." ) );
94    }
95
96    QFileInfo groupsFi( destDir.absoluteFilePath( "etc/group" ) );
97    QFile groupsFile( groupsFi.absoluteFilePath() );
98    if ( !groupsFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
99        return Calamares::JobResult::error( tr( "Cannot open groups file for reading." ) );
100    QString groupsData = QString::fromLocal8Bit( groupsFile.readAll() );
101    QStringList groupsLines = groupsData.split( '\n' );
102    for ( QStringList::iterator it = groupsLines.begin();
103          it != groupsLines.end(); ++it )
104    {
105        int indexOfFirstToDrop = it->indexOf( ':' );
106        it->truncate( indexOfFirstToDrop );
107    }
108
109    foreach ( const QString& group, m_defaultGroups )
110        if ( !groupsLines.contains( group ) )
111            CalamaresUtils::System::instance()->
112                    targetEnvCall( { "groupadd", group } );
113
114    QString defaultGroups = m_defaultGroups.join( ',' );
115    if ( m_autologin )
116    {
117        QString autologinGroup;
118        if ( gs->contains( "autologinGroup" ) &&
119                !gs->value( "autologinGroup" ).toString().isEmpty() )
120        {
121            autologinGroup = gs->value( "autologinGroup" ).toString();
122            CalamaresUtils::System::instance()->targetEnvCall( { "groupadd", autologinGroup } );
123            defaultGroups.append( QString( ",%1" ).arg( autologinGroup ) );
124        }
125    }
126
127    // If we're looking to reuse the contents of an existing /home
128    if ( gs->value( "reuseHome" ).toBool() )
129    {
130        QString shellFriendlyHome = "/home/" + m_userName;
131        QDir existingHome( destDir.absolutePath() + shellFriendlyHome );
132        if ( existingHome.exists() )
133        {
134            QString backupDirName = "dotfiles_backup_" +
135                                    QDateTime::currentDateTime()
136                                        .toString( "yyyy-MM-dd_HH-mm-ss" );
137            existingHome.mkdir( backupDirName );
138
139            CalamaresUtils::System::instance()->
140                    targetEnvCall( { "sh",
141                                     "-c",
142                                     "mv -f " +
143                                        shellFriendlyHome + "/.* " +
144                                        shellFriendlyHome + "/" +
145                                        backupDirName
146                                   } );
147        }
148    }
149
150    QStringList useradd{ "useradd", "-m", "-U" };
151    QString shell = gs->value( "userShell" ).toString();
152    if ( !shell.isEmpty() )
153        useradd << "-s" << shell;
154    useradd << "-c" << m_fullName;
155    useradd << m_userName;
156
157    auto pres = CalamaresUtils::System::instance()->targetEnvCommand( useradd );
158    if ( pres.getExitCode() )
159    {
160        cError() << "useradd failed" << pres.getExitCode();
161        return pres.explainProcess( useradd, 10 /* bogus timeout */ );
162    }
163
164    pres = CalamaresUtils::System::instance()->targetEnvCommand(
165        { "usermod", "-aG", defaultGroups, m_userName } );
166    if ( pres.getExitCode() )
167    {
168        cError() << "usermod failed" << pres.getExitCode();
169        return pres.explainProcess( "usermod", 10 );
170    }
171
172    QString userGroup = QString( "%1:%2" ).arg( m_userName ).arg( m_userName );
173    QString homeDir = QString( "/home/%1" ).arg( m_userName );
174    pres = CalamaresUtils::System::instance()->targetEnvCommand(
175        { "chown", "-R", userGroup, homeDir } );
176    if ( pres.getExitCode() )
177    {
178        cError() << "chown failed" << pres.getExitCode();
179        return pres.explainProcess( "chown", 10 );
180    }
181
182    return Calamares::JobResult::ok();
183}
Note: See TracBrowser for help on using the repository browser.