Moving away from string exceptions
[mirror/userdir-ldap.git] / ud-generate
index b00125c..8001012 100755 (executable)
 
 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 *
 
 global Allowed;
 global CurrentHost;
 
 PasswdAttrs = None;
+DisabledUsers = []
+RetiredUsers = []
 GroupIDMap = {};
 SubGroupMap = {};
 Allowed = None;
@@ -72,6 +75,36 @@ def DoLink(From,To,File):
    except: pass;
    posix.link(From+File,To+File);
 
+def IsRetired(DnRecord):
+   """
+   Looks for accountStatus in the LDAP record and tries to
+   match it against one of the known retired statuses
+   """
+
+   status = GetAttr(DnRecord,"accountStatus", None)
+   if status is None:
+      return False
+
+   line = status.split()
+   status = line[0]
+   
+   if status == "inactive":
+      return True
+
+   elif status == "memorial":
+      return True
+
+   elif status == "retiring":
+      # We'll give them a few extra days over what we said
+      age = 6 * 31 * 24 * 60 * 60
+      try:
+         if (time.time() - time.mktime(time.strptime(line[1], "%Y-%m-%d"))) > age:
+            return True
+      except IndexError:
+         return False
+
+   return False
+
 # See if this user is in the group list
 def IsInGroup(DnRecord):
   if Allowed == None:
@@ -125,8 +158,6 @@ def GenPasswd(l,File,HomePrefix,PwdMarker):
    userlist = {}
    # Fetch all the users
    global PasswdAttrs;
-   if PasswdAttrs == None:
-      raise "No Users";
 
    I = 0;
    for x in PasswdAttrs:
@@ -169,8 +200,6 @@ def GenShadow(l,File):
 
    # Fetch all the users
    global PasswdAttrs;
-   if PasswdAttrs == None:
-      raise "No Users";
 
    I = 0;
    for x in PasswdAttrs:
@@ -217,8 +246,6 @@ def GenShadowSudo(l,File, untrusted):
 
    # Fetch all the users
    global PasswdAttrs;
-   if PasswdAttrs == None:
-      raise "No Users";
 
    for x in PasswdAttrs:
       Pass = '*'
@@ -267,23 +294,19 @@ def GenSSHShadow(l):
    userfiles = []
 
    global PasswdAttrs;
-   if PasswdAttrs == None:
-      raise "No Users";
 
    safe_rmtree(os.path.join(GlobalDir, 'userkeys'))
    safe_makedirs(os.path.join(GlobalDir, 'userkeys'))
 
    for x in PasswdAttrs:
-      # If the account is locked, do not write it.
-      # This is a partial stop-gap. The ssh also needs to change this
-      # to ignore ~/.ssh/authorized* files.
-      if (GetAttr(x,"userPassword").find("*LK*") != -1) \
-             or GetAttr(x,"userPassword").startswith("!"):
-         continue;
+
+      if x in DisabledUsers:
+         continue
 
       if x[1].has_key("uidNumber") == 0 or \
          x[1].has_key("sshRSAAuthKey") == 0:
          continue;
+
       User = GetAttr(x,"uid");
       F = None;
 
@@ -395,8 +418,6 @@ def GenGroup(l,File):
 
    # Fetch all the users
    global PasswdAttrs;
-   if PasswdAttrs == None:
-      raise "No Users";
 
    # Sort them into a list of groups having a set of users
    for x in PasswdAttrs:
@@ -446,8 +467,6 @@ def GenForward(l,File):
 
    # Fetch all the users
    global PasswdAttrs;
-   if PasswdAttrs == None:
-      raise "No Users";
 
    # Write out the email address for each user
    for x in PasswdAttrs:
@@ -480,8 +499,6 @@ def GenAllForward(l,File):
 
    # Fetch all the users
    global PasswdAttrs;
-   if PasswdAttrs == None:
-      raise "No Users";
 
    # Write out the email address for each user
    for x in PasswdAttrs:
@@ -515,8 +532,6 @@ def GenMarkers(l,File):
 
    # Fetch all the users
    global PasswdAttrs;
-   if PasswdAttrs == None:
-      raise "No Users";
 
    # Write out the position for each user
    for x in PasswdAttrs:
@@ -543,19 +558,12 @@ def GenPrivate(l,File):
 
    # 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;
@@ -585,8 +593,7 @@ def GenDisabledAccounts(l,File):
 
    # Fetch all the users
    global PasswdAttrs;
-   if PasswdAttrs == None:
-      raise "No Users";
+   global DisabledUsers
 
    I = 0;
    for x in PasswdAttrs:
