3 # Copyright (C) 2008-2011 W. Trevor King
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 """LDAP address searches for Mutt.
20 Add :file:`mutt-ldap.py` to your ``PATH`` and add the following line
21 to your :file:`.muttrc`::
23 set query_command = "mutt-ldap.py '%s'"
25 Search for addresses with `^t`, optionally after typing part of the
26 name. Configure your connection by creating :file:`~/.mutt-ldap.py`
27 contaning something like::
30 server = myserver.example.net
31 basedn = ou=people,dc=example,dc=net
33 See the `CONFIG` options for other available settings.
45 CONFIG = ConfigParser.SafeConfigParser()
46 CONFIG.add_section('connection')
47 CONFIG.set('connection', 'server', 'domaincontroller.yourdomain.com')
48 CONFIG.set('connection', 'port', '389') # set to 636 for default over SSL
49 CONFIG.set('connection', 'ssl', 'no')
50 CONFIG.set('connection', 'basedn', 'ou=x co.,dc=example,dc=net')
51 CONFIG.add_section('auth')
52 CONFIG.set('auth', 'user', '')
53 CONFIG.set('auth', 'password', '')
54 CONFIG.set('auth', 'gssapi', 'no')
55 CONFIG.read(os.path.expanduser('~/.mutt-ldap.rc'))
59 if CONFIG.getboolean('connection', 'ssl'):
61 url = '%s://%s:%s' % (
63 CONFIG.get('connection', 'server'),
64 CONFIG.get('connection', 'port'))
65 connection = ldap.initialize(url)
66 if CONFIG.getboolean('auth', 'gssapi'):
67 sasl = ldap.sasl.gssapi()
68 connection.sasl_interactive_bind_s('', sasl)
71 CONFIG.get('auth', 'user'),
72 CONFIG.get('auth', 'password'),
76 def search(query, connection=None):
77 local_connection = False
80 local_connection = True
81 connection = connect()
85 filterstr = '(|%s)' % (
86 u' '.join([u'(%s=*%s%s)' % (field, query, post)
87 for field in ['cn', 'rdn', 'uid', 'mail']]))
88 r = connection.search_s(
89 CONFIG.get('connection', 'basedn'),
91 filterstr.encode('utf-8'))
93 if local_connection and connection:
97 def format_entry(entry):
100 for m in data['mail']:
101 yield email.utils.formataddr((data['cn'][-1], m))
104 if __name__ == '__main__':
107 query = unicode(' '.join(sys.argv[1:]), 'utf-8')
108 entries = search(query)
109 addresses = list(itertools.chain(
110 *[format_entry(e) for e in sorted(entries)]))
111 print '%d addresses found:' % len(addresses)
112 print '\n'.join(addresses)