00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <qlayout.h>
00029 #include <qlabel.h>
00030 #include <qlineedit.h>
00031 #include <qvalidator.h>
00032 #include <qmessagebox.h>
00033 #include <qhbox.h>
00034 #include <qtoolbutton.h>
00035
00036
00037
00038 #include <sys/types.h>
00039 #include <pwd.h>
00040 #include <shadow.h>
00041 #include <stdio.h>
00042 #include <time.h>
00043 #include <unistd.h>
00044
00045
00046 extern "C" char* crypt( const char*, const char* );
00047
00048
00049
00050 #include "passworddialogimpl.h"
00051
00052
00053
00054 static int i64c(int i) {
00055 if (i <= 0)
00056 return ('.');
00057 if (i == 1)
00058 return ('/');
00059 if (i >= 2 && i < 12)
00060 return ('0' - 2 + i);
00061 if (i >= 12 && i < 38)
00062 return ('A' - 12 + i);
00063 if (i >= 38 && i < 63)
00064 return ('a' - 38 + i);
00065 return ('z');
00066 }
00067
00068
00069 static char *crypt_make_salt() {
00070 time_t now;
00071 static unsigned long x;
00072 static char result[3];
00073
00074 ::time(&now);
00075 x += now + getpid() + clock();
00076 result[0] = i64c(((x >> 18) ^ (x >> 6)) & 077);
00077 result[1] = i64c(((x >> 12) ^ x) & 077);
00078 result[2] = '\0';
00079 return result;
00080 }
00081
00082
00083
00084
00085
00086
00087 PasswordDialogImpl::PasswordDialogImpl( QWidget* parent )
00088 : PasswordDialog( parent, 0, true ), m_isSet( PasswordDialogImpl::needDialog() ) {
00089 }
00090
00091 PasswordDialogImpl::~PasswordDialogImpl() {
00092
00093 }
00094
00095 void PasswordDialogImpl::done(int res) {
00096 m_isSet = true;
00097
00098
00099
00100
00101
00102
00103 if ( res == Accepted )
00104 writePassword();
00105 else if(PasswordDialogImpl::needDialog() ) {
00106 switch( QMessageBox::warning(this,tr("Trying to leave without password set") ,
00107 tr("<qt>No password was set. This could lead to you not beeing"
00108 "able to remotely connect to your machine."
00109 "Do you want to continue not setting a password?</qt>" ),
00110 QMessageBox::Ok, QMessageBox::Cancel ) ) {
00111 case QMessageBox::Cancel:
00112 m_isSet = false;
00113 break;
00114 case QMessageBox::Ok:
00115 default:
00116 break;
00117 }
00118
00119 }
00120
00121 if(m_isSet)
00122 PasswordDialog::done( res );
00123 }
00124
00125
00126
00127
00128
00133 void PasswordDialogImpl::writePassword() {
00134
00135
00136
00137 if ( m_pass->text() != m_confirm->text() )
00138 return error( tr("Passwords don't match"),
00139 tr("<qt>The two passwords don't match. Please try again.</qt>") );
00140
00141
00142
00143
00144
00145 char* password = ::crypt( m_pass->text().latin1(), crypt_make_salt() );
00146
00147 if ( !password )
00148 return error( tr("Password not legal" ),
00149 tr("<qt>The entered password is not a valid password."
00150 "Please try entering a valid password.</qt>" ) );
00151
00152
00153 ::setpwent();
00154
00155 FILE* file = ::fopen( "/etc/passwd.new", "w" );
00156 struct passwd* pass;
00157 while ( (pass = ::getpwent()) != 0l ) {
00158
00159 if ( pass->pw_uid == 0 )
00160 pass->pw_passwd = password;
00161
00162 ::putpwent( pass, file );
00163 }
00164
00165 ::fclose( file );
00166 ::endpwent();
00167 ::rename("/etc/passwd.new","/etc/passwd" );
00168
00169
00170 #ifdef OPIE_LOGIN_SHADOW_PW
00171 #error "Can't write Shadow Passwords fixme"
00172 #endif
00173 }
00174
00179 void PasswordDialogImpl::error( const QString& caption, const QString& text ) {
00180 m_isSet = false;
00181 QMessageBox::critical(this,caption, text,
00182 QMessageBox::Ok, QMessageBox::NoButton );
00183
00184 m_pass->setText("");
00185 m_pass->setFocus();
00186
00187 m_confirm->setText("");
00188 }
00189
00190 void PasswordDialogImpl::slotToggleEcho( bool b ) {
00191 m_pass-> setEchoMode( b ? QLineEdit::Normal : QLineEdit::Password );
00192 m_confirm->setEchoMode( b ? QLineEdit::Normal : QLineEdit::Password );
00193 }
00194
00198
00203 bool PasswordDialogImpl::needDialog() {
00204
00205
00206
00207
00208
00209 bool need = false;
00210 struct passwd *pwd;
00211 ::setpwent();
00212
00213 while((pwd = ::getpwent() ) ) {
00214
00215 if( pwd->pw_uid == 0 ) {
00216 QString str = QString::fromLatin1(pwd->pw_passwd );
00217
00218
00219
00220
00221
00222
00223 if(str.isEmpty() || str == '*' )
00224 need = true;
00225 else if ( str == 'x' )
00226 #ifdef OPIE_LOGIN_SHADOW_PW
00227 need = QString::fromLatin1( ::getspnam( pwd->pw_name )->sp_pwdp ).isEmpty();
00228 #else
00229 ;
00230 #endif
00231 break;
00232 }
00233 }
00234 ::endpwent();
00235
00236 return need;
00237 }