lists.arthurdejong.org
RSS feed

nss-pam-ldapd commit: r1588 - nss-pam-ldapd/pynslcd

[Date Prev][Date Next] [Thread Prev][Thread Next]

nss-pam-ldapd commit: r1588 - nss-pam-ldapd/pynslcd



Author: arthur
Date: Fri Jan  6 14:59:50 2012
New Revision: 1588
URL: http://arthurdejong.org/viewvc/nss-pam-ldapd?revision=1588&view=revision

Log:
user the logging framework, handle exceptions properly and some cleanups

Modified:
   nss-pam-ldapd/pynslcd/alias.py
   nss-pam-ldapd/pynslcd/cfg.py
   nss-pam-ldapd/pynslcd/common.py
   nss-pam-ldapd/pynslcd/ether.py
   nss-pam-ldapd/pynslcd/group.py
   nss-pam-ldapd/pynslcd/host.py
   nss-pam-ldapd/pynslcd/mypidfile.py
   nss-pam-ldapd/pynslcd/netgroup.py
   nss-pam-ldapd/pynslcd/network.py
   nss-pam-ldapd/pynslcd/pam.py
   nss-pam-ldapd/pynslcd/passwd.py
   nss-pam-ldapd/pynslcd/protocol.py
   nss-pam-ldapd/pynslcd/pynslcd.py
   nss-pam-ldapd/pynslcd/rpc.py

Modified: nss-pam-ldapd/pynslcd/alias.py
==============================================================================
--- nss-pam-ldapd/pynslcd/alias.py      Thu Jan  5 22:30:59 2012        (r1587)
+++ nss-pam-ldapd/pynslcd/alias.py      Fri Jan  6 14:59:50 2012        (r1588)
@@ -1,7 +1,7 @@
 
 # alias.py - lookup functions for aliasnet addresses
 #
-# Copyright (C) 2010, 2011 Arthur de Jong
+# Copyright (C) 2010, 2011, 2012 Arthur de Jong
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -18,10 +18,8 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 # 02110-1301 USA
 
-import logging
-
-import constants
 import common
+import constants
 
 
 attmap = common.Attributes(cn='cn', rfc822MailMember='rfc822MailMember')

Modified: nss-pam-ldapd/pynslcd/cfg.py
==============================================================================
--- nss-pam-ldapd/pynslcd/cfg.py        Thu Jan  5 22:30:59 2012        (r1587)
+++ nss-pam-ldapd/pynslcd/cfg.py        Fri Jan  6 14:59:50 2012        (r1588)
@@ -1,7 +1,7 @@
 
 # cfg.py - module for accessing configuration information
 #
-# Copyright (C) 2010 Arthur de Jong
+# Copyright (C) 2010, 2011, 2012 Arthur de Jong
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -18,6 +18,7 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 # 02110-1301 USA
 
+import logging
 import re
 import sys
 
@@ -207,7 +208,6 @@
                          '|'.join(_scope_options.keys())),
                      line, re.IGNORECASE)
         if m:
-            keyword = m.group('keyword').lower()
             mod = maps[str(m.group('map')).lower()]
             mod.scope = _scope_options[m.group('keyword').lower()]
             continue
@@ -234,7 +234,6 @@
         m = re.match('nss_initgroups_ignoreusers\s+(?P<value>\S.*)',
                      line, re.IGNORECASE)
         if m:
-            global nss_initgroups_ignoreusers
             users = m.group('value')
             if users.lower() == 'alllocal':
                 # get all users known to the system currently (since nslcd 
isn't yet
@@ -283,4 +282,4 @@
     # dump config (debugging code)
     for k, v in globals().items():
         if not k.startswith('_'):
-            print '%s=%r' % (k, v)
+            logging.debug('%s=%r', k, v)

Modified: nss-pam-ldapd/pynslcd/common.py
==============================================================================
--- nss-pam-ldapd/pynslcd/common.py     Thu Jan  5 22:30:59 2012        (r1587)
+++ nss-pam-ldapd/pynslcd/common.py     Fri Jan  6 14:59:50 2012        (r1588)
@@ -1,7 +1,7 @@
 
 # common.py - functions that are used by different modules
 #