@@ -604,6 +611,8 @@ def GenDisabledAccounts(l,File):
       if Line != "":
          F.write(Sanitize(Line) + "\n")
 
+      DisabledUsers.append(x)
+
   # Oops, something unspeakable happened.
   except:
    Die(File,F,None);
@@ -618,8 +627,6 @@ def GenMailDisable(l,File):
 
    # Fetch all the users
    global PasswdAttrs;
-   if PasswdAttrs == None:
-      raise "No Users";
 
    for x in PasswdAttrs:
       Reason = None
@@ -654,8 +661,6 @@ def GenMailBool(l,File,Key):
 
    # Fetch all the users
    global PasswdAttrs;
-   if PasswdAttrs == None:
-      raise "No Users";
 
    for x in PasswdAttrs:
       Reason = None
@@ -691,8 +696,6 @@ def GenMailList(l,File,Key):
 
    # Fetch all the users
    global PasswdAttrs;
-   if PasswdAttrs == None:
-      raise "No Users";
 
    for x in PasswdAttrs:
       Reason = None
@@ -753,8 +756,6 @@ def GenDNS(l,File,HomePrefix):
 
    # 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:
@@ -809,7 +810,7 @@ def GenSSHFP(l,File,HomePrefix):
    # Fetch all the hosts
    global HostAttrs
    if HostAttrs == None:
-      raise "No Hosts"
+      raise UDEmptyList, "No Hosts"
 
    for x in HostAttrs:
       if x[1].has_key("hostname") == 0 or \
@@ -843,8 +844,6 @@ def GenBSMTP(l,File,HomePrefix):
 
    # 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:
@@ -889,9 +888,10 @@ def HostToIP(Host):
         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]]
+        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]
 
@@ -906,7 +906,7 @@ def GenSSHKnown(l,File,mode=None):
 
    global HostAttrs
    if HostAttrs == None:
-      raise "No Hosts";
+      raise UDEmptyList, "No Hosts"
 
    for x in HostAttrs:
       if x[1].has_key("hostname") == 0 or \
@@ -963,7 +963,7 @@ def GenHosts(l,File):
                            ["hostname"])
 
     if hostnames == None:
-       raise "No Hosts"
+       raise UDEmptyList, "No Hosts"
 
     seen = set()
     for x in hostnames:
@@ -1025,7 +1025,11 @@ PasswdAttrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"uid=*",\
                  "allowedHost","sshRSAAuthKey","dnsZoneEntry","cn","sn",\
                  "keyFingerPrint","privateSub","mailDisableMessage",\
                  "mailGreylisting","mailCallout","mailRBL","mailRHSBL",\
-                 "mailWhitelist", "sudoPassword", "objectClass"]);
+                 "mailWhitelist", "sudoPassword", "objectClass", "accountStatus"])
+
+if PasswdAttrs is None:
+   raise UDEmptyList, "No Users"
+
 # Fetch all the hosts
 HostAttrs    = l.search_s(HostBaseDn,ldap.SCOPE_ONELEVEL,"sshRSAHostKey=*",\
                 ["hostname","sshRSAHostKey","purpose"]);
@@ -1038,6 +1042,14 @@ else:
 
 # Generate global things
 GlobalDir = GenerateDir+"/";
+GenMailDisable(l,GlobalDir+"mail-disable")
+
+for x in PasswdAttrs:
+   if IsRetired(x):
+      RetiredUsers.append(x)
+
+PasswdAttrs = filter(lambda x: not x in RetiredUsers, PasswdAttrs)
+
 SSHFiles = GenSSHShadow(l);
 GenAllForward(l,GlobalDir+"mail-forward.cdb");
 GenMarkers(l,GlobalDir+"markers");
@@ -1046,7 +1058,6 @@ GenDisabledAccounts(l,GlobalDir+"disabled-accounts");
 GenSSHKnown(l,GlobalDir+"ssh_known_hosts");
 #GenSSHKnown(l,GlobalDir+"authorized_keys", 'authorized_keys');
 GenHosts(l,GlobalDir+"debianhosts");
-GenMailDisable(l,GlobalDir+"mail-disable");
 GenMailBool(l,GlobalDir+"mail-greylist","mailGreylisting");
 GenMailBool(l,GlobalDir+"mail-callout","mailCallout");
 GenMailList(l,GlobalDir+"mail-rbl","mailRBL");
@@ -1057,6 +1068,8 @@ GenKeyrings(l,GlobalDir);
 # Compatibility.
 GenForward(l,GlobalDir+"forward-alias");
 
+PasswdAttrs = filter(lambda x: not x in DisabledUsers, PasswdAttrs)
+
 while(1):
    Line = F.readline();
    if Line == "":