- complete addpopuser
git-svn-id: file:///home/www/usr01/svn/gnuviechadmin/gnuviech.info/gnuviechadmin/trunk@122 a67ec6bc-e5d5-0310-a910-815c51eb3124
This commit is contained in:
parent
13b09a8844
commit
8a0c22bdae
3 changed files with 116 additions and 21 deletions
|
@ -33,9 +33,9 @@ if __name__ == "__main__":
|
|||
sys.exit(1)
|
||||
|
||||
# specify the domain
|
||||
domain = dict(options[0])['--domain']
|
||||
domain = None
|
||||
try:
|
||||
DomainTools.validate_domain(domain)
|
||||
domain = DomainTools.Domain(dict(options[0])['--domain'])
|
||||
except DomainTools.InvalidDomain, iv:
|
||||
print iv
|
||||
sys.exit(1)
|
||||
|
@ -48,7 +48,4 @@ if __name__ == "__main__":
|
|||
if (password == None):
|
||||
password = PasswordTools.generate_password()
|
||||
|
||||
print domain
|
||||
print password
|
||||
|
||||
print PasswordTools.md5_crypt_password(password)
|
||||
domain.makePopUser(password)
|
||||
|
|
|
@ -1,30 +1,122 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import psycopg
|
||||
import Settings
|
||||
import psycopg, pwd, grp, smtplib, os
|
||||
from email.MIMEText import MIMEText
|
||||
import Settings, PasswordTools
|
||||
|
||||
class InvalidDomain(Exception):
|
||||
"""This Exception is thrown if an invalid domain is used."""
|
||||
"""This exception is raised if an invalid domain is used."""
|
||||
def __init__(self, domain):
|
||||
self.domain = domain
|
||||
|
||||
def __str__(self):
|
||||
return repr("Invalid domain %s" % (self.domain))
|
||||
|
||||
def validate_domain(domain):
|
||||
class NoSysuserForDomain(Exception):
|
||||
"""This exception is raised if no system user is associated with a domain."""
|
||||
def __init__(self, domain):
|
||||
self.domain = domain
|
||||
|
||||
def __str__(self):
|
||||
return repr("No system user for domain %s" % (self.domain))
|
||||
|
||||
class Domain:
|
||||
"""A Domain representation object with service methods."""
|
||||
def __init__(self, domain):
|
||||
self.cnx = psycopg.connect("user=%(dbuser)s password=%(dbpassword)s dbname=%(dbname)s" % Settings.dbsettings)
|
||||
self.domain = domain
|
||||
self.validate_domain()
|
||||
|
||||
def validate_domain(self):
|
||||
"""This function validates whether the given domain is allowed.
|
||||
That means that the domain needs to be registered in the database.
|
||||
|
||||
If the domain is invalid InvalidDomain is raised."""
|
||||
cnx = psycopg.connect("user=%(dbuser)s password=%(dbpassword)s dbname=%(dbname)s" % Settings.dbsettings)
|
||||
cr = cnx.cursor()
|
||||
cr = self.cnx.cursor()
|
||||
|
||||
cr.execute("SELECT * FROM domain WHERE domainname=%(name)s" %
|
||||
{'name': psycopg.QuotedString(domain)})
|
||||
cnx.commit()
|
||||
{'name': psycopg.QuotedString(self.domain)})
|
||||
self.cnx.commit()
|
||||
|
||||
result = cr.fetchall()
|
||||
if (not result):
|
||||
raise InvalidDomain(domain)
|
||||
raise InvalidDomain(self)
|
||||
|
||||
def __str__(self):
|
||||
return repr(self.domain)
|
||||
|
||||
def getSysuser(self):
|
||||
"""Gets the system user id of the domain."""
|
||||
cr = self.cnx.cursor()
|
||||
|
||||
cr.execute("""SELECT sysuser.name FROM domain, sysuser
|
||||
WHERE domain.domainname=%(name)s
|
||||
AND domain.sysuserid=sysuser.sysuserid""" %
|
||||
{'name': psycopg.QuotedString(self.domain)})
|
||||
self.cnx.commit()
|
||||
|
||||
result = cr.fetchall()
|
||||
if (not result):
|
||||
raise NoSysuserForDomain(self)
|
||||
# return row 0, field 0
|
||||
return result[0][0]
|
||||
|
||||
def getNextPopUser(self):
|
||||
"""Gets the user id of the next available POP3/IMAP-user for the domain."""
|
||||
cr = self.cnx.cursor()
|
||||
|
||||
sysuser = self.getSysuser()
|
||||
|
||||
cr.execute("""SELECT max(id) FROM mailpasswd WHERE
|
||||
id LIKE %(username)s""" %
|
||||
{'username': psycopg.QuotedString(sysuser+'%')})
|
||||
self.cnx.commit()
|
||||
|
||||
result = cr.fetchall()
|
||||
if (not result):
|
||||
return sysuser + "p01"
|
||||
|
||||
maxpopuser = result[0][0]
|
||||
num = int(maxpopuser[len(sysuser)+1:])+1
|
||||
return "%sp%d" % (sysuser, num)
|
||||
|
||||
def makePopUser(self, password):
|
||||
"""Creates a new POP3/IMAP-user for the domain using the given password."""
|
||||
cr = self.cnx.cursor()
|
||||
|
||||
sysuser = self.getSysuser()
|
||||
popaccount = self.getNextPopUser()
|
||||
crypted = PasswordTools.md5_crypt_password(password)
|
||||
uid = pwd.getpwnam(sysuser)[2]
|
||||
gid = grp.getgrnam(Settings.popgroup)[2]
|
||||
homedir = Settings.pophome + popaccount
|
||||
|
||||
os.mkdir(homedir, 0660)
|
||||
os.system("maildirmake \"%s/Maildir\"" % (homedir))
|
||||
os.system("chown %s.%s %s" % ( sysuser, Settings.popgroup, homedir ))
|
||||
|
||||
cr = self.cnx.cursor()
|
||||
cr.execute("""INSERT INTO mailpasswd (id, crypt, clear, uid, gid, home)
|
||||
VALUES (%(id)s, %(crypt)s, %(clear)s, %(uid)d, %(gid)d, %(home)s)""" % {
|
||||
'id': psycopg.QuotedString(popaccount),
|
||||
'crypt': psycopg.QuotedString(crypted),
|
||||
'clear': psycopg.QuotedString(password),
|
||||
'uid': uid, 'gid': gid,
|
||||
'home': psycopg.QuotedString(homedir)})
|
||||
self.cnx.commit()
|
||||
|
||||
text = """A new POP3/IMAP account has been created
|
||||
Domain: %(domain)s
|
||||
User: %(user)s
|
||||
Password: %(password)s""" % {'domain': self.domain,
|
||||
'user': popaccount,
|
||||
'password': password}
|
||||
themail = MIMEText(text)
|
||||
themail['Subject'] = "A new POP3/IMAP account has been created"
|
||||
themail['From'] = Settings.mailsender
|
||||
themail['To'] = Settings.mailreceiver
|
||||
|
||||
s = smtplib.SMTP()
|
||||
s.connect()
|
||||
s.sendmail(Settings.mailsender, [Settings.mailreceiver], themail.as_string())
|
||||
s.close()
|
||||
|
|
|
@ -3,3 +3,9 @@
|
|||
dbsettings = { 'dbuser': 'exim4',
|
||||
'dbpassword' : 'CotOgigmeIk5',
|
||||
'dbname' : 'gnuviechadmin' }
|
||||
|
||||
mailsender = 'root@gnuviech.info'
|
||||
mailreceiver = 'root@gnuviech.info'
|
||||
popgroup = 'poponly'
|
||||
popgroup = 'poponly'
|
||||
pophome = '/home/mail/'
|
||||
|
|
Loading…
Reference in a new issue