I am working on making a website for a class that you log into with a username and password, and then it takes you to a page that shows your grades in the class.
The website is being run with a bash script, and will be hosted on a machine where the users already have a username and password to login.
I also have a script called calcgrade.sh
that will calculate the grades for either the user who is currently logged in, or the user passed to the script as an argument.
So originally, I was going to use this command:
echo -e "$password\n" | sudo -Sk -u $user ./website/calcgrade.sh
to run calcgrade.sh
as the user of the website. However, I found out that sudo
asks for the password of the user who is currently logged in, not the target user you are trying to run a command as.
So after some reading, I found a better option would be to use su
with an expect
script, but I can't get it to work. Here is the code for the expect
script (currently username and password are hard coded in for testing):
#!/usr/bin/expect
log_user 0
spawn /bin/su myusername
expect "Password: "
send "mypassword"
spawn "./website/calcgrade.sh"
interact
When I run this script, it doesn't seem to log in the user with su
, as it goes on to run calcgrade.sh
with my account, rather than the user's.
Do you see what is wrong with my script? Or can you see a better way to do what I want?
Also, another problem with this method is that calcgrade.sh
is supposed to send some output to stderr
, but when I run it with the expect
script, the error messages get sent to the website (the server works by sending the html for the website to stdout
). Is there a way around this, or might it be better to have the expect
script just check with su
if username/password is correct, and then if so, then run ./calcgrade.sh $user
afterwards?
First of all, here's the correct way to do what you want to do:
sudo
permissions to run ./website/calcgrade.sh
as any user, without requiring a password. sudo -u someuser ./website/calcgrade.sh
, no password required.Now let's look at why your approach didn't work:
It's commonly believed that su
switches user. This is not the case. It actually starts a new shell running as another user.
This means that you can't spawn su otheruser
, let it finish, and then afterwards spawn calcgrade.sh
.
Instead you have to run su otheruser
, and then send commands to the shell that su
starts:
#!/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