made ud-generate support new ssh key syntax
[mirror/userdir-ldap.git] / ud-generate
index 3880d21..fd0c53b 100755 (executable)
@@ -12,6 +12,7 @@
 #   Copyright (c) 2008 Luk Claes <luk@debian.org>
 #   Copyright (c) 2008 Thomas Viehmann <tv@beamnet.de>
 #   Copyright (c) 2009 Stephen Gran <steve@lobefin.net>
+#   Copyright (c) 2010 Helmut Grohne <helmut@subdivi.de>
 #
 #   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
 import string, re, time, ldap, getopt, sys, os, pwd, posix, socket, base64, sha, shutil, errno, tarfile, grp
 from userdir_ldap import *
 from userdir_exceptions import *
+try:
+   from cStringIO import StringIO
+except ImportError:
+   from StringIO import StringIO
 
 global Allowed
 global CurrentHost
@@ -48,7 +53,7 @@ EmailCheck = re.compile("^([^ <>@]+@[^ ,<>@]+)?$")
 BSMTPCheck = re.compile(".*mx 0 (master)\.debian\.org\..*",re.DOTALL)
 PurposeHostField = re.compile(r".*\[\[([\*\-]?[a-z0-9.\-]*)(?:\|.*)?\]\]")
 IsV6Addr = re.compile("^[a-fA-F0-9:]+$")
-IsDebianHost = re.compile("[a-zA-Z0-9\.]+\.debian\.org$")
+IsDebianHost = re.compile(ConfModule.dns_hostmatch)
 DNSZone = ".debian.net"
 Keyrings = ConfModule.sync_keyrings.split(":")
 
@@ -385,7 +390,20 @@ def GenSSHtarballs(userlist, SSHFiles, grouprevmap, target):
       to.uname = f
       to.gname = grname
       to.mode  = 0400
-      tf.addfile(to, file(os.path.join(GlobalDir, 'userkeys', f)))
+
+      contents = file(os.path.join(GlobalDir, 'userkeys', f)).read()
+      lines = []
+      for line in contents.splitlines():
+         if line.startswith("allowed_hosts=") and ' ' in line:
+            machines, line = line.split('=', 1)[1].split(' ', 1)
+            if CurrentHost not in machines.split(','):
+               continue # skip this key
+         lines.append(line)
+      if not lines:
+         continue # no keys for this host
+      contents = "\n".join(lines)
+      to.size = len(contents)
+      tf.addfile(to, StringIO(contents))
 
    tf.close()
    os.rename(os.path.join(GlobalDir, 'ssh-keys-%s.tar.gz' % CurrentHost), target)
@@ -426,6 +444,7 @@ def GenGroup(File):
       GroupMap = {}
       for x in GroupIDMap.keys():
          GroupMap[x] = []
+      GroupHasPrimaryMembers = {}
      
       # Fetch all the users
       global PasswdAttrs
@@ -433,6 +452,8 @@ def GenGroup(File):
       # Sort them into a list of groups having a set of users
       for x in PasswdAttrs:
          uid = GetAttr(x, "uid")
+         if 'gidNumber' in x[1]:
+            GroupHasPrimaryMembers[ int(x[1]["gidNumber"][0]) ] = True
          if x[1].has_key("uidNumber") == 0 or not IsInGroup(x):
             continue
          if x[1].has_key("supplementaryGid") == 0:
@@ -446,9 +467,14 @@ def GenGroup(File):
       # Output the group file.
       J = 0
       for x in GroupMap.keys():
-         grouprevmap[GroupIDMap[x]] = x
          if GroupIDMap.has_key(x) == 0:
             continue
+
+         if len(GroupMap[x]) == 0 and GroupIDMap[x] not in GroupHasPrimaryMembers:
+            continue
+
+         grouprevmap[GroupIDMap[x]] = x
+
          Line = "%s:x:%u:" % (x, GroupIDMap[x])
          Comma = ''
          for I in GroupMap[x]:
@@ -832,25 +858,26 @@ def ExtractDNSInfo(x):
          else:
             DNSInfo.append("%sIN\tA\t%s" % (TTLprefix, I))
 
-   Host = GetAttr(x, "hostname")
-   Arch = GetAttr(x, "architecture")
    Algorithm = None
 
-   for I in x[1]["sshRSAHostKey"]:
-      Split = I.split()
-      if Split[0] == 'ssh-rsa':
-         Algorithm = 1
-      if Split[0] == 'ssh-dss':
-         Algorithm = 2
-      if Algorithm == None:
-         continue
-      Fingerprint = sha.new(base64.decodestring(Split[1])).hexdigest()
-      DNSInfo.append("%sIN\tSSHFP\t%u 1 %s" % (TTLprefix, Algorithm, Fingerprint))
+   if 'sshRSAHostKey' in x[1]:
+      for I in x[1]["sshRSAHostKey"]:
+         Split = I.split()
+         if Split[0] == 'ssh-rsa':
+            Algorithm = 1
+         if Split[0] == 'ssh-dss':
+            Algorithm = 2
+         if Algorithm == None:
+            continue
+         Fingerprint = sha.new(base64.decodestring(Split[1])).hexdigest()
+         DNSInfo.append("%sIN\tSSHFP\t%u 1 %s" % (TTLprefix, Algorithm, Fingerprint))
 
-   Mach = ""
-   if x[1].has_key("machine"):
-      Mach = " " + GetAttr(x, "machine")
-   DNSInfo.append("%sIN\tHINFO\t\"%s%s\" \"%s\"" % (TTLprefix, Arch, Mach, "Debian GNU/Linux"))
+   if 'architecture' in x[1]:
+      Arch = GetAttr(x, "architecture")
+      Mach = ""
+      if x[1].has_key("machine"):
+         Mach = " " + GetAttr(x, "machine")
+      DNSInfo.append("%sIN\tHINFO\t\"%s%s\" \"%s\"" % (TTLprefix, Arch, Mach, "Debian GNU/Linux"))
 
    if x[1].has_key("mXRecord"):
       for I in x[1]["mXRecord"]:
@@ -868,9 +895,7 @@ def GenZoneRecords(File):
       global HostAttrs
 
       for x in HostAttrs:
-         if x[1].has_key("hostname") == 0 or \
-            x[1].has_key("architecture") == 0 or\
-            x[1].has_key("sshRSAHostKey") == 0:
+         if x[1].has_key("hostname") == 0:
             continue
 
          if IsDebianHost.match(GetAttr(x, "hostname")) is None:
@@ -1180,6 +1205,9 @@ for host in HostAttrs:
    DoLink(GlobalDir, OutDir, "mail-rbl")
    DoLink(GlobalDir, OutDir, "mail-rhsbl")
    DoLink(GlobalDir, OutDir, "mail-whitelist")
+   GenCDB(OutDir + "user-forward.cdb", filter(lambda x: IsInGroup(x), PasswdAttrs), 'emailForward')
+   GenCDB(OutDir + "batv-tokens.cdb", filter(lambda x: IsInGroup(x), PasswdAttrs), 'bATVToken')
+   GenCDB(OutDir + "default-mail-options.cdb", filter(lambda x: IsInGroup(x), PasswdAttrs), 'mailDefaultOptions')
 
    # Compatibility.
    DoLink(GlobalDir, OutDir, "forward-alias")