-# Copyright (C) 2010, 2011 Arthur de Jong
+# Copyright (C) 2010, 2011, 2012 Arthur de Jong
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -18,14 +18,15 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 # 02110-1301 USA
 
-import re
+import logging
+import sys
+
 import ldap
 import ldap.dn
-import sys
 
+from attmap import Attributes
 import cfg
 import constants
-from attmap import Attributes
 
 
 def isvalidname(name):
@@ -106,7 +107,7 @@
         # get search results
         filter = self.mk_filter()
         for base in self.bases:
-            print 'SEARCHING %s' % base
+            logging.debug('SEARCHING %s', base)
             # do the LDAP search
             try:
                 for entry in self.conn.search_s(base, self.scope, filter, 
self.attributes):
@@ -118,12 +119,15 @@
                 # FIXME: log message
                 pass
 
+    def escape(self, value):
+        """Escape the provided value so it may be used in a search filter."""
+        return ldap.filter.escape_filter_chars(str(value))
+
     def mk_filter(self):
         """Return the active search filter (based on the read parameters)."""
         if self.parameters:
             return '(&%s(%s))' % (self.filter,
-                ')('.join('%s=%s' % (self.attmap[attribute],
-                                     
ldap.filter.escape_filter_chars(str(value)))
+                ')('.join('%s=%s' % (self.attmap[attribute], 
self.escape(value))
                           for attribute, value in self.parameters.items()))
         return self.filter
 
@@ -143,21 +147,19 @@
         # check that these attributes have at least one value
         for attr in self.required:
             if not attributes.get(attr, None):
-                print '%s: %s: missing' % (dn, self.attmap[attr])
+                logging.warning('%s: %s: missing', dn, self.attmap[attr])
                 return
         # check that requested attribute is present (case sensitive)
         for attr in self.case_sensitive:
             value = self.parameters.get(attr, None)
             if value and str(value) not in attributes[attr]:
-                # TODO: log at debug level, this can happen in normal cases
-                print '%s: %s: does not contain %r value' % (dn, 
self.attmap[attr], value)
+                logging.debug('%s: %s: does not contain %r value', dn, 
self.attmap[attr], value)
                 return  # not found, skip entry
         # check that requested attribute is present (case insensitive)
         for attr in self.case_insensitive:
             value = self.parameters.get(attr, None)
             if value and str(value).lower() not in (x.lower() for x in 
attributes[attr]):
-                # TODO: log at debug level, this can happen in normal cases
-                print '%s: %s: does not contain %r value' % (dn, 
self.attmap[attr], value)
+                logging.debug('%s: %s: does not contain %r value', dn, 
self.attmap[attr], value)
                 return  # not found, skip entry
         # limit attribute values to requested value
         for attr in self.limit_attributes:

Modified: nss-pam-ldapd/pynslcd/ether.py
==============================================================================
--- nss-pam-ldapd/pynslcd/ether.py      Thu Jan  5 22:30:59 2012        (r1587)
+++ nss-pam-ldapd/pynslcd/ether.py      Fri Jan  6 14:59:50 2012        (r1588)
@@ -1,7 +1,7 @@
 
 # ether.py - lookup functions for ethernet addresses
 #
-# Copyright (C) 2010, 2011 Arthur de Jong
+# Copyright (C) 2010, 2011, 2012 Arthur de Jong
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -20,8 +20,8 @@
 
 import struct
 
-import constants
 import common
+import constants
 
 
 def ether_aton(ether):

Modified: nss-pam-ldapd/pynslcd/group.py
==============================================================================
--- nss-pam-ldapd/pynslcd/group.py      Thu Jan  5 22:30:59 2012        (r1587)
+++ nss-pam-ldapd/pynslcd/group.py      Fri Jan  6 14:59:50 2012        (r1588)
@@ -1,7 +1,7 @@
 
 # group.py - group entry lookup routines
 #
-# Copyright (C) 2010, 2011 Arthur de Jong
+# Copyright (C) 2010, 2011, 2012 Arthur de Jong
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -19,11 +19,10 @@
 # 02110-1301 USA
 
 import logging
-import ldap.filter
 
-import constants
-import common
 from passwd import dn2uid, uid2dn
+import common
+import constants
 
 
 def clean(lst):
@@ -60,8 +59,8 @@
             dn = uid2dn(self.conn, memberuid)
             if dn:
                 return '(&%s(|(%s=%s)(%s=%s)))' % (self.filter,
-                          attmap['memberUid'], 
ldap.filter.escape_filter_chars(memberuid),
-                          attmap['member'], 
ldap.filter.escape_filter_chars(dn))
+                          attmap['memberUid'], self.escape(memberuid),
+                          attmap['member'], self.escape(dn))
         return super(Search, self).mk_filter()
 
 
