summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/opie-login/passworddialogimpl.cpp1
1 files changed, 0 insertions, 1 deletions
diff --git a/core/opie-login/passworddialogimpl.cpp b/core/opie-login/passworddialogimpl.cpp
index aeb7516..951c4e1 100644
--- a/core/opie-login/passworddialogimpl.cpp
+++ b/core/opie-login/passworddialogimpl.cpp
@@ -1,232 +1,231 @@
1/* 1/*
2               =. This file is part of the OPIE Project 2               =. This file is part of the OPIE Project
3             .=l. Copyright (c) 2004 Holger Hans Peter Freyther <zecke@handhelds.org> 3             .=l. Copyright (c) 2004 Holger Hans Peter Freyther <zecke@handhelds.org>
4           .>+-= 4           .>+-=
5 _;:,     .>    :=|. This file is free software; you can 5 _;:,     .>    :=|. This file is free software; you can
6.> <`_,   >  .   <= redistribute it and/or modify it under 6.> <`_,   >  .   <= redistribute it and/or modify it under
7:`=1 )Y*s>-.--   : the terms of the GNU General Public 7:`=1 )Y*s>-.--   : the terms of the GNU General Public
8.="- .-=="i,     .._ License as published by the Free Software 8.="- .-=="i,     .._ License as published by the Free Software
9 - .   .-<_>     .<> Foundation; either version 2 of the License, 9 - .   .-<_>     .<> Foundation; either version 2 of the License,
10     ._= =}       : or (at your option) any later version. 10     ._= =}       : or (at your option) any later version.
11    .%`+i>       _;_. 11    .%`+i>       _;_.
12    .i_,=:_.      -<s. This file is distributed in the hope that 12    .i_,=:_.      -<s. This file is distributed in the hope that
13     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY; 13     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
14    : ..    .:,     . . . without even the implied warranty of 14    : ..    .:,     . . . without even the implied warranty of
15    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A 15    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
16  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU General 16  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU General
17..}^=.=       =       ; Public License for more details. 17..}^=.=       =       ; Public License for more details.
18++=   -.     .`     .: 18++=   -.     .`     .:
19 :     =  ...= . :.=- You should have received a copy of the GNU 19 :     =  ...= . :.=- You should have received a copy of the GNU
20 -.   .:....=;==+<; General Public License along with this file; 20 -.   .:....=;==+<; General Public License along with this file;
21  -_. . .   )=.  = see the file COPYING. If not, write to the 21  -_. . .   )=.  = see the file COPYING. If not, write to the
22    --        :-=` Free Software Foundation, Inc., 22    --        :-=` Free Software Foundation, Inc.,
23 59 Temple Place - Suite 330, 23 59 Temple Place - Suite 330,
24 Boston, MA 02111-1307, USA. 24 Boston, MA 02111-1307, USA.
25 25
26*/ 26*/
27 27
28 28
29#include <qlayout.h> 29#include <qlayout.h>
30#include <qlabel.h> 30#include <qlabel.h>
31#include <qlineedit.h> 31#include <qlineedit.h>
32#include <qvalidator.h> 32#include <qvalidator.h>
33#include <qmessagebox.h> 33#include <qmessagebox.h>
34#include <qhbox.h> 34#include <qhbox.h>
35#include <qtoolbutton.h> 35#include <qtoolbutton.h>
36 36
37#include <sys/types.h> 37#include <sys/types.h>
38#include <pwd.h> 38#include <pwd.h>
39#include <shadow.h> 39#include <shadow.h>
40#include <stdio.h> 40#include <stdio.h>
41#include <time.h> 41#include <time.h>
42#include <unistd.h> 42#include <unistd.h>
43 43
44 44
45#include "passworddialogimpl.h" 45#include "passworddialogimpl.h"
46 46
47 47
48// This function is taken from 'busybox'. 48// This function is taken from 'busybox'.
49static int i64c(int i) { 49static int i64c(int i) {
50 if (i <= 0) 50 if (i <= 0)
51 return ('.'); 51 return ('.');
52 if (i == 1) 52 if (i == 1)
53 return ('/'); 53 return ('/');
54 if (i >= 2 && i < 12) 54 if (i >= 2 && i < 12)
55 return ('0' - 2 + i); 55 return ('0' - 2 + i);
56 if (i >= 12 && i < 38) 56 if (i >= 12 && i < 38)
57 return ('A' - 12 + i); 57 return ('A' - 12 + i);
58 if (i >= 38 && i < 63) 58 if (i >= 38 && i < 63)
59 return ('a' - 38 + i); 59 return ('a' - 38 + i);
60 return ('z'); 60 return ('z');
61} 61}
62 62
63// This function is taken from 'busybox'. 63// This function is taken from 'busybox'.
64static char *crypt_make_salt() { 64static char *crypt_make_salt() {
65 time_t now; 65 time_t now;
66 static unsigned long x; 66 static unsigned long x;
67 static char result[3]; 67 static char result[3];
68 68
69 ::time(&now); 69 ::time(&now);
70 x += now + getpid() + clock(); 70 x += now + getpid() + clock();
71 result[0] = i64c(((x >> 18) ^ (x >> 6)) & 077); 71 result[0] = i64c(((x >> 18) ^ (x >> 6)) & 077);
72 result[1] = i64c(((x >> 12) ^ x) & 077); 72 result[1] = i64c(((x >> 12) ^ x) & 077);
73 result[2] = '\0'; 73 result[2] = '\0';
74 return result; 74 return result;
75} 75}
76 76
77/* 77/*
78 * Modal dialog to force root password. It is quite hard as it only leave 78 * Modal dialog to force root password. It is quite hard as it only leave
79 * when a password is set. 79 * when a password is set.
80 * Also it prevalidates the password... 80 * Also it prevalidates the password...
81 */ 81 */
82PasswordDialogImpl::PasswordDialogImpl( QWidget* parent ) 82PasswordDialogImpl::PasswordDialogImpl( QWidget* parent )
83 : PasswordDialog( parent, 0, true ), m_isSet( PasswordDialogImpl::needDialog() ) { 83 : PasswordDialog( parent, 0, true ), m_isSet( PasswordDialogImpl::needDialog() ) {
84} 84}
85 85
86PasswordDialogImpl::~PasswordDialogImpl() { 86PasswordDialogImpl::~PasswordDialogImpl() {
87 /* qt does the stuff for us */ 87 /* qt does the stuff for us */
88} 88}
89 89
90void PasswordDialogImpl::done(int res) { 90void PasswordDialogImpl::done(int res) {
91 m_isSet = true; 91 m_isSet = true;
92 92
93 /* 93 /*
94 * The user hit 'Ok' see if we can safe the file 94 * The user hit 'Ok' see if we can safe the file
95 * if not an error will be raised and m_isSet altered. 95 * if not an error will be raised and m_isSet altered.
96 * On cancel we will see if it is now ok... 96 * On cancel we will see if it is now ok...
97 */ 97 */
98 if ( res == Accepted ) 98 if ( res == Accepted )
99 writePassword(); 99 writePassword();
100 else if(PasswordDialogImpl::needDialog() ) { 100 else if(PasswordDialogImpl::needDialog() ) {
101 switch( QMessageBox::warning(this,tr("Trying to leave without password set") , 101 switch( QMessageBox::warning(this,tr("Trying to leave without password set") ,
102 tr("<qt>No password was set. This could lead to you not beeing" 102 tr("<qt>No password was set. This could lead to you not beeing"
103 "able to remotely connect to your machine." 103 "able to remotely connect to your machine."
104 "Do you want to continue not setting a password?</qt>" ), 104 "Do you want to continue not setting a password?</qt>" ),
105 QMessageBox::Ok, QMessageBox::Cancel ) ) { 105 QMessageBox::Ok, QMessageBox::Cancel ) ) {
106 case QMessageBox::Cancel: 106 case QMessageBox::Cancel:
107 m_isSet = false; 107 m_isSet = false;
108 break; 108 break;
109 case QMessageBox::Ok: 109 case QMessageBox::Ok:
110 default: 110 default:
111 break; 111 break;
112 } 112 }
113 113
114 } 114 }
115 115
116 if(m_isSet) 116 if(m_isSet)
117 PasswordDialog::done( res ); 117 PasswordDialog::done( res );
118} 118}
119 119
120/* 120/*
121 * Lets see if we can write either shadow 121 * Lets see if we can write either shadow
122 * 122 *
123 */ 123 */
124/** 124/**
125 * CRYPT the password and then tries to write it either to the shadow password 125 * CRYPT the password and then tries to write it either to the shadow password
126 * or to the plain /etc/passwd 126 * or to the plain /etc/passwd
127 */ 127 */
128void PasswordDialogImpl::writePassword() { 128void PasswordDialogImpl::writePassword() {
129 /* 129 /*
130 * Check if both texts are the same 130 * Check if both texts are the same
131 */ 131 */
132 if ( m_pass->text() != m_confirm->text() ) 132 if ( m_pass->text() != m_confirm->text() )
133 return error( tr("Passwords don't match"), 133 return error( tr("Passwords don't match"),
134 tr("<qt>The two passwords don't match. Please try again.</qt>") ); 134 tr("<qt>The two passwords don't match. Please try again.</qt>") );
135 135
136 136
137 /* 137 /*
138 * Now crypt the password so we can write it later 138 * Now crypt the password so we can write it later
139 */ 139 */
140 char* password = ::crypt( m_pass->text().latin1(), crypt_make_salt() ); 140 char* password = ::crypt( m_pass->text().latin1(), crypt_make_salt() );
141 141
142 if ( !password ) 142 if ( !password )
143 return error( tr("Password not legal" ), 143 return error( tr("Password not legal" ),
144 tr("<qt>The entered password is not a valid password." 144 tr("<qt>The entered password is not a valid password."
145 "Please try entering a valid password.</qt>" ) ); 145 "Please try entering a valid password.</qt>" ) );
146 146
147 /* rewind and rewrite the password file */ 147 /* rewind and rewrite the password file */
148 ::setpwent(); 148 ::setpwent();
149 149
150 FILE* file = ::fopen( "/etc/passwd.new", "w" ); 150 FILE* file = ::fopen( "/etc/passwd.new", "w" );
151 struct passwd* pass; 151 struct passwd* pass;
152 while ( (pass = ::getpwent()) != 0l ) { 152 while ( (pass = ::getpwent()) != 0l ) {
153 /* no shadow password support */ 153 /* no shadow password support */
154 if ( pass->pw_uid == 0 ) 154 if ( pass->pw_uid == 0 )
155 pass->pw_passwd = password; 155 pass->pw_passwd = password;
156 156
157 ::putpwent( pass, file ); 157 ::putpwent( pass, file );
158 } 158 }
159 159
160 ::fclose( file ); 160 ::fclose( file );
161 ::endpwent(); 161 ::endpwent();
162 ::unlink("/etc/passwd");
163 ::rename("/etc/passwd.new","/etc/passwd" ); 162 ::rename("/etc/passwd.new","/etc/passwd" );
164 163
165 /* should be done now */ 164 /* should be done now */
166#ifdef OPIE_LOGIN_SHADOW_PW 165#ifdef OPIE_LOGIN_SHADOW_PW
167 #error "Can't write Shadow Passwords fixme" 166 #error "Can't write Shadow Passwords fixme"
168#endif 167#endif
169} 168}
170 169
171/** 170/**
172 * Raise an error. Delete input and set the focus after showing 171 * Raise an error. Delete input and set the focus after showing
173 * the error to the user 172 * the error to the user
174 */ 173 */
175void PasswordDialogImpl::error( const QString& caption, const QString& text ) { 174void PasswordDialogImpl::error( const QString& caption, const QString& text ) {
176 m_isSet = false; 175 m_isSet = false;
177 QMessageBox::critical(this,caption, text, 176 QMessageBox::critical(this,caption, text,
178 QMessageBox::Ok, QMessageBox::NoButton ); 177 QMessageBox::Ok, QMessageBox::NoButton );
179 178
180 m_pass->setText(""); 179 m_pass->setText("");
181 m_pass->setFocus(); 180 m_pass->setFocus();
182 181
183 m_confirm->setText(""); 182 m_confirm->setText("");
184} 183}
185 184
186void PasswordDialogImpl::slotToggleEcho( bool b ) { 185void PasswordDialogImpl::slotToggleEcho( bool b ) {
187 m_pass-> setEchoMode( b ? QLineEdit::Normal : QLineEdit::Password ); 186 m_pass-> setEchoMode( b ? QLineEdit::Normal : QLineEdit::Password );
188 m_confirm->setEchoMode( b ? QLineEdit::Normal : QLineEdit::Password ); 187 m_confirm->setEchoMode( b ? QLineEdit::Normal : QLineEdit::Password );
189} 188}
190 189
191///////////////////////// 190/////////////////////////
192/// static functions 191/// static functions
193/// 192///
194 193
195/** 194/**
196 * Ask whether or not we need to show the dialog. It returns true if 195 * Ask whether or not we need to show the dialog. It returns true if
197 * no root password is set so that the user will be able to set one. 196 * no root password is set so that the user will be able to set one.
198 */ 197 */
199bool PasswordDialogImpl::needDialog() { 198bool PasswordDialogImpl::needDialog() {
200 /* 199 /*
201 * This can cope with no password and shadow passwords 200 * This can cope with no password and shadow passwords
202 * Let us go through the user database until we find 'root' and then 201 * Let us go through the user database until we find 'root' and then
203 * see if it is 'shadow' and see if shadow is empty or see if the password is empty 202 * see if it is 'shadow' and see if shadow is empty or see if the password is empty
204 */ 203 */
205 bool need = false; 204 bool need = false;
206 struct passwd *pwd; 205 struct passwd *pwd;
207 ::setpwent(); 206 ::setpwent();
208 207
209 while((pwd = ::getpwent() ) ) { 208 while((pwd = ::getpwent() ) ) {
210 /* found root */ 209 /* found root */
211 if( pwd->pw_uid == 0 ) { 210 if( pwd->pw_uid == 0 ) {
212 QString str = QString::fromLatin1(pwd->pw_passwd ); 211 QString str = QString::fromLatin1(pwd->pw_passwd );
213 212
214 /* 213 /*
215 * If str is really empty it is passwordless anyway... 214 * If str is really empty it is passwordless anyway...
216 * else it is shadow based 215 * else it is shadow based
217 */ 216 */
218 if(str.isEmpty() ) 217 if(str.isEmpty() )
219 need = true; 218 need = true;
220 else if ( str == '*' || str == 'x' ) 219 else if ( str == '*' || str == 'x' )
221#ifdef OPIE_LOGIN_SHADOW_PW 220#ifdef OPIE_LOGIN_SHADOW_PW
222 need = QString::fromLatin1( ::getspnam( pwd->pw_name )->sp_pwdp ).isEmpty(); 221 need = QString::fromLatin1( ::getspnam( pwd->pw_name )->sp_pwdp ).isEmpty();
223#else 222#else
224 ; 223 ;
225#endif 224#endif
226 break; 225 break;
227 } 226 }
228 } 227 }
229 ::endpwent(); 228 ::endpwent();
230 229
231 return need; 230 return need;
232} 231}