smailr 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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