1
0
Fork 0

- 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:
Jan Dittberner 2005-09-28 22:02:42 +00:00
parent 13b09a8844
commit 8a0c22bdae
3 changed files with 116 additions and 21 deletions

View file

@ -33,9 +33,9 @@ if __name__ == "__main__":
sys.exit(1) sys.exit(1)
# specify the domain # specify the domain
domain = dict(options[0])['--domain'] domain = None
try: try:
DomainTools.validate_domain(domain) domain = DomainTools.Domain(dict(options[0])['--domain'])
except DomainTools.InvalidDomain, iv: except DomainTools.InvalidDomain, iv:
print iv print iv
sys.exit(1) sys.exit(1)
@ -48,7 +48,4 @@ if __name__ == "__main__":
if (password == None): if (password == None):
password = PasswordTools.generate_password() password = PasswordTools.generate_password()
print domain domain.makePopUser(password)
print password
print PasswordTools.md5_crypt_password(password)

View file

@ -1,30 +1,122 @@
#!/usr/bin/env python #!/usr/bin/env python
import psycopg import psycopg, pwd, grp, smtplib, os
import Settings from email.MIMEText import MIMEText
import Settings, PasswordTools
class InvalidDomain(Exception): 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): def __init__(self, domain):
self.domain = domain self.domain = domain
def __str__(self): def __str__(self):
return repr("Invalid domain %s" % (self.domain)) return repr("Invalid domain %s" % (self.domain))
def validate_domain(domain): class NoSysuserForDomain(Exception):
"""This function validates whether the given domain is allowed. """This exception is raised if no system user is associated with a domain."""
That means that the domain needs to be registered in the database. 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.""" If the domain is invalid InvalidDomain is raised."""
cnx = psycopg.connect("user=%(dbuser)s password=%(dbpassword)s dbname=%(dbname)s" % Settings.dbsettings) cr = self.cnx.cursor()
cr = cnx.cursor()
cr.execute("SELECT * FROM domain WHERE domainname=%(name)s" % cr.execute("SELECT * FROM domain WHERE domainname=%(name)s" %
{'name': psycopg.QuotedString(domain)}) {'name': psycopg.QuotedString(self.domain)})
cnx.commit() self.cnx.commit()
result = cr.fetchall() result = cr.fetchall()
if (not result): 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()

View file

@ -3,3 +3,9 @@
dbsettings = { 'dbuser': 'exim4', dbsettings = { 'dbuser': 'exim4',
'dbpassword' : 'CotOgigmeIk5', 'dbpassword' : 'CotOgigmeIk5',
'dbname' : 'gnuviechadmin' } 'dbname' : 'gnuviechadmin' }
mailsender = 'root@gnuviech.info'
mailreceiver = 'root@gnuviech.info'
popgroup = 'poponly'
popgroup = 'poponly'
pophome = '/home/mail/'