1<?php 2/** 3 * Copyright 2000-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 2000-2017 Horde LLC 10 * @license http://www.horde.org/licenses/gpl GPL 11 * @package Passwd 12 */ 13 14/** 15 * Changes a password on a samba server. 16 * 17 * @author Rene Lund Jensen <Rene@lundjensen.net> 18 * @category Horde 19 * @copyright 2000-2017 Horde LLC 20 * @license http://www.horde.org/licenses/gpl GPL 21 * @package Passwd 22 */ 23class Passwd_Driver_Smbpasswd extends Passwd_Driver 24{ 25 /** 26 * Socket connection resource. 27 * 28 * @var resource 29 */ 30 protected $_fp; 31 32 /** 33 */ 34 public function __construct(array $params = array()) 35 { 36 parent::__construct(array_merge(array( 37 'host' => 'localhost', 38 'program' => '/usr/bin/smbpasswd' 39 ), $params)); 40 } 41 42 /** 43 * Connects a pipe to the sambaserver using the smbpasswd program. 44 * 45 * @param string $user The user to change the password for 46 * @param string $tmpfile The name of a temporary file in which to write 47 * output. 48 * 49 * @throws Passwd_Exception 50 */ 51 protected function _connect($user, $tmpfile) 52 { 53 if (!is_executable($this->_params['program'])) { 54 throw new Passwd_Exception(_("Passwd is not properly configured.")); 55 } 56 57 $cmd = sprintf( 58 '%s -r %s -s -U "%s" > %s 2>&1', 59 $this->_params['program'], 60 $this->_params['host'], 61 $user, 62 $tmpfile 63 ); 64 65 if (!($this->_fp = @popen($cmd, 'w'))) { 66 throw new Passwd_Exception(_("Could not open pipe to smbpasswd.")); 67 } 68 } 69 70 /** 71 * Disconnects the pipe to the sambaserver. 72 */ 73 protected function _disconnect() 74 { 75 @pclose($this->_fp); 76 } 77 78 /** 79 * Sends a string to the waiting sambaserver. 80 * 81 * @param string $cmd The string to send to the server. 82 * 83 * @throws Passwd_Exception 84 */ 85 protected function _sendCommand($cmd) 86 { 87 if (fputs($this->_fp, $cmd . "\n") == -1) { 88 throw new Passwd_Exception(_("Error sending data to smbpasswd.")); 89 } 90 sleep(1); 91 } 92 93 /** 94 */ 95 protected function _changePassword($user, $oldpass, $newpass) 96 { 97 // Clean up user name in case evil characters are in it. 98 $user = escapeshellcmd($user); 99 100 $tmpfile = Horde::getTempFile('smbpasswd'); 101 102 $this->_connect($user, $tmpfile); 103 $this->_sendCommand($oldpass); 104 $this->_sendCommand($newpass); 105 $this->_sendCommand($newpass); 106 $this->_disconnect(); 107 108 $res = file($tmpfile); 109 if (strstr($res[count($res) - 1], 'Password changed for user') === false) { 110 throw new Passwd_Exception(strrchr(trim($res[count($res) - 2]), ':')); 111 } 112 } 113 114} 115