@@ -91,7 +90,7 @@
         # actually return the results
         for name in names:
             if not common.isvalidname(name):
-                print '%s: %s: denied by validnames option' % (dn, 
attmap['cn'])
+                logging.warning('%s: %s: denied by validnames option', dn, 
attmap['cn'])
             else:
                 for gid in gids:
                     self.fp.write_int32(constants.NSLCD_RESULT_BEGIN)

Modified: nss-pam-ldapd/pynslcd/host.py
==============================================================================
--- nss-pam-ldapd/pynslcd/host.py       Thu Jan  5 22:30:59 2012        (r1587)
+++ nss-pam-ldapd/pynslcd/host.py       Fri Jan  6 14:59:50 2012        (r1588)
@@ -1,7 +1,7 @@
 
 # host.py - lookup functions for host names and addresses
 #
-# Copyright (C) 2011 Arthur de Jong
+# Copyright (C) 2011, 2012 Arthur de Jong
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -18,10 +18,8 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 # 02110-1301 USA
 
-import logging
-
-import constants
 import common
+import constants
 
 
 attmap = common.Attributes(cn='cn', ipHostNumber='ipHostNumber')

Modified: nss-pam-ldapd/pynslcd/mypidfile.py
==============================================================================
--- nss-pam-ldapd/pynslcd/mypidfile.py  Thu Jan  5 22:30:59 2012        (r1587)
+++ nss-pam-ldapd/pynslcd/mypidfile.py  Fri Jan  6 14:59:50 2012        (r1588)
@@ -1,7 +1,7 @@
 
 # mypidfile.py - functions for properly locking a PIDFile
 #
-# Copyright (C) 2010, 2011 Arthur de Jong
+# Copyright (C) 2010, 2011, 2012 Arthur de Jong
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -18,8 +18,8 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 # 02110-1301 USA
 
-import fcntl
 import errno
+import fcntl
 import os
 
 

Modified: nss-pam-ldapd/pynslcd/netgroup.py
==============================================================================
--- nss-pam-ldapd/pynslcd/netgroup.py   Thu Jan  5 22:30:59 2012        (r1587)
+++ nss-pam-ldapd/pynslcd/netgroup.py   Fri Jan  6 14:59:50 2012        (r1588)
@@ -1,7 +1,7 @@
 
 # netgroup.py - lookup functions for netgroups
 #
-# Copyright (C) 2011 Arthur de Jong
+# Copyright (C) 2011, 2012 Arthur de Jong
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -21,8 +21,8 @@
 import logging
 import re
 
-import constants
 import common
+import constants
 
 
 _netgroup_triple_re = 
re.compile(r'^\s*\(\s*(?P<host>.*)\s*,\s*(?P<user>.*)\s*,\s*(?P<domain>.*)\s*\)\s*$')
@@ -47,7 +47,7 @@
         for triple in attributes['nisNetgroupTriple']:
             m = _netgroup_triple_re.match(triple)
             if not m:
-                print '%s: %s: invalid value: %r' % (dn, 
attmap['nisNetgroupTriple'], triple)
+                logging.warning('%s: %s: invalid value: %r', dn, 
attmap['nisNetgroupTriple'], triple)
             else:
                 self.fp.write_int32(constants.NSLCD_RESULT_BEGIN)
                 self.fp.write_int32(constants.NSLCD_NETGROUP_TYPE_TRIPLE)

