1
|
#!/usr/bin/env python
|
2
|
# -*- coding: utf-8 -*-
|
3
|
# A not still so simple script to add contacts on an LDAP server
|
4
|
#
|
5
|
# Copyright (C) 2009 Simone Piccardi
|
6
|
#
|
7
|
# This program is free software; you can redistribute it and/or modify
|
8
|
# it under the terms of the GNU General Public License as published by
|
9
|
# the Free Software Foundation; either version 2 of the License, or (at
|
10
|
# your option) any later version.
|
11
|
#
|
12
|
# This program is distributed in the hope that it will be useful, but
|
13
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
# General Public License for more details.
|
16
|
#
|
17
|
# You should have received a copy of the GNU General Public License
|
18
|
# along with this program; if not, write to the Free Software
|
19
|
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
20
|
#
|
21
|
|
22
|
import csv
|
23
|
import getopt
|
24
|
import sys
|
25
|
import re
|
26
|
import time
|
27
|
import random, string
|
28
|
from datetime import datetime
|
29
|
from crypt import crypt
|
30
|
try:
|
31
|
import MySQLdb
|
32
|
except ImportError ,e:
|
33
|
print 'Cannot import the needed MySQLdb module, you must install it'
|
34
|
print 'on Debian systems just use the command'
|
35
|
print ' apt-get install python-mysqldb'
|
36
|
|
37
|
def usage():
|
38
|
print "Usage: inspostadmusers.py [options] users.csv"
|
39
|
print " -h print this help"
|
40
|
print " -t test run, do not insert, just print"
|
41
|
print " -u DB user"
|
42
|
print " -p DB password"
|
43
|
print " -D DB name"
|
44
|
print " -H DB host"
|
45
|
print " -q Quota in Mb (0 => no limit)"
|
46
|
print " -n char in seed"
|
47
|
print " -d debug info on"
|
48
|
print " -A create default alias for each domain"
|
49
|
print
|
50
|
print "the users.csv file must contains the user list with a line"
|
51
|
print "for each user, first line should be a title line with at least"
|
52
|
print "the following column names: "
|
53
|
print " * user - user part of the email (like user in user@domain.com)"
|
54
|
print " * password - cleartext password"
|
55
|
print " * domain - domain name (like 'domain.com')"
|
56
|
print " * name - full user name ('Name Surname')"
|
57
|
print
|
58
|
print "the 'name' column is optional, other columns will be ignored"
|
59
|
|
60
|
|
61
|
# option parsing
|
62
|
try:
|
63
|
opts, args = getopt.getopt(sys.argv[1:], 'u:p:d:D:H:htdA')
|
64
|
optval={}
|
65
|
for opt, val in opts:
|
66
|
if opt == "-h":
|
67
|
usage()
|
68
|
sys.exit(0)
|
69
|
else:
|
70
|
optval[opt]=val
|
71
|
except getopt.GetoptError:
|
72
|
usage()
|
73
|
sys.exit(2)
|
74
|
|
75
|
#
|
76
|
# Setup DB connection
|
77
|
#
|
78
|
MYSQLDB="postfixadmin"
|
79
|
MYSQLUSER="postfixadmin"
|
80
|
MYSQLPASSWORD=""
|
81
|
MYSQLHOST="localhost"
|
82
|
|
83
|
# settings by command line options
|
84
|
if optval.has_key('-u'):
|
85
|
MYSQLUSER = optval['-u']
|
86
|
if optval.has_key('-p'):
|
87
|
MYSQLPASSWORD = optval['-p']
|
88
|
if optval.has_key('-D'):
|
89
|
MYSQLDB = optval['-D']
|
90
|
if optval.has_key('-H'):
|
91
|
MYSQLHOST = optval['-H']
|
92
|
|
93
|
if optval.has_key('-q'):
|
94
|
quota = optval['-q']
|
95
|
else:
|
96
|
quota = 0
|
97
|
|
98
|
if optval.has_key('-n'):
|
99
|
seed_len = optval['-n']
|
100
|
else:
|
101
|
seed_len = 8
|
102
|
|
103
|
# check arguments, only the user list file must be present
|
104
|
if len(args) !=1:
|
105
|
print 'Need just one argument'
|
106
|
usage()
|
107
|
sys.exit(1)
|
108
|
|
109
|
# MySQL connection (skipped in test run)
|
110
|
if optval.has_key('-t'):
|
111
|
print "Test Run"
|
112
|
else:
|
113
|
try:
|
114
|
connection = MySQLdb.connect(host=MYSQLHOST, user=MYSQLUSER,
|
115
|
db=MYSQLDB, passwd=MYSQLPASSWORD)
|
116
|
except MySQLdb.MySQLError, e:
|
117
|
print "Database connection error"
|
118
|
print e
|
119
|
sys.exit(1)
|
120
|
|
121
|
cursor = connection.cursor()
|
122
|
|
123
|
#
|
124
|
# Main body
|
125
|
#
|
126
|
NOW = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
127
|
|
128
|
# read and convert CSV data
|
129
|
lista = csv.DictReader(open(args[0]))
|
130
|
|
131
|
def gen_seed(seed_len, chars):
|
132
|
return '$1$'+''.join([random.choice(chars) for _ in xrange(seed_len)])+'$'
|
133
|
|
134
|
def insert_record(cursor,table,record):
|
135
|
columns = record.keys()
|
136
|
query = "INSERT INTO " + table + "(" + ','.join(columns) + ") VALUES (" + ','.join(len(columns)*['%s']) + ")"
|
137
|
try:
|
138
|
cursor.execute(query, record.values())
|
139
|
return 0
|
140
|
except MySQLdb.MySQLError, e:
|
141
|
print "Database insertion error"
|
142
|
print e
|
143
|
print "Record was:"
|
144
|
print record.values()
|
145
|
print "Query was:"
|
146
|
print query
|
147
|
|
148
|
# defining default values for tables (mailbox, alias and domain)
|
149
|
mailbox = {
|
150
|
'created': NOW,
|
151
|
'modified': NOW,
|
152
|
'active': 1,
|
153
|
'quota': quota
|
154
|
}
|
155
|
aliases = {
|
156
|
'created': NOW,
|
157
|
'modified': NOW,
|
158
|
'active': 1
|
159
|
}
|
160
|
domain = {
|
161
|
'description': "",
|
162
|
'aliases': 0,
|
163
|
'mailboxes': 0,
|
164
|
'quota': 0,
|
165
|
'transport': 'virtual',
|
166
|
'backupmx': 0,
|
167
|
'created': NOW,
|
168
|
'modified': NOW,
|
169
|
'active': 1
|
170
|
}
|
171
|
|
172
|
# list of default alias
|
173
|
def_alias = ['abuse','hostmaster','postmaster','webmaster']
|
174
|
|
175
|
domain_list = {}
|
176
|
chars = string.letters + string.digits
|
177
|
|
178
|
# loop over the CSV
|
179
|
for row in lista:
|
180
|
# create domain if it does not exists
|
181
|
if domain_list.has_key(row["domain"]):
|
182
|
if optval.has_key('-d'):
|
183
|
print "Domain " + row["domain"] + "already exixts"
|
184
|
else:
|
185
|
domain_list[row["domain"]] = 1
|
186
|
domain['domain'] = row["domain"]
|
187
|
if optval.has_key('-t'):
|
188
|
print "Inserting domain"
|
189
|
print domain
|
190
|
else:
|
191
|
insert_record(cursor,'domain',domain)
|
192
|
if optval.has_key('-A'):
|
193
|
for i in def_alias:
|
194
|
aliases['address']= i+'@'+row["domain"]
|
195
|
aliases['goto']= aliases['address']
|
196
|
aliases['domain'] = row["domain"]
|
197
|
if optval.has_key('-t'):
|
198
|
print "Inserting alias"
|
199
|
print aliases
|
200
|
else:
|
201
|
insert_record(cursor,'alias',aliases)
|
202
|
|
203
|
# build query data for mailbox table
|
204
|
mailbox['username']=row["user"]+'@'+row["domain"]
|
205
|
encpass=crypt(row["password"], gen_seed(seed_len,chars))
|
206
|
mailbox['password'] = encpass
|
207
|
mailbox['name'] = row["name"]
|
208
|
mailbox['maildir'] = row["domain"]+'/'+row["user"]+'/'
|
209
|
mailbox['local_part'] =row["user"]
|
210
|
mailbox['domain'] = row["domain"]
|
211
|
|
212
|
# build query data for alias table
|
213
|
aliases['address']= mailbox['username']
|
214
|
aliases['goto']= mailbox['username']
|
215
|
aliases['domain'] = row["domain"]
|
216
|
|
217
|
# inserting data for mailbox (and relate alias)
|
218
|
if optval.has_key('-t'):
|
219
|
print "Inserting mailbox"
|
220
|
print mailbox
|
221
|
print aliases
|
222
|
else:
|
223
|
insert_record(cursor,'mailbox',mailbox)
|
224
|
insert_record(cursor,'alias',aliases)
|
225
|
|
226
|
|
227
|
sys.exit(0)
|