summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/settings/usermanager/passwd.cpp23
-rw-r--r--noncore/settings/usermanager/userdialog.cpp35
-rw-r--r--noncore/settings/usermanager/userdialog.h9
3 files changed, 51 insertions, 16 deletions
diff --git a/noncore/settings/usermanager/passwd.cpp b/noncore/settings/usermanager/passwd.cpp
index 5063661..0a2bfba 100644
--- a/noncore/settings/usermanager/passwd.cpp
+++ b/noncore/settings/usermanager/passwd.cpp
@@ -22,253 +22,276 @@ Passwd::~Passwd() {
}
// This function is taken from 'busybox'.
int Passwd::i64c(int i)
{
if (i <= 0)
return ('.');
if (i == 1)
return ('/');
if (i >= 2 && i < 12)
return ('0' - 2 + i);
if (i >= 12 && i < 38)
return ('A' - 12 + i);
if (i >= 38 && i < 63)
return ('a' - 38 + i);
return ('z');
}
// This function is taken from 'busybox'.
char *Passwd::crypt_make_salt() {
time_t now;
static unsigned long x;
static char result[3];
time(&now);
x += now + getpid() + clock();
result[0] = i64c(((x >> 18) ^ (x >> 6)) & 077);
result[1] = i64c(((x >> 12) ^ x) & 077);
result[2] = '\0';
return result;
}
+// opens the files /etc/passwd & /etc/group and loads the contents into passwdStringList & groupStringList
bool Passwd::open() {
int returnvalue=false;
QFile passwd_file("/etc/passwd");
QFile group_file("/etc/group");
passwdStringList.clear();
groupStringList.clear();
if((passwd_file.open(IO_ReadOnly))) {
if((group_file.open(IO_ReadOnly))) {
QTextStream ts_passwd(&passwd_file);
while(!(ts_passwd.eof())) {
passwdStringList << ts_passwd.readLine();
}
QTextStream ts_group(&group_file);
while(!(ts_group.eof())) {
groupStringList << ts_group.readLine();
}
returnvalue=true;
group_file.close();
}
passwd_file.close();
}
return returnvalue;
}
+// Writes back the contents of passwdStringList to /etc/passwd & groupStringList to /etc/group
bool Passwd::close() {
int returnvalue=false;
QFile passwd_file("/etc/passwd");
QFile group_file("/etc/group");
if((passwd_file.open(IO_WriteOnly))) {
if((group_file.open(IO_WriteOnly))) {
QTextStream ts_passwd(&passwd_file);
for(QStringList::Iterator it=passwdStringList.begin(); it!=passwdStringList.end(); ++it) {
ts_passwd << (*it) + "\n";
}
QTextStream ts_group(&group_file);
for(QStringList::Iterator it=groupStringList.begin(); it!=groupStringList.end(); ++it) {
ts_group << (*it) + "\n";
}
returnvalue=true;
group_file.close();
}
passwd_file.close();
}
return returnvalue;
}
+// Splits a "passwd" line into the components and stores them in the pw_* variables.
void Passwd::splitPasswdEntry(QString &userString) {
userdataStringList=QStringList::split(":",userString,true);
QStringList::Iterator it=userdataStringList.begin();
pw_name=(*it++);
pw_passwd=(*it++);
pw_uid=(*it++).toInt();
pw_gid=(*it++).toInt();
pw_gecos=(*it++);
pw_dir=(*it++);
pw_shell=(*it++);
}
+// Splits a "group" line into the components and stores them in the gr_* variables.
void Passwd::splitGroupEntry(QString &groupString) {
groupdataStringList=QStringList::split(":",groupString,true);
QStringList::Iterator it=groupdataStringList.begin();
gr_name=(*it++);
it++;
gr_gid=(*it++).toInt();
gr_mem=QStringList::split(" ",(*it++));
}
+// Find a user in the passwdStringList. Return true if found and also fill the pw_* variables.
bool Passwd::searchUser(QRegExp &userRegExp) {
QStringList tempStringList(passwdStringList.grep(userRegExp));
if((tempStringList.isEmpty())) {
return false;
} else {
userString=(*(tempStringList.begin()));
splitPasswdEntry(userString);
}
return true;
}
+// Find a user by login.
bool Passwd::findUser(const char *username) {
QRegExp userRegExp(QString("^%1\\:").arg(username));
return searchUser(userRegExp);
}
+// Find a user by uid.
bool Passwd::findUser(int uid) {
QRegExp userRegExp(QString(":%1\\:").arg(uid));
return searchUser(userRegExp);
}
+// Add a user to the passwdStringList, create home directory, and optionally create a group for the user.
bool Passwd::addUser(QString pw_name, QString pw_passwd, int pw_uid, int pw_gid, QString pw_gecos,QString pw_dir, QString pw_shell, bool createGroup) {
QString tempString;
if((createGroup) && (!(findGroup(pw_gid)))) addGroup(pw_name,pw_gid);
pw_passwd = crypt(pw_passwd, crypt_make_salt());
tempString=pw_name+":"+pw_passwd+":"+QString::number(pw_uid)+":"+QString::number(pw_gid)+":"+pw_gecos+":"+pw_dir+":"+pw_shell;
passwdStringList.append(tempString);
// Make home dir.
QDir d;
if(!(d.exists(pw_dir))) {
d.mkdir(pw_dir);
chown(pw_dir,pw_uid,pw_gid);
chmod(pw_dir,S_IRUSR|S_IWUSR|S_IXUSR);
}
return 1;
}
+// Update info for a user in passwdStringList, take info from the pw_* fields.
bool Passwd::updateUser(QString login) {
QRegExp userRegExp(QString("^%1\\:").arg(login));
for(QStringList::Iterator it=passwdStringList.begin(); it!=passwdStringList.end(); ++it) {
if(userRegExp.find((*it),0)!=-1) {
*it=QString(pw_name+":"+pw_passwd+":"+QString::number(pw_uid)+":"+QString::number(pw_gid)+":"+pw_gecos+":"+pw_dir+":"+pw_shell);
return true;
}
}
return false;
}
+// Delete a user from passwdStringList.
bool Passwd::deleteUser(QRegExp &userRegExp, bool delGroup) {
for(QStringList::Iterator it=passwdStringList.begin(); it!=passwdStringList.end(); ++it) {
if(userRegExp.find((*it),0)!=-1) {
splitPasswdEntry(*it);
if(delGroup) this->delGroup(pw_gid);
passwdStringList.remove(it);
return true;
}
}
return false;
}
+// Delete a user by login, and optionally also delete group.
bool Passwd::delUser(const char *username, bool delGroup) {
QRegExp userRegExp(QString("^%1\\:").arg(username));
return deleteUser(userRegExp,delGroup);
}
+// Delete a user by uid, and optionally also delete group.
bool Passwd::delUser(int uid, bool delGroup) {
QRegExp userRegExp(QString(":%1\\:").arg(uid));
return deleteUser(userRegExp,delGroup);
}
+// Locate a group in the groupStringList, fill out the gr_* variables and return "true" if found.
bool Passwd::searchGroup(QRegExp &groupRegExp) {
QStringList tempStringList(groupStringList.grep(groupRegExp));
if((tempStringList.isEmpty())) {
return false;
} else {
groupString=(*(tempStringList.begin()));
splitGroupEntry(groupString);
}
return true;
}
+// Find a group by groupname.
bool Passwd::findGroup(const char *groupname) {
QRegExp groupRegExp(QString("^%1\\:").arg(groupname));
return searchGroup(groupRegExp);
}
+// Find a group by gid.
bool Passwd::findGroup(int gid) {
QRegExp groupRegExp(QString(":%1\\:").arg(gid));
return searchGroup(groupRegExp);
}
+// Add a group to groupStringList
bool Passwd::addGroup(QString gr_name, int gr_gid) {
QString tempString;
tempString=gr_name+":*:"+QString::number(gr_gid)+":";
groupStringList.append(tempString);
return 1;
}
+// Update fields for a group in groupStringList, take info from the gr_* variables.
bool Passwd::updateGroup(int gid) {
QRegExp groupRegExp(QString(":%1\\:").arg(QString::number(gid)));
for(QStringList::Iterator it=groupStringList.begin(); it!=groupStringList.end(); ++it) {
if(groupRegExp.find((*it),0)!=-1) {
*it=QString(gr_name+":*:"+QString::number(gr_gid)+":");
for(QStringList::Iterator member=gr_mem.begin(); member!=gr_mem.end(); ++member) {
*it+=*member;
*it+=" ";
}
return true;
}
}
return false;
}
+// Delete a group from groupStringList.
bool Passwd::deleteGroup(QRegExp &groupRegExp) {
for(QStringList::Iterator it=groupStringList.begin(); it!=groupStringList.end(); ++it) {
if(groupRegExp.find((*it),0)!=-1) {
groupStringList.remove(it);
return true;
}
}
return false;
}
+// Delete a group by groupname.
bool Passwd::delGroup(const char *groupname) {
QRegExp groupRegExp(QString("^%1\\:").arg(groupname));
return deleteGroup(groupRegExp);
}
+// Delete a group by gid.
bool Passwd::delGroup(int gid) {
QRegExp groupRegExp(QString(":%1\\:").arg(gid));
return deleteGroup(groupRegExp);
}
+// Add a user as a member to a group in groupStringList.
bool Passwd::addGroupMember(QString groupname, QString member) {
if(!(findGroup(groupname))) return false;
gr_mem << member;
if(!(updateGroup(gr_gid))) return false;
return true;
}
+// Delete a user as a groupmember from a group in groupStringList.
bool Passwd::delGroupMember(QString groupname, QString member) {
if(!(findGroup(groupname))) return false;
for(QStringList::Iterator it=gr_mem.begin(); it!=gr_mem.end(); ++it) {
if(*it==member) {
gr_mem.remove(it);
it=gr_mem.end();
}
}
if(!(updateGroup(gr_gid))) return false;
return true;
}
+// Global Object
Passwd *accounts;
diff --git a/noncore/settings/usermanager/userdialog.cpp b/noncore/settings/usermanager/userdialog.cpp
index 36bcf86..c82cc9d 100644
--- a/noncore/settings/usermanager/userdialog.cpp
+++ b/noncore/settings/usermanager/userdialog.cpp
@@ -3,65 +3,66 @@
* 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 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "userdialog.h"
#include <qlayout.h>
#include <qlabel.h>
#include <qmessagebox.h>
#include <qfile.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include "passwd.h"
#include <opie/odevice.h>
using namespace Opie;
/**
* UserDialog constructor. Setup the dialog, fill the groupComboBox & groupsListView with all groups.
*
*/
-UserDialog::UserDialog(QWidget* parent, const char* name, bool modal, WFlags fl) : QDialog(parent, name, modal, fl) {
+UserDialog::UserDialog(int viewmode, QWidget* parent, const char* name, bool modal, WFlags fl) : QDialog(parent, name, modal, fl) {
+ vm=viewmode;
QVBoxLayout *layout = new QVBoxLayout(this);
myTabWidget=new QTabWidget(this,"User Tab Widget");
layout->addWidget(myTabWidget);
setupTab1();
setupTab2();
accounts->groupStringList.sort();
// And also fill the listview & the combobox with all available groups.
for( QStringList::Iterator it = accounts->groupStringList.begin(); it!=accounts->groupStringList.end(); ++it) {
accounts->splitGroupEntry(*it);
new QCheckListItem(groupsListView,accounts->gr_name,QCheckListItem::CheckBox);
groupComboBox->insertItem(accounts->gr_name);
}
showMaximized();
}
/**
* Empty destructor.
*
*/
UserDialog::~UserDialog() {
}
/**
* Creates the first tab, all userinfo is here.
*
*/
void UserDialog::setupTab1() {
QPixmap mypixmap;
QWidget *tabpage = new QWidget(myTabWidget,"page1");
QVBoxLayout *layout = new QVBoxLayout(tabpage);
layout->setMargin(5);
@@ -80,152 +81,157 @@ void UserDialog::setupTab1() {
// UID
QLabel *uidLabel=new QLabel(tabpage,"uid: ");
uidLabel->setText("UserID: ");
uidLineEdit=new QLineEdit(tabpage,"uid: ");
uidLineEdit->setEnabled(false);
// Username (gecos)
QLabel *gecosLabel=new QLabel(tabpage,"gecos");
gecosLabel->setText("Username: ");
gecosLineEdit=new QLineEdit(tabpage,"gecos");
// Password
QLabel *passwordLabel=new QLabel(tabpage,"password");
passwordLabel->setText("Password: ");
passwordLineEdit=new QLineEdit(tabpage,"password");
passwordLineEdit->setEchoMode(QLineEdit::Password);
// Shell
QLabel *shellLabel=new QLabel(tabpage,"shell");
shellLabel->setText("Shell: ");
shellComboBox=new QComboBox(tabpage,"shell");
shellComboBox->setEditable(true);
shellComboBox->insertItem("/bin/sh");
shellComboBox->insertItem("/bin/ash");
shellComboBox->insertItem("/bin/false");
// Primary Group
QLabel *groupLabel=new QLabel(tabpage,"group");
groupLabel->setText("Primary group: ");
groupComboBox=new QComboBox(tabpage,"PrimaryGroup");
- // Copy /etc/skel
- QLabel *skelLabel=new QLabel(tabpage,"skel");
- skelLabel->setText("Copy /etc/skel: ");
- skelCheckBox=new QCheckBox(tabpage);
- skelCheckBox->setChecked(true);
-// skelLabel->setDisabled(true);
-// skelCheckBox->setDisabled(true);
+ if(vm==VIEWMODE_NEW) {
+ // Copy /etc/skel
+ skelLabel=new QLabel(tabpage,"skel");
+ skelLabel->setText("Copy /etc/skel: ");
+ skelCheckBox=new QCheckBox(tabpage);
+ skelCheckBox->setChecked(true);
+ }
// Widget layout
QHBoxLayout *hlayout=new QHBoxLayout(-1,"hlayout");
layout->addWidget(picturePushButton);
layout->addSpacing(5);
layout->addLayout(hlayout);
QVBoxLayout *vlayout1=new QVBoxLayout(-1,"vlayout1");
QVBoxLayout *vlayout2=new QVBoxLayout(-1,"vlayout2");
// First column, labels
vlayout1->addWidget(loginLabel);
vlayout1->addSpacing(5);
vlayout1->addWidget(uidLabel);
vlayout1->addSpacing(5);
vlayout1->addWidget(gecosLabel);
vlayout1->addSpacing(5);
vlayout1->addWidget(passwordLabel);
vlayout1->addSpacing(5);
vlayout1->addWidget(shellLabel);
vlayout1->addSpacing(5);
vlayout1->addWidget(groupLabel);
- vlayout1->addSpacing(5);
- vlayout1->addWidget(skelLabel);
+ if(vm==VIEWMODE_NEW) {
+ vlayout1->addSpacing(5);
+ vlayout1->addWidget(skelLabel);
+ }
// Second column, data
vlayout2->addWidget(loginLineEdit);
vlayout2->addSpacing(5);
vlayout2->addWidget(uidLineEdit);
vlayout2->addSpacing(5);
vlayout2->addWidget(gecosLineEdit);
vlayout2->addSpacing(5);
vlayout2->addWidget(passwordLineEdit);
vlayout2->addSpacing(5);
vlayout2->addWidget(shellComboBox);
vlayout2->addSpacing(5);
vlayout2->addWidget(groupComboBox);
- vlayout2->addSpacing(5);
- vlayout2->addWidget(skelCheckBox);
+ if(vm==VIEWMODE_NEW) {
+ vlayout2->addSpacing(5);
+ vlayout2->addWidget(skelCheckBox);
+ }
hlayout->addLayout(vlayout1);
hlayout->addLayout(vlayout2);
myTabWidget->addTab(tabpage,"User Info");
}
/**
* Creates the second tab containing additional groups for the user.
*
*/
void UserDialog::setupTab2() {
QWidget *tabpage = new QWidget(myTabWidget,"page2");
QVBoxLayout *layout = new QVBoxLayout(tabpage);
layout->setMargin(5);
// Additional groups
groupsListView=new QListView(tabpage,"groups");
groupsListView->addColumn("Additional groups");
groupsListView->setColumnWidthMode(0,QListView::Maximum);
groupsListView->setMultiSelection(false);
groupsListView->setAllColumnsShowFocus(false);
layout->addSpacing(5);
// Grouplist
layout->addWidget(groupsListView);
myTabWidget->addTab(tabpage,"User Groups");
}
/**
* Static function that creates the userinfo dialog.
* The user will be prompted to add a user.
*
* @param uid This is a suggested available UID.
* @param gid This is a suggested available GID.
*
* @return <code>true</code> if the user was successfully added, otherwise <code>false</code>.
*
*/
bool UserDialog::addUser(int uid, int gid) {
QCheckListItem *temp;
QFile ozTest;
int oz=false;
if(ODevice::inst()->system()==System_OpenZaurus) oz=true;
- UserDialog *adduserDialog=new UserDialog();
+ // viewmode is a workaround for a bug in qte-2.3.4 that gives bus error on manipulating adduserDialog's widgets here.
+ UserDialog *adduserDialog=new UserDialog(VIEWMODE_NEW);
adduserDialog->setCaption(tr("Add User"));
adduserDialog->userID=uid; // Set next available UID as default uid.
adduserDialog->groupID=gid; // Set next available GID as default gid.
// Insert default group into groupComboBox
adduserDialog->groupComboBox->insertItem("<create new group>",0);
adduserDialog->uidLineEdit->setText(QString::number(uid));
// If we're running on OZ, add new users to some default groups.
if(oz) {
QListViewItemIterator iter( adduserDialog->groupsListView );
for ( ; iter.current(); ++iter ) {
temp=(QCheckListItem*)iter.current();
if (temp->text()=="video") temp->setOn(true);
if (temp->text()=="audio") temp->setOn(true);
if (temp->text()=="time") temp->setOn(true);
if (temp->text()=="power") temp->setOn(true);
if (temp->text()=="input") temp->setOn(true);
if (temp->text()=="sharp") temp->setOn(true);
if (temp->text()=="tty") temp->setOn(true);
}
}
// Show the dialog!
if(!(adduserDialog->exec())) return false;
if((adduserDialog->groupComboBox->currentItem()!=0)) {
accounts->findGroup(adduserDialog->groupComboBox->currentText());
adduserDialog->groupID=accounts->gr_gid;
qWarning(QString::number(accounts->gr_gid));
}
if(!(accounts->addUser(adduserDialog->loginLineEdit->text(), adduserDialog->passwordLineEdit->text(),
adduserDialog->uidLineEdit->text().toInt(), adduserDialog->groupID, adduserDialog->gecosLineEdit->text(),
QString("/home/")+adduserDialog->loginLineEdit->text() , adduserDialog->shellComboBox->currentText()))) {
QMessageBox::information(0,"Ooops!","Something went wrong!\nUnable to add user.");
return false;
@@ -269,65 +275,66 @@ bool UserDialog::addUser(int uid, int gid) {
/**
* Deletes the user account.
*
* @param username User to be deleted.
*
* @return <code>true</code> if the user was successfully deleted, otherwise <code>false</code>.
*
*/
bool UserDialog::delUser(const char *username) {
if((accounts->findUser(username))) { // Does that user exist?
if(!(accounts->delUser(username))) { // Delete the user.
QMessageBox::information(0,"Ooops!","Something went wrong\nUnable to delete user: "+QString(username)+".");
}
} else {
QMessageBox::information(0,"Invalid Username","That username ("+QString(username)+")does not exist.");
return false;
}
return true;
}
/**
* This displays a confirmation dialog wether a user should be deleted or not.
* (And also deletes the account)
*
* @param username User to be deleted.
*
* @return <code>true</code> if the user was successfully deleted, otherwise <code>false</code>.
*
*/
bool UserDialog::editUser(const char *username) {
int invalid_group=0;
- UserDialog *edituserDialog=new UserDialog(); // Create Dialog
+ // viewmode is a workaround for a bug in qte-2.3.4 that gives bus error on manipulating edituserDialog's widgets here.
+ UserDialog *edituserDialog=new UserDialog(VIEWMODE_EDIT); // Create Dialog
edituserDialog->setCaption(tr("Edit User"));
accounts->findUser(username); // Locate user in database and fill variables in 'accounts' object.
if(!(accounts->findGroup(accounts->pw_gid))) { // Locate the user's primary group, and fill group variables in 'accounts' object.
invalid_group=1;
}
// Fill widgets with userinfo.
edituserDialog->loginLineEdit->setText(accounts->pw_name);
edituserDialog->uidLineEdit->setText(QString::number(accounts->pw_uid));
edituserDialog->gecosLineEdit->setText(accounts->pw_gecos);
// Set password to '........', we will later check if this still is the contents, if not, the password has been changed.
edituserDialog->passwordLineEdit->setText("........");
// If this user is not using /bin/sh,/bin/ash or /bin/false as shell, add that entry to the shell-combobox.
if(accounts->pw_shell!="/bin/sh" && accounts->pw_shell!="/bin/ash" && accounts->pw_shell!="/bin/false") {
edituserDialog->shellComboBox->insertItem(accounts->pw_shell,0);
edituserDialog->shellComboBox->setCurrentItem(0);
}
// Select the primary group for this user.
for(int i=0;i<edituserDialog->groupComboBox->count();++i) {
if(accounts->gr_name==edituserDialog->groupComboBox->text(i)) {
edituserDialog->groupComboBox->setCurrentItem(i);
break;
}
}
if(invalid_group) {
edituserDialog->groupComboBox->insertItem("<Undefined group>",0);
edituserDialog->groupComboBox->setCurrentItem(0);
}
// Select the groups in the listview, to which the user belongs.
QCheckListItem *temp;
QRegExp userRegExp(QString("[:\\s]%1\\s").arg(username));
QStringList tempList=accounts->groupStringList.grep(userRegExp); // Find all entries in the group database, that the user is a member of.
for(QStringList::Iterator it=tempList.begin(); it!=tempList.end(); ++it) { // Iterate over all of them.
diff --git a/noncore/settings/usermanager/userdialog.h b/noncore/settings/usermanager/userdialog.h
index 133b35d..b7b925d 100644
--- a/noncore/settings/usermanager/userdialog.h
+++ b/noncore/settings/usermanager/userdialog.h
@@ -13,49 +13,54 @@
#include <qlineedit.h>
#include <qcombobox.h>
#include <qlistview.h>
#include <qtabwidget.h>
#include <qpushbutton.h>
#include <qcheckbox.h>
#include <qpe/resource.h>
#include <opie/ofiledialog.h>
class UserDialog : public QDialog
{
Q_OBJECT
private:
QTabWidget *myTabWidget;
QPushButton *picturePushButton;
QLineEdit *loginLineEdit;
QLineEdit *uidLineEdit;
QLineEdit *gecosLineEdit;
QLineEdit *passwordLineEdit;
QComboBox *shellComboBox;
QComboBox *groupComboBox;
QLabel *skelLabel;
QCheckBox *skelCheckBox;
QListView *groupsListView;
QStringList groupMembers;
QString pictureLocation;
QImage userImage;
int groupID;
int userID;
-
+ int vm;
+ enum VIEWMODE {
+ VIEWMODE_NEW,
+ VIEWMODE_EDIT
+ };
+
void setupTab1(void);
void setupTab2(void);
void accept(void);
private slots:
void clickedPicture(void);
public:
- UserDialog( QWidget* parent = 0, const char* name = 0, bool modal=true, WFlags fl = 0 );
+ UserDialog( int viewmode=VIEWMODE_NEW, QWidget* parent = 0, const char* name = 0, bool modal=true, WFlags fl = 0 );
~UserDialog();
static bool addUser(int uid, int gid);
static bool editUser(const char *username);
static bool delUser(const char *username);
};
#endif