forked from waja-archive/dovecotpfd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdovecotpfd.php
executable file
·102 lines (87 loc) · 4.21 KB
/
dovecotpfd.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
<?php
/**
* Dovecot Password File Driver (dovecotpfd)
*
* Roundcube password plugin driver that adds functionality to change passwords stored in
* Dovecot passwd/userdb files (see: http://wiki.dovecot.org/AuthDatabase/PasswdFile)
*
* Copyright (C) 2011, Charlie Orford
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*
* SCRIPT REQUIREMENTS:
*
* - PHP 5.3.0 or higher, shell access and the ability to run php scripts from the CLI
*
* - chgdovecotpw and dovecotpfd-setuid.c (these two files should have been bundled with this driver)
*
* - dovecotpfd-setuid.c must be compiled and the resulting dovecotpfd-setuid binary placed in the same directory
* as this script (see dovecotpfd-setuid.c source for compilation instructions, security info and options)
*
* - chgdovecotpw must be placed in a location where dovecotpfd-setuid can access it once it has changed UID (normally /usr/sbin is a good choice)
*
* - chgdovecotpw should only be executable by the user dovecotpfd-setuid changes UID to
*
* - the dovecot passwd/userdb file must be accessible and writable by the same user dovecotpfd-setuid changes UID to
*
* - dovecotpw (usually packaged with dovecot itself and found in /usr/sbin) must be available and executable by chgdovecotpw
*
*
* @version 1.1 (2011-09-08)
* @author Charlie Orford (charlie.orford@attackplan.net)
**/
class rcube_dovecotpfd_password
{
function save($currpass, $newpass)
{
$rcmail = rcmail::get_instance();
$currdir = realpath(dirname(__FILE__));
list($user, $domain) = explode("@", $_SESSION['username']);
$username = (rcmail::get_instance()->config->get('password_dovecotpfd_format') == "%n") ? $user : $_SESSION['username'];
$scheme = rcmail::get_instance()->config->get('password_dovecotpfd_scheme');
// Set path to dovecot passwd/userdb file
// (the example below shows how you can support multiple passwd files, one for each domain. If you just use one file, replace sprintf with a simple string of the path to the passwd file)
// You may override this in main.inc.php
$passwdfile = rcmail::get_instance()->config->get('password_dovecotpfd_passwdfile');
if ( empty($passwdfile) ) $passwdfile = sprintf("/home/mail/%s/passwd", $domain);
// Build command to call dovecotpfd-setuid wrapper
$exec_cmd = sprintf("%s/dovecotpfd-setuid -f=%s -u=%s -s=%s -p=\"%s\" 2>&1", $currdir, escapeshellcmd($passwdfile), escapeshellcmd($username), escapeshellcmd($scheme), escapeshellcmd($newpass));
// Call wrapper to change password
if ($ph = @popen($exec_cmd, "r"))
{
$response = "";
while (!feof($ph))
$response .= fread($ph, 8192);
if (pclose($ph) == 0)
return PASSWORD_SUCCESS;
raise_error(array(
'code' => 600,
'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Password plugin: $currdir/dovecotpfd-setuid returned an error"
), true, false);
return PASSWORD_ERROR;
} else {
raise_error(array(
'code' => 600,
'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Password plugin: error calling $currdir/dovecotpfd-setuid"
), true, false);
return PASSWORD_ERROR;
}
}
}
?>