Changing user system passwords with a PHP script - php

So I have a PHP script that needs to change a Linux user password programatically.
The script is running as www-data (which is the username given to apache2). I execute chpasswd with popen, and then fwrite the username:password pair. This causes an error.
Dropping down to a bash shell, I try to see what's going on here. Naturally, I suspect it's some kind of permissions issue. So, I change users to www-data and try to execute chpasswd manually:
# su www-data
$ /usr/sbin/chpasswd
jsmith:mysecretpassword
Changing password for jsmith.
chpasswd: (user jsmith) pam_chauthtok() failed, error:
Authentication token manipulation error
chpasswd: (line 1, user jsmith) password not changed
So this reveals why PHP is unable to execute the command. The error message is not exactly straightforward, but I suppose the gist of it is that a PAM authentication problem occurred (which I assume basically means a Linux permissions problem). So, if I su to root, I'm successfully able to change the password via chpasswd.
So obviously the problem here is that apache2 (user www-data) doesn't have sudo privileges. Is the only solution here to add www-data to the sudo group? Because I'd rather not do that. But I don't see any other option here.
More generally speaking - apart from the specifics of this situation - how is it even theoretically possible for a web program that might need to change user passwords to be able to do so without having sudo privileges? But if the web program has sudo privileges, then isn't that a major security problem?

I would likely setup a queuing system that runs as root and have the php script add to the queue instead of having PHP have access to any privilege escalation. This will also close some security holes although having web interface to changing linux user passwords still sounds like a bad idea.

Look into this and this. The second alternative, even though they have a "security" section at the bottom with suggestions, doesn't seem safe to me, but it's just a feeling.
I'd go for web-chpass.

Related

Running command-line application from PHP which can be run with sudo

I am a newbie here, I am having a bash script which can be executed through terminal with sudo permission only. I want to run it from PHP with proper security. I dont know where to start to accomplish this considering security in mind. Should I create a additional user or what Will be the better way to achieve this. I got a reference with Running command-line application from PHP as specific user, but I am using Nginx and the mentioned solution does not work for me.
NGINX is a web server and not the interpreter. It is not very relevant.
In the standard NGINX + PHP-FPM setup, you should have a separate system user for your website anyway. So you don't need to create an extra user just for that command.
Simply ensure that this "website user" is able to sudo run your script, without being prompted for their password. This is achieved by visudo.
example ALL=/path/to/your/script
Where example is the PHP-FPM pool user, aka, the "website user" and the owner of the website's files.

Best Practice: Managing system programs from PHP site

