Home Accessibility Courses Diary The Mouth Forum Resources Site Map About Us Contact
Python and Tcl - public course schedule [here]
Private courses on your site - see [here]
Please ask about maintenance training for Perl, PHP, Lua, etc
A Web interface for your Linux admin tasks

Do you need to set up and maintain a whole load of accounts for users on your web server - giving them each their own area of the LAMP server, log in account, password, and MySQL database too? Do you have to set up a whole series of these accounts in a short period and are you fearful of getting one line wrong?

You could use a shell script (example to follow) ... but you need to be logged in as root and/or mess about with suid (setuid) bits, and it's not a way to do it flexibly.

Second approach - run the script via an expect session so that you can add an account from any logged in account if you know appropriate passwords. (example follows)

Third alternative - provide a web front end to your expect script. (again, example to follow)


# Create a full user account

/usr/sbin/useradd -m -k /home/template -g apache $1
echo "$2" | /usr/bin/passwd --stdin $1
chmod 750 /home/$1

echo "create database $1; GRANT all on $1.* to $1@'localhost' identified by '$2'" | \
  /usr/local/mysql/bin/mysql -hlocalhost -uroot -p$3

echo "set password for '$1'@'localhost' = OLD_PASSWORD('$2')" | \
     /usr/local/mysql/bin/mysql -hlocalhost -uroot -p$3

This script (called up under the name fulluser at the next level) creates a Linux and a MySQL account for a new user, both password protected. The final password (re)setting command is only needed if you're using a recent MySQL with older client code.

 fulluser username userspassword databaserootpassword

The script assumed that the person running it is cleanly entering three parameters (but then at this level, this script will only work for the administrator anyway, and only if he/she gives the MySQL root password too). Also assumes that the MySQL server is on the same host ("localhost").

A template (initial contents) for each user's new home directory should be provided in /home/template. Include things such as a .my.cnf file, a README file, a link to the acceptable user policy document, and their public_html directory, seeded with an appropriate index.html


Use expect for this. Expect is an extension of Tcl (the tool control language) and should come with your Linux distribution. It allows you to choreograph a terminal session along the lines of "I say this, computer replies that" and in this instance we're using it to obtain a log in, switch across to the root user, and run the fulluser script shown above.


# Connect as root

set rootpw [lindex $argv 3]
set adminpw [lindex $argv 2]

spawn telnet localhost

expect "login: "
send "webadmin\r"
expect "sword: "
send "$adminpw\r"
expect {$ }

