1<?php 2/** 3 * Copyright 2004-2017 Horde LLC (http://www.horde.org/) 4 * 5 * See the enclosed file COPYING for license information (GPL). If you 6 * did not receive this file, see http://www.horde.org/licenses/gpl. 7 * 8 * @category Horde 9 * @copyright 2004-2017 Horde LLC 10 * @license http://www.horde.org/licenses/gpl GPL 11 * @package Passwd 12 */ 13 14/** 15 * The PSPasswd class changes a user's password on any Windows Machine 16 * (NT+) using the pspasswd free utility available at Sysinternals 17 * website: http://www.sysinternals.com/ntw2k/freeware/pspasswd.shtml 18 * 19 * IMPORTANT! 20 * 21 * This driver should be used only as a last resort when there's no 22 * possibility of using the ADSI or LDAP drivers, which are far more 23 * secure and fast. This driver needs administrative credentials 24 * exposed on the backends.php file, which is required by the 25 * pspasswd.exe tool. It's an alternative driver that should be 26 * avoided, but could also be the only option for a few scenarios. 27 * (eg: When you don't have ADSI or LDAP support) 28 * 29 * Sample backend configuration: 30 * <code> 31 * $backends['pspasswd'] = array( 32 * 'name' => 'Sample pspasswd backend', 33 * 'preferred' => 'localhost', 34 * 'policy' => array( 35 * 'minLength' => 8, 36 * 'maxLength' => 14 37 * ), 38 * 'driver' => 'pspasswd', 39 * 'params' => array( 40 * 'server' => 'YOUR_SERVER_NAME', 41 * 'bin' => 'DRIVE:\\DIR\\pspasswd.exe', // Notice: "\\" 42 * 'admusr' => 'Administrator', 43 * 'admpwd' => 'Password', 44 * 'domain' => 'YOUR_DOMAIN_NAME' 45 * ) 46 * ); 47 * </code> 48 * 49 * Backend parameters:<pre> 50 * server = Machine where you want to change the password (Required) 51 * bin = Full pathname of the pspasswd.exe program (Required) 52 * admusr = User with administrative privileges (Required) 53 * admpwd = Password of the administrative user (Required) 54 * domain = Windows domain name (Optional) 55 * </pre> 56 * 57 * For example: Passing a NT4 PDC server name to the server parameter 58 * means you can change the user's password on that NT4 Domain. 59 * 60 * Special thanks to Mark Russinovich (mark@sysinternals.com) for the 61 * tool and helping me solve some questions about it. 62 * 63 * @author Luiz R Malheiros (malheiros@gmail.com) 64 * @category Horde 65 * @copyright 2000-2017 Horde LLC 66 * @license http://www.horde.org/licenses/gpl GPL 67 * @package Passwd 68 */ 69class Passwd_Driver_Pspasswd extends Passwd_Driver 70{ 71 /** 72 */ 73 public function __construct(array $params = array()) 74 { 75 if (empty($params['server']) || 76 empty($params['bin']) || 77 empty($params['admusr']) || 78 empty($params['admpwd'])) { 79 throw new Passwd_Exception(_("Password module is missing required parameters.")); 80 } 81 82 if (!file_exists($params['bin'])) { 83 throw new Passwd_Exception(_("Password module can't find the supplied bin.")); 84 } 85 86 parent::__construct($params); 87 } 88 89 /** 90 */ 91 protected function _changePassword($user, $oldpass, $newpass) 92 { 93 $server = $this->_params['server']; 94 $chpwd_adm = $this->_params['admusr']; 95 $chpwd_usr = $user; 96 97 if (!empty($this->_params['domain'])) { 98 $chpwd_adm = $this->_params['domain'] . "\\" . $chpwd_adm; 99 $chpwd_usr = $this->_params['domain'] . "\\" . $chpwd_usr_name; 100 } 101 102 exec('NET USE \\\\' . $server . '\\IPC$ /D >NUL 2>NUL'); 103 104 $cmdline = 'NET USE \\\\' . $server . '\\IPC$ "' . $oldpass 105 . '" /USER:' . $chpwd_usr; 106 exec($cmdline, $cmdreply, $retval); 107 108 if (strpos(implode(' ', $cmdreply), 'The command completed successfully.') === false) { 109 throw new Passwd_Exception(_("Failed to verify old password.")); 110 } 111 112 exec('NET USE \\\\' . $server . '\\IPC$ /D >NUL 2>NUL'); 113 114 $cmdline = $this->_params['bin'] . ' \\\\' . $server . ' -u ' . $chpwd_adm . ' -p ' . $this->_params['admpwd'] . ' ' . $user. ' ' . $newpass; 115 exec($cmdline, $cmdreply, $retval); 116 exec('NET USE \\\\' . $server . '\\IPC$ /D >NUL 2>NUL'); 117 118 if (strpos(implode(' ', $cmdreply), 'Password for ' . $server . '\\' . $user. ' successfully changed.') === false) { 119 throw new Passwd_Exception(_("Access Denied.")); 120 } 121 } 122 123} 124