Saturday, October 20, 2007

Python Scripting Tutorial, Part two

Here is my second part of the hands on tutorial on basic python script. It works in an interactive mode just like adduser on a linux system, only
it sets a very strong random password (using a little utility called pwgen - you can install it from /usr/ports/sysutils/pwgen2) for the user, gives you
the ability of making a system user, a ftp user or both. My pure-ftpd is based on MySQL table auth. It also makes a public_html for the user and
build a virtual host for the user. Check the script out because I think it is pretty straightforward. Tweak it a bit so you can use it as your own.
On the next tutorial we'll the users a mail with the password and also add them to an LDAP directory.
PS: I'm aware that some things could be done more easily by using hefty tricks, but hey, I aimed for easy understanding.


import os
import getopt
import sys
import MySQLdb

# Where should i write the vhost details?
VHOSTS_CONFIG = "/usr/local/etc/apache22/extra/httpd-vhosts.conf"

# Init the variables
user_flag = -1
ftp_flag = -1

# MySQL authentification variables
mysql_user = "user"
mysql_pass = "password"
mysql_host = "localhost"
mysql_database = "pureftpd"

# The usage() function that gets used when we call the script with the -h option
def usage():
print """
Usage: sudo python : create a user in the system.
You can create a ftp user only, a system user or both.
It also adds the corresponding vhost to the configuration and builds the
home directory. If run with no arguments it will go into interactive mode. [-h]

-h print this help

# Parse the command line arguments
# Basicly this looks for the -h argument only but could be
# easily extended to something else

o, a = getopt.getopt(sys.argv[1:], 'h')
opts = {}
for k,v in o:
opts[k] = v
if opts.has_key('-h'):

# Check to see if we're running as superuser
uid = `os.getuid()`
if uid != "0":
print "You must be superuser in order to run this program"

# Make a system user?
user_input = raw_input("Do you want to add a system user [n/Y]: ")
if user_input.lower() == "y":
user_flag = 1
if user_input.lower() == "n":
user_flag = 0
user_flag = 1

# Make a ftp user?
ftp_input = raw_input("Do you want to add a ftp user [n/Y]: ")
if ftp_input.lower() == "y":
ftp_flag = 1
if ftp_input.lower() == "n":
ftp_flag = 0
ftp_flag = 1

# If you do not want a system user or a ftp user then ... you don't want anything
if ftp_flag == 0 and user_flag == 0:
print "Come back when you know what you want"

# How do you want to name your user?
user_name = raw_input("Username: ")

# Try to figure out the shell or input another shell
# something like /usr/local/bin/rssh
if user_flag == 1:
user_shell = raw_input("Shell [/usr/local/bin/bash]: ")
# Make /usr/local/bin/bash the default shell if the user presses enter
if user_shell == "":
user_shell = "/usr/local/bin/bash"

# Basicly we have to types of accounts
# Those that are the system users with ssh account and those with only ftp access
# System users have the /home/user directory
# whilst the ftp users have /home/ftpusers/user

if user_flag == 1:
home = "/home/" + user_name
home = "/home/ftpusers/" + user_name

# But if you want you can input another directory as the home directory
# We are making this script a little more interactive
home_dir = raw_input("Home directory [" + home + "]: ")
if home_dir == "":
home_dir = home

# We generate a new random password. This is based on the pwgen port
# Please install it before if you don't have it:
# cd /usr/ports/sysutils/pwgen2 && sudo make search install
newpassword = os.popen("pwgen -s -n -B -c 12 1").readline().split()[-1]
if user_flag == 1:
# Add the new user using the randomly generated password earlier
# This command enters:
# echo pass | pw user add -d /home/user -m -s /usr/local/bin/bash -n user -g users -h 0
# -d - home directory
# -m - builds the home directory if it doesn't exist
# -s - the shell to user
# -n - the name of the user
# -g - the original group for the user
# -h 0 - get the password from stdin
cmd = "echo " + newpassword + " | pw user add -d " + home_dir + " -m -s " + user_shell + " -n " + user_name + " -g users -h 0"
# Save the new password somewhere as you don't want an inactive account or manually input another pasword
f = open("/root/accounts", "a+")
line = user_name + " " + newpassword + " " + `user_flag` + " " + `ftp_flag` + "\n"
print "Details have been saved to /root/accounts. Please mail the information to the user and then delete the file"
# Make the /home/user/public_html directory so the user can have his own web server
# at the http://host/~user address
os.mkdir(home_dir + "/public_html")
# Change the vhost configuration to a new entry so
# http://host/~user is mapped as
# This is much more professional in my opinion
f = open(VHOSTS_CONFIG, "a")
vhost = """<VirtualHost *:80>
DocumentRoot """ + home_dir + """/public_html
ServerName """ + user_name + """.host
ErrorLog /var/log/httpd/""" + user_name + """-error_log
CustomLog /var/log/httpd/""" + user_name + """-access_log combined
# Restart the Apache Webserver
os.system("apachectl graceful")
# For the ftp users only you should manage their accounts using the system account ftpusers
if user_flag == 0 and ftp_flag == 1:
group = "ftpusers"
uid = "ftpusers"
uid = user_name
group = "users"
# Add the ftp user to the existing MySQL table (I do MySQL auth to my ftp server)
# with the same use
so if you give ftp access to a system user he can login with
# the same password
You should only give a user access to the system with no ftp
# access if you want him to make transactions
only with ssh (through scp)
if ftp_flag == 1:
# Open the MySQL database
db = MySQLdb.connect(mysql_host,mysql_user,mysql_pass,mysql_database)
# Make a cursor (a pointer to that database)
cursor = db.cursor()
# Execute an insert query
cursor.execute("INSERT INTO `pureftpd`.`users` (`User`, `Password`, `Uid`, `Gid`, `Dir`, `QuotaSize`) VALUES (\'%s', MD5(\'%s\'), \'%s\', \'%s\', \'%s\', \'%s\');" % (user_name,newpassword,uid,group,home_dir,100))
if ftp_flag == 1 and user_flag == 0:

Powered by ScribeFire.

1 comment:

Anonymous said...

Looking forward to the seeing how to interact with LDAP.