How to automate FTP user creation with Pure-FTPd on Mac OS X?
December 8, 2008 7:10 AM   Subscribe

How to automate FTP user creation with Pure-FTPd on Mac OS X (running Apache) retrieving usernames and passwords from another http (linux) server?

I have made for a client a website with user registration feature, hosted on a shared linux hosting.

The client of the website has an internal always turned-on Mac with XAMPP and Pure-FTPd running on OS X, connected to Internet with a static IP.

In the website, I can create a button/link which connects with phpWebFTP (a nice web FTP client) installed in htdocs on the Mac server, which connects to the FTP server (pure-FTPd) on the same machine (localhost, i.e. the Mac server); the link/button can send the username, and phpWebFTP will ask for the password. No problem on this side.

Said that, I need this: when a user registers on the website (maybe not in the very same moment, even at regular intervals is good enough), an FTP account should be created on the Mac server, with same username/password used for registration.
So I need some sort of chron job, script, reading a file from the linux server, etc... well, I don't know!

I have found the following useful page on Pure-FTPd documentation:


Unfortunately, I need pretty detailed and straightforward instructions on what to do on the Mac side, because:

- I am not a Mac user (but I am comfortable with terminal, command-line utils and this sort of things)

- the internal Mac server is located in a pretty distant place from me

- I have a limited amount of time to put my hands on the server, after which I have to schedule a new trip

So, for the linux shared hosting php part no details needed; for the Mac server part, something like a tutorial would be very appreciated.
Thanks, sincerely
posted by lion to Computers & Internet (8 answers total) 1 user marked this as a favorite
Synchronizing the accounts will be hard.

Where is the auth information stored? Can you share an authentication database, instead? LDAP, or RADIUS, or NIS, perhaps?

If the web server saves its auth information in a flat file, can the FTP server read from the same file?
posted by cmiller at 7:31 AM on December 8, 2008

I would compile PureFTPd with MySQL support and use that to bridge your apps together, assuming you can access your mysql server from your mac?

See: pureftpd docs
posted by mebibyte at 9:19 AM on December 8, 2008

In terms of things you could look into, I'd suggest looking at SSH using public/private keys. This works well for automated scripts. (Google "ssh without passwords" for a variety of howtos.) Once you get SSH access to the mac you can start playing around with scripts.

With SSH you can run commands via SSH non-interactively. For example, you could do "ssh ls -l" to get a listing of adminuser's home directory. When the keys are setup this should just exectute like it's on a local machine, not asking for a password at all.

Now, for setting this up to add accounts, I'd take a look at "useradd" - or the variation under Darwin. I see mentions of ports of it. There seems to be many different ways, all depending on things installed or versions of Darwin/OSX in use. I looked at many things when I Googled "add user from mac command line" that may be of help.

Under Linux, the "useradd" command to add a user quickly would be:

useradd -c 'Test User' -d '/var/www' -N -s '/bin/bash' -p '$1$yy7i7KfQ$DXkFMmROZC5u1EH60/jL1.' testuser

That would setup a new account called "testuser" with the name "Test User", with a home directory of "/var/www" and a password of "password". The "-N" means to not setup a new group for this user. You can also specify a group or groups, just check the man page.

The "$1$yy7i7KfQ$DXkFMmROZC5u1EH60/jL1." is the output of "echo crypt('password');" in PHP, as an example.

Running it multiple times doesn't have any effect if the user already exists, it just displays a message and exits.

Once you're up and running, with SSH working with keys, and with an admin user on the Mac, and you've figured out the right command line to use to make an account, then you'd be looking at running something like this:

ssh useradd -c 'Test User' -d '/var/www' -N -s '/bin/bash' -p '$1$yy7i7KfQ$DXkFMmROZC5u1EH60/jL1.' testuser

Of course, the opposite could work as well, to delete a user:

ssh userdel testuser

There's a variety of commands in PHP for running system commands - exec() and passthru() might be of interest.

Now, this says nothing about security, so I'm inserting the standard disclaimer about this being potentially unsafe, especially considering you'll be running an admin/root level account remotely and in an automated fashion.
posted by Fat Elvis at 1:00 PM on December 8, 2008

FTP virtual users are definitely the way to go here, especially since it sounds like you're not creating system-level accounts on the shared linux host.

The virtual-users file you linked in your question seems pretty straightforward.
Presumably you have access to all the user information for these newly-created accounts.

You'd want to write a script that runs 'pure-pw useradd' with the the correct arguments regarding where your passwd file and whatnot is on the Mac (locations, home directory structue, etc. that you would have chosen). From there, I can think of several triggers. You could periodically compare users on the linux host to those on the mac and create any missing, or you could add a hook into the linux user creation process that spawns something like "ssh mac pw-add-script username" (assuming I wasn't allowed to re-architect this, that's how I'd do it)

Otherwise, yes, you're looking at implementing a shared authentication scheme of some kind - LDAP, NIS, Kerberos, etc...all of which are drastically overkill for this scenario.
posted by namewithoutwords at 4:40 PM on December 8, 2008

