+ Die(File,F,None);
+ raise;
+ Done(File,F,None);
+
+def GenAllForward(l,File):
+ Fdb = None;
+ try:
+ OldMask = os.umask(0022);
+ Fdb = os.popen("cdbmake %s %s.tmp"%(File,File),"w");
+ os.umask(OldMask);
+
+ # Fetch all the users
+ global PasswdAttrs;
+ if PasswdAttrs == None:
+ raise "No Users";
+
+ # Write out the email address for each user
+ for x in PasswdAttrs:
+ if x[1].has_key("emailForward") == 0:
+ continue;
+
+ # Do not allow people to try to buffer overflow busted parsers
+ Forward = GetAttr(x,"emailForward");
+ if len(Forward) > 200:
+ continue;
+
+ # Check the forwarding address
+ if EmailCheck.match(Forward) == None:
+ continue;
+
+ User = GetAttr(x,"uid");
+ Fdb.write("+%d,%d:%s->%s\n"%(len(User),len(Forward),User,Forward));
+ Fdb.write("\n");
+ # Oops, something unspeakable happened.
+ except:
+ Fdb.close();
+ raise;
+ if Fdb.close() != None:
+ raise "cdbmake gave an error";
+
+# Generate the anon XEarth marker file
+def GenMarkers(l,File):
+ F = None;
+ try:
+ F = open(File + ".tmp","w");
+
+ # Fetch all the users
+ global PasswdAttrs;
+ if PasswdAttrs == None:
+ raise "No Users";
+
+ # 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:
+ continue;
+ try:
+ Line = "%8s %8s \"\""%(DecDegree(GetAttr(x,"latitude"),1),DecDegree(GetAttr(x,"longitude"),1));
+ Line = Sanitize(Line) + "\n";
+ F.write(Line);
+ except:
+ pass;
+
+ # Oops, something unspeakable happened.
+ except:
+ Die(File,F,None);
+ raise;
+ Done(File,F,None);
+
+# Generate the debian-private subscription list
+def GenPrivate(l,File):
+ F = None;
+ try:
+ F = open(File + ".tmp","w");
+
+ # Fetch all the users
+ global PasswdAttrs;
+ if PasswdAttrs == None:
+ raise "No Users";
+
+ # Write out the position for each user
+ for x in PasswdAttrs:
+ if x[1].has_key("privateSub") == 0:
+ continue;
+
+ # If the account is locked, do not write it
+ if (GetAttr(x,"userPassword").find("*LK*") != -1) \
+ or GetAttr(x,"userPassword").startswith("!"):
+ continue;
+
+ # If the account has no PGP key, do not write it
+ if x[1].has_key("keyFingerPrint") == 0:
+ continue;
+
+ # Must be in the Debian group (yuk, hard coded for now)
+ if GetAttr(x,"gidNumber") != "800":
+ continue;
+
+ try:
+ Line = "%s"%(GetAttr(x,"privateSub"));
+ 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 locked accounts
+def GenDisabledAccounts(l,File):
+ F = None;
+ try:
+ F = open(File + ".tmp","w");
+
+ # Fetch all the users
+ global PasswdAttrs;
+ if PasswdAttrs == None:
+ raise "No Users";
+
+ I = 0;
+ for x in PasswdAttrs:
+ if x[1].has_key("uidNumber") == 0:
+ continue;
+
+ Pass = GetAttr(x,"userPassword");
+ Line = ""
+ # *LK* is the reference value for a locked account
+ # password starting with ! is also a locked account
+ if Pass.find("*LK*") != -1 or Pass.startswith("!"):
+ # Format is <login>:<reason>
+ Line = "%s:%s" % (GetAttr(x,"uid"), "Account is locked")
+
+ if Line != "":
+ F.write(Sanitize(Line) + "\n")
+
+ # Oops, something unspeakable happened.
+ except:
+ Die(File,F,None);
+ raise;
+ Done(File,F,None);
+
+# Generate the list of local addresses that refuse all mail
+def GenMailDisable(l,File):
+ F = None;
+ try:
+ F = open(File + ".tmp","w");
+
+ # Fetch all the users
+ global PasswdAttrs;
+ if PasswdAttrs == None:
+ raise "No Users";
+
+ for x in PasswdAttrs:
+ Reason = None
+
+ # If the account is locked, disable incoming mail
+ if (GetAttr(x,"userPassword").find("*LK*") != -1):
+ if GetAttr(x,"uid") == "luther":
+ continue
+ else:
+ Reason = "user account locked"
+ else:
+ if x[1].has_key("mailDisableMessage"):
+ Reason = GetAttr(x,"mailDisableMessage")
+ else:
+ continue
+
+ # Must be in the Debian group (yuk, hard coded for now)
+ if GetAttr(x,"gidNumber") != "800":
+ continue;
+
+ try:
+ Line = "%s: %s"%(GetAttr(x,"uid"),Reason);
+ 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 uids that should have boolean affects applied
+def GenMailBool(l,File,Key):
+ F = None;
+ try:
+ F = open(File + ".tmp","w");
+
+ # Fetch all the users
+ global PasswdAttrs;
+ if PasswdAttrs == None:
+ raise "No Users";
+
+ for x in PasswdAttrs:
+ Reason = None
+
+ if x[1].has_key(Key) == 0:
+ continue
+
+ # Must be in the Debian group (yuk, hard coded for now)
+ if GetAttr(x,"gidNumber") != "800":
+ 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(l,File,Key):
+ F = None;
+ try:
+ F = open(File + ".tmp","w");
+
+ # Fetch all the users
+ global PasswdAttrs;
+ if PasswdAttrs == None:
+ raise "No Users";
+
+ for x in PasswdAttrs:
+ Reason = None
+
+ if x[1].has_key(Key) == 0:
+ continue
+
+ # Must be in the Debian group (yuk, hard coded for now)
+ if GetAttr(x,"gidNumber") != "800":
+ 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);
+
+# Generate the DNS Zone file
+def GenDNS(l,File,HomePrefix):
+ F = None;
+ try:
+ F = open(File + ".tmp","w");
+
+ # Fetch all the users
+ global PasswdAttrs;
+ if PasswdAttrs == None:
+ raise "No Users";
+
+ # 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:
+ 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(l,File,HomePrefix):
+ F = None
+ try:
+ F = open(File + ".tmp","w")
+
+ # Fetch all the hosts
+ global HostAttrs
+ if HostAttrs == None:
+ raise "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(l,File,HomePrefix):
+ F = None;
+ try:
+ F = open(File + ".tmp","w");
+
+ # Fetch all the users
+ global PasswdAttrs;
+ if PasswdAttrs == None:
+ raise "No Users";
+
+ # 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:
+ 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 = []
+ 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(l,File,mode=None):
+ F = None;
+ try:
+ OldMask = os.umask(0022);
+ F = open(File + ".tmp","w",0644);
+ os.umask(OldMask);
+
+ global HostAttrs
+ if HostAttrs == None:
+ raise "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 ]
+ SHost = Host.find(".")
+ if SHost != None: HostNames += [Host[0:SHost]]
+
+ 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(HNames + 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);