0

I asked this question about six months ago and I thought I might get better responses here.

I have a website written almost exclusively in javascript (HTML canvas), and a MySQL database managed via PHP. Serverside, scripts I execute are axecuted as user www-data. Now suppose I want to create a new linux account as well as adding the user's name/password to the database. How would I automate this?

The actual functionality I would like extends to also creating groups for the user, creating a skeleton directory for the home folder, and having read/write access to their home folder and sub folders. In essence, I need to execute certain commands as root but I obviously can not type them in from a keyboard.

One idea I had was to set up a /home/www-data/.ssh/ folder with keyless ssh login to root, but I am worried that is giving too much power.


Mad Hatter pointed out that this is a potential duplicate of this question so I am refining my original question.

In my website each user is allowed to create their own scripts and execute them. There is a complex library created, which can dynamically load javascript scripts, execute them, almost always redrawing the HTML Canvas element. In addition to this, they can create PHP scripts.

Because the user can create their own PHP scripts, I can't just hand over root access for creating new users to www-data (by editing the /etc/sudoers file). What I want is a way to execute the below command/PHP script when the user is registering (therefore connecting as user www-data)

shell_exec("sudo useradd J.C.Denton");

But avoid the situation where, afterwards, a user writes a PHP script to use the above PHP file to start creating their own users.

My ideal scenario would be to be able to log in a user not only as a PHP session and give him access to only elements of the SQL database he/she has rights to, but to actually log him into the Apache server as, in this case, J.C.Denton