I'm working on a VPN signup site, which is written in PHP and runs on the same Ubuntu server that the VPN server runs on. It allows users to sign up for VPN services, but currently it just emails the support staff their information, and they manually edit the config files on the server. I'm using PPP to handle authentication, so I have a file containing information like below:
# user server password ip
test l2tpd testpassword *
In order for a new user to be added to the VPN service, their details must be appended to the above table, and the command
sudo /etc/init.d/xl2tpd restart
run in order to apply the new changes. What I am looking to do is automate the process. From what I can tell, there are two options. One is to create a shell script, and then use shell_exec('./adduser test testpassword');. The other is to do it directly in PHP, by opening the file, modifying it and saving it again.
From a security and speed point of view, which approach is better, or is there another one which I haven't thought of?
sudo can be configured to execute just a specific command for a specific user, so modifying your sudoers file can mean you can use sudo in a more secure way to execute specific commands.
You could combine this with a wrapper script so that php was only executing a localised script with limited rights.
So your wrapper script, let's call it 'restart_auth.sh` may contain:
#!/bin/sh
sudo /etc/init.d/xl2tpd restart
You would then shell_exec('restart_auth.sh') from php to run that script.
You would edit your sudoers file to allow the user that the script was run as (your php user) to run /etc/init.d/xl2tpd. so if your php user is www_data edit sudoers (using visudo ) to contain:
user host = (www_data) NOPASSWD: /etc/init.d/xl2tpd
Provided no tainted data - that is unvalidated information that may contain shell escape characters - is passed through to a shell exec command then it is secure.
As someone else suggested it may be better to write the data to a pending list then read from that, rather than passing it on a shell_exec() line. However that can still introduce insecurities, so making sure the values you are writing to the file are untainted is the most important thing.
Also never run that full script as root even as a cron job, but instead use the same approach with sudoers to only permit the running script to execute specific commands as root. For instance you could allow sudo "cat changes.txt >> auth_file"

What are the caveats when leaving apache with ALL(ALL) = ALL?

I'm creating a web app (php) that handles the creation of Drupal sites on a live server.
The system is able to create new sites and give some maintenance on existing ones. And, as this is a web-hosting environment, each folder may belong to a different user.
In order to do that properly I need to let the apache user run some commands as some other user.
What I do to create new files (and interact with git/drush/etc) is something similar to:
$some_command = `echo "PASSWD" | sudo -u USER -S do_something 2>&1; echo $?;`;
I already have a set of commands on the sudoers file that the apache user can run as the git user.
My issue now is that I need to let apache run as ANY user that may have a hosting account on the server.
My idea was to create a apache ALL=(ALL) ALL entry on the sudoers file. I would still leave all those commands asking for the users password.
With that in mind, is this wise to go with this approach? And if not, maybe I could apply the "allow all" policy only to the users that have a hosting account. If so, how do I narrow the policy to only one group?
Thanks
Edit: I though on using suPHP for this, as it allows apache to run each PHP script as its owner. But I would still need to run some other commands as another user (as creating files in someone else's home folder/public_html), so it seems that it isn't an option.
Based on our discussion in comments, I would advise installing something like suPHP so that each of your user's scripts are owned by their actual user and not Apache.
I figure you are having this issue is (maybe) because you want to be able to perform the administrative functions of other user's sites from a web interface. If you have a generic user like apache that other users can run scripts as, allowing that user automatic sudo permission is a bad idea since it could easily be exploited to gain unauthorized access.
To get around that, make sure you run your administrative functions as a special admin user that has permission to modify other people's files. Also make sure to chown any files you create as the appropriate user so they can read/write them. And as long as no other users can access that admin account or run PHP scripts as them, you should be much safer.
If you're running the admin functions from the console then it should be even easier, otherwise just set up a suPHP user to run your master functions from the web and use good credentials for the account.
Doing something like that will be more secure and should allow you to do everything you need without opening things up more than necessary.

Running a linux command from a PHP script?

I know this is a simple question, but I can't for the life of me get it to work. If I log in to my server via SSH (linux) and type in : /home/username/public_html/x/foo.cgi f=subscribe l=list e=abcd#gmail.com the script runs perfectly. However, if I try to run the script via PHP by the likes of : shell_exec("/home/username/public_html/x/foo.cgi f=subscribe l=list e=abcd#gmail.com"); nothing happens.
Can anyone point me in the right direction?
Thanks ahead of time!
Tre
"Nothing happens" isn't a very descriptive error message. Nevertheless, three possibilities come to mind:
Differences between the server-hosted environment versus the shell environment.
Your server or hosting site may have disabled shell_exec or other functionality.
You may need to be running PHP as the same user you SSH'd in as (or otherwise get the correct permissions).
Some other piece of the stack are in disarray due to mis-configuration or misuse.
Take your pick. Check your logs. Make sure you don't leave any holes available for attackers to get in.
If you are managing the server, most likely this is a permissions issue. Your webserver is running as www-data or some similar user. It needs execute permissions on the script file to run it. Try changing the script's owner with the chmod command or give the file you're trying to run more liberal access permissions with the chown command.
Another thing to consider is that shell_exec may be disabled if PHP is running in safe mode.

linux server restart in php script

I would like to know if it is possible to restart the Linux server using PHP script? In related to changing IP Address from Static to DHCP, I need to reboot the system so that it will take effect.
i tried this code:
system("/usr/bin/reboot");
error message is :
reboot: must be useruser
here'e the another:
system('/etc/init.d/network restart');
the error is:
Shutting down loopback interface: [FAILED] Bringing up loopback interface: [FAILED]
Hope you can help me in this.
Thank you!
Regards to all.
You can restart it if the program-users-context of your interpreter, webserver has the rights to execute these commands. A webserver or php interpreter should not be run as root. You may use sudo, sudoers in order to escalate privileges in these both cases.
You will need to use sudo like this:
system("sudo /usr/bin/reboot");
in your /etc/sudoers add the following:
apache ALL=(ALL) NOPASSWD: /usr/bin/reboot
Where apache is the username under which the PHP script runs.
Be aware of the security impication of doing this - anyone with access to PHP scripts on the server to reboot the server.
In related to changing IP Address from Static to DHCP, I need to reboot the system
No you don't. This is not Microsoft Windows. But the command for remapping the network interfaces varies from distribution to distribution - and you don't say which this is. Similarly, access the reboot, shutdown, init and telinit commands varies by distribution.
I am working in local server
So why not just do it via ssh or at the console?
Since you have stated that you're a newbie to Linux, I feel that it's worth pointing out that it's much much less common to need to reboot a Linux box compared to a Windows one.
You shouldn't need to reboot even after updating core software packages. Even if something crashes badly, you can ususally recover without a reboot.
You haven't stated why you'd want to be doing a reboot, but rebooting the whole box really should be an absolute last resort. In fact, rebooting simply to clear an issue is consdered very bad practice for a Linux administrator because it tends to wipe out evidence of what caused the problem, and does nothing to prevent the problem from recurring.
On Linux, most issues that would require a Windows box to be rebooted only require the individual program or service to be restarted.
Finally, a note on security: Doing major system operations such as this via a PHP program is bad security practice because it exposes root level functionality to non-root users. I assume (well, I hope!) that you're planning to lock down access to this PHP page, but even the best secured web page should not be considered secure enough to be running root-level operations.
In short, my advice is that you shouldn't do this. If you must do it, #qbert220's answer should work, but please don't do it.
[EDIT]
With specific regard to changing the IP address from DHCP to static, this should not require a server reboot in Linux. You simply need to restart the networking interface.
Once you've changed the config, something like this should be enough to restart your network interface with the new IP address in place:
sudo /etc/init.d/networking restart
You haven't specified what variety of Linux you're using, but here's a link to a page which details how to do it from the commandline in Ubuntu.
It does require root priviledges though, so you would need to use sudo to achieve it and to add your web user to the sudoers list, which as I said before is really not great from a security point of view.
Script must be set to run as root:
reboot.php
<?php
exec("reboot -d -f -i");
?>
Meke it a root script:
chown root.root reboot.php
chmod 700 reboot.php
But why do this with php? Just make a script in sh like so:
#! /bin/sh
PATH=/sbin:/usr/sbin:/bin:/usr/bin
reboot -d -f -i

Categories