-rw-r--r-- | noncore/settings/usermanager/groupdialog.cpp | 106 | ||||
-rw-r--r-- | noncore/settings/usermanager/groupdialog.h | 36 | ||||
-rw-r--r-- | noncore/settings/usermanager/main.cpp | 19 | ||||
-rw-r--r-- | noncore/settings/usermanager/opie-usermanager.control | 10 | ||||
-rw-r--r-- | noncore/settings/usermanager/passwd.cpp | 271 | ||||
-rw-r--r-- | noncore/settings/usermanager/passwd.h | 85 | ||||
-rw-r--r-- | noncore/settings/usermanager/userdialog.cpp | 319 | ||||
-rw-r--r-- | noncore/settings/usermanager/userdialog.h | 55 | ||||
-rw-r--r-- | noncore/settings/usermanager/usermanager.cpp | 242 | ||||
-rw-r--r-- | noncore/settings/usermanager/usermanager.h | 65 | ||||
-rw-r--r-- | noncore/settings/usermanager/usermanager.pro | 10 |
11 files changed, 1218 insertions, 0 deletions
diff --git a/noncore/settings/usermanager/groupdialog.cpp b/noncore/settings/usermanager/groupdialog.cpp new file mode 100644 index 0000000..b595d31 --- a/dev/null +++ b/noncore/settings/usermanager/groupdialog.cpp | |||
@@ -0,0 +1,106 @@ | |||
1 | /*************************************************************************** | ||
2 | * * | ||
3 | * This program is free software; you can redistribute it and/or modify * | ||
4 | * it under the terms of the GNU General Public License as published by * | ||
5 | * the Free Software Foundation; either version 2 of the License, or * | ||
6 | * (at your option) any later version. * | ||
7 | * * | ||
8 | ***************************************************************************/ | ||
9 | |||
10 | #include "groupdialog.h" | ||
11 | |||
12 | #include <qlabel.h> | ||
13 | #include <qlayout.h> | ||
14 | #include <qmessagebox.h> | ||
15 | |||
16 | #include <stdlib.h> | ||
17 | |||
18 | #include "passwd.h" | ||
19 | |||
20 | GroupDialog::GroupDialog(QWidget* parent, const char* name, bool modal, WFlags fl) : QDialog(parent, name, modal, fl) { | ||
21 | // GID | ||
22 | QLabel *gidLabel=new QLabel(this,"gid: "); | ||
23 | gidLabel->setText("GroupID: "); | ||
24 | gidLineEdit=new QLineEdit(this,"gid: "); | ||
25 | gidLineEdit->setEnabled(false); | ||
26 | |||
27 | // Groupname | ||
28 | QLabel *groupnameLabel=new QLabel(this,"groupname"); | ||
29 | groupnameLabel->setText("Groupname: "); | ||
30 | groupnameLineEdit=new QLineEdit(this,"groupname"); | ||
31 | |||
32 | // Widget layout | ||
33 | QVBoxLayout *layout=new QVBoxLayout(this); | ||
34 | layout->setMargin(5); | ||
35 | QHBoxLayout *hlayout=new QHBoxLayout(-1,"hlayout"); | ||
36 | layout->addLayout(hlayout); | ||
37 | QVBoxLayout *vlayout1=new QVBoxLayout(-1,"vlayout1"); | ||
38 | QVBoxLayout *vlayout2=new QVBoxLayout(-1,"vlayout2"); | ||
39 | // First column, labels | ||
40 | vlayout1->addWidget(gidLabel); | ||
41 | vlayout1->addWidget(groupnameLabel); | ||
42 | // Second column, data | ||
43 | vlayout2->addWidget(gidLineEdit); | ||
44 | vlayout2->addWidget(groupnameLineEdit); | ||
45 | hlayout->addLayout(vlayout1); | ||
46 | hlayout->addLayout(vlayout2); | ||
47 | layout->addSpacing(5); | ||
48 | |||
49 | //showMaximized(); | ||
50 | } | ||
51 | |||
52 | GroupDialog::~GroupDialog() { | ||
53 | } | ||
54 | |||
55 | bool GroupDialog::addGroup(int gid) { | ||
56 | GroupDialog *addgroupDialog=new GroupDialog();// Make a groupinfo dialog. | ||
57 | addgroupDialog->setCaption(tr("Add Group"));// Set the caption. | ||
58 | addgroupDialog->gidLineEdit->setText(QString::number(gid));// Set the next available gid. | ||
59 | if(!(addgroupDialog->exec())) return false;// View the dialog, and only continue if 'ok' was pressed. | ||
60 | if(!(accounts->addGroup(addgroupDialog->groupnameLineEdit->text(),addgroupDialog->gidLineEdit->text().toInt()))) {// Try to add the group. | ||
61 | QMessageBox::information(0,"Ooops!","Something went wrong.\nUnable to add group."); | ||
62 | return false; | ||
63 | } | ||
64 | return true; | ||
65 | } | ||
66 | |||
67 | bool GroupDialog::editGroup(int gid) { | ||
68 | GroupDialog *addgroupDialog=new GroupDialog();// Create the groupinfo dialog. | ||
69 | accounts->findGroup(gid);// Locate the group in the database, and fill out the variables in 'accounts'. | ||
70 | // Fill out the widgets with previous data for this group. | ||
71 | addgroupDialog->setCaption(tr("Edit Group")); | ||
72 | addgroupDialog->gidLineEdit->setText(QString::number(accounts->gr_gid)); | ||
73 | addgroupDialog->groupnameLineEdit->setText(accounts->gr_name); | ||
74 | if(!(addgroupDialog->exec())) return false;// View the dialog, and only continue if 'ok' was pressed. | ||
75 | accounts->findGroup(gid);// Locate the group, and fill out the variables in 'accounts' with all info about the group. | ||
76 | accounts->gr_name=addgroupDialog->groupnameLineEdit->text();// Change the name | ||
77 | accounts->gr_gid=addgroupDialog->gidLineEdit->text().toInt();// Change the GID. (Unneeded as its disabled right now.) | ||
78 | accounts->updateGroup(gid);// Update the database with the variables (gr_name,gr_gid,gr_mem) in 'accounts'. | ||
79 | return true; | ||
80 | } | ||
81 | |||
82 | bool GroupDialog::delGroup(const char *groupname) { | ||
83 | if((accounts->findGroup(groupname))) {// Does this group exist? | ||
84 | if(!(accounts->delGroup(groupname))) {// Try to delete it. | ||
85 | QMessageBox::information(0,"Ooops!","Something went wrong\nUnable to delete group: "+QString(groupname)+"."); | ||
86 | } | ||
87 | } else { | ||
88 | QMessageBox::information(0,"Invalid Groupname","That groupname ("+QString(groupname)+")does not exist."); | ||
89 | return false; | ||
90 | } | ||
91 | return true; | ||
92 | } | ||
93 | |||
94 | void GroupDialog::accept() { | ||
95 | // Check if gid is already taken. | ||
96 | //if((accounts->findGroup(gidLineEdit->text().toInt()))) { | ||
97 | // QMessageBox::information(this,"GroupID taken","That GroupID is already taken."); | ||
98 | // return; | ||
99 | //} | ||
100 | // Check if groupname is already taken. | ||
101 | if((accounts->findGroup(groupnameLineEdit->text()))) { | ||
102 | QMessageBox::information(0,"Groupname taken","That groupname is already taken."); | ||
103 | return;// Don't close the dialog. | ||
104 | } | ||
105 | QDialog::accept(); | ||
106 | } | ||
diff --git a/noncore/settings/usermanager/groupdialog.h b/noncore/settings/usermanager/groupdialog.h new file mode 100644 index 0000000..8b37039 --- a/dev/null +++ b/noncore/settings/usermanager/groupdialog.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /*************************************************************************** | ||
2 | * * | ||
3 | * This program is free software; you can redistribute it and/or modify * | ||
4 | * it under the terms of the GNU General Public License as published by * | ||
5 | * the Free Software Foundation; either version 2 of the License, or * | ||
6 | * (at your option) any later version. * | ||
7 | * * | ||
8 | ***************************************************************************/ | ||
9 | |||
10 | #ifndef GROUPDIALOG_H | ||
11 | #define GROUPDIALOG_H | ||
12 | |||
13 | #include <qdialog.h> | ||
14 | #include <qlineedit.h> | ||
15 | |||
16 | class GroupDialog : public QDialog | ||
17 | { | ||
18 | Q_OBJECT | ||
19 | private: | ||
20 | QStringgid; | ||
21 | QStringgroupname; | ||
22 | QLineEdit *gidLineEdit; | ||
23 | QLineEdit *groupnameLineEdit; | ||
24 | int execStatus; | ||
25 | |||
26 | void accept(void); | ||
27 | |||
28 | public: | ||
29 | GroupDialog( QWidget* parent = 0, const char* name = 0, bool modal=true, WFlags fl = 0 ); | ||
30 | ~GroupDialog(); | ||
31 | static bool addGroup(int gid); | ||
32 | static bool delGroup(const char *groupname); | ||
33 | static bool editGroup(int gid); | ||
34 | }; | ||
35 | |||
36 | #endif | ||
diff --git a/noncore/settings/usermanager/main.cpp b/noncore/settings/usermanager/main.cpp new file mode 100644 index 0000000..aa78286 --- a/dev/null +++ b/noncore/settings/usermanager/main.cpp | |||
@@ -0,0 +1,19 @@ | |||
1 | /*************************************************************************** | ||
2 | * * | ||
3 | * This program is free software; you can redistribute it and/or modify * | ||
4 | * it under the terms of the GNU General Public License as published by * | ||
5 | * the Free Software Foundation; either version 2 of the License, or * | ||
6 | * (at your option) any later version. * | ||
7 | * * | ||
8 | ***************************************************************************/ | ||
9 | |||
10 | #include "usermanager.h" | ||
11 | #include <qpe/qpeapplication.h> | ||
12 | |||
13 | int main( int argc, char ** argv ) | ||
14 | { | ||
15 | QPEApplication a( argc, argv ); | ||
16 | UserConfig mw(0,0,0); | ||
17 | a.showMainWidget( &mw ); | ||
18 | return a.exec(); | ||
19 | } | ||
diff --git a/noncore/settings/usermanager/opie-usermanager.control b/noncore/settings/usermanager/opie-usermanager.control new file mode 100644 index 0000000..956d98e --- a/dev/null +++ b/noncore/settings/usermanager/opie-usermanager.control | |||
@@ -0,0 +1,10 @@ | |||
1 | Package: userconfig | ||
2 | Files: bin/usermanager apps/Settings/usermanager.desktop pics/userconfig/* | ||
3 | Priority: optional | ||
4 | Section: opie/settings | ||
5 | Version: $QPE_VERSION-$SUB_VERSION-0.9 | ||
6 | Depends: opie-base ($QPE_VERSION) | ||
7 | Architecture: arm | ||
8 | Maintainer: Ted Parnefors <zaurus@bredband.net> | ||
9 | License: GPL | ||
10 | Description: User/Group manager for OPIE. | ||
diff --git a/noncore/settings/usermanager/passwd.cpp b/noncore/settings/usermanager/passwd.cpp new file mode 100644 index 0000000..310cef8 --- a/dev/null +++ b/noncore/settings/usermanager/passwd.cpp | |||
@@ -0,0 +1,271 @@ | |||
1 | /*************************************************************************** | ||
2 | * * | ||
3 | * This program is free software; you can redistribute it and/or modify * | ||
4 | * it under the terms of the GNU General Public License as published by * | ||
5 | * the Free Software Foundation; either version 2 of the License, or * | ||
6 | * (at your option) any later version. * | ||
7 | * * | ||
8 | ***************************************************************************/ | ||
9 | |||
10 | #include "passwd.h" | ||
11 | |||
12 | // Needed for crypt_make_salt(); | ||
13 | #include <sys/types.h> | ||
14 | #include <unistd.h> | ||
15 | #include <time.h> | ||
16 | |||
17 | Passwd::Passwd() { | ||
18 | } | ||
19 | |||
20 | Passwd::~Passwd() { | ||
21 | } | ||
22 | |||
23 | // This function is taken from 'busybox'. | ||
24 | int Passwd::i64c(int i) | ||
25 | { | ||
26 | if (i <= 0) | ||
27 | return ('.'); | ||
28 | if (i == 1) | ||
29 | return ('/'); | ||
30 | if (i >= 2 && i < 12) | ||
31 | return ('0' - 2 + i); | ||
32 | if (i >= 12 && i < 38) | ||
33 | return ('A' - 12 + i); | ||
34 | if (i >= 38 && i < 63) | ||
35 | return ('a' - 38 + i); | ||
36 | return ('z'); | ||
37 | } | ||
38 | |||
39 | // This function is taken from 'busybox'. | ||
40 | char *Passwd::crypt_make_salt() { | ||
41 | time_t now; | ||
42 | static unsigned long x; | ||
43 | static char result[3]; | ||
44 | |||
45 | time(&now); | ||
46 | x += now + getpid() + clock(); | ||
47 | result[0] = i64c(((x >> 18) ^ (x >> 6)) & 077); | ||
48 | result[1] = i64c(((x >> 12) ^ x) & 077); | ||
49 | result[2] = '\0'; | ||
50 | return result; | ||
51 | } | ||
52 | |||
53 | bool Passwd::open() { | ||
54 | int returnvalue=false; | ||
55 | |||
56 | QFile passwd_file("/etc/passwd"); | ||
57 | QFile group_file("/etc/group"); | ||
58 | passwdStringList.clear(); | ||
59 | groupStringList.clear(); | ||
60 | if((passwd_file.open(IO_ReadOnly))) { | ||
61 | if((group_file.open(IO_ReadOnly))) { | ||
62 | QTextStream ts_passwd(&passwd_file); | ||
63 | while(!(ts_passwd.eof())) { | ||
64 | passwdStringList << ts_passwd.readLine(); | ||
65 | } | ||
66 | QTextStream ts_group(&group_file); | ||
67 | while(!(ts_group.eof())) { | ||
68 | groupStringList << ts_group.readLine(); | ||
69 | } | ||
70 | returnvalue=true; | ||
71 | group_file.close(); | ||
72 | } | ||
73 | passwd_file.close(); | ||
74 | } | ||
75 | return returnvalue; | ||
76 | } | ||
77 | |||
78 | bool Passwd::close() { | ||
79 | int returnvalue=false; | ||
80 | QFile passwd_file("/etc/passwd"); | ||
81 | QFile group_file("/etc/group"); | ||
82 | if((passwd_file.open(IO_WriteOnly))) { | ||
83 | if((group_file.open(IO_WriteOnly))) { | ||
84 | QTextStream ts_passwd(&passwd_file); | ||
85 | for(QStringList::Iterator it=passwdStringList.begin(); it!=passwdStringList.end(); ++it) { | ||
86 | ts_passwd << (*it) + "\n"; | ||
87 | } | ||
88 | QTextStream ts_group(&group_file); | ||
89 | for(QStringList::Iterator it=groupStringList.begin(); it!=groupStringList.end(); ++it) { | ||
90 | ts_group << (*it) + "\n"; | ||
91 | } | ||
92 | returnvalue=true; | ||
93 | group_file.close(); | ||
94 | } | ||
95 | passwd_file.close(); | ||
96 | } | ||
97 | return returnvalue; | ||
98 | } | ||
99 | |||
100 | void Passwd::splitPasswdEntry(QString &userString) { | ||
101 | userdataStringList=QStringList::split(":",userString,true); | ||
102 | QStringList::Iterator it=userdataStringList.begin(); | ||
103 | pw_name=(*it++); | ||
104 | pw_passwd=(*it++); | ||
105 | pw_uid=(*it++).toInt(); | ||
106 | pw_gid=(*it++).toInt(); | ||
107 | pw_gecos=(*it++); | ||
108 | pw_dir=(*it++); | ||
109 | pw_shell=(*it++); | ||
110 | } | ||
111 | |||
112 | void Passwd::splitGroupEntry(QString &groupString) { | ||
113 | groupdataStringList=QStringList::split(":",groupString,true); | ||
114 | QStringList::Iterator it=groupdataStringList.begin(); | ||
115 | gr_name=(*it++); | ||
116 | it++; | ||
117 | gr_gid=(*it++).toInt(); | ||
118 | gr_mem=QStringList::split(" ",(*it++)); | ||
119 | } | ||
120 | |||
121 | bool Passwd::searchUser(QRegExp &userRegExp) { | ||
122 | QStringList tempStringList(passwdStringList.grep(userRegExp)); | ||
123 | if((tempStringList.isEmpty())) { | ||
124 | return false; | ||
125 | } else { | ||
126 | userString=(*(tempStringList.begin())); | ||
127 | splitPasswdEntry(userString); | ||
128 | } | ||
129 | return true; | ||
130 | } | ||
131 | |||
132 | bool Passwd::findUser(const char *username) { | ||
133 | QRegExp userRegExp(QString("^%1\\:").arg(username)); | ||
134 | return searchUser(userRegExp); | ||
135 | } | ||
136 | |||
137 | bool Passwd::findUser(int uid) { | ||
138 | QRegExp userRegExp(QString(":%1\\:").arg(uid)); | ||
139 | return searchUser(userRegExp); | ||
140 | } | ||
141 | |||
142 | 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=true) { | ||
143 | QString tempString; | ||
144 | if((createGroup) && (!(findGroup(pw_gid)))) addGroup(pw_name,pw_gid); | ||
145 | pw_passwd = crypt(pw_passwd, crypt_make_salt()); | ||
146 | tempString=pw_name+":"+pw_passwd+":"+QString::number(pw_uid)+":"+QString::number(pw_gid)+":"+pw_gecos+":"+pw_dir+":"+pw_shell; | ||
147 | passwdStringList.append(tempString); | ||
148 | // Make home dir. | ||
149 | QDir d; | ||
150 | if(!(d.exists(pw_dir))) { | ||
151 | d.mkdir(pw_dir); | ||
152 | } | ||
153 | return 1; | ||
154 | } | ||
155 | |||
156 | bool Passwd::updateUser(QString login) { | ||
157 | QRegExp userRegExp(QString("^%1\\:").arg(login)); | ||
158 | for(QStringList::Iterator it=passwdStringList.begin(); it!=passwdStringList.end(); ++it) { | ||
159 | if(userRegExp.find((*it),0)!=-1) { | ||
160 | *it=QString(pw_name+":"+pw_passwd+":"+QString::number(pw_uid)+":"+QString::number(pw_gid)+":"+pw_gecos+":"+pw_dir+":"+pw_shell); | ||
161 | return true; | ||
162 | } | ||
163 | } | ||
164 | return false; | ||
165 | } | ||
166 | |||
167 | bool Passwd::deleteUser(QRegExp &userRegExp, bool delGroup) { | ||
168 | for(QStringList::Iterator it=passwdStringList.begin(); it!=passwdStringList.end(); ++it) { | ||
169 | if(userRegExp.find((*it),0)!=-1) { | ||
170 | splitPasswdEntry(*it); | ||
171 | if(delGroup) this->delGroup(pw_gid); | ||
172 | passwdStringList.remove(it); | ||
173 | return true; | ||
174 | } | ||
175 | } | ||
176 | return false; | ||
177 | } | ||
178 | |||
179 | bool Passwd::delUser(const char *username, bool delGroup) { | ||
180 | QRegExp userRegExp(QString("^%1\\:").arg(username)); | ||
181 | return deleteUser(userRegExp,delGroup); | ||
182 | } | ||
183 | |||
184 | bool Passwd::delUser(int uid, bool delGroup) { | ||
185 | QRegExp userRegExp(QString(":%1\\:").arg(uid)); | ||
186 | return deleteUser(userRegExp,delGroup); | ||
187 | } | ||
188 | |||
189 | bool Passwd::searchGroup(QRegExp &groupRegExp) { | ||
190 | QStringList tempStringList(groupStringList.grep(groupRegExp)); | ||
191 | if((tempStringList.isEmpty())) { | ||
192 | return false; | ||
193 | } else { | ||
194 | groupString=(*(tempStringList.begin())); | ||
195 | splitGroupEntry(groupString); | ||
196 | } | ||
197 | return true; | ||
198 | } | ||
199 | |||
200 | bool Passwd::findGroup(const char *groupname) { | ||
201 | QRegExp groupRegExp(QString("^%1\\:").arg(groupname)); | ||
202 | return searchGroup(groupRegExp); | ||
203 | } | ||
204 | |||
205 | bool Passwd::findGroup(int gid) { | ||
206 | QRegExp groupRegExp(QString(":%1\\:").arg(gid)); | ||
207 | return searchGroup(groupRegExp); | ||
208 | } | ||
209 | |||
210 | bool Passwd::addGroup(QString gr_name, int gr_gid) { | ||
211 | QString tempString; | ||
212 | tempString=gr_name+":*:"+QString::number(gr_gid)+":"; | ||
213 | groupStringList.append(tempString); | ||
214 | return 1; | ||
215 | } | ||
216 | |||
217 | bool Passwd::updateGroup(int gid) { | ||
218 | QRegExp groupRegExp(QString(":%1\\:").arg(QString::number(gid))); | ||
219 | for(QStringList::Iterator it=groupStringList.begin(); it!=groupStringList.end(); ++it) { | ||
220 | if(groupRegExp.find((*it),0)!=-1) { | ||
221 | *it=QString(gr_name+":*:"+QString::number(gr_gid)+":"); | ||
222 | for(QStringList::Iterator member=gr_mem.begin(); member!=gr_mem.end(); ++member) { | ||
223 | *it+=*member; | ||
224 | *it+=" "; | ||
225 | } | ||
226 | return true; | ||
227 | } | ||
228 | } | ||
229 | return false; | ||
230 | } | ||
231 | |||
232 | bool Passwd::deleteGroup(QRegExp &groupRegExp) { | ||
233 | for(QStringList::Iterator it=groupStringList.begin(); it!=groupStringList.end(); ++it) { | ||
234 | if(groupRegExp.find((*it),0)!=-1) { | ||
235 | groupStringList.remove(it); | ||
236 | return true; | ||
237 | } | ||
238 | } | ||
239 | return false; | ||
240 | } | ||
241 | |||
242 | bool Passwd::delGroup(const char *groupname) { | ||
243 | QRegExp groupRegExp(QString("^%1\\:").arg(groupname)); | ||
244 | return deleteGroup(groupRegExp); | ||
245 | } | ||
246 | |||
247 | bool Passwd::delGroup(int gid) { | ||
248 | QRegExp groupRegExp(QString(":%1\\:").arg(gid)); | ||
249 | return deleteGroup(groupRegExp); | ||
250 | } | ||
251 | |||
252 | bool Passwd::addGroupMember(QString groupname, QString member) { | ||
253 | if(!(findGroup(groupname))) return false; | ||
254 | gr_mem << member; | ||
255 | if(!(updateGroup(gr_gid))) return false; | ||
256 | return true; | ||
257 | } | ||
258 | |||
259 | bool Passwd::delGroupMember(QString groupname, QString member) { | ||
260 | if(!(findGroup(groupname))) return false; | ||
261 | for(QStringList::Iterator it=gr_mem.begin(); it!=gr_mem.end(); ++it) { | ||
262 | if(*it==member) { | ||
263 | gr_mem.remove(it); | ||
264 | it=gr_mem.end(); | ||
265 | } | ||
266 | } | ||
267 | if(!(updateGroup(gr_gid))) return false; | ||
268 | return true; | ||
269 | } | ||
270 | |||
271 | Passwd *accounts; | ||
diff --git a/noncore/settings/usermanager/passwd.h b/noncore/settings/usermanager/passwd.h new file mode 100644 index 0000000..37c41dc --- a/dev/null +++ b/noncore/settings/usermanager/passwd.h | |||
@@ -0,0 +1,85 @@ | |||
1 | /*************************************************************************** | ||
2 | * * | ||
3 | * This program is free software; you can redistribute it and/or modify * | ||
4 | * it under the terms of the GNU General Public License as published by * | ||
5 | * the Free Software Foundation; either version 2 of the License, or * | ||
6 | * (at your option) any later version. * | ||
7 | * * | ||
8 | ***************************************************************************/ | ||
9 | |||
10 | #ifndef PASSWD_H | ||
11 | #define PASSWD_H | ||
12 | |||
13 | #include <qobject.h> | ||
14 | #include <qfile.h> | ||
15 | #include <qstring.h> | ||
16 | #include <qstringlist.h> | ||
17 | #include <qtextstream.h> | ||
18 | #include <qregexp.h> | ||
19 | #include <qdir.h> | ||
20 | |||
21 | #include <crypt.h> | ||
22 | #include <pwd.h> | ||
23 | #include <grp.h> | ||
24 | |||
25 | class Passwd | ||
26 | { | ||
27 | public: | ||
28 | QStringList passwdStringList;// List of all users (name,passwd,uid,gid,gecos,dir,shell) | ||
29 | QStringList groupStringList;// List of all groups (name,gid,mem) | ||
30 | |||
31 | // pwentry | ||
32 | QString pw_name; | ||
33 | QString pw_passwd; | ||
34 | int pw_uid; | ||
35 | int pw_gid; | ||
36 | QString pw_gecos; | ||
37 | QString pw_dir; | ||
38 | QString pw_shell; | ||
39 | |||
40 | // grentry | ||
41 | QString gr_name; | ||
42 | int gr_gid; | ||
43 | QStringList gr_mem; | ||
44 | |||
45 | Passwd(void); | ||
46 | ~Passwd(void); | ||
47 | bool open(void); | ||
48 | bool close(void); | ||
49 | char *crypt_make_salt(void); | ||
50 | void splitPasswdEntry(QString &userString); | ||
51 | void splitGroupEntry(QString &groupString); | ||
52 | bool findUser(const char *username); | ||
53 | bool findUser(int uid); | ||
54 | bool addUser(QString pw_name, QString pw_passwd, int pw_uid, int pw_gid, QString pw_gecos, QString pw_dir, QString pw_shell, bool createGroup=true); | ||
55 | bool updateUser(QString login); | ||
56 | bool delUser(const char *username, bool delGroup=true); | ||
57 | bool delUser(int uid, bool delGroup=true); | ||
58 | bool findGroup(const char *groupname); | ||
59 | bool findGroup(int gid); | ||
60 | bool addGroup(QString gr_name, int gr_gid); | ||
61 | bool updateGroup(int gid); | ||
62 | bool delGroup(const char *groupname); | ||
63 | bool delGroup(int gid); | ||
64 | bool addGroupMember(QString groupname,QString member); | ||
65 | bool delGroupMember(QString groupname,QString member); | ||
66 | |||
67 | private: | ||
68 | QString userString; | ||
69 | QString groupString; | ||
70 | |||
71 | int i64c(int i); | ||
72 | bool searchUser(QRegExp &userRegExp); | ||
73 | bool deleteUser(QRegExp &userRegExp, bool delGroup); | ||
74 | bool searchGroup(QRegExp &groupRegExp); | ||
75 | bool deleteGroup(QRegExp &groupRegExp); | ||
76 | QStringList userdataStringList; | ||
77 | QStringList groupdataStringList; | ||
78 | |||
79 | QFile *passwd_file; | ||
80 | QFile *group_file; | ||
81 | }; | ||
82 | |||
83 | extern Passwd *accounts;// Create a global object. | ||
84 | |||
85 | #endif | ||
diff --git a/noncore/settings/usermanager/userdialog.cpp b/noncore/settings/usermanager/userdialog.cpp new file mode 100644 index 0000000..892fc8a --- a/dev/null +++ b/noncore/settings/usermanager/userdialog.cpp | |||
@@ -0,0 +1,319 @@ | |||
1 | /*************************************************************************** | ||
2 | * * | ||
3 | * This program is free software; you can redistribute it and/or modify * | ||
4 | * it under the terms of the GNU General Public License as published by * | ||
5 | * the Free Software Foundation; either version 2 of the License, or * | ||
6 | * (at your option) any later version. * | ||
7 | * * | ||
8 | ***************************************************************************/ | ||
9 | |||
10 | #include "userdialog.h" | ||
11 | |||
12 | #include <qlayout.h> | ||
13 | #include <qlabel.h> | ||
14 | #include <qmessagebox.h> | ||
15 | |||
16 | #include <stdlib.h> | ||
17 | |||
18 | #include <stdio.h> | ||
19 | #include <sys/types.h> | ||
20 | #include <sys/wait.h> | ||
21 | #include <unistd.h> | ||
22 | #include <signal.h> | ||
23 | |||
24 | #include "passwd.h" | ||
25 | |||
26 | /** | ||
27 | * UserDialog constructor. Setup the dialog, fill the groupComboBox & groupsListView with all groups. | ||
28 | * | ||
29 | */ | ||
30 | UserDialog::UserDialog(QWidget* parent, const char* name, bool modal, WFlags fl) : QDialog(parent, name, modal, fl) { | ||
31 | QVBoxLayout *layout = new QVBoxLayout(this); | ||
32 | myTabWidget=new QTabWidget(this,"User Tab Widget"); | ||
33 | layout->addWidget(myTabWidget); | ||
34 | setupTab1(); | ||
35 | setupTab2(); | ||
36 | |||
37 | // And also fill the listview & the combobox with all available groups. | ||
38 | for( QStringList::Iterator it = accounts->groupStringList.begin(); it!=accounts->groupStringList.end(); ++it) { | ||
39 | accounts->splitGroupEntry(*it); | ||
40 | new QListViewItem(groupsListView,accounts->gr_name); | ||
41 | groupComboBox->insertItem(accounts->gr_name); | ||
42 | } | ||
43 | |||
44 | showMaximized(); | ||
45 | } | ||
46 | |||
47 | /** | ||
48 | * Empty destructor. | ||
49 | * | ||
50 | */ | ||
51 | UserDialog::~UserDialog() { | ||
52 | } | ||
53 | |||
54 | /** | ||
55 | * Creates the first tab, all userinfo is here. | ||
56 | * | ||
57 | */ | ||
58 | void UserDialog::setupTab1() { | ||
59 | QPixmap mypixmap; | ||
60 | QWidget *tabpage = new QWidget(myTabWidget,"page1"); | ||
61 | QVBoxLayout *layout = new QVBoxLayout(tabpage); | ||
62 | layout->setMargin(5); | ||
63 | |||
64 | // Picture | ||
65 | picturePushButton = new QPushButton(tabpage,"Label"); | ||
66 | picturePushButton->setMinimumSize(48,48); | ||
67 | picturePushButton->setMaximumSize(48,48); | ||
68 | picturePushButton->setPixmap(Resource::loadPixmap("userconfig/usericon"));// Load default usericon. | ||
69 | connect(picturePushButton,SIGNAL(clicked()),this,SLOT(clickedPicture()));// Clicking the picture should invoke pictureselector. | ||
70 | |||
71 | // Login | ||
72 | QLabel *loginLabel=new QLabel(tabpage,"Login: "); | ||
73 | loginLabel->setText("Login: "); | ||
74 | loginLineEdit=new QLineEdit(tabpage,"Login: "); | ||
75 | |||
76 | // UID | ||
77 | QLabel *uidLabel=new QLabel(tabpage,"uid: "); | ||
78 | uidLabel->setText("UserID: "); | ||
79 | uidLineEdit=new QLineEdit(tabpage,"uid: "); | ||
80 | uidLineEdit->setEnabled(false); | ||
81 | |||
82 | // Username (gecos) | ||
83 | QLabel *gecosLabel=new QLabel(tabpage,"gecos"); | ||
84 | gecosLabel->setText("Username: "); | ||
85 | gecosLineEdit=new QLineEdit(tabpage,"gecos"); | ||
86 | |||
87 | // Password | ||
88 | QLabel *passwordLabel=new QLabel(tabpage,"password"); | ||
89 | passwordLabel->setText("Password: "); | ||
90 | passwordLineEdit=new QLineEdit(tabpage,"password"); | ||
91 | passwordLineEdit->setEchoMode(QLineEdit::Password); | ||
92 | |||
93 | // Shell | ||
94 | QLabel *shellLabel=new QLabel(tabpage,"shell"); | ||
95 | shellLabel->setText("Shell: "); | ||
96 | shellComboBox=new QComboBox(tabpage,"shell"); | ||
97 | shellComboBox->setEditable(true); | ||
98 | shellComboBox->insertItem("/bin/sh"); | ||
99 | shellComboBox->insertItem("/bin/ash"); | ||
100 | shellComboBox->insertItem("/bin/false"); | ||
101 | |||
102 | // Primary Group | ||
103 | QLabel *groupLabel=new QLabel(tabpage,"group"); | ||
104 | groupLabel->setText("Primary group: "); | ||
105 | groupComboBox=new QComboBox(tabpage,"PrimaryGroup"); | ||
106 | |||
107 | // Widget layout | ||
108 | QHBoxLayout *hlayout=new QHBoxLayout(-1,"hlayout"); | ||
109 | layout->addWidget(picturePushButton); | ||
110 | layout->addSpacing(5); | ||
111 | layout->addLayout(hlayout); | ||
112 | QVBoxLayout *vlayout1=new QVBoxLayout(-1,"vlayout1"); | ||
113 | QVBoxLayout *vlayout2=new QVBoxLayout(-1,"vlayout2"); | ||
114 | // First column, labels | ||
115 | vlayout1->addWidget(loginLabel); | ||
116 | vlayout1->addSpacing(5); | ||
117 | vlayout1->addWidget(uidLabel); | ||
118 | vlayout1->addSpacing(5); | ||
119 | vlayout1->addWidget(gecosLabel); | ||
120 | vlayout1->addSpacing(5); | ||
121 | vlayout1->addWidget(passwordLabel); | ||
122 | vlayout1->addSpacing(5); | ||
123 | vlayout1->addWidget(shellLabel); | ||
124 | vlayout1->addSpacing(5); | ||
125 | vlayout1->addWidget(groupLabel); | ||
126 | // Second column, data | ||
127 | vlayout2->addWidget(loginLineEdit); | ||
128 | vlayout2->addSpacing(5); | ||
129 | vlayout2->addWidget(uidLineEdit); | ||
130 | vlayout2->addSpacing(5); | ||
131 | vlayout2->addWidget(gecosLineEdit); | ||
132 | vlayout2->addSpacing(5); | ||
133 | vlayout2->addWidget(passwordLineEdit); | ||
134 | vlayout2->addSpacing(5); | ||
135 | vlayout2->addWidget(shellComboBox); | ||
136 | vlayout2->addSpacing(5); | ||
137 | vlayout2->addWidget(groupComboBox); | ||
138 | hlayout->addLayout(vlayout1); | ||
139 | hlayout->addLayout(vlayout2); | ||
140 | |||
141 | myTabWidget->addTab(tabpage,"User Info"); | ||
142 | } | ||
143 | |||
144 | /** | ||
145 | * Creates the second tab containing additional groups for the user. | ||
146 | * | ||
147 | */ | ||
148 | void UserDialog::setupTab2() { | ||
149 | QWidget *tabpage = new QWidget(myTabWidget,"page2"); | ||
150 | QVBoxLayout *layout = new QVBoxLayout(tabpage); | ||
151 | layout->setMargin(5); | ||
152 | |||
153 | // Additional groups | ||
154 | groupsListView=new QListView(tabpage,"groups"); | ||
155 | groupsListView->addColumn("Additional groups"); | ||
156 | groupsListView->setColumnWidthMode(0,QListView::Maximum); | ||
157 | groupsListView->setMultiSelection(true); | ||
158 | |||
159 | layout->addSpacing(5); | ||
160 | // Grouplist | ||
161 | layout->addWidget(groupsListView); | ||
162 | |||
163 | myTabWidget->addTab(tabpage,"User Groups"); | ||
164 | } | ||
165 | |||
166 | /** | ||
167 | * Static function that creates the userinfo dialog. | ||
168 | * The user will be prompted to add a user. | ||
169 | * | ||
170 | * @param uid This is a suggested available UID. | ||
171 | * @param gid This is a suggested available GID. | ||
172 | * | ||
173 | * @return <code>true</code> if the user was successfully added, otherwise <code>false</code>. | ||
174 | * | ||
175 | */ | ||
176 | bool UserDialog::addUser(int uid, int gid) { | ||
177 | UserDialog *adduserDialog=new UserDialog(); | ||
178 | adduserDialog->setCaption(tr("Add User")); | ||
179 | adduserDialog->userID=uid;// Set next available UID as default uid. | ||
180 | adduserDialog->groupID=gid;// Set next available GID as default gid. | ||
181 | // Insert default group into groupComboBox | ||
182 | adduserDialog->groupComboBox->insertItem("<create new group>",0); | ||
183 | adduserDialog->uidLineEdit->setText(QString::number(uid)); | ||
184 | // Show the dialog! | ||
185 | if(!(adduserDialog->exec())) return false; | ||
186 | if((adduserDialog->groupComboBox->currentItem()!=0)) { | ||
187 | accounts->findGroup(adduserDialog->groupComboBox->currentText()); | ||
188 | adduserDialog->groupID=accounts->gr_gid; | ||
189 | qWarning(QString::number(accounts->gr_gid)); | ||
190 | } | ||
191 | if(!(accounts->addUser(adduserDialog->loginLineEdit->text(), adduserDialog->passwordLineEdit->text(), | ||
192 | adduserDialog->uidLineEdit->text().toInt(), adduserDialog->groupID, adduserDialog->gecosLineEdit->text(), | ||
193 | QString("/home/")+adduserDialog->loginLineEdit->text() , adduserDialog->shellComboBox->currentText()))) { | ||
194 | QMessageBox::information(0,"Ooops!","Something went wrong!\nUnable to add user."); | ||
195 | return false; | ||
196 | } | ||
197 | |||
198 | // Add User to additional groups. | ||
199 | QListViewItemIterator it( adduserDialog->groupsListView ); | ||
200 | for ( ; it.current(); ++it ) { | ||
201 | if ( it.current()->isSelected() ) | ||
202 | accounts->addGroupMember(it.current()->text(0),adduserDialog->loginLineEdit->text()); | ||
203 | } | ||
204 | return true; | ||
205 | } | ||
206 | |||
207 | /** | ||
208 | * Deletes the user account. | ||
209 | * | ||
210 | * @param username User to be deleted. | ||
211 | * | ||
212 | * @return <code>true</code> if the user was successfully deleted, otherwise <code>false</code>. | ||
213 | * | ||
214 | */ | ||
215 | bool UserDialog::delUser(const char *username) { | ||
216 | if((accounts->findUser(username))) {// Does that user exist? | ||
217 | if(!(accounts->delUser(username))) {// Delete the user. | ||
218 | QMessageBox::information(0,"Ooops!","Something went wrong\nUnable to delete user: "+QString(username)+"."); | ||
219 | } | ||
220 | } else { | ||
221 | QMessageBox::information(0,"Invalid Username","That username ("+QString(username)+")does not exist."); | ||
222 | return false; | ||
223 | } | ||
224 | return true; | ||
225 | } | ||
226 | |||
227 | /** | ||
228 | * This displays a confirmation dialog wether a user should be deleted or not. | ||
229 | * (And also deletes the account) | ||
230 | * | ||
231 | * @param username User to be deleted. | ||
232 | * | ||
233 | * @return <code>true</code> if the user was successfully deleted, otherwise <code>false</code>. | ||
234 | * | ||
235 | */ | ||
236 | bool UserDialog::editUser(const char *username) { | ||
237 | UserDialog *edituserDialog=new UserDialog();// Create Dialog | ||
238 | edituserDialog->setCaption(tr("Edit User")); | ||
239 | accounts->findUser(username);// Locate user in database and fill variables in 'accounts' object. | ||
240 | accounts->findGroup(accounts->pw_gid);// Locate the user's primary group, and fill group variables in 'accounts' object. | ||
241 | // Fill widgets with userinfo. | ||
242 | edituserDialog->loginLineEdit->setText(accounts->pw_name); | ||
243 | edituserDialog->uidLineEdit->setText(QString::number(accounts->pw_uid)); | ||
244 | edituserDialog->gecosLineEdit->setText(accounts->pw_gecos); | ||
245 | // Set password to '........', we will later check if this still is the contents, if not, the password has been changed. | ||
246 | edituserDialog->passwordLineEdit->setText("........"); | ||
247 | // If this user is not using /bin/sh,/bin/ash or /bin/false as shell, add that entry to the shell-combobox. | ||
248 | if(accounts->pw_shell!="/bin/sh" && accounts->pw_shell!="/bin/ash" && accounts->pw_shell!="/bin/false") { | ||
249 | edituserDialog->shellComboBox->insertItem(accounts->pw_shell,0); | ||
250 | edituserDialog->shellComboBox->setCurrentItem(0); | ||
251 | } | ||
252 | // Select the primary group for this user. | ||
253 | for(int i=0;i<edituserDialog->groupComboBox->count();++i) { | ||
254 | if(accounts->gr_name==edituserDialog->groupComboBox->text(i)) { | ||
255 | edituserDialog->groupComboBox->setCurrentItem(i); | ||
256 | } | ||
257 | } | ||
258 | // Select the groups in the listview, to which the user belongs. | ||
259 | QRegExp userRegExp(QString("[:\\s]%1\\s").arg(username)); | ||
260 | QStringList tempList=accounts->groupStringList.grep(userRegExp);// Find all entries in the group database, that the user is a member of. | ||
261 | for(QStringList::Iterator it=tempList.begin(); it!=tempList.end(); ++it) {// Iterate over all of them. | ||
262 | QListViewItemIterator lvit( edituserDialog->groupsListView );// Compare to all groups. | ||
263 | for ( ; lvit.current(); ++lvit ) { | ||
264 | if(lvit.current()->text(0)==(*it).left((*it).find(":"))) { | ||
265 | lvit.current()->setSelected(true);// If we find a line with that groupname, select it.; | ||
266 | } | ||
267 | } | ||
268 | } | ||
269 | |||
270 | if(!(edituserDialog->exec())) return false;// SHOW THE DIALOG! | ||
271 | |||
272 | accounts->findUser(username);// Fill user variables in 'acccounts' object. | ||
273 | accounts->pw_name=edituserDialog->loginLineEdit->text(); | ||
274 | // Has the password been changed ? Make a new "crypt":ed password. | ||
275 | if(edituserDialog->passwordLineEdit->text()!="........") accounts->pw_passwd=crypt(edituserDialog->passwordLineEdit->text(), accounts->crypt_make_salt()); | ||
276 | |||
277 | // Set all variables in accounts object, that will be used when calling 'updateUser()' | ||
278 | accounts->pw_uid=edituserDialog->uidLineEdit->text().toInt(); | ||
279 | accounts->findGroup(edituserDialog->groupComboBox->currentText());// Fill all group variables in 'accounts' object. | ||
280 | accounts->pw_gid=accounts->gr_gid; | ||
281 | accounts->pw_gecos=edituserDialog->gecosLineEdit->text(); | ||
282 | accounts->pw_shell=edituserDialog->shellComboBox->currentText(); | ||
283 | // Update userinfo, using the information stored in the user variables stored in the accounts object. | ||
284 | accounts->updateUser(username); | ||
285 | |||
286 | // Remove user from all groups he/she is a member of. (could be done in a better way I guess, this was simple though.) | ||
287 | for(QStringList::Iterator it=tempList.begin(); it!=tempList.end(); ++it) { | ||
288 | accounts->delGroupMember((*it).left((*it).find(":")),username); | ||
289 | } | ||
290 | |||
291 | // Add User to additional groups that he/she is a member of. | ||
292 | QListViewItemIterator it( edituserDialog->groupsListView ); | ||
293 | for ( ; it.current(); ++it ) { | ||
294 | if ( it.current()->isSelected() ) | ||
295 | accounts->addGroupMember(it.current()->text(0),edituserDialog->loginLineEdit->text()); | ||
296 | } | ||
297 | return true; | ||
298 | } | ||
299 | |||
300 | /** | ||
301 | * "OK" has been clicked. Verify some information before closing the dialog. | ||
302 | * | ||
303 | */ | ||
304 | void UserDialog::accept() { | ||
305 | // Add checking... valid username? username taken? | ||
306 | if(loginLineEdit->text().isEmpty()) { | ||
307 | QMessageBox::information(0,"Empty Login","Please enter a login."); | ||
308 | return; | ||
309 | } | ||
310 | QDialog::accept(); | ||
311 | } | ||
312 | |||
313 | /** | ||
314 | * This slot is called when the usericon is clicked, this loads (should) the iconselector. | ||
315 | * | ||
316 | */ | ||
317 | void UserDialog::clickedPicture() { | ||
318 | QMessageBox::information(0,"Sorry!","Icon selection not yet implemented.\nComming real soon now! (tm)"); | ||
319 | } | ||
diff --git a/noncore/settings/usermanager/userdialog.h b/noncore/settings/usermanager/userdialog.h new file mode 100644 index 0000000..b44de9e --- a/dev/null +++ b/noncore/settings/usermanager/userdialog.h | |||
@@ -0,0 +1,55 @@ | |||
1 | /*************************************************************************** | ||
2 | * * | ||
3 | * This program is free software; you can redistribute it and/or modify * | ||
4 | * it under the terms of the GNU General Public License as published by * | ||
5 | * the Free Software Foundation; either version 2 of the License, or * | ||
6 | * (at your option) any later version. * | ||
7 | * * | ||
8 | ***************************************************************************/ | ||
9 | #ifndef USERDIALOG_H | ||
10 | #define USERDIALOG_H | ||
11 | |||
12 | #include <qdialog.h> | ||
13 | #include <qlineedit.h> | ||
14 | #include <qcombobox.h> | ||
15 | #include <qlistview.h> | ||
16 | #include <qtabwidget.h> | ||
17 | #include <qpushbutton.h> | ||
18 | |||
19 | #include <qpe/resource.h> | ||
20 | |||
21 | class UserDialog : public QDialog | ||
22 | { | ||
23 | Q_OBJECT | ||
24 | private: | ||
25 | QTabWidget *myTabWidget; | ||
26 | QPushButton *picturePushButton; | ||
27 | QLineEdit *loginLineEdit; | ||
28 | QLineEdit *uidLineEdit; | ||
29 | QLineEdit *gecosLineEdit; | ||
30 | QLineEdit *passwordLineEdit; | ||
31 | QComboBox *shellComboBox; | ||
32 | QComboBox *groupComboBox; | ||
33 | QListView *groupsListView; | ||
34 | |||
35 | QStringList groupMembers; | ||
36 | QString pictureLocation; | ||
37 | int groupID; | ||
38 | int userID; | ||
39 | |||
40 | void setupTab1(void); | ||
41 | void setupTab2(void); | ||
42 | void accept(void); | ||
43 | |||
44 | private slots: | ||
45 | void clickedPicture(void); | ||
46 | |||
47 | public: | ||
48 | UserDialog( QWidget* parent = 0, const char* name = 0, bool modal=true, WFlags fl = 0 ); | ||
49 | ~UserDialog(); | ||
50 | static bool addUser(int uid, int gid); | ||
51 | static bool editUser(const char *username); | ||
52 | static bool delUser(const char *username); | ||
53 | }; | ||
54 | |||
55 | #endif | ||
diff --git a/noncore/settings/usermanager/usermanager.cpp b/noncore/settings/usermanager/usermanager.cpp new file mode 100644 index 0000000..883e5d7 --- a/dev/null +++ b/noncore/settings/usermanager/usermanager.cpp | |||
@@ -0,0 +1,242 @@ | |||
1 | /*************************************************************************** | ||
2 | * * | ||
3 | * This program is free software; you can redistribute it and/or modify * | ||
4 | * it under the terms of the GNU General Public License as published by * | ||
5 | * the Free Software Foundation; either version 2 of the License, or * | ||
6 | * (at your option) any later version. * | ||
7 | * * | ||
8 | ***************************************************************************/ | ||
9 | |||
10 | #include "usermanager.h" | ||
11 | |||
12 | #include <qlayout.h> | ||
13 | #include <stdio.h> | ||
14 | |||
15 | #include <qmessagebox.h> | ||
16 | #include <qfile.h> | ||
17 | #include <qpe/resource.h> | ||
18 | |||
19 | #include <qregexp.h> | ||
20 | |||
21 | /** | ||
22 | * The mainwindow constructor. | ||
23 | * | ||
24 | * @param QWidget *parent | ||
25 | * @param const char *name | ||
26 | * @ param WFlags fl | ||
27 | * | ||
28 | */ | ||
29 | UserConfig::UserConfig(QWidget* parent, const char* name, WFlags fl) : QMainWindow(parent, name, fl) { | ||
30 | setCaption(tr("OPIE User Manager")); | ||
31 | |||
32 | // Create an instance of the global object 'accounts'. This holds all user/group info, and functions to modify them. | ||
33 | accounts=new Passwd(); | ||
34 | accounts->open();// This actually loads the files /etc/passwd & /etc/group into memory. | ||
35 | |||
36 | // Create the toolbar. | ||
37 | QPEToolBar *toolbar = new QPEToolBar(this,"Toolbar"); | ||
38 | toolbar->setHorizontalStretchable(1); // Is there any other way to get the toolbar to stretch of the full screen!? | ||
39 | adduserToolButton = new QToolButton(Resource::loadPixmap("userconfig/adduser"),"Add User",0,this,SLOT(addUser()),toolbar,"Add User"); | ||
40 | edituserToolButton = new QToolButton(Resource::loadPixmap("userconfig/edituser"),"Edit User",0,this,SLOT(editUser()),toolbar,"Edit User"); | ||
41 | deleteuserToolButton = new QToolButton(Resource::loadPixmap("userconfig/deleteuser"),"Delete User",0,this,SLOT(delUser()),toolbar,"Delete User"); | ||
42 | QToolButton *userstext = new QToolButton(0,"User",0,0,0,toolbar,"User"); | ||
43 | userstext->setUsesTextLabel(true); | ||
44 | toolbar->addSeparator(); | ||
45 | addgroupToolButton = new QToolButton(Resource::loadPixmap("userconfig/addgroup"),"Add Group",0,this,SLOT(addGroup()),toolbar,"Add Group"); | ||
46 | editgroupToolButton = new QToolButton(Resource::loadPixmap("userconfig/editgroup"),"Edit Group",0,this,SLOT(editGroup()),toolbar,"Edit Group"); | ||
47 | deletegroupToolButton = new QToolButton(Resource::loadPixmap("userconfig/deletegroup"),"Delete Group",0,this,SLOT(delGroup()),toolbar,"Delete Group"); | ||
48 | QToolButton *groupstext = new QToolButton(0,"Group",0,0,0,toolbar,"Group"); | ||
49 | groupstext->setUsesTextLabel(true); | ||
50 | addToolBar(toolbar,"myToolBar"); | ||
51 | |||
52 | // Add a tabwidget and all the tabs. | ||
53 | myTabWidget = new QTabWidget(this,"My Tab Widget"); | ||
54 | setupTabAccounts(); | ||
55 | setupTabAllUsers(); | ||
56 | setupTabAllGroups(); | ||
57 | |||
58 | getUsers(); // Fill out the iconview & listview with all users. | ||
59 | getGroups(); // Fill out the group listview with all groups. | ||
60 | |||
61 | setCentralWidget(myTabWidget); | ||
62 | } | ||
63 | |||
64 | UserConfig::~UserConfig() { | ||
65 | accounts->close(); | ||
66 | delete accounts; | ||
67 | } | ||
68 | |||
69 | void UserConfig::setupTabAccounts() { | ||
70 | QWidget *tabpage = new QWidget(this); | ||
71 | QVBoxLayout *layout = new QVBoxLayout(tabpage); | ||
72 | layout->setMargin(5); | ||
73 | |||
74 | usersIconView=new QIconView(tabpage,"users"); | ||
75 | usersIconView->setItemTextPos(QIconView::Right); | ||
76 | layout->addWidget(usersIconView); | ||
77 | |||
78 | myTabWidget->addTab(tabpage,"Users"); | ||
79 | } | ||
80 | |||
81 | void UserConfig::setupTabAllUsers() { | ||
82 | QWidget *tabpage = new QWidget(this); | ||
83 | QVBoxLayout *layout = new QVBoxLayout(tabpage); | ||
84 | layout->setMargin(5); | ||
85 | |||
86 | usersListView=new QListView(tabpage,"allusers"); | ||
87 | usersListView->addColumn("UID"); | ||
88 | usersListView->addColumn("Login"); | ||
89 | usersListView->addColumn("Username"); | ||
90 | layout->addWidget(usersListView); | ||
91 | usersListView->setSorting(1,1); | ||
92 | usersListView->setAllColumnsShowFocus(true); | ||
93 | |||
94 | myTabWidget->addTab(tabpage,"All Users"); | ||
95 | } | ||
96 | |||
97 | void UserConfig::setupTabAllGroups() { | ||
98 | QWidget *tabpage = new QWidget(this); | ||
99 | QVBoxLayout *layout = new QVBoxLayout(tabpage); | ||
100 | layout->setMargin(5); | ||
101 | |||
102 | groupsListView=new QListView(tabpage,"groups"); | ||
103 | groupsListView->addColumn("GID"); | ||
104 | groupsListView->addColumn("Groupname"); | ||
105 | layout->addWidget(groupsListView); | ||
106 | groupsListView->setSorting(1,1); | ||
107 | groupsListView->setAllColumnsShowFocus(true); | ||
108 | |||
109 | myTabWidget->addTab(tabpage,"All Groups"); | ||
110 | } | ||
111 | void UserConfig::getUsers() { | ||
112 | QString mytext; | ||
113 | QPixmap mypixmap; | ||
114 | |||
115 | // Empty the iconview & the listview. | ||
116 | usersIconView->clear(); | ||
117 | usersListView->clear(); | ||
118 | |||
119 | // availableUID is used as a deposite for the next available UID on the system, this should start at an ID over 500. | ||
120 | availableUID=500; | ||
121 | for(QStringList::Iterator it=accounts->passwdStringList.begin(); it!=accounts->passwdStringList.end(); ++it) { | ||
122 | accounts->splitPasswdEntry(*it); // Split the string into it's components and store in variables in the accounts object. ("pr_name" and so on.) | ||
123 | new QListViewItem(usersListView,QString::number(accounts->pw_uid),accounts->pw_name,accounts->pw_gecos); | ||
124 | if((accounts->pw_uid>=500) && (accounts->pw_uid<65000)) {// Is this user a "normal" user ? | ||
125 | mytext=QString(accounts->pw_name)+" - ("+QString(accounts->pw_gecos)+")"; // The string displayed next to the icon. | ||
126 | mypixmap=Resource::loadPixmap(QString("users/"+accounts->pw_name));// Is there an icon for this user? | ||
127 | if(mypixmap.isNull()) { | ||
128 | mypixmap=Resource::loadPixmap(QString("userconfig/usericon"));// If this user has no icon, load the default icon. | ||
129 | } | ||
130 | new QIconViewItem(usersIconView,mytext,mypixmap);// Add the icon+text to the qiconview. | ||
131 | } | ||
132 | if((accounts->pw_uid>=availableUID) && (accounts->pw_uid<65000)) availableUID=accounts->pw_uid+1; // Increase 1 to the latest know UID to get a free uid. | ||
133 | } | ||
134 | } | ||
135 | |||
136 | void UserConfig::addUser() { | ||
137 | if(UserDialog::addUser(availableUID,availableGID)) {// Add the user to the system, also send next available UID and GID. | ||
138 | getUsers(); // Update users views. | ||
139 | getGroups(); // Update groups view. | ||
140 | } | ||
141 | } | ||
142 | |||
143 | void UserConfig::editUser() { | ||
144 | QString username; | ||
145 | if(myTabWidget->currentPageIndex()==0) {// Users | ||
146 | if(usersIconView->currentItem()) {// Any icon selected? | ||
147 | username=usersIconView->currentItem()->text();// Get the text associated with the icon. | ||
148 | username=username.left(username.find(" - (",0,true));// Strip out the username. | ||
149 | if(UserDialog::editUser(username)) {// Bring up the userinfo dialog. | ||
150 | // If there were any changed also update the views. | ||
151 | getUsers(); | ||
152 | getGroups(); | ||
153 | } | ||
154 | } else { | ||
155 | QMessageBox::information(this,"No selection.","No user has been selected."); | ||
156 | } | ||
157 | } | ||
158 | if(myTabWidget->currentPageIndex()==1) {// All users | ||
159 | if(usersListView->currentItem()) {// Anything changed!? | ||
160 | username=usersListView->currentItem()->text(1);// Get the username. | ||
161 | if(UserDialog::editUser(username)) {// Bring up the userinfo dialog. | ||
162 | // And again update the views if there were any changes. | ||
163 | getUsers(); | ||
164 | getGroups(); | ||
165 | } | ||
166 | } else { | ||
167 | QMessageBox::information(this,"No selection.","No user has been selected."); | ||
168 | } | ||
169 | } | ||
170 | } | ||
171 | |||
172 | void UserConfig::delUser() { | ||
173 | QString username; | ||
174 | |||
175 | if(myTabWidget->currentPageIndex()==0) {// Users, Iconview. | ||
176 | if(usersIconView->currentItem()) {// Anything selected? | ||
177 | username=usersIconView->currentItem()->text();// Get string associated with icon. | ||
178 | username=username.left(username.find(" - (",0,true));// Strip out the username. | ||
179 | if(QMessageBox::warning(this,"Delete user","Are you sure you want to\ndelete this user? \""+QString(username)+"\" ?","&No","&Yes",0,0,1)) { | ||
180 | if(UserDialog::delUser(username)) {// Delete the user if possible. | ||
181 | // Update views. | ||
182 | getUsers(); | ||
183 | getGroups(); | ||
184 | } | ||
185 | } | ||
186 | } else { | ||
187 | QMessageBox::information(this,"No selection","No user has been selected."); | ||
188 | } | ||
189 | } | ||
190 | if(myTabWidget->currentPageIndex()==1) {// All users | ||
191 | if(usersListView->currentItem()) {// Anything changed!? | ||
192 | username=usersListView->currentItem()->text(1);// Get the username. | ||
193 | if(QMessageBox::warning(this,"Delete user","Are you sure you want to\ndelete this user? \""+QString(username)+"\" ?","&No","&Yes",0,0,1)) { | ||
194 | if(UserDialog::delUser(username)) {// Try to delete the user. | ||
195 | // Update views. | ||
196 | getUsers(); | ||
197 | getGroups(); | ||
198 | } | ||
199 | } | ||
200 | } else { | ||
201 | QMessageBox::information(this,"No selection","No user has been selected."); | ||
202 | } | ||
203 | } | ||
204 | |||
205 | } | ||
206 | |||
207 | void UserConfig::getGroups() { | ||
208 | groupsListView->clear();// Empty the listview. | ||
209 | availableGID=500;// We need to find the next free GID, and are only interested in values between 500 & 65000. | ||
210 | for(QStringList::Iterator it=accounts->groupStringList.begin(); it!=accounts->groupStringList.end(); ++it) {// Split the list into lines. | ||
211 | accounts->splitGroupEntry(*it);// Split the line into its components and fill the variables of 'accounts'. (gr_name, gr_uid & gr_mem). | ||
212 | new QListViewItem(groupsListView,QString::number(accounts->gr_gid),accounts->gr_name); | ||
213 | if((accounts->gr_gid>=availableGID) && (accounts->gr_gid<65000)) availableGID=accounts->gr_gid+1;// Maybe a new free GID. | ||
214 | } | ||
215 | } | ||
216 | |||
217 | void UserConfig::addGroup() { | ||
218 | if(GroupDialog::addGroup(availableGID)) getGroups();// Bring up the add group dialog. | ||
219 | } | ||
220 | |||
221 | void UserConfig::editGroup() { | ||
222 | int gid; | ||
223 | if(groupsListView->currentItem()) {// Any group selected? | ||
224 | gid=groupsListView->currentItem()->text(0).toInt();// Get the GID from the listview. | ||
225 | if(GroupDialog::editGroup(gid)) getGroups();// Bring up the edit group dialog. | ||
226 | } else { | ||
227 | QMessageBox::information(this,"No selection","No group has been selected."); | ||
228 | } | ||
229 | } | ||
230 | |||
231 | void UserConfig::delGroup() { | ||
232 | const char *groupname; | ||
233 | if(groupsListView->currentItem()) {// Any group selected? | ||
234 | groupname=groupsListView->currentItem()->text(1);// Get the groupname from the listview. | ||
235 | if(QMessageBox::warning(this,"Delete group","Are you sure you want to\ndelete the group \""+QString(groupname)+"\" ?","&No","&Yes",0,0,1)) { | ||
236 | // If confirmed, try to delete the group. | ||
237 | if(GroupDialog::delGroup(groupname)) getGroups(); // And also update the view afterwards if the user was deleted. | ||
238 | } | ||
239 | } else { | ||
240 | QMessageBox::information(this,"No selection","No group has been selected."); | ||
241 | } | ||
242 | } | ||
diff --git a/noncore/settings/usermanager/usermanager.h b/noncore/settings/usermanager/usermanager.h new file mode 100644 index 0000000..bb5d04f --- a/dev/null +++ b/noncore/settings/usermanager/usermanager.h | |||
@@ -0,0 +1,65 @@ | |||
1 | /*************************************************************************** | ||
2 | * * | ||
3 | * This program is free software; you can redistribute it and/or modify * | ||
4 | * it under the terms of the GNU General Public License as published by * | ||
5 | * the Free Software Foundation; either version 2 of the License, or * | ||
6 | * (at your option) any later version. * | ||
7 | * * | ||
8 | ***************************************************************************/ | ||
9 | |||
10 | #ifndef USERCONFIG_H | ||
11 | #define USERCONFIG_H | ||
12 | |||
13 | #include <qmainwindow.h> | ||
14 | #include <qtabwidget.h> | ||
15 | #include <qlistview.h> | ||
16 | #include <qiconview.h> | ||
17 | |||
18 | #include <qpe/qpemenubar.h> | ||
19 | #include <qpopupmenu.h> | ||
20 | #include <qpe/qpetoolbar.h> | ||
21 | #include <qtoolbutton.h> | ||
22 | |||
23 | #include "userdialog.h" | ||
24 | #include "groupdialog.h" | ||
25 | #include "passwd.h" | ||
26 | |||
27 | class UserConfig : public QMainWindow | ||
28 | { | ||
29 | Q_OBJECT | ||
30 | |||
31 | public: | ||
32 | UserConfig( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); | ||
33 | ~UserConfig(); | ||
34 | |||
35 | private: | ||
36 | QToolButton *adduserToolButton; | ||
37 | QToolButton *edituserToolButton; | ||
38 | QToolButton *deleteuserToolButton; | ||
39 | QToolButton *addgroupToolButton; | ||
40 | QToolButton *editgroupToolButton; | ||
41 | QToolButton *deletegroupToolButton; | ||
42 | QTabWidget *myTabWidget; | ||
43 | QIconView *usersIconView; | ||
44 | QListView *usersListView; | ||
45 | QListView *groupsListView; | ||
46 | int availableUID; | ||
47 | int availableGID; | ||
48 | void setupTabAccounts(); | ||
49 | void setupTabAllUsers(); | ||
50 | void setupTabAllGroups(); | ||
51 | void setupTabPrefs(); | ||
52 | void setupTabAbout(); | ||
53 | void getUsers(); | ||
54 | void getGroups(); | ||
55 | |||
56 | private slots: | ||
57 | void addUser(); | ||
58 | void editUser(); | ||
59 | void delUser(); | ||
60 | void addGroup(); | ||
61 | void editGroup(); | ||
62 | void delGroup(); | ||
63 | }; | ||
64 | |||
65 | #endif // USERCONFIG_H | ||
diff --git a/noncore/settings/usermanager/usermanager.pro b/noncore/settings/usermanager/usermanager.pro new file mode 100644 index 0000000..956d98e --- a/dev/null +++ b/noncore/settings/usermanager/usermanager.pro | |||
@@ -0,0 +1,10 @@ | |||
1 | Package: userconfig | ||
2 | Files: bin/usermanager apps/Settings/usermanager.desktop pics/userconfig/* | ||
3 | Priority: optional | ||
4 | Section: opie/settings | ||
5 | Version: $QPE_VERSION-$SUB_VERSION-0.9 | ||
6 | Depends: opie-base ($QPE_VERSION) | ||
7 | Architecture: arm | ||
8 | Maintainer: Ted Parnefors <zaurus@bredband.net> | ||
9 | License: GPL | ||
10 | Description: User/Group manager for OPIE. | ||