MediaWiki
REL1_24
|
00001 <?php 00023 require_once __DIR__ . '/Maintenance.php'; 00024 00032 class WrapOldPasswords extends Maintenance { 00033 public function __construct() { 00034 parent::__construct(); 00035 $this->mDescription = "Wrap all passwords of a certain type in a new layered type"; 00036 $this->addOption( 'type', 00037 'Password type to wrap passwords in (must inherit LayeredParameterizedPassword)', true, true ); 00038 $this->addOption( 'verbose', 'Enables verbose output', false, false, 'v' ); 00039 $this->setBatchSize( 100 ); 00040 } 00041 00042 public function execute() { 00043 global $wgAuth; 00044 00045 if ( !$wgAuth->allowSetLocalPassword() ) { 00046 $this->error( '$wgAuth does not allow local passwords. Aborting.', true ); 00047 } 00048 00049 $passwordFactory = new PasswordFactory(); 00050 $passwordFactory->init( RequestContext::getMain()->getConfig() ); 00051 00052 $typeInfo = $passwordFactory->getTypes(); 00053 $layeredType = $this->getOption( 'type' ); 00054 00055 // Check that type exists and is a layered type 00056 if ( !isset( $typeInfo[$layeredType] ) ) { 00057 $this->error( 'Undefined password type', true ); 00058 } 00059 00060 $passObj = $passwordFactory->newFromType( $layeredType ); 00061 if ( !$passObj instanceof LayeredParameterizedPassword ) { 00062 $this->error( 'Layered parameterized password type must be used.', true ); 00063 } 00064 00065 // Extract the first layer type 00066 $typeConfig = $typeInfo[$layeredType]; 00067 $firstType = $typeConfig['types'][0]; 00068 00069 // Get a list of password types that are applicable 00070 $dbw = $this->getDB( DB_MASTER ); 00071 $typeCond = 'user_password' . $dbw->buildLike( ":$firstType:", $dbw->anyString() ); 00072 00073 $minUserId = 0; 00074 do { 00075 $dbw->begin(); 00076 00077 $res = $dbw->select( 'user', 00078 array( 'user_id', 'user_name', 'user_password' ), 00079 array( 00080 'user_id > ' . $dbw->addQuotes( $minUserId ), 00081 $typeCond 00082 ), 00083 __METHOD__, 00084 array( 00085 'ORDER BY' => 'user_id', 00086 'LIMIT' => $this->mBatchSize, 00087 'LOCK IN SHARE MODE', 00088 ) 00089 ); 00090 00092 $updateUsers = array(); 00093 foreach ( $res as $row ) { 00094 if ( $this->hasOption( 'verbose' ) ) { 00095 $this->output( "Updating password for user {$row->user_name} ({$row->user_id}).\n" ); 00096 } 00097 00098 $user = User::newFromId( $row->user_id ); 00100 $password = $passwordFactory->newFromCiphertext( $row->user_password ); 00102 $layeredPassword = $passwordFactory->newFromType( $layeredType ); 00103 $layeredPassword->partialCrypt( $password ); 00104 00105 $updateUsers[] = $user; 00106 $dbw->update( 'user', 00107 array( 'user_password' => $layeredPassword->toString() ), 00108 array( 'user_id' => $row->user_id ), 00109 __METHOD__ 00110 ); 00111 00112 $minUserId = $row->user_id; 00113 } 00114 00115 $dbw->commit(); 00116 00117 // Clear memcached so old passwords are wiped out 00118 foreach ( $updateUsers as $user ) { 00119 $user->clearSharedCache(); 00120 } 00121 } while ( $res->numRows() ); 00122 } 00123 } 00124 00125 $maintClass = "WrapOldPasswords"; 00126 require_once RUN_MAINTENANCE_IF_MAIN;