smailr 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/smailr ADDED
@@ -0,0 +1,165 @@
1
+ #!/usr/bin/env ruby
2
+ $: << File.expand_path('../../lib', __FILE__)
3
+
4
+ require 'smailr'
5
+
6
+ DB = Sequel.connect("sqlite:///etc/exim4/smailr.sqlite")
7
+
8
+ #
9
+ # CLI Helpers
10
+ #
11
+ def determine_object(string)
12
+ return :domain if string =~ /^[^@][A-Z0-9.-]+\.[A-Z]{2,6}$/i
13
+ return :address if string =~ /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6}$/i
14
+ end
15
+
16
+ def ask_password
17
+ min_password_length = 5
18
+ password = ask("Password: ") { |q| q.echo = "*" }
19
+ confirm = ask("Confirm: ") { |q| q.echo = "*" }
20
+
21
+ if password != confirm
22
+ say("Mismatch; try again.")
23
+ ask_password
24
+ end
25
+
26
+ if password.length < min_password_length
27
+ say("Too short; try again.")
28
+ ask_password
29
+ end
30
+
31
+ return password
32
+ end
33
+
34
+ program :version, Smailr::VERSION
35
+ program :description, 'Simple MAIL mangaR - Virtual mail hosting management from the CLI'
36
+
37
+ #
38
+ # Commands
39
+ #
40
+ command :add do |c|
41
+ c.syntax = 'smailr add domain | mailbox | alias [options]'
42
+ c.summary = 'Add a new domain, mailbox or alias to the mail system.'
43
+ c.example 'Add a domain', 'smailr add example.com'
44
+ c.example 'Add a mailbox', 'smailr add user@example.com'
45
+ c.example 'Add an alias', 'smailr add alias@localdom.com --alias user@example.com,user1@example.com'
46
+ c.example 'Setup DKIM for a domain', 'smailr add ono.at --dkim'
47
+ c.option '--alias STRING', String, 'Specify the alias destination.'
48
+ c.option '--password STRING', String, 'The password for a new mailbox. If you omit this option, it prompts for one.'
49
+ c.option '--dkim', String, 'Add a DKIM Key for a domain'
50
+ c.action do |args, options|
51
+ address = args[0]
52
+ type = determine_object(address)
53
+
54
+ case type
55
+ when :domain
56
+ if options.dkim
57
+ Smailr::Dkim.add(address, options)
58
+ else
59
+ Smailr::Domain.add(address)
60
+ end
61
+
62
+ when :address
63
+ if options.alias
64
+ source = args[0]
65
+ destinations = options.alias.split(',')
66
+ Smailr::Alias.add(source, destinations)
67
+ else
68
+ options.password ||= ask_password
69
+ Smailr::Mailbox.add(address, options.password)
70
+ end
71
+
72
+ end
73
+ end
74
+ end
75
+
76
+ command :ls do |c|
77
+ c.syntax = 'smailr ls [domain]'
78
+ c.summary = 'List domains or mailboxes of a specific domain.'
79
+ c.action do |args, options|
80
+ case args[0]
81
+ when /^[^@][A-Z0-9.-]+\.[A-Z]{2,6}$/i then
82
+ domain = Smailr::Model::Domain[:fqdn => args[0]]
83
+ domain.mailboxes.each do |mbox|
84
+ puts "m: #{mbox.localpart}@#{args[0]}"
85
+ end
86
+ domain.aliases.each do |aliass|
87
+ puts "a: #{aliass.localpart}@#{args[0]} > #{aliass.dstlocalpart}@#{aliass.dstdomain}"
88
+ end
89
+ when nil
90
+ domains = DB[:domains]
91
+ domains.all.each do |d|
92
+ domain = Smailr::Model::Domain[:fqdn => d[:fqdn]]
93
+ puts d[:fqdn]
94
+ end
95
+ else
96
+ error "You can either list a domains or a domains addresses."
97
+ exit 1
98
+ end
99
+ end
100
+ end
101
+
102
+ command :rm do |c|
103
+ c.syntax = 'smailr rm domain | mailbox [options]'
104
+ c.summary = 'Remove a domain, mailbox or alias known to the mail system.'
105
+ c.example 'Remove a domain', 'smailr rm example.com'
106
+ c.option '--force', 'Force the operation, do not ask for confirmation.'
107
+ c.option '--dkim', 'Remove a dkim key.'
108
+ c.option '--alias STRING', String, 'Specify the alias which you want to remove.'
109
+ c.action do |args, options|
110
+ address = args[0]
111
+ type = determine_object(address)
112
+ case type
113
+ when :domain
114
+ if options.dkim
115
+ Smailr::Dkim.rm(address, options)
116
+ else
117
+ Smailr::Domain.rm(address, options.force)
118
+ end
119
+
120
+ when :address
121
+ if options.alias
122
+ source = args[0]
123
+ destinations = options.alias.split(',')
124
+
125
+ Smailr::Alias.rm(source, destinations)
126
+ else
127
+ Smailr::Mailbox.rm(address, options)
128
+ end
129
+ end
130
+ end
131
+ end
132
+
133
+
134
+ command :migrate do |c|
135
+ c.syntax = 'smailr migrate [options]'
136
+ c.summary = 'Create database and run migrations'
137
+ c.option '--to VERSION', String, 'Migrate the database to a specifict version.'
138
+ c.action do |args,options|
139
+ require 'sequel/extensions/migration'
140
+ raise "Database not configured" unless DB
141
+
142
+ if options.version.nil?
143
+ Sequel::Migrator.apply(DB, Smailr.migrations_directory)
144
+ else
145
+ Sequel::Migrator.apply(DB, Smailr.migrations_directory, :target => options.version.to_i)
146
+ end
147
+ end
148
+ end
149
+
150
+
151
+ command :mutt do |c|
152
+ c.syntax = "smailr mutt address"
153
+ c.summary = "View the mailbox of the specified address in mutt."
154
+ c.description = "Open the mailbox of the specified address in mutt.\n\n " +
155
+ "Requires that mutt is installed and assumes the default mail\n " +
156
+ "storage directory structure: /srv/mail/users/<fqdn>/<localpart>"
157
+ c.example 'Open test@example.com', 'smailr mutt test@example.com'
158
+ c.action do |args,options|
159
+ localpart, fqdn = args[0].split('@')
160
+ `command -v mutt >/dev/null 2>&1 || { echo "Please install mutt first. Aborting." >&2; exit 1; }`
161
+ if not $?
162
+ exec "MAIL=/srv/mail/users/#{fqdn}/#{localpart} MAILDIR=$MAIL mutt -mMaildir]"
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,135 @@
1
+ # This file is opened as root, so it should be owned by root and mode 0600.
2
+ #
3
+ # http://wiki.dovecot.org/AuthDatabase/SQL
4
+ #
5
+ # For the sql passdb module, you'll need a database with a table that
6
+ # contains fields for at least the username and password. If you want to
7
+ # use the user@domain syntax, you might want to have a separate domain
8
+ # field as well.
9
+ #
10
+ # If your users all have the same uig/gid, and have predictable home
11
+ # directories, you can use the static userdb module to generate the home
12
+ # dir based on the username and domain. In this case, you won't need fields
13
+ # for home, uid, or gid in the database.
14
+ #
15
+ # If you prefer to use the sql userdb module, you'll want to add fields
16
+ # for home, uid, and gid. Here is an example table:
17
+ #
18
+ # CREATE TABLE users (
19
+ # username VARCHAR(128) NOT NULL,
20
+ # domain VARCHAR(128) NOT NULL,
21
+ # password VARCHAR(64) NOT NULL,
22
+ # home VARCHAR(255) NOT NULL,
23
+ # uid INTEGER NOT NULL,
24
+ # gid INTEGER NOT NULL,
25
+ # active CHAR(1) DEFAULT 'Y' NOT NULL
26
+ # );
27
+
28
+ # Database driver: mysql, pgsql, sqlite
29
+ driver = sqlite
30
+
31
+ # Database connection string. This is driver-specific setting.
32
+ #
33
+ # pgsql:
34
+ # For available options, see the PostgreSQL documention for the
35
+ # PQconnectdb function of libpq.
36
+ #
37
+ # mysql:
38
+ # Basic options emulate PostgreSQL option names:
39
+ # host, port, user, password, dbname
40
+ #
41
+ # But also adds some new settings:
42
+ # client_flags - See MySQL manual
43
+ # ssl_ca, ssl_ca_path - Set either one or both to enable SSL
44
+ # ssl_cert, ssl_key - For sending client-side certificates to server
45
+ # ssl_cipher - Set minimum allowed cipher security (default: HIGH)
46
+ # option_file - Read options from the given file instead of
47
+ # the default my.cnf location
48
+ # option_group - Read options from the given group (default: client)
49
+ #
50
+ # You can connect to UNIX sockets by using host: host=/var/run/mysqld/mysqld.sock
51
+ # Note that currently you can't use spaces in parameters.
52
+ #
53
+ # MySQL supports multiple host parameters for load balancing / HA.
54
+ #
55
+ # sqlite:
56
+ # The path to the database file.
57
+ #
58
+ # Examples:
59
+ # connect = host=192.168.1.1 dbname=users
60
+ # connect = host=sql.example.com dbname=virtual user=virtual password=blarg
61
+ # connect = /etc/dovecot/authdb.sqlite
62
+ #
63
+ connect = /etc/exim4/smailr.sqlite
64
+
65
+ # Default password scheme.
66
+ #
67
+ # List of supported schemes is in
68
+ # http://wiki.dovecot.org/Authentication/PasswordSchemes
69
+ #
70
+ default_pass_scheme = MD5
71
+
72
+ # passdb query to retrieve the password. It can return fields:
73
+ # password - The user's password. This field must be returned.
74
+ # user - user@domain from the database. Needed with case-insensitive lookups.
75
+ # username and domain - An alternative way to represent the "user" field.
76
+ #
77
+ # The "user" field is often necessary with case-insensitive lookups to avoid
78
+ # e.g. "name" and "nAme" logins creating two different mail directories. If
79
+ # your user and domain names are in separate fields, you can return "username"
80
+ # and "domain" fields instead of "user".
81
+ #
82
+ # The query can also return other fields which have a special meaning, see
83
+ # http://wiki.dovecot.org/PasswordDatabase/ExtraFields
84
+ #
85
+ # Commonly used available substitutions (see http://wiki.dovecot.org/Variables
86
+ # for full list):
87
+ # %u = entire user@domain
88
+ # %n = user part of user@domain
89
+ # %d = domain part of user@domain
90
+ #
91
+ # Note that these can be used only as input to SQL query. If the query outputs
92
+ # any of these substitutions, they're not touched. Otherwise it would be
93
+ # difficult to have eg. usernames containing '%' characters.
94
+ #
95
+ # Example:
96
+ # password_query = SELECT userid AS user, pw AS password \
97
+ # FROM users WHERE userid = '%u' AND active = 'Y'
98
+ #
99
+ #password_query = \
100
+ # SELECT username, domain, password \
101
+ # FROM users WHERE username = '%n' AND domain = '%d'
102
+
103
+ # userdb query to retrieve the user information. It can return fields:
104
+ # uid - System UID (overrides mail_uid setting)
105
+ # gid - System GID (overrides mail_gid setting)
106
+ # home - Home directory
107
+ # mail - Mail location (overrides mail_location setting)
108
+ #
109
+ # None of these are strictly required. If you use a single UID and GID, and
110
+ # home or mail directory fits to a template string, you could use userdb static
111
+ # instead. For a list of all fields that can be returned, see
112
+ # http://wiki.dovecot.org/UserDatabase/ExtraFields
113
+ #
114
+ # Examples:
115
+ # user_query = SELECT home, uid, gid FROM users WHERE userid = '%u'
116
+ # user_query = SELECT dir AS home, user AS uid, group AS gid FROM users where userid = '%u'
117
+ # user_query = SELECT home, 501 AS uid, 501 AS gid FROM users WHERE userid = '%u'
118
+ #
119
+ #user_query = \
120
+ # SELECT home, uid, gid \
121
+ # FROM users WHERE username = '%n' AND domain = '%d'
122
+
123
+ # If you wish to avoid two SQL lookups (passdb + userdb), you can use
124
+ # userdb prefetch instead of userdb sql in dovecot.conf. In that case you'll
125
+ # also have to return userdb fields in password_query prefixed with "userdb_"
126
+ # string. For example:
127
+
128
+ password_query = \
129
+ SELECT mailboxes.password AS password, \
130
+ mailboxes.localpart AS username, \
131
+ domains.fqdn AS domain \
132
+ FROM mailboxes, domains \
133
+ WHERE mailboxes.localpart = '%n' \
134
+ AND domains.fqdn = '%d' \
135
+ AND domains.id = mailboxes.domain_id