Roundcube从1.3升级至1.4后密码重置插件报PHP错误求助
问题根因
- 核心故障点为Python3的字符串编码规则差异:Python3中
subprocess.Popen的communicate()方法向子进程标准输入写入数据时,默认要求传入*字节类型(bytes)*参数,但原始chpasswd-wrapper.py脚本中传入的是未编码的字符串(str类型),直接触发TypeError: a bytes-like object is required, not 'str'报错,导致脚本执行异常退出,返回非0状态码,因此Roundcube端抛出执行失败提示。 - 补充说明:你之前直接给脚本传递命令行参数的测试方式不符合脚本设计逻辑,该脚本是从标准输入读取
用户名:密码格式的内容,而非读取命令行入参,正确的命令行测试方式为echo "测试用户名:测试密码" | sudo /usr/sbin/chpasswd-wrapper.py。 - 注意检查sudoers配置:你当前配置的免密执行路径为
/usr/sbin/chpasswd,但Roundcube实际调用的是/usr/sbin/chpasswd-wrapper.py,如果简化版脚本可正常运行,说明你可能已经调整了该配置,否则需要补充对应免密规则。
修复方案
仅需要修改chpasswd-wrapper.py脚本,两种修复方案二选一即可:
方案1:对传入字符串手动编码(兼容性最好)
找到脚本中handle.communicate('%s:%s' % (username, password))这一行,修改为:
handle.communicate(('%s:%s' % (username, password)).encode('utf-8'))
该方案无需修改其他代码,兼容所有Python3版本。
方案2:指定subprocess为文本模式(代码更简洁)
修改subprocess.Popen初始化参数,添加text=True(Python3.7及以上版本支持,旧版本替换为universal_newlines=True),让框架自动处理字符串和字节的转换:
handle = subprocess.Popen('/usr/sbin/chpasswd', stdin = subprocess.PIPE, text=True) handle.communicate('%s:%s' % (username, password))
验证步骤
- 命令行验证:执行
echo "testuser:testpass123" | sudo /usr/sbin/chpasswd-wrapper.py,无报错且返回状态码为0(执行echo $?可查看返回码),说明脚本修复成功。 - 功能验证:登录Roundcube账号尝试修改密码,确认不再弹出「Could not save new password.」错误提示即可。
内容的提问来源于stack exchange,提问作者StevieD
相关产品推荐
相关产品推荐