send "su -\r"
expect "sword: "
send "$rootpw\r"
expect {# }

send "/usr/local/bin/fulluser $argv\r"
expect {# }

Note that the \r is the code for a new line - you don't use \n when you're doing a send in expect. The expect sequence is a trigger that we're looking for before proceeding and is the end of the word "password"; the trailing space is VITAL so as to ensure that the password isn't sent until the prompt has been completed.

 webuser username userspassword nextpassword rootpassword

In our example, "nextpassword" is the password that's used for both the MySQL root and also for the webadmin account that we've created as part of our build. The "userpassword" is the password that we want assigned to our new user and "rootpassword" is the password that is the linux administrator's password. We COULD split "nextpassword" into two different passwords, but there's a limit to how many passwords even the best of admins can deal with in his head at any one time.

In our example, passwords are given on the command line. It's technically possible to write passwords into the script but you should understand the security implications before you make such a change and if in doubt, don't.


Finally, here's the script that allows webuser to be run from a browser.

if ($_POST[filled] == 1) {
 $resp = shell_exec("/usr/local/bin/webuser".
            " $_POST[acname]".
              " $_POST[acpass]".
              " $_POST[wapass]".
              " $_POST[ropass]");
     $say = "New account $_POST[acname] added";
} else {
      $say = "-";
<title>User account creation</title>
<h1>Adding a user account</h1>
<b><?php print($say); ?></b><br><br>
<form method=post>
Name of new account <input name=acname><br>
New account password <input name=acpass>
(add 2 x entry and obscure later)<br>
Webadmin password <input name=wapass type=password><br>
System admin password <input name=ropass type=password><br>
<input type=submit><input name=filled type=hidden value=1>

When this page is called up by a link from another page or by having its URL typed in, the form is displayed; the absence of a posted element called "filled" ensures that no action is taken.

When the form is completed and submitted back (to itself), the presence of a "filled" element with the value "1" causes the webuser script to be run and the account added. The form is then offered again as it's more than likely that the user will want to set up a whole series of accounts.

Note that I've used type=password to obscure the incoming passwords, but I have NOT used it for the new account's password


Please, PLEASE don't try to install all three of these scripts at once and hope that they all work together. Start off with fulluser and add a user from the root account. Then when you know that works, run webuser from a regular account.

Only when those first two stages have checked out should you risk running the web page script, knowing that any problems issues remaining will be at the PHP level.


Be aware - this page is just a demonstration; there's a lot more that you could / might / should do to use it in a production environment.

1. Check each of the elements to ensure they have worked and flag errors if there are any problems.

2. Check for duplicated user names

3. Add facilities to update password for an existing user, etc.

4. Add in a facility to enter the email address of the user and have the system email them to tell them about their new account

It's also worth remembering that you MUST plan your basic security properly before you write the scripts such as this to control it - especially if you're going to be something of a specialised ISP / WSP. The model we have used has all users in group "apache", with the web server running in that same group; on a machine that's only got web user accounts, you may be better advised to have all users in a group that has NO permissions for server files, and have the web server access the files it needs from an individual's area by higher access rights for other. If in doubt, read up or ask!

By the time you get all this done, perhaps you should be looking at a tool such as plesk rather than rolling your own - but then the code shown in this example is superbly tuneable

See also All files (including sample template)

Please note that articles in this section of our web site were current and correct to the best of our ability when published, but by the nature of our business may go out of date quite quickly. The quoting of a price, contract term or any other information in this area of our website is NOT an offer to supply now on those terms - please check back via our main web site

Related Material

PHP - Further Web Page and Network Handling
  [4483] Moving from mysql to mysqli - simple worked example - (2015-05-03)
  [4070] Passing variable between PHP pages - hidden fields, cookies and sessions - (2013-04-26)
  [3918] Multiple page web applications - maintaining state - PHP - (2012-11-10)
  [3568] Telling which ServerAlias your visitor used - useful during merging domains - (2012-01-04)
  [3540] Easy session example in PHP - keeping each customers data apart - (2011-12-06)
  [3432] 3 digit HTTP status codes - what are they, which are most common, which should be a concern? - (2011-09-11)
  [3036] Sending out an email containing HTML from within a PHP page - (2010-11-07)
  [2918] Downloading a report from the web for further local analysis - (2010-08-13)
  [2729] Uploading a document or image to its own URL via a browser - (2010-04-18)
  [2679] How to build a test harness into your PHP - (2010-03-16)
  [2632] Shipping a test harness with your class in PHP - (2010-02-12)
  [1549] http, https and ajp - comparison and choice - (2008-02-22)
  [1518] Downloading data for use in Excel (from PHP / MySQL) - (2008-01-25)
  [1515] Keeping staff up to date on hotel room status - (2008-01-22)
  [1505] Script to present commonly used images - PHP - (2008-01-13)
  [1496] PHP / Web 2 logging - (2008-01-06)
  [1495] Single login and single threaded models - Java and PHP - (2008-01-04)
  [1485] Copyright and theft of images, bandwidth and members. - (2007-12-26)
  [1379] Simple page password protection - PHP - (2007-10-04)
  [1355] .php or .html extension? Morally Static Pages - (2007-09-17)
  [1210] PHP header() function - uses and new restrictions - (2007-05-30)
  [1187] Updating a page strictly every minute (PHP, Perl) - (2007-05-14)
  [1183] Improving searches - from OR to AND? - (2007-05-11)
  [1114] PHP Image upload script - (2007-03-21)
  [1009] Passing GET parameters through Apache mod_rewrite - (2006-12-27)
  [936] Global, Superglobal, Session variables - scope and persistance in PHP - (2006-11-21)
  [904] Of course I'll tell you by email - (2006-10-25)
  [847] Image maps for navigation - a straightforward example - (2006-08-28)
  [789] Hot answers in PHP - (2006-07-02)
  [767] Finding the language preference of a web site visitor - (2006-06-18)
  [675] Adding PHP tags to an old cgi program - (2006-04-08)
  [603] PHP - setting sort order with an associative array - (2006-02-13)
  [565] Using PHP to output images, XML, Style sheets, etc - (2006-01-15)
  [542] Morning image, afternoon image - (2005-12-26)
  [537] Daily Image Santafied - (2005-12-22)
  [484] Setting the file name for a downloaded document - (2005-11-03)
  [451] Accessing a page via POST from within a PHP script - (2005-09-26)
  [443] Server side scripting of styles to suit the browser - (2005-09-12)
  [425] Caching an XML feed - (2005-08-26)
  [410] Reading a news or blog feed (RSS) in your PHP page - (2005-08-12)
  [376] What brings people to my web site? - (2005-07-13)
  [372] Time calculation in PHP - (2005-07-08)
  [356] Sudoku helper or sudoku cheat - (2005-06-23)
  [345] Spotting a denial of service attack - (2005-06-12)
  [314] What language is this written in? - (2005-05-17)
  [220] When to use Frames - (2005-02-19)

Web Application Deployment - Apache httpd - Sourcing, Installation, Testing
  [4437] Adding a PHP build option, rotating an image based on camera data, and a new look at thumbnails in PHP - (2015-02-22)
  [3426] Automed web site testing scripted in Ruby using watir-webdriver - (2011-09-09)
  [2520] Global and Enable - two misused words! - (2009-11-30)
  [2184] Choosing the right version of Java and Tomcat - (2009-05-16)
  [2096] Where is my new Apache httpd installed - (2009-03-22)
  [2080] Using ApacheBench and jconsole to test and monitor Tomcat - (2009-03-14)
  [1945] Summary - Apache httpd build on Linux - (2008-12-14)
  [1768] What is built in to this httpd and PHP? - (2008-08-23)
  [1731] Apache httpd, MySQL, PHP - installation procedure - (2008-08-01)
  [1707] Configuring Apache httpd - (2008-07-12)
  [1455] Connecting to MySQL 5 from PHP on Mac OSX Leopard - (2007-12-03)
  [1449] Upgrade Mac OSX to Leopard, Web Server Apache httpd config lost - (2007-11-29)
  [1292] DHCP automatic IP address v Static IP - (2007-08-06)
  [1095] Apache httpd , browser, MySQL and MySQL client downloads - (2007-02-28)
  [982] Notes from the white board - (2006-12-14)
  [907] Browser -> httpd -> Tomcat -> MySQL. Restarting. - (2006-10-28)
  [660] Stopping and restarting Apache httpd cleanly - (2006-03-29)
  [550] 2006 - Making business a pleasure - (2006-01-01)
  [526] Apache httpd - serving web documents from different directories - (2005-12-12)
  [523] Apache httpd release 2.2 - (2005-12-10)

Web Application Deployment - Further httpd Configuration
  [4307] Identifying and clearing denial of service attacks on your Apache server - (2014-09-27)
  [4001] Helping search engines with appropriate 400 error codes - (2013-02-11)
  [3955] Building up from a small PHP setup to an enterprise one - (2012-12-16)
  [3862] Forwarding a whole domain, except for a few directories - Apache http server - (2012-09-17)
  [3635] Parse error: parse error, unexpected T_STRING on brand new web site - why? - (2012-03-03)
  [3449] Apache Internal Dummy Connection - what is it and what should I do with it? - (2011-09-19)
  [3133] An image from a website that occasionally comes out as hyroglyphics - (2011-01-14)
  [2900] Redirecting a page - silent, temporary or permanent? - (2010-08-03)
  [2478] How did I do THAT? - (2009-10-26)
  [2272] Monitoring and loading tools for testing Apache Tomcat - (2009-07-07)
  [2060] Database connection Pooling, SSL, and command line deployment - httpd and Tomcat - (2009-03-01)
  [1974] Moving a directory on your web site - (2009-01-03)
  [1955] How to avoid duplicating web page maintainance - (2008-12-20)
  [1954] mod_rewrite for newcomers - (2008-12-20)
  [1939] mod_proxy_ajp and mod_proxy_balancer examples - (2008-12-13)
  [1778] Pointing all the web pages in a directory at a database - (2008-08-30)
  [1767] mod_proxy and mod_proxy_ajp - httpd - (2008-08-22)
  [1762] WEB-INF (Tomcat) and .htaccess (httpd) - (2008-08-20)
  [1707] Configuring Apache httpd - (2008-07-12)
  [1636] What to do if the Home Page is missing - (2008-05-08)
  [1619] User and Group settings for Apache httpd web server - (2008-04-22)
  [1566] Strange behaviour of web directory requests without a trailing slash - (2008-03-06)
  [1564] Default file (MiMe types) for Apache httpd and Apache Tomcat - (2008-03-04)
  [1554] Online hotel reservations - Melksham, Wiltshire (near Bath) - (2008-02-24)
  [1551] Which modules are loaded in my Apache httpd - (2008-02-23)
  [1381] Using a MySQL database to control mod_rewrite via PHP - (2007-10-06)
  [1377] Load Balancing with Apache mod_jk (httpd/Tomcat) - (2007-10-02)
  [1355] .php or .html extension? Morally Static Pages - (2007-09-17)
  [1351] Compressing web pages sent out from server. Is it worth it? - (2007-09-14)
  [1207] Simple but effective use of mod_rewrite (Apache httpd) - (2007-05-27)
  [1121] Sharing the load with Apache httpd and perhaps Tomcat - (2007-03-29)
  [1080] httpd.conf or .htaccess? - (2007-02-14)
  [1009] Passing GET parameters through Apache mod_rewrite - (2006-12-27)
  [934] Clustering, load balancing, mod_rewrite and mod_proxy - (2006-11-21)
  [853] To list a directory under httpd on a web server, or not? - (2006-09-02)
  [755] Using different URLs to navigate around a single script - (2006-06-11)
  [662] An unhelpful error message from Apache httpd - (2006-03-30)
  [649] Denial of Service ''attack'' - (2006-03-17)
  [631] Apache httpd to Tomcat - jk v proxy - (2006-03-03)
  [550] 2006 - Making business a pleasure - (2006-01-01)
  [526] Apache httpd - serving web documents from different directories - (2005-12-12)
  [466] Separating 'per instance' data from binaries and web sites - (2005-10-16)
  [345] Spotting a denial of service attack - (2005-06-12)

Web Application Deployment - Users and Groups
  [4045] Linux Web Server - User Roles, User Accounts, and shared administration - (2013-03-16)
  [2639] su or su - ... what is the difference? - (2010-02-17)
  [2491] Root is root for a reason! - (2009-11-03)
  [2301] Mistaken identity? - (2009-07-22)
  [2203] Always use su with minus. And where do programs come from? - (2009-05-27)
  [2117] Choosing a railway station fairly in PHP - (2009-04-04)
  [2103] Ask the Tutor - Open Source forum - (2009-03-25)
  [1904] Ruby, Perl, Linux, MySQL - some training notes - (2008-11-23)
  [1902] sstrwxrwxrwx - Unix and Linux file permissions - (2008-11-23)
  [1773] The Longest Possible Day - (2008-08-26)
  [1650] Looking for files with certain characteristics (Linux / Unix) - (2008-05-22)
  [1619] User and Group settings for Apache httpd web server - (2008-04-22)
  [1592] Setting up a new user - Linux or Unix - (2008-03-26)
  [683] Supporting users on Linux and Unix - (2006-04-13)
  [431] File permissions of Linux and Unix systems - (2005-08-31)
  [409] Functions and commands with dangerous names - (2005-08-11)

Tcl/Tk - What is Expect? Why use it?
  [4678] Expect with Ruby - a training example to get you started - (2016-05-18)
  [4405] Backup procedures - via backup server - (2015-01-24)
  [3572] Adding Expect on top of Tcl - what is it and where can I get a training course to learn about it? - (2012-01-08)
  [3286] Should we cover expect and/or Tk on our public Tcl courses? - (2011-05-11)
  [3009] Expect in Perl - a short explanation and a practical example - (2010-10-22)
  [2489] Parallel Pinging, using Python Threads or Expect spawn lists - (2009-11-02)
  [2474] Using Tcl and Expect to automate repetitive jobs - (2009-10-24)
  [1602] Automating processes through Expect - (2008-04-05)
  [1531] Expecting a item from a list of possibles - (2008-02-04)
  [1469] Curley brackets v double quotes - Tcl, Tk, Expect - (2007-12-12)
  [1411] Buffering of inputs to expect, and match order - (2007-10-27)
  [1409] What is Expect? - (2007-10-26)
  [1174] Installing Tcl and Expect on Solaris 10 - a checklist - (2007-05-02)
  [1173] Cheat Sheet / Check list for Expect maintainers - (2007-05-02)
  [435] Expect for Windows - (2005-09-04)
  [286] Automating regular manual procedures - (2005-04-21)

resource index - PHP
Solutions centre home page

You'll find shorter technical items at The Horse's Mouth and delegate's questions answered at the Opentalk forum.

At Well House Consultants, we provide training courses on subjects such as Ruby, Lua, Perl, Python, Linux, C, C++, Tcl/Tk, Tomcat, PHP and MySQL. We're asked (and answer) many questions, and answers to those which are of general interest are published in this area of our site.

You can Add a comment or ranking to this page

© WELL HOUSE CONSULTANTS LTD., 2019: Well House Manor • 48 Spa Road • Melksham, Wiltshire • United Kingdom • SN12 7NY
PH: 01225 708225 • FAX: 01225 793803 • EMAIL: info@wellho.net • WEB: http://www.wellho.net • SKYPE: wellho

PAGE: http://www.wellho.net/solutions/php-a-we ... tasks.html • PAGE BUILT: Wed Mar 28 07:47:11 2012 • BUILD SYSTEM: wizard