summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pynslcd/cache.py4
-rw-r--r--pynslcd/cfg.py5
-rw-r--r--pynslcd/group.py8
-rw-r--r--pynslcd/nscd.py4
-rwxr-xr-xpynslcd/pynslcd.py32
-rw-r--r--pynslcd/search.py2
-rw-r--r--pynslcd/shadow.py2
-rw-r--r--pynslcd/tio.py8
-rw-r--r--pynslcd/usermod.py10
-rwxr-xr-xutils/chsh.py51
-rwxr-xr-xutils/getent.py68
-rw-r--r--utils/nslcd.py12
-rw-r--r--utils/users.py4
13 files changed, 104 insertions, 106 deletions
diff --git a/pynslcd/cache.py b/pynslcd/cache.py
index ce706be..7089d41 100644
--- a/pynslcd/cache.py
+++ b/pynslcd/cache.py
@@ -1,7 +1,7 @@
# cache.py - caching layer for pynslcd
#
-# Copyright (C) 2012 Arthur de Jong
+# Copyright (C) 2012, 2013 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
@@ -29,8 +29,6 @@ import sqlite3
# TODO: probably create a config table
-
-
# FIXME: store the cache in the right place and make it configurable
filename = '/tmp/cache.sqlite'
dirname = os.path.dirname(filename)
diff --git a/pynslcd/cfg.py b/pynslcd/cfg.py
index baa29ec..a9f1d89 100644
--- a/pynslcd/cfg.py
+++ b/pynslcd/cfg.py
@@ -20,12 +20,9 @@
import logging
import re
-import sys
import ldap
-from expr import Expression
-
# the number of threads to start
threads = 5
@@ -134,6 +131,7 @@ def _get_maps():
# separate function as not to pollute the namespace and avoid import loops
import alias, ether, group, host, netgroup, network, passwd
import protocol, rpc, service, shadow
+ import sys
return dict(
alias=alias, aliases=alias,
ether=ether, ethers=ether,
@@ -274,6 +272,7 @@ def read(filename):
# pam_authz_search <FILTER>
m = re.match('pam_authz_search\s+(?P<value>\S.*)', line, re.IGNORECASE)
if m:
+ from expr import Expression
pam_authz_searches.append(Expression(m.group('value')))
# TODO: check pam_authz_search expression to only contain
# username, service, ruser, rhost, tty, hostname, fqdn, dn or
diff --git a/pynslcd/group.py b/pynslcd/group.py
index 71a1173..a72c57d 100644
--- a/pynslcd/group.py
+++ b/pynslcd/group.py
@@ -65,9 +65,11 @@ class Search(search.LDAPSearch):
memberuid = self.parameters['memberUid']
dn = uid2dn(self.conn, memberuid)
if dn:
- return '(&%s(|(%s=%s)(%s=%s)))' % (self.filter,
- attmap['memberUid'], escape_filter_chars(memberuid),
- attmap['member'], escape_filter_chars(dn))
+ return '(&%s(|(%s=%s)(%s=%s)))' % (
+ self.filter,
+ attmap['memberUid'], escape_filter_chars(memberuid),
+ attmap['member'], escape_filter_chars(dn)
+ )
return super(Search, self).mk_filter()
diff --git a/pynslcd/nscd.py b/pynslcd/nscd.py
index 19e5ceb..e71bd04 100644
--- a/pynslcd/nscd.py
+++ b/pynslcd/nscd.py
@@ -22,7 +22,6 @@ import fcntl
import logging
import os
import subprocess
-import struct
import cfg
@@ -74,9 +73,8 @@ def loop(fd):
os.environ['PATH'] = '/usr/sbin:/usr/bin:/sbin:/bin'
while True:
db = os.read(fd, 1)
- # FIXME: define the characters and maps somewhere
if db == '':
- break
+ break # close process down
db = _char_to_db.get(db, None)
if db:
exec_invalidate(db)
diff --git a/pynslcd/pynslcd.py b/pynslcd/pynslcd.py
index 35ecb08..99bfda8 100755
--- a/pynslcd/pynslcd.py
+++ b/pynslcd/pynslcd.py
@@ -73,8 +73,8 @@ class MySysLogHandler(logging.Handler):
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)
+ for line in msg.splitlines():
+ syslog.syslog(priority, line)
# configure logging
@@ -113,8 +113,9 @@ def parse_cmdline():
global program_name
program_name = sys.argv[0] or program_name
try:
- optlist, args = getopt.gnu_getopt(sys.argv[1:],
- 'cdhV', ('check', 'debug', 'help', 'version', ))
+ optlist, args = getopt.gnu_getopt(
+ sys.argv[1:], 'cdhV',
+ ('check', 'debug', 'help', 'version'))
for flag, arg in optlist:
if flag in ('-c', '--check'):
global checkonly
@@ -131,10 +132,12 @@ def parse_cmdline():
if len(args):
raise getopt.GetoptError('unrecognized option \'%s\'' % args[0], args[0])
except getopt.GetoptError, reason:
- sys.stderr.write("%(program_name)s: %(reason)s\n"
- "Try '%(program_name)s --help' for more information.\n"
- % {'program_name': program_name,
- 'reason': reason, })
+ sys.stderr.write(
+ "%(program_name)s: %(reason)s\n"
+ "Try '%(program_name)s --help' for more information.\n" % {
+ 'program_name': program_name,
+ 'reason': reason,
+ })
sys.exit(1)
@@ -168,7 +171,7 @@ def getpeercred(fd):
"""Return uid, gid and pid of calling application."""
import struct
import socket
- SO_PEERCRED = 17
+ SO_PEERCRED = getattr(socket, 'SO_PEERCRED', 17)
creds = fd.getsockopt(socket.SOL_SOCKET, SO_PEERCRED, struct.calcsize('3i'))
pid, uid, gid = struct.unpack('3i', creds)
return uid, gid, pid
@@ -181,12 +184,12 @@ handlers.update(common.get_handlers('group'))
handlers.update(common.get_handlers('host'))
handlers.update(common.get_handlers('netgroup'))
handlers.update(common.get_handlers('network'))
-handlers.update(common.get_handlers('pam'))
handlers.update(common.get_handlers('passwd'))
handlers.update(common.get_handlers('protocol'))
handlers.update(common.get_handlers('rpc'))
handlers.update(common.get_handlers('service'))
handlers.update(common.get_handlers('shadow'))
+handlers.update(common.get_handlers('pam'))
handlers.update(common.get_handlers('usermod'))
@@ -196,8 +199,7 @@ def acceptconnection(session):
# See: http://docs.python.org/library/socket.html#socket.socket.settimeout
fp = None
try:
- # probably use finally
- # indicate new connection to logging module (genrates unique id)
+ # indicate new connection to logging module (generates unique id)
log_newsession()
# log connection
try:
@@ -292,9 +294,9 @@ if __name__ == '__main__':
sys.exit(1)
# daemonize
if debugging:
- daemon = pidfile
+ ctx = pidfile
else:
- daemon = daemon.DaemonContext(
+ ctx = daemon.DaemonContext(
pidfile=pidfile,
signal_map={
signal.SIGTERM: 'terminate',
@@ -302,7 +304,7 @@ if __name__ == '__main__':
signal.SIGPIPE: None,
})
# start daemon
- with daemon:
+ with ctx:
try:
# start normal logging as configured
if not debugging:
diff --git a/pynslcd/search.py b/pynslcd/search.py
index 219929b..3db6e9d 100644
--- a/pynslcd/search.py
+++ b/pynslcd/search.py
@@ -25,7 +25,6 @@ import ldap
import ldap.ldapobject
import cfg
-import nscd
# global indicator that there was some error connection to an LDAP server
@@ -56,6 +55,7 @@ class Connection(ldap.ldapobject.ReconnectLDAPObject):
self.set_option(ldap.OPT_X_TLS, ldap.OPT_X_TLS_HARD)
def reconnect_after_fail(self):
+ import nscd
logging.info('connected to LDAP server %s', cfg.uri)
nscd.invalidate()
diff --git a/pynslcd/shadow.py b/pynslcd/shadow.py
index 6f7df10..bedac50 100644
--- a/pynslcd/shadow.py
+++ b/pynslcd/shadow.py
@@ -95,7 +95,7 @@ class ShadowRequest(common.Request):
# return results
for name in names:
yield (name, passwd, lastchangedate, mindays, maxdays, warndays,
- inactdays, expiredate, flag)
+ inactdays, expiredate, flag)
class ShadowByNameRequest(ShadowRequest):
diff --git a/pynslcd/tio.py b/pynslcd/tio.py
index 9e7f99b..02b7ec6 100644
--- a/pynslcd/tio.py
+++ b/pynslcd/tio.py
@@ -1,7 +1,7 @@
# tio.py - I/O functions
#
-# Copyright (C) 2010, 2011 Arthur de Jong
+# Copyright (C) 2010, 2011, 2012, 2013 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
@@ -51,10 +51,10 @@ class TIOStream(object):
return _int32.unpack(self.read(_int32.size))[0]
def read_string(self, maxsize=None):
- len = self.read_int32()
- if maxsize and len >= maxsize:
+ num = self.read_int32()
+ if maxsize and num >= maxsize:
raise TIOStreamError()
- return self.read(len)
+ return self.read(num)
def read_address(self):
"""Read an address (usually IPv4 or IPv6) from the stream and return
diff --git a/pynslcd/usermod.py b/pynslcd/usermod.py
index c957b97..9622fb2 100644
--- a/pynslcd/usermod.py
+++ b/pynslcd/usermod.py
@@ -26,9 +26,7 @@ import os.path
import ldap
-import cache
import cfg
-import common
import constants
import pam
import passwd
@@ -94,10 +92,10 @@ class UserModRequest(pam.PAMRequest):
mods.append((ldap.MOD_REPLACE, passwd.attmap['homeDirectory'], [homedir]))
elif not os.path.isabs(homedir):
self.write_result(constants.NSLCD_USERMOD_HOMEDIR,
- 'should be an absolute path')
+ 'should be an absolute path')
elif not os.path.isdir(homedir):
self.write_result(constants.NSLCD_USERMOD_HOMEDIR,
- 'not a directory')
+ 'not a directory')
else:
mods.append((ldap.MOD_REPLACE, passwd.attmap['homeDirectory'], [homedir]))
# check login shell modification
@@ -107,10 +105,10 @@ class UserModRequest(pam.PAMRequest):
mods.append((ldap.MOD_REPLACE, passwd.attmap['loginShell'], [shell]))
elif shell not in list_shells():
self.write_result(constants.NSLCD_USERMOD_SHELL,
- 'unlisted shell')
+ 'unlisted shell')
elif not os.path.isfile(shell) or not os.access(shell, os.X_OK):
self.write_result(constants.NSLCD_USERMOD_SHELL,
- 'not an executable')
+ 'not an executable')
else:
mods.append((ldap.MOD_REPLACE, passwd.attmap['loginShell'], [shell]))
# get a connection and perform the modification
diff --git a/utils/chsh.py b/utils/chsh.py
index 30c5c12..2f81f13 100755
--- a/utils/chsh.py
+++ b/utils/chsh.py
@@ -31,14 +31,13 @@ import users
# set up command line parser
parser = argparse.ArgumentParser(
- description='Change the user login shell in LDAP.',
- epilog='Report bugs to <%s>.' % constants.PACKAGE_BUGREPORT
- )
+ description='Change the user login shell in LDAP.',
+ epilog='Report bugs to <%s>.' % constants.PACKAGE_BUGREPORT)
parser.add_argument('-V', '--version', action=VersionAction)
parser.add_argument('-s', '--shell', help='login shell for the user account')
parser.add_argument('-l', '--list-shells', action=ListShellsAction)
parser.add_argument('username', metavar='USER', nargs='?',
- help="the user who's shell to change")
+ help="the user who's shell to change")
def ask_shell(oldshell):
@@ -47,24 +46,26 @@ def ask_shell(oldshell):
return shell or oldshell
-# parse arguments
-args = parser.parse_args()
-# check username part
-user = users.User(args.username)
-user.check()
-# check the command line shell if one was provided (to fail early)
-shell = args.shell
-if shell is not None:
- shells.check(shell, user.asroot)
-# prompt for a password if required
-password = user.get_passwd()
-# prompt for a shell if it was not specified on the command line
-if shell is None:
- print 'Enter the new value, or press ENTER for the default'
- shell = ask_shell(user.shell)
- shells.check(shell, user.asroot)
-# perform the modification
-result = nslcd.usermod(user.username, user.asroot, password, {
- constants.NSLCD_USERMOD_SHELL: shell,
- })
-# TODO: print proper response
+if __name__ == '__main__':
+ # parse arguments
+ args = parser.parse_args()
+ # check username part
+ user = users.User(args.username)
+ user.check()
+ # check the command line shell if one was provided (to fail early)
+ shell = args.shell
+ if shell is not None:
+ shells.check(shell, user.asroot)
+ # prompt for a password if required
+ password = user.get_passwd()
+ # prompt for a shell if it was not specified on the command line
+ if shell is None:
+ print 'Enter the new value, or press ENTER for the default'
+ shell = ask_shell(user.shell)
+ shells.check(shell, user.asroot)
+ # perform the modification
+ result = nslcd.usermod(
+ user.username, user.asroot, password, {
+ constants.NSLCD_USERMOD_SHELL: shell,
+ })
+ # TODO: print proper response
diff --git a/utils/getent.py b/utils/getent.py
index 07cc670..d662272 100755
--- a/utils/getent.py
+++ b/utils/getent.py
@@ -33,14 +33,13 @@ from nslcd import NslcdClient
# set up command line parser
parser = argparse.ArgumentParser(
- description='Query information in LDAP.',
- epilog='Report bugs to <%s>.' % constants.PACKAGE_BUGREPORT
- )
+ description='Query information in LDAP.',
+ epilog='Report bugs to <%s>.' % constants.PACKAGE_BUGREPORT)
parser.add_argument('-V', '--version', action=VersionAction)
parser.add_argument('database', metavar='DATABASE',
- help='any of those supported by nslcd')
+ help='any of those supported by nslcd')
parser.add_argument('key', metavar='KEY', nargs='?',
- help='information to lookup')
+ help='information to lookup')
def getent_aliases(database, key=None):
@@ -312,32 +311,33 @@ def getent_shadow(database, key=None):
)
-args = parser.parse_args()
-try:
- if args.database == 'aliases':
- getent_aliases(args.database, args.key)
- elif args.database == 'ethers':
- getent_ethers(args.database, args.key)
- elif args.database in ('group', 'group.bymember'):
- getent_group(args.database, args.key)
- elif args.database in ('hosts', 'hostsv4', 'hostsv6'):
- getent_hosts(args.database, args.key)
- elif args.database in ('netgroup', 'netgroup.norec'):
- getent_netgroup(args.database, args.key)
- elif args.database in ('networks', 'networksv4', 'networksv6'):
- getent_networks(args.database, args.key)
- elif args.database == 'passwd':
- getent_passwd(args.database, args.key)
- elif args.database == 'protocols':
- getent_protocols(args.database, args.key)
- elif args.database == 'rpc':
- getent_rpc(args.database, args.key)
- elif args.database == 'services':
- getent_services(args.database, args.key)
- elif args.database == 'shadow':
- getent_shadow(args.database, args.key)
- else:
- parser.error('Unknown database: %s' % args.database)
-except struct.error:
- print 'Problem contacting nslcd'
- sys.exit(1)
+if __name__ == '__main__':
+ args = parser.parse_args()
+ try:
+ if args.database == 'aliases':
+ getent_aliases(args.database, args.key)
+ elif args.database == 'ethers':
+ getent_ethers(args.database, args.key)
+ elif args.database in ('group', 'group.bymember'):
+ getent_group(args.database, args.key)
+ elif args.database in ('hosts', 'hostsv4', 'hostsv6'):
+ getent_hosts(args.database, args.key)
+ elif args.database in ('netgroup', 'netgroup.norec'):
+ getent_netgroup(args.database, args.key)
+ elif args.database in ('networks', 'networksv4', 'networksv6'):
+ getent_networks(args.database, args.key)
+ elif args.database == 'passwd':
+ getent_passwd(args.database, args.key)
+ elif args.database == 'protocols':
+ getent_protocols(args.database, args.key)
+ elif args.database == 'rpc':
+ getent_rpc(args.database, args.key)
+ elif args.database == 'services':
+ getent_services(args.database, args.key)
+ elif args.database == 'shadow':
+ getent_shadow(args.database, args.key)
+ else:
+ parser.error('Unknown database: %s' % args.database)
+ except struct.error:
+ print 'Problem contacting nslcd'
+ sys.exit(1)
diff --git a/utils/nslcd.py b/utils/nslcd.py
index 389b194..031319c 100644
--- a/utils/nslcd.py
+++ b/utils/nslcd.py
@@ -71,12 +71,12 @@ class NslcdClient(object):
return _int32.unpack(self.read(_int32.size))[0]
def read_string(self):
- len = self.read_int32()
- return self.read(len)
+ num = self.read_int32()
+ return self.read(num)
def read_stringlist(self):
- len = self.read_int32()
- return [self.read_string() for x in xrange(len)]
+ num = self.read_int32()
+ return [self.read_string() for x in xrange(num)]
def read_ether(self):
value = self.fp.read(6)
@@ -87,8 +87,8 @@ class NslcdClient(object):
return af, socket.inet_ntop(af, self.read_string())
def read_addresslist(self):
- len = self.read_int32()
- return [self.read_address() for x in xrange(len)]
+ num = self.read_int32()
+ return [self.read_address() for x in xrange(num)]
def get_response(self):
# complete the request if required and check response header
diff --git a/utils/users.py b/utils/users.py
index 02216d6..3387318 100644
--- a/utils/users.py
+++ b/utils/users.py
@@ -34,8 +34,8 @@ class User(object):
else:
self.asroot = False
userinfo = pwd.getpwuid(self.myuid)
- (self.username, ignore, self.uid, self.gid, self.gecos, self.homedir,
- self.shell) = userinfo
+ (self.username, self.password, self.uid, self.gid, self.gecos,
+ self.homedir, self.shell) = userinfo
# if we are trying to modify another user we should be root
self.asroot = self.myuid != self.uid