Get rid of global variable PasswdAttrs
authorPeter Palfrader <peter@palfrader.org>
Mon, 2 Aug 2010 23:30:03 +0000 (23:30 +0000)
committerPeter Palfrader <peter@palfrader.org>
Mon, 2 Aug 2010 23:30:03 +0000 (23:30 +0000)
UDLdap.py
ud-generate

index dcf0bb4..2e45092 100644 (file)
--- a/UDLdap.py
+++ b/UDLdap.py
@@ -3,7 +3,9 @@ import time
 import userdir_ldap
 
 class Account:
 import userdir_ldap
 
 class Account:
-    array_values = ['objectClass', 'keyFingerPrint', 'mailWhitelist', 'mailRBL', 'mailRHSBL', 'supplementaryGid', 'sshRSAAuthKey', 'sudoPassword', 'dnsZoneEntry']
+    array_values = ['objectClass', 'keyFingerPrint', 'mailWhitelist', 'mailRBL',
+                    'mailRHSBL', 'supplementaryGid', 'sshRSAAuthKey',
+                    'sudoPassword', 'dnsZoneEntry', 'allowedHost']
     int_values = ['shadowExpire', 'gidNumber', 'uidNumber']
     defaults = {
                  'accountStatus': 'active',
     int_values = ['shadowExpire', 'gidNumber', 'uidNumber']
     defaults = {
                  'accountStatus': 'active',
@@ -94,6 +96,9 @@ class Account:
 
         return '(%s)'%(', '.join(status))
 
 
         return '(%s)'%(', '.join(status))
 
+    def delete_mailforward(self):
+        del self.attributes['emailForward']
+
     def get_dn(self):
         return self.dn
 
     def get_dn(self):
         return self.dn
 
index eed7698..850bb51 100755 (executable)
@@ -44,9 +44,7 @@ if os.getuid() == 0:
    sys.stderr.write("You should probably not run ud-generate as root.\n")
    sys.exit(1)
 
    sys.stderr.write("You should probably not run ud-generate as root.\n")
    sys.exit(1)
 
-PasswdAttrs = None
 DebianUsers = None
 DebianUsers = None
-DisabledUsers = []
 GroupIDMap = {}
 SubGroupMap = {}
 Allowed = None
 GroupIDMap = {}
 SubGroupMap = {}
 Allowed = None
@@ -91,19 +89,17 @@ def DoLink(From, To, File):
       pass
    posix.link(From + File, To + File)
 
       pass
    posix.link(From + File, To + File)
 
-def IsRetired(DnRecord):
+def IsRetired(account):
    """
    Looks for accountStatus in the LDAP record and tries to
    match it against one of the known retired statuses
    """
 
    """
    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
+   status = account['accountStatus']
 
    line = status.split()
    status = line[0]
 
    line = status.split()
    status = line[0]
-   
+
    if status == "inactive":
       return True
 
    if status == "inactive":
       return True
 
@@ -122,32 +118,25 @@ def IsRetired(DnRecord):
 
    return False
 
 
    return False
 
-def IsGidDebian(x):
-   try:
-      return int(GetAttr(x, "gidNumber", 0)) == 800
-   except ValueError:
-      return False
+#def IsGidDebian(account):
+#   return account['gidNumber'] == 800
 
 # See if this user is in the group list
 
 # See if this user is in the group list
-def IsInGroup(DnRecord):
+def IsInGroup(account):
   if Allowed is None:
      return True
 
   # See if the primary group is in the list
   if Allowed is None:
      return True
 
   # See if the primary group is in the list
-  if Allowed.has_key(GetAttr(DnRecord, "gidNumber")) != 0:
-     return True
+  if str(account['gidNumber']) in Allowed: return True
 
   # Check the host based ACL
 
   # Check the host based ACL
-  if DnRecord[1].has_key("allowedHost") != 0:
-     if CurrentHost in DnRecord[1]["allowedHost"]:
-        return True
+  if 'allowedHost' in account and CurrentHost in account['allowedHost']: return True
 
   # See if there are supplementary groups
 
   # See if there are supplementary groups
-  if DnRecord[1].has_key("supplementaryGid") == 0:
-     return False
+  if not 'supplementaryGid' in account: return False
 
   supgroups=[]
 
   supgroups=[]
-  addGroups(supgroups, DnRecord[1]["supplementaryGid"], GetAttr(DnRecord, "uid"))
+  addGroups(supgroups, account['supplementaryGid'], account['uid'])
   for g in supgroups:
      if Allowed.has_key(g):
         return True
   for g in supgroups:
      if Allowed.has_key(g):
         return True
@@ -176,19 +165,15 @@ def Done(File, F, Fdb):
       os.rename(File + ".tdb.tmp", File + ".tdb")
 
 # Generate the password list
       os.rename(File + ".tdb.tmp", File + ".tdb")
 
 # Generate the password list
-def GenPasswd(File, HomePrefix, PwdMarker):
+def GenPasswd(accounts, File, HomePrefix, PwdMarker):
    F = None
    try:
       F = open(File + ".tdb.tmp", "w")
    F = None
    try:
       F = open(File + ".tdb.tmp", "w")
-     
-      userlist = {}
-      # Fetch all the users
-      global PasswdAttrs
 
 
+      userlist = {}
       i = 0
       i = 0
-      for x in PasswdAttrs:
-         a = UDLdap.Account(x[0], x[1])
-         if not IsInGroup(x): continue
+      for a in accounts:
+         if not IsInGroup(a): continue
 
          # Do not let people try to buffer overflow some busted passwd parser.
          if len(a['gecos']) > 100 or len(a['loginShell']) > 50: continue
 
          # Do not let people try to buffer overflow some busted passwd parser.
          if len(a['gecos']) > 100 or len(a['loginShell']) > 50: continue
@@ -218,20 +203,17 @@ def GenPasswd(File, HomePrefix, PwdMarker):
    return userlist
 
 # Generate the shadow list
    return userlist
 
 # Generate the shadow list
-def GenShadow(File):
+def GenShadow(accounts, File):
    F = None
    try:
       OldMask = os.umask(0077)
       F = open(File + ".tdb.tmp", "w", 0600)
       os.umask(OldMask)
    F = None
    try:
       OldMask = os.umask(0077)
       F = open(File + ".tdb.tmp", "w", 0600)
       os.umask(OldMask)
-     
-      # Fetch all the users
-      global PasswdAttrs
-     
+
       i = 0
       i = 0
-      for x in PasswdAttrs:
-         a = UDLdap.Account(x[0], x[1])
-         if not IsInGroup(x): continue
+      for a in accounts:
+         Pass = '*'
+         if not IsInGroup(a): continue
 
          # If the account is locked, mark it as such in shadow
          # See Debian Bug #308229 for why we set it to 1 instead of 0
 
          # If the account is locked, mark it as such in shadow
          # See Debian Bug #308229 for why we set it to 1 instead of 0
@@ -259,20 +241,16 @@ def GenShadow(File):
    Done(File, None, F)
 
 # Generate the sudo passwd file
    Done(File, None, F)
 
 # Generate the sudo passwd file
-def GenShadowSudo(File, untrusted):
+def GenShadowSudo(accounts, File, untrusted):
    F = None
    try:
       OldMask = os.umask(0077)
       F = open(File + ".tmp", "w", 0600)
       os.umask(OldMask)
    F = None
    try:
       OldMask = os.umask(0077)
       F = open(File + ".tmp", "w", 0600)
       os.umask(OldMask)
-     
-      # Fetch all the users
-      global PasswdAttrs
-     
-      for x in PasswdAttrs:
-         a = UDLdap.Account(x[0], x[1])
+
+      for a in accounts:
          Pass = '*'
          Pass = '*'
-         if not IsInGroup(x): continue
+         if not IsInGroup(a): continue
      
          if 'sudoPassword' in a:
             for entry in a['sudoPassword']:
      
          if 'sudoPassword' in a:
             for entry in a['sudoPassword']:
@@ -310,17 +288,14 @@ def GenShadowSudo(File, untrusted):
    Done(File, F, None)
 
 # Generate the shadow list
    Done(File, F, None)
 
 # Generate the shadow list
-def GenSSHShadow():
+def GenSSHShadow(accounts):
    # Fetch all the users
    userfiles = []
 
    # Fetch all the users
    userfiles = []
 
-   global PasswdAttrs
-
    safe_rmtree(os.path.join(GlobalDir, 'userkeys'))
    safe_makedirs(os.path.join(GlobalDir, 'userkeys'))
 
    safe_rmtree(os.path.join(GlobalDir, 'userkeys'))
    safe_makedirs(os.path.join(GlobalDir, 'userkeys'))
 
-   for x in PasswdAttrs:
-      a = UDLdap.Account(x[0], x[1])
+   for a in accounts:
       if not 'sshRSAAuthKey' in a: continue
 
       F = None
       if not 'sshRSAAuthKey' in a: continue
 
       F = None
@@ -434,7 +409,7 @@ def addGroups(existingGroups, newGroups, uid):
          addGroups(existingGroups, SubGroupMap[group], uid)
 
 # Generate the group list
          addGroups(existingGroups, SubGroupMap[group], uid)
 
 # Generate the group list
-def GenGroup(File):
+def GenGroup(accounts, File):
    grouprevmap = {}
    F = None
    try:
    grouprevmap = {}
    F = None
    try:
@@ -445,15 +420,11 @@ def GenGroup(File):
       for x in GroupIDMap.keys():
          GroupMap[x] = []
       GroupHasPrimaryMembers = {}
       for x in GroupIDMap.keys():
          GroupMap[x] = []
       GroupHasPrimaryMembers = {}
-     
-      # Fetch all the users
-      global PasswdAttrs
-     
+
       # Sort them into a list of groups having a set of users
       # Sort them into a list of groups having a set of users
-      for x in PasswdAttrs:
-         a = UDLdap.Account(x[0], x[1])
+      for a in accounts:
          GroupHasPrimaryMembers[ a['gidNumber'] ] = True
          GroupHasPrimaryMembers[ a['gidNumber'] ] = True
-         if not IsInGroup(x): continue
+         if not IsInGroup(a): continue
          if not 'supplementaryGid' in a: continue
 
          supgroups=[]
          if not 'supplementaryGid' in a: continue
 
          supgroups=[]
@@ -491,51 +462,43 @@ def GenGroup(File):
   
    return grouprevmap
 
   
    return grouprevmap
 
-def CheckForward():
-   global PasswdAttrs
-   for x in PasswdAttrs:
-      if x[1].has_key("emailForward") == 0:
-         continue
-   
-      if not IsInGroup(x):
-         x[1].pop("emailForward")
-         continue
+def CheckForward(accounts):
+   for a in accounts:
+      if not 'emailForward' in a: continue
 
 
-      # Do not allow people to try to buffer overflow busted parsers
-      if len(GetAttr(x, "emailForward")) > 200:
-         x[1].pop("emailForward")
-         continue
 
 
+      delete = False
+
+      if not IsInGroup(a): delete = True
+      # Do not allow people to try to buffer overflow busted parsers
+      elif len(a['emailForward']) > 200: delete = True
       # Check the forwarding address
       # Check the forwarding address
-      if EmailCheck.match(GetAttr(x, "emailForward")) == None:
-         x[1].pop("emailForward")
+      elif EmailCheck.match(a['emailForward']) is None: delete = True
+
+      if delete:
+         a.delete_mailforward()
 
 # Generate the email forwarding list
 
 # Generate the email forwarding list
-def GenForward(File):
+def GenForward(accounts, File):
    F = None
    try:
       OldMask = os.umask(0022)
       F = open(File + ".tmp", "w", 0644)
       os.umask(OldMask)
    F = None
    try:
       OldMask = os.umask(0022)
       F = open(File + ".tmp", "w", 0644)
       os.umask(OldMask)
-     
-      # Fetch all the users
-      global PasswdAttrs
-     
-      # Write out the email address for each user
-      for x in PasswdAttrs:
-         a = UDLdap.Account(x[0], x[1])
+
+      for a in accounts:
          if not 'emailForward' in a: continue
          Line = "%s: %s" % (a['uid'], a['emailForward'])
          Line = Sanitize(Line) + "\n"
          F.write(Line)
          if not 'emailForward' in a: continue
          Line = "%s: %s" % (a['uid'], a['emailForward'])
          Line = Sanitize(Line) + "\n"
          F.write(Line)
-  
+
    # Oops, something unspeakable happened.
    except:
       Die(File, F, None)
       raise
    Done(File, F, None)
 
    # Oops, something unspeakable happened.
    except:
       Die(File, F, None)
       raise
    Done(File, F, None)
 
-def GenCDB(File, Users, key):
+def GenCDB(accounts, File, key):
    Fdb = None
    try:
       OldMask = os.umask(0022)
    Fdb = None
    try:
       OldMask = os.umask(0022)
@@ -543,8 +506,7 @@ def GenCDB(File, Users, key):
       os.umask(OldMask)
 
       # Write out the email address for each user
       os.umask(OldMask)
 
       # Write out the email address for each user
-      for x in Users:
-         a = UDLdap.Account(x[0], x[1])
+      for a in accounts:
          if not key in a: continue
          value = a[key]
          user = a['uid']
          if not key in a: continue
          value = a[key]
          user = a['uid']
@@ -559,17 +521,13 @@ def GenCDB(File, Users, key):
       raise "cdbmake gave an error"
 
 # Generate the anon XEarth marker file
       raise "cdbmake gave an error"
 
 # Generate the anon XEarth marker file
-def GenMarkers(File):
+def GenMarkers(accounts, File):
    F = None
    try:
       F = open(File + ".tmp", "w")
    F = None
    try:
       F = open(File + ".tmp", "w")
-     
-      # Fetch all the users
-      global PasswdAttrs
-     
+
       # Write out the position for each user
       # Write out the position for each user
-      for x in PasswdAttrs:
-         a = UDLdap.Account(x[0], x[1])
+      for a in accounts:
          if not ('latitude' in a and 'longitude' in a): continue
          try:
             Line = "%8s %8s \"\""%(a.latitude_dec(True), a.longitude_dec(True))
          if not ('latitude' in a and 'longitude' in a): continue
          try:
             Line = "%8s %8s \"\""%(a.latitude_dec(True), a.longitude_dec(True))
@@ -585,17 +543,13 @@ def GenMarkers(File):
    Done(File, F, None)
 
 # Generate the debian-private subscription list
    Done(File, F, None)
 
 # Generate the debian-private subscription list
-def GenPrivate(File):
+def GenPrivate(accounts, File):
    F = None
    try:
       F = open(File + ".tmp", "w")
    F = None
    try:
       F = open(File + ".tmp", "w")
-     
-      # Fetch all the users
-      global DebianDDUsers
-     
+
       # Write out the position for each user
       # Write out the position for each user
-      for x in DebianDDUsers:
-         a = UDLdap.Account(x[0], x[1])
+      for a in accounts:
          if not a.is_active_user(): continue
          if not 'privateSub' in a: continue
          try:
          if not a.is_active_user(): continue
          if not 'privateSub' in a: continue
          try:
@@ -612,21 +566,17 @@ def GenPrivate(File):
    Done(File, F, None)
 
 # Generate a list of locked accounts
    Done(File, F, None)
 
 # Generate a list of locked accounts
-def GenDisabledAccounts(File):
+def GenDisabledAccounts(accounts, File):
    F = None
    try:
       F = open(File + ".tmp", "w")
    F = None
    try:
       F = open(File + ".tmp", "w")
-     
+      disabled_accounts = []
+
       # Fetch all the users
       # Fetch all the users
-      global PasswdAttrs
-      global DisabledUsers
-     
-      I = 0
-      for x in PasswdAttrs:
-         a = UDLdap.Account(x[0], x[1])
+      for a in accounts:
          if a.pw_active(): continue
          Line = "%s:%s" % (a['uid'], "Account is locked")
          if a.pw_active(): continue
          Line = "%s:%s" % (a['uid'], "Account is locked")
-         DisabledUsers.append(x)
+         disabled_accounts.append(a)
          F.write(Sanitize(Line) + "\n")
 
    # Oops, something unspeakable happened.
          F.write(Sanitize(Line) + "\n")
 
    # Oops, something unspeakable happened.
@@ -634,23 +584,20 @@ def GenDisabledAccounts(File):
       Die(File, F, None)
       raise
    Done(File, F, None)
       Die(File, F, None)
       raise
    Done(File, F, None)
+   return disabled_accounts
 
 # Generate the list of local addresses that refuse all mail
 
 # Generate the list of local addresses that refuse all mail
-def GenMailDisable(File):
+def GenMailDisable(accounts, File):
    F = None
    try:
       F = open(File + ".tmp", "w")
    F = None
    try:
       F = open(File + ".tmp", "w")
-     
-      # Fetch all the users
-      global PasswdAttrs
-     
-      for x in PasswdAttrs:
-         a = UDLdap.Account(x[0], x[1])
+
+      for a in accounts:
          if not 'mailDisableMessage' in a: continue
          Line = "%s: %s"%(a['uid'], a['mailDisableMessage'])
          Line = Sanitize(Line) + "\n"
          F.write(Line)
          if not 'mailDisableMessage' in a: continue
          Line = "%s: %s"%(a['uid'], a['mailDisableMessage'])
          Line = Sanitize(Line) + "\n"
          F.write(Line)
-  
+
    # Oops, something unspeakable happened.
    except:
       Die(File, F, None)
    # Oops, something unspeakable happened.
    except:
       Die(File, F, None)
@@ -658,16 +605,12 @@ def GenMailDisable(File):
    Done(File, F, None)
 
 # Generate a list of uids that should have boolean affects applied
    Done(File, F, None)
 
 # Generate a list of uids that should have boolean affects applied
-def GenMailBool(File, key):
+def GenMailBool(accounts, File, key):
    F = None
    try:
       F = open(File + ".tmp", "w")
    F = None
    try:
       F = open(File + ".tmp", "w")
-     
-      # Fetch all the users
-      global PasswdAttrs
-     
-      for x in PasswdAttrs:
-         a = UDLdap.Account(x[0], x[1])
+
+      for a in accounts:
          if not key in a: continue
          if not a[key] == 'TRUE': continue
          Line = "%s"%(a['uid'])
          if not key in a: continue
          if not a[key] == 'TRUE': continue
          Line = "%s"%(a['uid'])
@@ -681,19 +624,15 @@ def GenMailBool(File, key):
    Done(File, F, None)
 
 # Generate a list of hosts for RBL or whitelist purposes.
    Done(File, F, None)
 
 # Generate a list of hosts for RBL or whitelist purposes.
-def GenMailList(File, key):
+def GenMailList(accounts, File, key):
    F = None
    try:
       F = open(File + ".tmp", "w")
    F = None
    try:
       F = open(File + ".tmp", "w")
-     
-      # Fetch all the users
-      global PasswdAttrs
-     
+
       if key == "mailWhitelist": validregex = re.compile('^[-\w.]+(/[\d]+)?$')
       else:                      validregex = re.compile('^[-\w.]+$')
 
       if key == "mailWhitelist": validregex = re.compile('^[-\w.]+(/[\d]+)?$')
       else:                      validregex = re.compile('^[-\w.]+$')
 
-      for x in PasswdAttrs:
-         a = UDLdap.Account(x[0], x[1])
+      for a in accounts:
          if not key in a: continue
 
          filtered = filter(lambda z: validregex.match(z), a[key])
          if not key in a: continue
 
          filtered = filter(lambda z: validregex.match(z), a[key])
@@ -713,18 +652,16 @@ def isRoleAccount(account):
    return 'debianRoleAccount' in account['objectClass']
 
 # Generate the DNS Zone file
    return 'debianRoleAccount' in account['objectClass']
 
 # Generate the DNS Zone file
-def GenDNS(File):
+def GenDNS(accounts, File):
    F = None
    try:
       F = open(File + ".tmp", "w")
    F = None
    try:
       F = open(File + ".tmp", "w")
-     
+
       # Fetch all the users
       # Fetch all the users
-      global PasswdAttrs
       RRs = {}
       RRs = {}
-     
+
       # Write out the zone file entry for each user
       # Write out the zone file entry for each user
-      for x in PasswdAttrs:
-         a = UDLdap.Account(x[0], x[1])
+      for a in accounts:
          if not 'dnsZoneEntry' in a: continue
          if not a.is_active_user() and not isRoleAccount(a): continue
 
          if not 'dnsZoneEntry' in a: continue
          if not a.is_active_user() and not isRoleAccount(a): continue
 
@@ -866,17 +803,13 @@ def GenZoneRecords(File):
    Done(File, F, None)
 
 # Generate the BSMTP file
    Done(File, F, None)
 
 # Generate the BSMTP file
-def GenBSMTP(File, HomePrefix):
+def GenBSMTP(accounts, File, HomePrefix):
    F = None
    try:
       F = open(File + ".tmp", "w")
      
    F = None
    try:
       F = open(File + ".tmp", "w")
      
-      # Fetch all the users
-      global PasswdAttrs
-
       # Write out the zone file entry for each user
       # Write out the zone file entry for each user
-      for x in PasswdAttrs:
-         a = UDLdap.Account(x[0], x[1])
+      for a in accounts:
          if not 'dnsZoneEntry' in a: continue
          if not a.is_active_user(): continue
 
          if not 'dnsZoneEntry' in a: continue
          if not a.is_active_user(): continue
 
@@ -1035,7 +968,7 @@ for x in Attrs:
       SubGroupMap.setdefault(x[1]["gid"][0], []).extend(x[1]["subGroup"])
 
 # Fetch all the users
       SubGroupMap.setdefault(x[1]["gid"][0], []).extend(x[1]["subGroup"])
 
 # Fetch all the users
-PasswdAttrs = l.search_s(BaseDn, ldap.SCOPE_ONELEVEL, "(&(uid=*)(!(uidNumber=0)))",\
+passwd_attrs = l.search_s(BaseDn, ldap.SCOPE_ONELEVEL, "(&(uid=*)(!(uidNumber=0)))",\
                 ["uid", "uidNumber", "gidNumber", "supplementaryGid",\
                  "gecos", "loginShell", "userPassword", "shadowLastChange",\
                  "shadowMin", "shadowMax", "shadowWarning", "shadowInactive",
                 ["uid", "uidNumber", "gidNumber", "supplementaryGid",\
                  "gecos", "loginShell", "userPassword", "shadowLastChange",\
                  "shadowMin", "shadowMax", "shadowWarning", "shadowInactive",
@@ -1046,10 +979,10 @@ PasswdAttrs = l.search_s(BaseDn, ldap.SCOPE_ONELEVEL, "(&(uid=*)(!(uidNumber=0))
                  "mailWhitelist", "sudoPassword", "objectClass", "accountStatus",\
                  "mailContentInspectionAction"])
 
                  "mailWhitelist", "sudoPassword", "objectClass", "accountStatus",\
                  "mailContentInspectionAction"])
 
-if PasswdAttrs is None:
+if passwd_attrs is None:
    raise UDEmptyList, "No Users"
    raise UDEmptyList, "No Users"
-
-PasswdAttrs.sort(lambda x, y: cmp((GetAttr(x, "uid")).lower(), (GetAttr(y, "uid")).lower()))
+accounts = map(lambda x: UDLdap.Account(x[0], x[1]), passwd_attrs)
+accounts.sort(lambda x,y: cmp(x['uid'].lower(), y['uid'].lower()))
 
 # Fetch all the hosts
 HostAttrs    = l.search_s(HostBaseDn, ldap.SCOPE_ONELEVEL, "objectClass=debianServer",\
 
 # Fetch all the hosts
 HostAttrs    = l.search_s(HostBaseDn, ldap.SCOPE_ONELEVEL, "objectClass=debianServer",\
@@ -1067,32 +1000,32 @@ if 'UD_GENERATEDIR' in os.environ:
 
 # Generate global things
 GlobalDir = GenerateDir + "/"
 
 # Generate global things
 GlobalDir = GenerateDir + "/"
-GenDisabledAccounts(GlobalDir + "disabled-accounts")
+accounts_disabled = GenDisabledAccounts(accounts, GlobalDir + "disabled-accounts")
 
 
-PasswdAttrs = filter(lambda x: not IsRetired(x), PasswdAttrs)
-DebianDDUsers = filter(lambda x: IsGidDebian(x), PasswdAttrs)
+accounts = filter(lambda x: not IsRetired(x), accounts)
+#accounts_DDs = filter(lambda x: IsGidDebian(x), accounts)
 
 
-CheckForward()
+CheckForward(accounts)
 
 
-GenMailDisable(GlobalDir + "mail-disable")
-GenCDB(GlobalDir + "mail-forward.cdb", PasswdAttrs, 'emailForward')
-GenCDB(GlobalDir + "mail-contentinspectionaction.cdb", PasswdAttrs, 'mailContentInspectionAction')
-GenPrivate(GlobalDir + "debian-private")
+GenMailDisable(accounts, GlobalDir + "mail-disable")
+GenCDB(accounts, GlobalDir + "mail-forward.cdb", 'emailForward')
+GenCDB(accounts, GlobalDir + "mail-contentinspectionaction.cdb", 'mailContentInspectionAction')
+GenPrivate(accounts, GlobalDir + "debian-private")
 GenSSHKnown(GlobalDir+"authorized_keys", 'authorized_keys')
 GenSSHKnown(GlobalDir+"authorized_keys", 'authorized_keys')
-GenMailBool(GlobalDir + "mail-greylist", "mailGreylisting")
-GenMailBool(GlobalDir + "mail-callout", "mailCallout")
-GenMailList(GlobalDir + "mail-rbl", "mailRBL")
-GenMailList(GlobalDir + "mail-rhsbl", "mailRHSBL")
-GenMailList(GlobalDir + "mail-whitelist", "mailWhitelist")
+GenMailBool(accounts, GlobalDir + "mail-greylist", "mailGreylisting")
+GenMailBool(accounts, GlobalDir + "mail-callout", "mailCallout")
+GenMailList(accounts, GlobalDir + "mail-rbl", "mailRBL")
+GenMailList(accounts, GlobalDir + "mail-rhsbl", "mailRHSBL")
+GenMailList(accounts, GlobalDir + "mail-whitelist", "mailWhitelist")
 GenKeyrings(GlobalDir)
 
 # Compatibility.
 GenKeyrings(GlobalDir)
 
 # Compatibility.
-GenForward(GlobalDir + "forward-alias")
+GenForward(accounts, GlobalDir + "forward-alias")
 
 
-PasswdAttrs = filter(lambda x: not x in DisabledUsers, PasswdAttrs)
+accounts = filter(lambda a: not a in accounts_disabled, accounts)
 
 
-SSHFiles = GenSSHShadow()
-GenMarkers(GlobalDir + "markers")
+SSHFiles = GenSSHShadow(accounts)
+GenMarkers(accounts, GlobalDir + "markers")
 GenSSHKnown(GlobalDir + "ssh_known_hosts")
 GenHosts(GlobalDir + "debianhosts")
 
 GenSSHKnown(GlobalDir + "ssh_known_hosts")
 GenHosts(GlobalDir + "debianhosts")
 
@@ -1133,19 +1066,19 @@ for host in HostAttrs:
 
    sys.stdout.flush()
    if 'NOPASSWD' in ExtraList:
 
    sys.stdout.flush()
    if 'NOPASSWD' in ExtraList:
-      userlist = GenPasswd(OutDir + "passwd", HomePrefix, "*")
+      userlist = GenPasswd(accounts, OutDir + "passwd", HomePrefix, "*")
    else:
    else:
-      userlist = GenPasswd(OutDir + "passwd", HomePrefix, "x")
+      userlist = GenPasswd(accounts, OutDir + "passwd", HomePrefix, "x")
    sys.stdout.flush()
    sys.stdout.flush()
-   grouprevmap = GenGroup(OutDir + "group")
-   GenShadowSudo(OutDir + "sudo-passwd", ('UNTRUSTED' in ExtraList) or ('NOPASSWD' in ExtraList))
+   grouprevmap = GenGroup(accounts, OutDir + "group")
+   GenShadowSudo(accounts, OutDir + "sudo-passwd", ('UNTRUSTED' in ExtraList) or ('NOPASSWD' in ExtraList))
 
    # Now we know who we're allowing on the machine, export
    # the relevant ssh keys
    GenSSHtarballs(userlist, SSHFiles, grouprevmap, os.path.join(OutDir, 'ssh-keys.tar.gz'))
 
    if not 'NOPASSWD' in ExtraList:
 
    # Now we know who we're allowing on the machine, export
    # the relevant ssh keys
    GenSSHtarballs(userlist, SSHFiles, grouprevmap, os.path.join(OutDir, 'ssh-keys.tar.gz'))
 
    if not 'NOPASSWD' in ExtraList:
-      GenShadow(OutDir + "shadow")
+      GenShadow(accounts, OutDir + "shadow")
 
    # Link in global things
    if not 'NOMARKERS' in ExtraList:
 
    # Link in global things
    if not 'NOMARKERS' in ExtraList:
@@ -1158,22 +1091,22 @@ for host in HostAttrs:
    DoLink(GlobalDir, OutDir, "mail-rbl")
    DoLink(GlobalDir, OutDir, "mail-rhsbl")
    DoLink(GlobalDir, OutDir, "mail-whitelist")
    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')
+   GenCDB(filter(lambda x: IsInGroup(x), accounts), OutDir + "user-forward.cdb", 'emailForward')
+   GenCDB(filter(lambda x: IsInGroup(x), accounts), OutDir + "batv-tokens.cdb", 'bATVToken')
+   GenCDB(filter(lambda x: IsInGroup(x), accounts), OutDir + "default-mail-options.cdb", 'mailDefaultOptions')
 
    # Compatibility.
    DoLink(GlobalDir, OutDir, "forward-alias")
 
    if 'DNS' in ExtraList:
 
    # Compatibility.
    DoLink(GlobalDir, OutDir, "forward-alias")
 
    if 'DNS' in ExtraList:
-      GenDNS(OutDir + "dns-zone")
+      GenDNS(accounts, OutDir + "dns-zone")
       GenZoneRecords(OutDir + "dns-sshfp")
 
    if 'AUTHKEYS' in ExtraList:
       DoLink(GlobalDir, OutDir, "authorized_keys")
 
    if 'BSMTP' in ExtraList:
       GenZoneRecords(OutDir + "dns-sshfp")
 
    if 'AUTHKEYS' in ExtraList:
       DoLink(GlobalDir, OutDir, "authorized_keys")
 
    if 'BSMTP' in ExtraList:
-      GenBSMTP(OutDir + "bsmtp", HomePrefix)
+      GenBSMTP(accounts, OutDir + "bsmtp", HomePrefix)
 
    if 'PRIVATE' in ExtraList:
       DoLink(GlobalDir, OutDir, "debian-private")
 
    if 'PRIVATE' in ExtraList:
       DoLink(GlobalDir, OutDir, "debian-private")