Let markers generation use Account class
[mirror/userdir-ldap.git] / ud-generate
index 358b375..b31418a 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 Peter Palfrader <peter@palfrader.org>
+#   Copyright (c) 2008,2009,2010 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>
@@ -31,6 +31,7 @@
 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 *
+import UDLdap
 try:
    from cStringIO import StringIO
 except ImportError:
@@ -39,6 +40,10 @@ except ImportError:
 global Allowed
 global CurrentHost
 
+if os.getuid() == 0:
+   sys.stderr.write("You should probably not run ud-generate as root.\n")
+   sys.exit(1)
+
 PasswdAttrs = None
 DebianUsers = None
 DisabledUsers = []
@@ -54,6 +59,7 @@ 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(ConfModule.dns_hostmatch)
+isSSHFP = re.compile("^\s*IN\s+SSHFP")
 DNSZone = ".debian.net"
 Keyrings = ConfModule.sync_keyrings.split(":")
 
@@ -575,10 +581,11 @@ def GenMarkers(File):
      
       # Write out the position for each user
       for x in PasswdAttrs:
-         if x[1].has_key("latitude") == 0 or x[1].has_key("longitude") == 0:
+         a = UDLdap.Account(x[0], x[1])
+         if not ('latitude' in a and 'longitude' in a):
             continue
          try:
-            Line = "%8s %8s \"\""%(DecDegree(GetAttr(x, "latitude"), 1), DecDegree(GetAttr(x, "longitude"), 1))
+            Line = "%8s %8s \"\""%(DecDegree(a['latitude'], 1), DecDegree(a['longitude'], 1))
             Line = Sanitize(Line) + "\n"
             F.write(Line)
          except:
@@ -778,29 +785,9 @@ def GenDNS(File):
    try:
       F = open(File + ".tmp", "w")
      
-#      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:
-#            continue
-#
-#         if IsDebianHost.match(GetAttr(x, "hostname")) is not None:
-#            continue
-#
-#         DNSInfo = ExtractDNSInfo(x)
-#         start = True
-#         for Line in DNSInfo:
-#            if start == True:
-#               Line = "%s.\t%s" % (GetAttr(x, "hostname"), Line)
-#               start = False
-#            else:
-#               Line = "\t\t\t%s" % (Line)
-#            F.write(Line + "\n")
-
       # Fetch all the users
       global PasswdAttrs
+      RRs = {}
      
       # Write out the zone file entry for each user
       for x in PasswdAttrs:
@@ -826,11 +813,13 @@ def GenDNS(File):
                      F.write("; Has BSMTP\n")
      
                   # Write some identification information
-                  if Split[2].lower() == "a":
-                     Line = "%s IN TXT \"%s\"\n"%(Split[0], EmailAddress(x))
-                     for y in x[1]["keyFingerPrint"]:
-                        Line = Line + "%s IN TXT \"PGP %s\"\n"%(Split[0], FormatPGPKey(y))
-                     F.write(Line)
+                  if not RRs.has_key(Host):
+                     if Split[2].lower() in ["a", "aaaa"]:
+                        Line = "%s IN TXT \"%s\"\n"%(Split[0], EmailAddress(x))
+                        for y in x[1]["keyFingerPrint"]:
+                           Line = Line + "%s IN TXT \"PGP %s\"\n"%(Split[0], FormatPGPKey(y))
+                           F.write(Line)
+                        RRs[Host] = 1
                else:
                   Line = "; Err %s"%(str(Split))
                   F.write(Line)
@@ -914,6 +903,29 @@ def GenZoneRecords(File):
 
             F.write(Line + "\n")
 
+        # this would write sshfp lines for services on machines
+        # but we can't yet, since some are cnames and we'll make
+        # an invalid zonefile
+        #
+        # for i in x[1].get("purpose", []):
+        #    m = PurposeHostField.match(i)
+        #    if m:
+        #       m = m.group(1)
+        #       # we ignore [[*..]] entries
+        #       if m.startswith('*'):
+        #          continue
+        #       if m.startswith('-'):
+        #          m = m[1:]
+        #       if m:
+        #          if not m.endswith(HostDomain):
+        #             continue
+        #          if not m.endswith('.'):
+        #             m = m + "."
+        #          for Line in DNSInfo:
+        #             if isSSHFP.match(Line):
+        #                Line = "%s\t%s" % (m, Line)
+        #                F.write(Line + "\n")
+
    # Oops, something unspeakable happened.
    except:
       Die(File, F, None)
@@ -1017,7 +1029,6 @@ def GenSSHKnown(File, mode=None):
                if 'sshdistAuthKeysHost' in x[1]:
                   hosts += x[1]['sshdistAuthKeysHost']
                Line = 'command="rsync --server --sender -pr . /var/cache/userdir-ldap/hosts/%s",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,from="%s" %s' % (Host, ",".join(hosts), I)
-               #Line = 'command="rsync --server --sender -pr . /var/cache/userdir-ldap/hosts/%s",no-port-forwarding,no-X11-forwarding,no-agent-forwarding %s' % (Host,I)
             else:
                Line = "%s %s" %(",".join(HostNames + HostToIP(x, False)), I)
             Line = Sanitize(Line) + "\n"
@@ -1067,9 +1078,14 @@ def GenKeyrings(OutDir):
 
 # Connect to the ldap server
 l = connectLDAP()
-F = open(PassDir + "/pass-" + pwd.getpwuid(os.getuid())[0], "r")
-Pass = F.readline().strip().split(" ")
-F.close()
+# for testing purposes it's sometimes useful to pass username/password
+# via the environment
+if 'UD_CREDENTIALS' in os.environ:
+   Pass = os.environ['UD_CREDENTIALS'].split()
+else:
+   F = open(PassDir + "/pass-" + pwd.getpwuid(os.getuid())[0], "r")
+   Pass = F.readline().strip().split(" ")
+   F.close()
 l.simple_bind_s("uid=" + Pass[0] + "," + BaseDn, Pass[1])
 
 # Fetch all the groups
@@ -1114,6 +1130,10 @@ if HostAttrs == None:
 
 HostAttrs.sort(lambda x, y: cmp((GetAttr(x, "hostname")).lower(), (GetAttr(y, "hostname")).lower()))
 
+# override globaldir for testing
+if 'UD_GENERATEDIR' in os.environ:
+   GenerateDir = os.environ['UD_GENERATEDIR']
+
 # Generate global things
 GlobalDir = GenerateDir + "/"
 GenDisabledAccounts(GlobalDir + "disabled-accounts")