puk
  • 285
  • 1
  • 6
  • 18
  • 1
    Does [incron](http://serverfault.com/questions/309849/allowing-any-valid-mysql-user-access-to-a-particular-table) help? – quanta Nov 04 '11 at 07:04
  • possible duplicate of [how do i perform root actions from non-root account?](http://serverfault.com/questions/319737/how-do-i-perform-root-actions-from-non-root-account) – MadHatter Nov 04 '11 at 07:17
  • I suppose that's a way to get around it. It's not ideal, however, to listen for changes to every table. – puk Nov 04 '11 at 07:20
  • @MadHatter you are right, it is a duplicate. I will refine my question. – puk Nov 04 '11 at 07:26

2 Answers2

1

Have you considered using something like pam_mysql or pam_ldap and put the user account information to database? That way you can separate your system accounts (local /etc/passwd) from your user accounts, increasing both flexibility and security. Managing your users would happen via MySQL, no root access needed.

pam_mkhomedir would then create the home dir (and needed skeleton files) upon first login.

Thanks to PAM most of the services I can imagine (shell access, e-mail, [s]ftp, www...) can use pam_mysql or pam_ldap transparently, your end users will not notice that in any way.

Janne Pikkarainen
  • 31,852
  • 4
  • 58
  • 81
  • I googled `pam_mysql` and `pam_ldap` but they were no help. I take it what you are suggesting is I copy file permissions to the database...right? – puk Nov 04 '11 at 08:01
  • No. What I'm suggesting is that you would use `pam_mysql` to store user information, just like it usually goes to `/etc/passwd` and `/etc/shadow`. – Janne Pikkarainen Nov 04 '11 at 08:11
  • For what purpose? I need to, for example, call `/home/J.C.Denton/helloWorld.php` or `rm /home/J.C.Denton/helloWorld.php`. How would having password access move me in that direction. – puk Nov 04 '11 at 08:15
  • unrelated, do you know why sometimes I can respond to someone's comment with the ampersat sign (ie. _AT_Janne Pikkarainen) but at other time's I can't? – puk Nov 04 '11 at 08:16
  • For exactly that purpose. PAM (Pluggable Authentication Module) is taking care for everything that is related to security: authentication, authorization and so on. Using `pam_mysql` IS same than storing your information to `/etc/passwd` and so on. `/etc/passwd`, `/etc/shadow` and `/etc/group` are much more than "having password access". They are used for mapping filesystem UIDs to user/group names and so on. Just believe me when I say `pam_mysql` and `pam_ldap` are widely used; they make life lots easier when you have more than one server and access rights need to be consistent. – Janne Pikkarainen Nov 04 '11 at 08:24
  • So PAM makes all this transparent by making sure a user logged in as `John` can't access files belonging to `Jill`. The [documentation](http://pam-mysql.sourceforge.net/) online does not appear to be very helpful. – puk Nov 04 '11 at 08:36
  • Take a look at `/etc/pam.d` directory. When using `/etc/passwd` and that usual stuff, `pam_unix` is what makes the magic happen underneath. What I'm suggesting is that you add there also `pam_mysql`, which will then query the data from MySQL instead of accessing plaintext files. Am I making any sense to you? – Janne Pikkarainen Nov 04 '11 at 08:40
  • I'm having a hard time following you, but here goes. Under normal circumstances, user permissions are determined via [pan_unix](http://linux.die.net/man/8/pam_unix). `pam_unix` usually uses `/etc/passwd` to determine this. `pam_mysql`, on the other hand, tricks the computer into using the database's version instead. – puk Nov 04 '11 at 08:48
  • Yes! Now you're starting to get it. :) Although "trick" is such harsh word in this case, since PAM is designed to be modular. It does not matter where the data is coming from, it can be from text files, from MySQL, from LDAP, from BerkeleyDB, from Microsoft Active Directory. As long there is a PAM module for it, you can use it. :) The actual programs do not care about the data source, PAM acts as a bridge between system security and the data source (such as text file or MySQL). – Janne Pikkarainen Nov 04 '11 at 08:54
  • So my main point for recommending `pam_mysql` to you is: thanks to it you don't need root access for managing user info; you just add and remove the user data to MySQL. PAM then uses that data in the exactly same way it would have been used when read from `/etc/passwd`. – Janne Pikkarainen Nov 04 '11 at 08:56
  • That's interesting, and will this work across sessions? For example if I have a dozen people viewing the web site at the same time? I am assuming it will work just like a dozen people ssh-ing into the same computer at the same time. Can you provide me with a link? The documentation page is just the FAQ page, and most other links link to '404 Not Found' pages. – puk Nov 04 '11 at 08:58
  • One last question to get rid of ambiguities: Would I be able to 'log in' a user in this way? Somehow to tell MySQL that "Hey, pretend I'm user J.C.Denton when you try to read/write/execute files". – puk Nov 04 '11 at 09:04
  • Everything will work _just_ like with plain text files. Let that be a shell login, scp/sftp transfer, e-mail login, http request made to your server... so yes, you could 'log in' a user this way. On the other hand, if you want to allow users stored in MySQL to just couple of services, then you only add that `pam_mysql` stanza to relevant files in `/etc/pam.d`. I'll try to look for a decent tutorial for you, I know those are hard to find. – Janne Pikkarainen Nov 04 '11 at 09:19
1

You can't "actually log him into the Apache server as, in this case, J.C.Denton" because unless you implement the relevant constructs within your application the functionality does not exist. While you can use HTTP authentication - this does not provide all the other parts necessary for a security model.

You're trying to deal with 3 different security models here

  • unix user security for filesystem access
  • mysql security for data access
  • application security within the web application

Yes, rationalizing these potentially conflicting models should be high on your list of design priorities - but should you really be basing it around the Unix permissions model? There are tools for extending this into the application domain using PHP - but it's not the only solution.

Leaving that aside for the moment, on a Unix/Linux/POSIX system creating users from the command line is simple - but there are some caveats. Similarly you can create mysql users using SQL. But note that the pam_mysql module which I know about does not use MySQL's authentication and user management functionality - but merely provides a repository for authentication data.

Bundling all this into a single shell or php script is trivial. The only caveat is that if you want to invoke this from something other than a shell owned by root, then you should still make it only readable/executable by root, but configure sudo to allow it to be run, e.g. from the webserver.

So to make your model work, you need to plan out how you're going to structure the Unix permissions in a bit more details and use suPHP.

symcbean
  • 21,009
  • 1
  • 31
  • 52
  • I guess I could go with suPHP and compare the MySQL user's name/groups and see if they have read/write/execute permissions over that file, and if they do, give them access to it. – puk Nov 04 '11 at 09:18
  • No - you've missed the point - either you implement the security yourself (in which case your code would "see if they have read/write/execute permissions over that file, and if they do, give them access to it") or you use an existing security system. – symcbean Nov 07 '11 at 11:57
  • I think my comment was valid. I will use an existing security system (in this case suPHP) and implement some of the security myself (in this case, the initial check in MySQL to ensure logged in user has rights to file they are accessing). – puk Nov 07 '11 at 17:10