+ # Oops, something unspeakable happened.
+ except:
+ Die(File, F, None)
+ raise
+ Done(File, F, None)
+
+# Generate a list of uids that should have boolean affects applied
+def GenMailBool(File, Key):
+ F = None
+ try:
+ F = open(File + ".tmp", "w")
+
+ # Fetch all the users
+ global DebianUsers
+
+ for x in DebianUsers:
+ Reason = None
+
+ if x[1].has_key(Key) == 0:
+ continue
+
+ if GetAttr(x, Key) != "TRUE":
+ continue
+
+ try:
+ Line = "%s"%(GetAttr(x, "uid"))
+ Line = Sanitize(Line) + "\n"
+ F.write(Line)
+ except:
+ pass
+
+ # Oops, something unspeakable happened.
+ except:
+ Die(File, F, None)
+ raise
+ Done(File, F, None)
+
+# Generate a list of hosts for RBL or whitelist purposes.
+def GenMailList(File, Key):
+ F = None
+ try:
+ F = open(File + ".tmp", "w")
+
+ # Fetch all the users
+ global DebianUsers
+
+ for x in DebianUsers:
+ Reason = None
+
+ if x[1].has_key(Key) == 0:
+ continue
+
+ try:
+ found = 0
+ Line = None
+ for z in x[1][Key]:
+ if Key == "mailWhitelist":
+ if re.match('^[-\w.]+(/[\d]+)?$', z) == None:
+ continue
+ else:
+ if re.match('^[-\w.]+$', z) == None:
+ continue
+ if found == 0:
+ found = 1
+ Line = GetAttr(x, "uid")
+ else:
+ Line += " "
+ Line += ": " + z
+ if Key == "mailRHSBL":
+ Line += "/$sender_address_domain"
+
+ if Line != None:
+ Line = Sanitize(Line) + "\n"
+ F.write(Line)
+ except:
+ pass
+
+ # Oops, something unspeakable happened.
+ except:
+ Die(File, F, None)
+ raise
+ Done(File, F, None)
+
+def isRoleAccount(pwEntry):
+ if not pwEntry.has_key("objectClass"):
+ raise "pwEntry has no objectClass"
+ oc = pwEntry['objectClass']
+ try:
+ i = oc.index('debianRoleAccount')
+ return True
+ except ValueError:
+ return False
+
+# Generate the DNS Zone file
+def GenDNS(File):
+ F = None
+ try:
+ F = open(File + ".tmp", "w")
+
+ # Fetch all the users
+ global PasswdAttrs
+
+ # Write out the zone file entry for each user
+ for x in PasswdAttrs:
+ if x[1].has_key("dnsZoneEntry") == 0:
+ continue
+
+ # If the account has no PGP key, do not write it
+ if x[1].has_key("keyFingerPrint") == 0 and not isRoleAccount(x[1]):
+ continue
+ try:
+ F.write("; %s\n"%(EmailAddress(x)))
+ for z in x[1]["dnsZoneEntry"]:
+ Split = z.lower().split()
+ if Split[1].lower() == 'in':
+ for y in range(0, len(Split)):
+ if Split[y] == "$":
+ Split[y] = "\n\t"
+ Line = " ".join(Split) + "\n"
+ F.write(Line)
+
+ Host = Split[0] + DNSZone
+ if BSMTPCheck.match(Line) != None:
+ 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)
+ else:
+ Line = "; Err %s"%(str(Split))
+ F.write(Line)
+
+ F.write("\n")
+ except:
+ F.write("; Errors\n")
+ pass
+
+ # Oops, something unspeakable happened.
+ except:
+ Die(File, F, None)
+ raise
+ Done(File, F, None)
+
+# Generate the DNS SSHFP records
+def GenSSHFP(File):
+ F = None
+ try:
+ F = open(File + ".tmp", "w")
+
+ # Fetch all the hosts
+ global HostAttrs
+ if HostAttrs == None:
+ raise UDEmptyList, "No Hosts"
+
+ for x in HostAttrs:
+ if x[1].has_key("hostname") == 0 or \
+ x[1].has_key("sshRSAHostKey") == 0:
+ continue
+ Host = GetAttr(x, "hostname")
+ 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()
+ Line = "%s. IN SSHFP %u 1 %s" % (Host, Algorithm, Fingerprint)
+ Line = Sanitize(Line) + "\n"
+ F.write(Line)
+ # Oops, something unspeakable happened.
+ except:
+ Die(File, F, None)
+ raise
+ Done(File, F, None)
+
+# Generate the BSMTP file
+def GenBSMTP(File, HomePrefix):
+ F = None
+ try:
+ F = open(File + ".tmp", "w")
+
+ # Fetch all the users
+ global DebianUsers
+
+ # Write out the zone file entry for each user
+ for x in DebianUsers:
+ if x[1].has_key("dnsZoneEntry") == 0:
+ continue
+
+ # If the account has no PGP key, do not write it
+ if x[1].has_key("keyFingerPrint") == 0:
+ continue
+ try:
+ for z in x[1]["dnsZoneEntry"]:
+ Split = z.lower().split()
+ if Split[1].lower() == 'in':
+ for y in range(0, len(Split)):
+ if Split[y] == "$":
+ Split[y] = "\n\t"
+ Line = " ".join(Split) + "\n"
+
+ Host = Split[0] + DNSZone
+ if BSMTPCheck.match(Line) != None:
+ F.write("%s: user=%s group=Debian file=%s%s/bsmtp/%s\n"%(Host,
+ GetAttr(x, "uid"), HomePrefix, GetAttr(x, "uid"), Host))
+
+ except:
+ F.write("; Errors\n")
+ pass
+
+ # Oops, something unspeakable happened.
+ except:
+ Die(File, F, None)
+ raise
+ Done(File, F, None)
+
+# cache IP adresses
+HostToIPCache = {}
+def HostToIP(Host):
+ global HostToIPCache
+ if not Host in HostToIPCache:
+ IPAdressesT = None
+ try:
+ IPAdressesT = list(set([ (a[0], a[4][0]) for a in socket.getaddrinfo(Host, None)]))
+ except socket.gaierror, (code):
+ if code[0] != -2:
+ raise
+ IPAdresses = []
+ if not IPAdressesT is None:
+ for addr in IPAdressesT:
+ if addr[0] == socket.AF_INET:
+ IPAdresses += [addr[1], "::ffff:"+addr[1]]
+ else:
+ IPAdresses += [addr[1]]
+ HostToIPCache[Host] = IPAdresses
+ return HostToIPCache[Host]
+
+# Generate the ssh known hosts file
+def GenSSHKnown(File, mode=None):
+ F = None
+ try:
+ OldMask = os.umask(0022)
+ F = open(File + ".tmp", "w", 0644)
+ os.umask(OldMask)
+
+ global HostAttrs
+ if HostAttrs is None:
+ raise UDEmptyList, "No Hosts"
+
+ for x in HostAttrs:
+ if x[1].has_key("hostname") == 0 or \
+ x[1].has_key("sshRSAHostKey") == 0:
+ continue
+ Host = GetAttr(x, "hostname")
+ HostNames = [ Host ]
+ if Host.endswith(HostDomain):
+ HostNames.append(Host[:-(len(HostDomain) + 1)])
+
+ # in the purpose field [[host|some other text]] (where some other text is optional)
+ # makes a hyperlink on the web thing. we now also add these hosts to the ssh known_hosts
+ # file. But so that we don't have to add everything we link we can add an asterisk
+ # and say [[*... to ignore it. In order to be able to add stuff to ssh without
+ # http linking it we also support [[-hostname]] entries.
+ 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:
+ HostNames.append(m)
+ if m.endswith(HostDomain):
+ HostNames.append(m[:-(len(HostDomain) + 1)])
+
+ for I in x[1]["sshRSAHostKey"]:
+ if mode and mode == 'authorized_keys':
+ 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(HostToIP(Host)), 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(Host)), I)
+ Line = Sanitize(Line) + "\n"
+ F.write(Line)
+ # Oops, something unspeakable happened.
+ except:
+ Die(File, F, None)
+ raise
+ Done(File, F, None)
+
+# Generate the debianhosts file (list of all IP addresses)
+def GenHosts(l, File):
+ F = None
+ try:
+ OldMask = os.umask(0022)
+ F = open(File + ".tmp", "w", 0644)
+ os.umask(OldMask)
+
+ # Fetch all the hosts
+ hostnames = l.search_s(HostBaseDn, ldap.SCOPE_ONELEVEL, "hostname=*",
+ ["hostname"])
+
+ if hostnames is None:
+ raise UDEmptyList, "No Hosts"
+
+ seen = set()
+ for x in hostnames:
+ host = GetAttr(x, "hostname", None)
+ if host:
+ addrs = []
+ try:
+ addrs += socket.getaddrinfo(host, None, socket.AF_INET)
+ except socket.error:
+ pass
+ try:
+ addrs += socket.getaddrinfo(host, None, socket.AF_INET6)
+ except socket.error:
+ pass
+
+ for addrinfo in addrs:
+ if addrinfo[0] in (socket.AF_INET, socket.AF_INET6):
+ addr = addrinfo[4][0]
+ if addr not in seen:
+ print >> F, addrinfo[4][0]
+ seen.add(addr)
+ # Oops, something unspeakable happened.
+ except:
+ Die(File, F, None)
+ raise
+ Done(File, F, None)
+
+def GenKeyrings(OutDir):
+ for k in Keyrings:
+ shutil.copy(k, OutDir)
+