Modified: nss-pam-ldapd/pynslcd/network.py
==============================================================================
--- nss-pam-ldapd/pynslcd/network.py    Thu Jan  5 22:30:59 2012        (r1587)
+++ nss-pam-ldapd/pynslcd/network.py    Fri Jan  6 14:59:50 2012        (r1588)
@@ -1,7 +1,7 @@
 
 # network.py - lookup functions for network names and addresses
 #
-# Copyright (C) 2011 Arthur de Jong
+# Copyright (C) 2011, 2012 Arthur de Jong
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -18,10 +18,8 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 # 02110-1301 USA
 
-import logging
-
-import constants
 import common
+import constants
 
 
 attmap = common.Attributes(cn='cn',

Modified: nss-pam-ldapd/pynslcd/pam.py
==============================================================================
--- nss-pam-ldapd/pynslcd/pam.py        Thu Jan  5 22:30:59 2012        (r1587)
+++ nss-pam-ldapd/pynslcd/pam.py        Fri Jan  6 14:59:50 2012        (r1588)
@@ -1,7 +1,7 @@
 
 # pam.py - functions authentication, authorisation and session handling
 #
-# Copyright (C) 2010, 2011 Arthur de Jong
+# Copyright (C) 2010, 2011, 2012 Arthur de Jong
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -19,17 +19,18 @@
 # 02110-1301 USA
 
 import logging
+
 import ldap
 
-import constants
-import common
 import cfg
+import common
+import constants
 import passwd
 
 
 def try_bind(userdn, password):
     # open a new connection
-    conn = ldap.initialize(cfg.ldap_uri)
+    conn = ldap.initialize(cfg.uri)
     # bind using the specified credentials
     conn.simple_bind_s(userdn, password)
     # perform search for own object (just to do any kind of search)
@@ -60,7 +61,7 @@
                 # get the username from the uid attribute
                 values = myldap_get_values(entry, passwd.attmap['uid'])
                 if not values or not values[0]:
-                    logging.warn('%s: is missing a %s attribute', dn, 
passwd.attmap['uid'])
+                    logging.warning('%s: is missing a %s attribute', dn, 
passwd.attmap['uid'])
                 value = values[0]
             # check the username
             if value and not common.isvalidname(value):

Modified: nss-pam-ldapd/pynslcd/passwd.py
==============================================================================
--- nss-pam-ldapd/pynslcd/passwd.py     Thu Jan  5 22:30:59 2012        (r1587)
+++ nss-pam-ldapd/pynslcd/passwd.py     Fri Jan  6 14:59:50 2012        (r1588)
@@ -1,7 +1,7 @@
 
 # passwd.py - lookup functions for user account information
 #
-# Copyright (C) 2010, 2011 Arthur de Jong
+# Copyright (C) 2010, 2011, 2012 Arthur de Jong
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -18,11 +18,10 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 # 02110-1301 USA
 
-import ldap
-import ldap.filter
+import logging
 
-import constants
 import common
+import constants
 
 
 attmap = common.Attributes(uid='uid',
@@ -61,7 +60,7 @@
         # write results
         for name in names:
             if not common.isvalidname(name):
-                print '%s: %s: denied by validnames option' % (dn, 
attmap['uid'])
+                logging.warning('%s: %s: denied by validnames option', dn, 
attmap['uid'])
             else:
                 for uid in uids:
                     self.fp.write_int32(constants.NSLCD_RESULT_BEGIN)

Modified: nss-pam-ldapd/pynslcd/protocol.py
==============================================================================
--- nss-pam-ldapd/pynslcd/protocol.py   Thu Jan  5 22:30:59 2012        (r1587)
+++ nss-pam-ldapd/pynslcd/protocol.py   Fri Jan  6 14:59:50 2012        (r1588)
@@ -1,7 +1,7 @@
 
 # protocol.py - protocol name and number lookup routines
 #
-# Copyright (C) 2011 Arthur de Jong
+# Copyright (C) 2011, 2012 Arthur de Jong
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -18,10 +18,8 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 # 02110-1301 USA
 
-import logging
-
-import constants
 import common
+import constants
 
 
 attmap = common.Attributes(cn='cn', ipProtocolNumber='ipProtocolNumber')

Modified: nss-pam-ldapd/pynslcd/pynslcd.py
==============================================================================
--- nss-pam-ldapd/pynslcd/pynslcd.py    Thu Jan  5 22:30:59 2012        (r1587)
+++ nss-pam-ldapd/pynslcd/pynslcd.py    Fri Jan  6 14:59:50 2012        (r1588)
@@ -2,7 +2,7 @@
 
 # pynslcd.py - main daemon module
 #
-# Copyright (C) 2010, 2011 Arthur de Jong
+# Copyright (C) 2010, 2011, 2012 Arthur de Jong
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -19,22 +19,23 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 # 02110-1301 USA
 
-import os
-import sys
 import daemon
-import mypidfile
-import threading
 import logging
 import logging.handlers
+import os
 import signal
+import sys
+import syslog
+import threading
+
 import ldap
 
-import constants  # from nslcd.h
-import config     # from configure
+from tio import TIOStream
 import cfg        # from nslcd.conf
 import common
-
-from tio import TIOStream
+import config     # from configure
+import constants  # from nslcd.h
+import mypidfile
 
 
 # the name of the program
@@ -47,36 +48,51 @@
 checkonly = False
 
 
-# configure logging
 class MyFormatter(logging.Formatter):
+
     def format(self, record):
-        msg = logging.Formatter.format(self, record)
+        msg = super(MyFormatter, self).format(record)
         if record.levelno == logging.DEBUG:
             msg = 'DEBUG: %s' % msg
         return msg
-#logging.basicConfig(level=logging.INFO)
-# , format='%(message)s'
+
+
+class MySysLogHandler(logging.Handler):
+
+    mapping = {
+        logging.DEBUG: syslog.LOG_DEBUG,
+        logging.INFO: syslog.LOG_INFO,
+        logging.WARNING: syslog.LOG_WARNING,
+        logging.ERROR: syslog.LOG_ERR,
+        logging.CRITICAL: syslog.LOG_CRIT,
+    }
+
+    def __init__(self):
+        super(MySysLogHandler, self).__init__()
+        syslog.openlog(program_name, syslog.LOG_PID, syslog.LOG_DAEMON)
+
+    def emit(self, record):
+        priority = self.mapping.get(record.levelno, syslog.LOG_WARNING)
+        msg = self.format(record)
+        for l in msg.splitlines():
+            syslog.syslog(priority, l)
+
+
+# configure logging
 formatter = MyFormatter('%(message)s')
 stderrhandler = logging.StreamHandler(sys.stderr)
 stderrhandler.setFormatter(formatter)
-##sysloghandler = logging.handlers.SysLogHandler(address='/dev/log')
-##sysloghandler.setFormatter(formatter)
-#logging.getLogger().setFormatter(MyFormatter())
+sysloghandler = MySysLogHandler()
+sysloghandler.setFormatter(formatter)
 logging.getLogger().addHandler(stderrhandler)
-
-#logger = logging.getLogger()
-#logger.setLevel(logging.INFO)
-#syslog = logging.handlers.SysLogHandler(address='/dev/log')
-#formatter = logging.Formatter('%(name)s: %(levelname)s %(message)s')
-#syslog.setFormatter(formatter)
-#logger.addHandler(syslog)
+logging.getLogger().setLevel(logging.INFO)
 
 
 def display_version(fp):
     fp.write('%(PACKAGE_STRING)s\n'
              'Written by Arthur de Jong.\n'
              '\n'
-             'Copyright (C) 2010, 2011 Arthur de Jong\n'
+             'Copyright (C) 2010-2012 Arthur de Jong\n'
              'This is free software; see the source for copying conditions.  
There is NO\n'
              'warranty; not even for MERCHANTABILITY or FITNESS FOR A 
PARTICULAR PURPOSE.\n'
              % {'PACKAGE_STRING': config.PACKAGE_STRING, })
@@ -198,7 +214,7 @@
         try:
             handler = handlers[action]
         except KeyError:
-            logging.warn('invalid action id: %r', action)
+            logging.warning('invalid action id: %r', action)
             return
         handler(fp, session, uid)()
     finally:
@@ -214,14 +230,13 @@
 
 
 def worker():
-    # create a new LDAP session
-    #session = myldap_create_session()
     session = ldap.initialize(cfg.uri)
-    # start waiting for incoming connections
     while True:
-        # wait for a new connection
-        acceptconnection(session)
-        # FIXME: handle exceptions
+        try:
+            acceptconnection(session)
+        except:
+            logging.exception('exception in worker')
+            # ignore all exceptions, just keep going
 
 
 if __name__ == '__main__':
@@ -237,7 +252,7 @@
     # set log level
     if debugging:
         logging.getLogger().setLevel(logging.DEBUG)
-    # FIXME: implement
+    # TODO: implement
     #if myldap_set_debuglevel(cfg.debug) != LDAP_SUCCESS:
     #    sys.exit(1)
     # read configuration file
@@ -272,36 +287,40 @@
                       })
     # start daemon
     with daemon:
-        # start normal logging
+        # start normal logging to syslog
         if not debugging:
-            log_startlogging()
+            logging.getLogger().addHandler(sysloghandler)
         logging.info('version %s starting', config.VERSION)
-        # create socket
-        nslcd_serversocket = create_socket()
-        # drop all supplemental groups
         try:
-            os.setgroups(())
-        except OSError, e:
-            logging.warn('cannot setgroups(()) (ignored): %s', e)
-        # change to nslcd gid
-        if cfg.gid is not None:
-            import grp
-            os.setgid(grp.getgrnam(cfg.gid).gr_gid)
-        # change to nslcd uid
-        if cfg.uid is not None:
-            import pwd
-            u = pwd.getpwnam(cfg.uid)
-            os.setuid(u.pw_uid)
-            os.environ['HOME'] = u.pw_dir
-        logging.info('accepting connections')
-        # start worker threads
-        threads = []
-        for i in range(cfg.threads):
-            thread = threading.Thread(target=worker, name='thread%d' % i)
-            thread.setDaemon(True)
-            thread.start()
-            logging.debug('started thread %s', thread.getName())
-            threads.append(thread)
-        # wait for all threads to die
-        for thread in threads:
-            thread.join(10000)
+            # create socket
+            nslcd_serversocket = create_socket()
+            # drop all supplemental groups
+            try:
+                os.setgroups(())
+            except OSError, e:
+                logging.warning('cannot setgroups(()) (ignored): %s', e)
+            # change to nslcd gid
+            if cfg.gid is not None:
+                import grp
+                os.setgid(grp.getgrnam(cfg.gid).gr_gid)
+            # change to nslcd uid
+            if cfg.uid is not None:
+                import pwd
+                u = pwd.getpwnam(cfg.uid)
+                os.setuid(u.pw_uid)
+                os.environ['HOME'] = u.pw_dir
+            logging.info('accepting connections')
+            # start worker threads
+            threads = []
+            for i in range(cfg.threads):
+                thread = threading.Thread(target=worker, name='thread%d' % i)
+                thread.setDaemon(True)
+                thread.start()
+                logging.debug('started thread %s', thread.getName())
+                threads.append(thread)
+            # wait for all threads to die
+            for thread in threads:
+                thread.join(10000)
+        except:
+            logging.exception('main loop exit')
+            # no need to re-raise since we are exiting anyway

Modified: nss-pam-ldapd/pynslcd/rpc.py
==============================================================================
--- nss-pam-ldapd/pynslcd/rpc.py        Thu Jan  5 22:30:59 2012        (r1587)
+++ nss-pam-ldapd/pynslcd/rpc.py        Fri Jan  6 14:59:50 2012        (r1588)
@@ -1,7 +1,7 @@
 
 # rpc.py - rpc name lookup routines
 #
-# Copyright (C) 2011 Arthur de Jong
+# Copyright (C) 2011, 2012 Arthur de Jong
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -18,8 +18,6 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 # 02110-1301 USA
 
-import logging
-
 import constants
 import common
 
-- 
To unsubscribe send an email to
nss-pam-ldapd-commits-unsubscribe@lists.arthurdejong.org or see
http://lists.arthurdejong.org/nss-pam-ldapd-commits/