Response by poster: @Fat Elvis: I prefer to avoid any ssh approach, for security reasons (I don't want hackers ssh'ing into the internal server).

@mebibyte: I prefer to avoid going into pure-ftpd compile troubles.

@cmiller: the auth info is stored on the web linux server, in a MySQL database. But I can easily write that also in a flat file, whenever a user registers, even in some encrypted form (php work). There's no problem for the mac server to read the file, I can also protect it in some way and let the php script on the mac server ovverride the protection, and decrypt the username/password pairs. This was already what I wanted to do.
My question, specifically, was (I will reformulate if it was not clear):

1) imagine the internal mac server can read every username/password reading a file on the web server;

2) imagine I can do whatever I want on the internal mac server; I already have XAMPP and Pure-FTPd running. Example: I can modify php.ini or whatever file, I can install stuff, etc. It's not a shared host, it's an always turned on mac connected to Internet with a static ip.

With 1) and 2), I would like the internal mac server to - example - scan the username/password file every hour, and create virtual ftp users accordingly (a command for virtual ftp users creation is written in the already linked README.Virtual-Users, and it's something like:

pure-pw useradd [-f ] -u [-g ]

I know this way I (i.e. phpWebFTP) will have to ask logged in users to type password for access to the ftp reserved folder (even if they are already logged in), but no problem.

But, I don't know how to do those things, especially on a mac.

Thanks to cmiller, mebibyte, Fat Elvis for your kind replies; looking forward for some other help towards cmiller's one, i.e. using a flat file accessible form the internal mac server, containing registered users' auth data.

The problem here is how to tell the mac something like: every hour, create this ftp user with this password (same username/password pair as in the web registration).


posted by lion at 5:01 PM on December 8, 2008

Response by poster: @namewithoutwords: I was writing my reply so I've read your submission after posting. Yes, you can see in my reply the direction I would prefer following, which is what you wrote in the first part. The problem here is I don't know how to write that script, where to place it on the mac, and how to tell the mac "please do it at specified time intervals..."

Thanks go to you too.

I'll read eventual other replies tomorrow.
posted by lion at 5:10 PM on December 8, 2008

Best answer: aha. Ok, so...

You'll need to add one "real" account on OSX for all your virtual users to share.

Create a flat file (via PHP, in your case) on the Linux server, in this format:

account:password:uid:gid:gecos:home directory:upload
bandwidth:download bandwidth:upload ratio:download ratio:max number
of connections:files quota:size quota:authorized local IPs:refused
local IPs:authorized client IPs:refused client IPs:time

All you need to worry about is account, password, uid, gid, and home directory - so this would be appropriate:


(Where 9999:8888 is your "real" user:group ids. Where the password field is the output of PHP's crypt($password);. I'm not sure if you need all those ":" for the empty fields, or if that's exactly the right number of them if you do.)

Then you'll need to get that file to the mac box. There's any number of ways of doing it, but I'd suggest perhaps putting it in a password protected folder in your web root, and accessing it via HTTPS:


Now you'll need to turn that myaccounts.txt file into a FTP accounts on the mac server:

pure-pw mkdb /etc/pureftpd.pdb -f /path/to/myaccounts.txt

The cool thing about this is that it'll add new users, delete old users, change passwords - in short, that file becomes the current password file for Pure FTPd. You'll need to find out if /etc/pureftpd.pdb is the right location or not for OSX. It may be elsewhere.

Lastly, you'll need a script with all these commands and a cron job to run it. The script could look like this:


if wget -q; then
    pure-pw mkdb /etc/pureftpd.pdb -f /path/to/myaccounts.txt
    echo `date` update sucessful.
    echo `date` update failed.

Save that as (on the mac) and run "chmod +x" to make it executable. (You could also make that pure-pw command into its own "if" block to test if it exits without error.)

Finally, you'll need to run "" as a cron job. It would appear that root's crontab is /private/etc/crontab - so you'll need to edit that file.

A line like this will enable the cron to run every hour at 15 minutes past the hour as roon, saving all the output of the command to a log file:

15 * * * * root /path/to/ &> /path/to/a/logfile.log

Save that crontab and watch the log.

I can't guarentee this will work out of the box, but it should get you going in the right direction.

References used:

posted by Fat Elvis at 7:38 AM on December 9, 2008

Response by poster: Great Fat Elvis, this is the type of thing I was asking for!
I'll look carefully to everything you've written, btw I've already read it all and it has already filled a lot of missing/blurred points in my knowledge.
This is definetely the right direction, sure it will be a little tricky to accomplish but I feel I can do that.

Other details/corrections/etc. to make my work as smooth as possible are of course welcome (remember that I have a limited amount of time to put my hands on the server, then I have to schedule a new trip :(

If I succeed I'll post here the complete "tutorial" answering my question (which essentially will be an updated version of Fat Elvis' one).

Thanks very much
posted by lion at 9:04 AM on December 9, 2008

« Older What's your idea of a romantic holidy in Europe?   |   Karaoke-like software that will show chords and... Newer »
This thread is closed to new comments.