ukui-control-center/group-manager-server/group_manager_server.cpp

566 lines
16 KiB
C++

/*
* Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/&gt;.
*
*/
#include "group_manager_server.h"
#include "custom_struct.h"
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <QtConcurrent/QtConcurrent>
#include <QDBusMessage>
#include <QDBusInterface>
#include <polkit-qt5-1/polkitqt1-authority.h>
group_manager_server::group_manager_server()
: QDBusContext()
{
}
// 解析组文件
QVariantList group_manager_server::getGroup()
{
const QString fileName = "/etc/group";
QFile groupFile(fileName);
QVariantList value;
QVariant cnt;
int lineCount = 1;
if(!groupFile.exists()){
printf("/etc/group file not exist \n");
}
if(!groupFile.open(QIODevice::ReadOnly | QIODevice::Text)){
printf("open /etc/group fail \n");
}
QTextStream in(&groupFile);
QString line = in.readLine();
struct custom_struct demo[200];
while(!line.isNull()){
QStringList lineList = line.split(":");
line = in.readLine();
demo[lineCount].groupname = lineList.at(0);
demo[lineCount].passphrase = lineList.at(1);
demo[lineCount].groupid = lineList.at(2);
demo[lineCount].usergroup = lineList.at(3);
cnt = QVariant::fromValue(demo[lineCount]);
value << cnt;
lineCount ++;
}
return value;
}
// 解析passwd文件
QVariantList group_manager_server::getPasswd()
{
const QString fileName = "/etc/passwd";
QFile passwdFile(fileName);
QVariantList value;
QVariant cnt;
int lineCount = 1;
if(!passwdFile.exists()){
printf("/etc/passwd file not exist \n");
}
if(!passwdFile.open(QIODevice::ReadOnly | QIODevice::Text)){
printf("open /etc/passwd fail \n");
}
QTextStream in(&passwdFile);
QString line = in.readLine();
struct custom_struct demo[200];
while(!line.isNull()){
QStringList lineList = line.split(":");
line = in.readLine();
demo[lineCount].groupname = lineList.at(0);
demo[lineCount].passphrase = lineList.at(1);
demo[lineCount].groupid = lineList.at(3);
cnt = QVariant::fromValue(demo[lineCount]);
value << cnt;
lineCount ++;
}
return value;
}
// 添加组
bool group_manager_server::add(QString groupName, QString groupId)
{
//密码校验
if (!authoriyEdit()){
return false;
}
QString groupadd = "/usr/sbin/groupadd";
QString addgroup = "/usr/sbin/addgroup";
QString command;
QFile groupaddFile("/usr/sbin/addgroup");
QFile addgroupFile("/usr/sbin/groupadd");
QProcess p(0);
QStringList args;
if(!addgroupFile.exists()){
printf("/usr/sbin/addgroup file not exist \n");
if(!groupaddFile.exists()){
return false;
}
command = groupadd;
args.append("-g");
args.append(groupId);
args.append(groupName);
}else{
command = addgroup;
args.append("-gid");
args.append(groupId);
args.append(groupName);
}
p.execute(command,args);//command是要执行的命令,args是参数
p.waitForFinished(-1);
// qDebug()<<QString::fromLocal8Bit(p.readAllStandardError());
return true;
}
// 修改组
bool group_manager_server::set(QString groupName, QString groupId)
{
//密码校验
if (!authoriyEdit()){
return false;
}
QString groupmod = "/usr/sbin/groupmod";
QFile groupmodFile(groupmod);
QProcess p(0);
QStringList args;
if(!groupmodFile.exists()){
printf("/usr/sbin/groupmod file not exist \n");
return false;
}
args.append("-g");
args.append(groupId);
//args.append("-n");
args.append(groupName);
p.execute(groupmod,args);//command是要执行的命令,args是参数
p.waitForFinished(-1);
// qDebug()<<QString::fromLocal8Bit(p.readAllStandardError());
return true;
}
// 删除组
bool group_manager_server::del(QString groupName)
{
//密码校验
if (!authoriyEdit()){
return false;
}
QString groupdel = "/usr/sbin/groupdel";
QFile groupdelFile(groupdel);
QProcess p(0);
QStringList args;
if(!groupdelFile.exists()){
printf("/usr/sbin/groupdel file not exist \n");
return false;
}
args.append(groupName);
p.execute(groupdel,args);//command是要执行的命令,args是参数
p.waitForFinished(-1);
// qDebug()<<QString::fromLocal8Bit(p.readAllStandardError());
return true;
}
// 添加用户到组
bool group_manager_server::_addUserToGroup(QString groupName, QString userName)
{
QString usermod = "/usr/sbin/usermod";
QString gpasswd = "/usr/bin/gpasswd";
QString command;
QFile usermodFile(usermod);
QFile gpasswdFile(gpasswd);
QProcess p(0);
QStringList args;
if(!usermodFile.exists()){
printf("/usr/sbin/usermod file not exist \n");
if(!gpasswdFile.exists()){
printf("/usr/sbin/gpasswd file not exist \n");
return false;
}
command = gpasswd;
args.append("-a");
args.append(userName);
args.append(groupName);
} else {
command = usermod;
args.append("-a");
args.append("-G");
args.append(groupName);
args.append(userName);
}
p.execute(command,args);//command是要执行的命令,args是参数
p.waitForFinished(-1);
// qDebug()<<QString::fromLocal8Bit(p.readAllStandardError());
return true;
}
bool group_manager_server::addUserToGroup(QString groupName, QStringList userNameList)
{
//密码校验
if (!authoriyEdit()){
return false;
}
foreach (QString userName,userNameList) {
bool ret = _addUserToGroup(groupName, userName);
if (!ret) {
qDebug() << "adduser " << userName << " to " << groupName << " failed!";
}
}
return true;
}
bool group_manager_server::authoriyEdit()
{
QDBusConnection conn = connection();
QDBusMessage msg = QDBusContext::message();
_id = conn.interface()->servicePid(msg.service()).value();
if (_id == 0)
return false;
PolkitQt1::Authority::Result result;
result = PolkitQt1::Authority::instance()->checkAuthorizationSync(
"org.ukui.groupmanager.action.edit",
PolkitQt1::UnixProcessSubject(_id),
PolkitQt1::Authority::AllowUserInteraction);
if (result == PolkitQt1::Authority::Yes){
_id = 0;
return true;
} else {
_id = 0;
return false;
}
}
bool group_manager_server::_delUserFromGroup(QString groupName, QString userName)
{
QString gpasswd = "/usr/bin/gpasswd";
QString command;
QFile gpasswdFile(gpasswd);
QProcess p(0);
QStringList args;
if(!gpasswdFile.exists()){
printf("/usr/sbin/gpasswd file not exist \n");
return false;
}
command = gpasswd;
args.append("-d");
args.append(userName);
args.append(groupName);
p.execute(command,args);//command是要执行的命令,args是参数
p.waitForFinished(-1);
// qDebug() << QString::fromLocal8Bit(p.readAllStandardError());
return true;
}
// 删除用户从组
bool group_manager_server::delUserFromGroup(QString groupName, QStringList userNameList)
{
//密码校验
if (!authoriyEdit()){
return false;
}
foreach (QString userName,userNameList) {
bool ret = _delUserFromGroup(groupName, userName);
if (!ret) {
qDebug() << "deluser " << userName << " to " << groupName << " failed!";
}
}
return true;
}
bool group_manager_server::_changeOtherUserPasswd(QString username, QString pwd)
{
std::string str1 = username.toStdString();
const char * user_name = str1.c_str();
QString output;
QString newPwd = pwd;
int i = 0;
for (i = 0; i < newPwd.count(); i++){
if (!(int(newPwd.at(i).toLatin1() >= 48 && int(newPwd.at(i).toLatin1()) <= 57) ||
int(newPwd.at(i).toLatin1() >= 65 && int(newPwd.at(i).toLatin1()) <= 90) ||
int(newPwd.at(i).toLatin1() >= 97 && int(newPwd.at(i).toLatin1()) <= 122))){
newPwd = newPwd.insert(i, QString("\\"));
i++;
}
}
std::string str2 = newPwd.toStdString();
const char * passwd = str2.c_str();
char * cmd = g_strdup_printf("/usr/bin/changeotheruserpwd '%s' %s", user_name, passwd);
FILE *stream;
char buf[256];
if ((stream = popen(cmd, "r" )) == NULL){
return false;
}
while(fgets(buf, 256, stream) != NULL){
output = QString(buf).simplified();
}
pclose(stream);
return true;
}
// 修改其他用户密码
bool group_manager_server::changeOtherUserPasswd(QString username, QString pwd)
{
//密码校验
if (!authoriyEdit()){
return false;
}
bool _changeRet = _changeOtherUserPasswd(username, pwd);
return _changeRet;
}
// 创建新用户
bool group_manager_server::createUser(QString name, QString fullname, int accounttype, QString faceicon, QString pwd)
{
//密码校验
if (!authoriyEdit()){
return false;
}
QDBusInterface iface("org.freedesktop.Accounts",
"/org/freedesktop/Accounts",
"org.freedesktop.Accounts",
QDBusConnection::systemBus());
QDBusReply<QDBusObjectPath> reply = iface.call("CreateUser", name, fullname, accounttype);
if (reply.isValid()){
QString op = reply.value().path();
if (!op.isEmpty()){
QDBusInterface ifaceUser("org.freedesktop.Accounts",
op,
"org.freedesktop.Accounts.User",
QDBusConnection::systemBus());
// 设置头像
ifaceUser.call("SetIconFile", faceicon);
// 设置密码
_changeOtherUserPasswd(name, pwd);
}
}
return true;
}
//获取免密登录状态
QString group_manager_server::getNoPwdLoginStatus()
{
QByteArray ba;
FILE * fp = NULL;
char cmd[128];
char buf[1024];
snprintf(cmd, 128, "cat /etc/group |grep nopasswdlogin");
if ((fp = popen(cmd, "r")) != NULL){
rewind(fp);
fgets(buf, sizeof (buf), fp);
ba.append(buf);
pclose(fp);
fp = NULL;
}else{
qDebug()<<"popen文件打开失败"<<endl;
}
return QString(ba);
}
//设置免密登录状态
bool group_manager_server::setNoPwdLoginStatus(bool status,QString username)
{
//密码校验
if (!authoriyEdit()){
return false;
}
if (username == nullptr) {
if (status == false) {
QString noPwdLoginUser = getNoPwdLoginStatus();
qDebug() << "noPwdLoginUser:" << noPwdLoginUser;
QStringList tmp = noPwdLoginUser.split(":", QString::SkipEmptyParts);
QString noPasswdUsers = tmp.at(tmp.count()-1);
QStringList noPasswdUsersList = noPasswdUsers.split(",", QString::SkipEmptyParts);
foreach (QString noPasswdUser, noPasswdUsersList) {
noPasswdUser.remove(QChar('\n'), Qt::CaseInsensitive);
qDebug() << "nopasswduser:" << noPasswdUser;
QString cmd = QString("gpasswd -d %1 nopasswdlogin").arg(noPasswdUser);;
QProcess::execute(cmd);
}
}
} else {
QString cmd;
if(true == status){
cmd = QString("gpasswd -a %1 nopasswdlogin").arg(username);
} else{
cmd = QString("gpasswd -d %1 nopasswdlogin").arg(username);
}
QProcess::execute(cmd);
}
NoPwdLogin = status;
notifyPropertyChanged("org.ukui.groupmanager", "NoPwdLoginStatus");
return true;
}
// 修改自动登录
bool group_manager_server::setAutomaticLogin(QString objpath, bool enabled)
{
//密码校验
if (!authoriyEdit()){
return false;
}
QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.Accounts",
objpath,
"org.freedesktop.Accounts.User",
"SetAutomaticLogin");
message << enabled;
QDBusMessage response = QDBusConnection::systemBus().call(message);
if (response.type() == QDBusMessage::ErrorMessage){
return false;
}
return true;
}
// 设置用户头像
bool group_manager_server::setIconFile(QString username, QString objpath, QString filename)
{
//密码校验
if (!authoriyEdit()){
return false;
}
QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.Accounts",
objpath,
"org.freedesktop.Accounts.User",
"SetIconFile");
message << filename;
QDBusMessage response = QDBusConnection::systemBus().call(message);
if (response.type() == QDBusMessage::ErrorMessage){
return false;
}
return true;
}
// 修改账户类型
bool group_manager_server::setAccountType(QString objpath, int accountType)
{
//密码校验
if (!authoriyEdit()){
return false;
}
QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.Accounts",
objpath,
"org.freedesktop.Accounts.User",
"SetAccountType");
message << accountType;
QDBusMessage response = QDBusConnection::systemBus().call(message);
if (response.type() == QDBusMessage::ErrorMessage){
return false;
}
return true;
}
// 删除用户
bool group_manager_server::deleteUser(qint64 id, bool removeFiles)
{
//密码校验
if (!authoriyEdit()){
return false;
}
QDBusInterface iface("org.freedesktop.Accounts",
"/org/freedesktop/Accounts",
"org.freedesktop.Accounts",
QDBusConnection::systemBus());
QDBusMessage response = iface.call("DeleteUser", id, removeFiles);
if (response.type() == QDBusMessage::ErrorMessage){
qDebug() << "====" << response.errorMessage();
return false;
}
return true;
}
void group_manager_server::notifyPropertyChanged( const QString& interface,
const QString& propertyName)
{
QDBusMessage signal = QDBusMessage::createSignal(
"/",
"org.freedesktop.DBus.Properties",
"PropertiesChanged");
signal << interface;
QVariantMap changedProps;
changedProps.insert(propertyName, property(propertyName.toLatin1().data()));
signal << changedProps;
signal << QStringList();
QDBusConnection::systemBus().send(signal);
}
bool group_manager_server::NoPwdLoginStatus() const
{
return NoPwdLogin;
}