more sha module
[mirror/userdir-ldap.git] / ud-generate
index 5529d93..6c69928 100755 (executable)
@@ -6,7 +6,7 @@
 #   Copyright (c) 2003-2004  James Troup <troup@debian.org>
 #   Copyright (c) 2004-2005,7  Joey Schulze <joey@infodrom.org>
 #   Copyright (c) 2001-2007  Ryan Murray <rmurray@debian.org>
-#   Copyright (c) 2008,2009,2010 Peter Palfrader <peter@palfrader.org>
+#   Copyright (c) 2008,2009,2010,2011 Peter Palfrader <peter@palfrader.org>
 #   Copyright (c) 2008 Andreas Barth <aba@not.so.argh.org>
 #   Copyright (c) 2008 Mark Hymers <mhy@debian.org>
 #   Copyright (c) 2008 Luk Claes <luk@debian.org>
@@ -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,11 +1173,21 @@ 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
 
@@ -1171,7 +1212,17 @@ for x in attrs:
 if 'UD_GENERATEDIR' in os.environ:
    GenerateDir = os.environ['UD_GENERATEDIR']
 
-generate_all(GenerateDir, l)
+try:
+   lock = get_lock( os.path.join(GenerateDir, 'ud-generate.lock') )
+   if lock is None:
+      sys.stderr.write("Could not acquire lock %s.\n"%(fn))
+      sys.exit(1)
+
+   generate_all(GenerateDir, l)
+
+finally:
+   if not lock is None:
+      lock.release()
 
 # vim:set et:
 # vim:set ts=3: