X-Git-Url: https://git.adam-barratt.org.uk/?a=blobdiff_plain;f=ud-generate;h=d3da30961a0658e9082c46336ccdfdda8ea409ea;hb=4da58c2caaf11463d5dd477308f619fffda9acd9;hp=5529d93a312b93d899aa177ac87a1c035b99c5c7;hpb=9b17f1fdeb031eb57906422dd4615d5a31f0f8a4;p=mirror%2Fuserdir-ldap.git diff --git a/ud-generate b/ud-generate index 5529d93..d3da309 100755 --- a/ud-generate +++ b/ud-generate @@ -6,7 +6,7 @@ # Copyright (c) 2003-2004 James Troup # Copyright (c) 2004-2005,7 Joey Schulze # Copyright (c) 2001-2007 Ryan Murray -# Copyright (c) 2008,2009,2010 Peter Palfrader +# Copyright (c) 2008,2009,2010,2011 Peter Palfrader # Copyright (c) 2008 Andreas Barth # Copyright (c) 2008 Mark Hymers # Copyright (c) 2008 Luk Claes @@ -28,7 +28,8 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -import string, re, time, ldap, getopt, sys, os, pwd, posix, socket, base64, sha, shutil, errno, tarfile, grp +import string, re, time, ldap, getopt, sys, os, pwd, posix, socket, base64, hashlib, shutil, errno, tarfile, grp +import lockfile from userdir_ldap import * from userdir_exceptions import * import UDLdap @@ -88,6 +89,27 @@ def safe_rmtree(dir): else: raise e +def get_lock(fn, wait=5*60, max_age=3600*6): + try: + stat = os.stat(fn) + if stat[ST_MTIME] < time.time() - max_age: + sys.stderr.write("Removing stale lock %s"%(fn)) + os.unlink(fn) + except OSError, error: + if error.errno == errno.ENOENT: + pass + else: + raise + + lock = lockfile.FileLock(fn) + try: + lock.acquire(timeout=wait) + except lockfile.LockTimeout: + return None + + return lock + + def Sanitize(Str): return Str.translate(string.maketrans("\n\r\t", "$$$")) @@ -759,7 +781,7 @@ def ExtractDNSInfo(x): Algorithm = 2 if Algorithm == None: continue - Fingerprint = sha.new(base64.decodestring(Split[1])).hexdigest() + Fingerprint = hashlib.new('sha1', base64.decodestring(Split[1])).hexdigest() DNSInfo.append("%sIN\tSSHFP\t%u 1 %s" % (TTLprefix, Algorithm, Fingerprint)) if 'architecture' in x[1]: @@ -959,14 +981,23 @@ def GenHosts(host_attrs, File): raise Done(File, F, None) +def replaceTree(src, dst_basedir): + bn = os.path.basename(src) + dst = os.path.join(dst_basedir, bn) + safe_rmtree(dst) + shutil.copytree(src, dst) + def GenKeyrings(OutDir): for k in Keyrings: - shutil.copy(k, OutDir) + if os.path.isdir(k): + replaceTree(k, OutDir) + else: + shutil.copy(k, OutDir) def get_accounts(ldap_conn): # Fetch all the users - passwd_attrs = ldap_conn.search_s(BaseDn, ldap.SCOPE_ONELEVEL, "(&(uid=*)(!(uidNumber=0)))",\ + passwd_attrs = ldap_conn.search_s(BaseDn, ldap.SCOPE_ONELEVEL, "(&(uid=*)(!(uidNumber=0))(objectClass=shadowAccount))",\ ["uid", "uidNumber", "gidNumber", "supplementaryGid",\ "gecos", "loginShell", "userPassword", "shadowLastChange",\ "shadowMin", "shadowMax", "shadowWarning", "shadowInactive", @@ -1142,16 +1173,60 @@ def generate_host(host, global_dir, accounts, ssh_files): if 'KEYRING' in ExtraList: for k in Keyrings: - DoLink(global_dir, OutDir, os.path.basename(k)) + bn = os.path.basename(k) + if os.path.isdir(k): + src = os.path.join(global_dir, bn) + replaceTree(src, OutDir) + else: + DoLink(global_dir, OutDir, bn) else: for k in Keyrings: try: - posix.remove(OutDir + os.path.basename(k)) + bn = os.path.basename(k) + target = os.path.join(OutDir, bn) + if os.path.isdir(target): + safe_rmtree(dst) + else: + posix.remove(target) except: pass l = make_ldap_conn() +mods = l.search_s('cn=log', + ldap.SCOPE_ONELEVEL, + '(&(&(!(reqMod=activity-from*))(!(reqMod=activity-pgp*)))(|(reqType=add)(reqType=delete)(reqType=modify)(reqType=modrdn)))', + ['reqEnd']) + +last = 0 + +# Sort the list by reqEnd +sorted_mods = sorted(mods, key=lambda mod: mod[1]['reqEnd'][0].split('.')[0]) +# Take the last element in the array +last = sorted_mods[-1][1]['reqEnd'][0].split('.')[0] + +# override globaldir for testing +if 'UD_GENERATEDIR' in os.environ: + GenerateDir = os.environ['UD_GENERATEDIR'] + +cache_last_mod = 0 + +try: + fd = open(os.path.join(GenerateDir, "last_update.trace"), "r") + cache_last_mod=fd.read().strip() + fd.close() +except IOError, e: + if e.errno == errno.ENOENT: + pass + else: + raise e +if cache_last_mod >= last: + sys.exit(0) + +fd = open(os.path.join(GenerateDir, "last_update.trace"), "w") +fd.write(last) +fd.close() + # Fetch all the groups GroupIDMap = {} attrs = l.search_s(BaseDn, ldap.SCOPE_ONELEVEL, "gid=*",\ @@ -1167,11 +1242,19 @@ for x in attrs: if x[1].has_key("subGroup") != 0: SubGroupMap.setdefault(x[1]["gid"][0], []).extend(x[1]["subGroup"]) -# override globaldir for testing -if 'UD_GENERATEDIR' in os.environ: - GenerateDir = os.environ['UD_GENERATEDIR'] +lock = None +try: + lockf = os.path.join(GenerateDir, 'ud-generate.lock') + lock = get_lock( lockf ) + if lock is None: + sys.stderr.write("Could not acquire lock %s.\n"%(lockf)) + sys.exit(1) + + generate_all(GenerateDir, l) -generate_all(GenerateDir, l) +finally: + if lock is not None: + lock.release() # vim:set et: # vim:set ts=3: