From 3b1de5ec091123e18839fffd529afd4912790168 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Sat, 18 Jun 2011 14:32:05 -0400 Subject: [PATCH] Add mutt-ldap.py. --- posts/LDAP.mdwn | 12 +++++ posts/LDAP/mutt-ldap.py | 105 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100755 posts/LDAP/mutt-ldap.py diff --git a/posts/LDAP.mdwn b/posts/LDAP.mdwn index 570cbcd..87ffb19 100644 --- a/posts/LDAP.mdwn +++ b/posts/LDAP.mdwn @@ -199,6 +199,17 @@ databases. Command line junkies will probably like [shelldap][]: ~ > cd ou=people ou=people,~ > ls +Mutt +---- + +If you use the [[Mutt]] email client (or just want a simple way to +query email addresses from the command line) there are a [number of +scripts][mutts] available. Pick whichever sounds most appealing to +you. I wrote up [[mutt-ldap.py]], which lets you configuration the +connection details via a config file (`~/.mutt-ldap.rc`) rather than +editing the script itself. Usage details are available in the +docstring. + References ---------- @@ -217,4 +228,5 @@ the countryName attribute, ... [python-ldap]: http://www.python-ldap.org/ [rfc4512]: http://tools.ietf.org/html/rfc4512 [shelldap]: http://projects.martini.nu/shelldap/ +[mutts]: http://wiki.mutt.org/?QueryCommand [schema]: http://www.oreillynet.com/pub/a/sysadmin/2006/11/09/demystifying-ldap-data.html diff --git a/posts/LDAP/mutt-ldap.py b/posts/LDAP/mutt-ldap.py new file mode 100755 index 0000000..e27a5e3 --- /dev/null +++ b/posts/LDAP/mutt-ldap.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python +# +# Copyright (C) 2008-2011 W. Trevor King +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +"""LDAP address searches for Mutt. + +Add :file:`mutt-ldap.py` to your ``PATH`` and add the following line +to your :file:`.muttrc`:: + + set query_command = "mutt-ldap.py '%s'" + +Search for addresses with `^t`, optionally after typing part of the +name. Configure your connection by creating :file:`~/.mutt-ldap.py` +contaning something like:: + + [connection] + server = myserver.example.net + basedn = ou=people,dc=example,dc=net + +See the `CONFIG` options for other available settings. +""" + +import email.utils +import itertools +import os.path +import ConfigParser + +import ldap + + +CONFIG = ConfigParser.SafeConfigParser() +CONFIG.add_section('connection') +CONFIG.set('connection', 'server', 'domaincontroller.yourdomain.com') +CONFIG.set('connection', 'port', '389') # set to 636 for default over SSL +CONFIG.set('connection', 'ssl', 'no') +CONFIG.set('connection', 'user', '') +CONFIG.set('connection', 'password', '') +CONFIG.set('connection', 'basedn', 'ou=x co.,dc=example,dc=net') +CONFIG.read(os.path.expanduser('~/.mutt-ldap.rc')) + +def connect(): + protocol = 'ldap' + if CONFIG.getboolean('connection', 'ssl'): + protocol = 'ldaps' + connection = ldap.initialize( + '%s://%s:%s' % ( + protocol, + CONFIG.get('connection', 'server'), + CONFIG.get('connection', 'port'))) + connection.bind( + CONFIG.get('connection', 'user'), + CONFIG.get('connection', 'password'), + ldap.AUTH_SIMPLE) + return connection + +def search(query, connection=None): + local_connection = False + try: + if not connection: + local_connection = True + connection = connect() + post = '' + if query: + post = '*' + filterstr = '(|%s)' % ( + u' '.join([u'(%s=*%s%s)' % (field, query, post) + for field in ['cn', 'rdn', 'uid', 'mail']])) + r = connection.search_s( + CONFIG.get('connection', 'basedn'), + ldap.SCOPE_SUBTREE, + filterstr.encode('utf-8')) + finally: + if local_connection and connection: + connection.unbind() + return r + +def format_entry(entry): + cn,data = entry + if 'mail' in data: + for m in data['mail']: + yield email.utils.formataddr((data['cn'][-1], m)) + + +if __name__ == '__main__': + import sys + + query = unicode(' '.join(sys.argv[1:]), 'utf-8') + entries = search(query) + addresses = list(itertools.chain( + *[format_entry(e) for e in sorted(entries)])) + print '%d addresses found:' % len(addresses) + print '\n'.join(addresses) -- 2.26.2