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