使用su和expect脚本登录用户时出现问题

3
我正在制作一个网站,用于课堂作业成绩管理。用户需使用用户名和密码登录,之后进入页面即可查看成绩。
这个网站是由一份名为“bash脚本”的文件(Github链接)运行的,并将托管在已有用户登录凭证的机器上。
我还编写了一个叫做“calcgrade.sh”的脚本,它能够计算当前登录用户或通过参数传递给脚本的其他用户的成绩。
最初,我打算使用下面这个命令:
echo -e "$password\n" | sudo -Sk -u $user ./website/calcgrade.sh

要运行网站用户的calcgrade.sh脚本,但我发现sudo要求当前登录的用户输入密码,而不是你尝试以命令运行的目标用户。
因此,经过一些阅读,我发现更好的选项是使用su与一个expect脚本,但我无法使其工作。这是expect脚本的代码(目前为了测试用户名和密码已硬编码):
#!/usr/bin/expect

log_user 0

spawn /bin/su myusername
expect "Password: "
send "mypassword"
spawn "./website/calcgrade.sh"

interact

当我运行这个脚本时,似乎不能使用su登录用户,因为它继续使用我的账户运行calcgrade.sh,而不是用户的账户。
你能看出我的脚本有什么问题吗?或者你能想到更好的方法来实现我的需求吗?
此外,使用这种方法的另一个问题是,calcgrade.sh应该向stderr发送一些输出,但是当我使用expect脚本运行它时,错误消息被发送到网站(服务器通过将网站的html发送到stdout来工作)。有没有办法解决这个问题,或者使用expect脚本只检查用户名/密码是否正确,然后再运行./calcgrade.sh $user会更好呢?

这个是否提供了相同的解决方案? https://dev59.com/s2w05IYBdhLWcg3w_Guw - Carol Domokos
1个回答

3
首先,这是您想要做的正确方法:
1. 给您的Web服务器用户sudo权限,以任何用户身份运行./website/calcgrade.sh,无需密码。 2. 通过您认为合适的方式对用户进行身份验证。 3. 运行sudo -u someuser ./website/calcgrade.sh,无需密码。
现在让我们看看为什么您的方法不起作用:
通常认为su切换用户。但实际上,它会启动一个以另一个用户身份运行的新shell。
这意味着您不能生成su otheruser,让它完成,然后再生成calcgrade.sh。
相反,您必须运行su otheruser,并向su启动的shell发送命令:
#!/usr/bin/expect 

log_user 0

spawn /bin/su someuser 
expect "Password: "
send "somepassword\n" 

# Now wait for a prompt and send the command to run
expect "$"
send "./website/calcgrade.sh\n"
interact

谢谢!现在明白了。至于你提出的正确方式的建议,由于我们的 Web 服务器是从头开始构建的,你会如何实现第二个步骤?使用 expect 中的 su 命令来检查登录是否成功? - user3791260
如果您正在使用框架编写Web服务器,请使用框架的身份验证模块,并将其配置为针对系统用户数据库验证凭据。如何实现这一点取决于所使用的框架。如果您没有使用框架,则可以使用系统的身份验证库(例如Linux上的libpam)。 - that other guy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接