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;
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:
if DnRecord[1].has_key("supplementaryGid") == 0:
return 0;
- # Check the supplementary groups
- for I in DnRecord[1]["supplementaryGid"]:
- s = I.split('@', 1)
- group = s[0]
- if len(s) == 2 and s[1] != CurrentHost:
- continue;
- if Allowed.has_key(group):
+ supgroups=[]
+ addGroups(supgroups, DnRecord[1]["supplementaryGid"], GetAttr(DnRecord,"uid"))
+ for g in supgroups:
+ if Allowed.has_key(g):
return 1;
return 0;
userlist = {}
# Fetch all the users
global PasswdAttrs;
- if PasswdAttrs == None:
- raise "No Users";
I = 0;
for x in PasswdAttrs:
# Fetch all the users
global PasswdAttrs;
- if PasswdAttrs == None:
- raise "No Users";
I = 0;
for x in PasswdAttrs:
# Fetch all the users
global PasswdAttrs;
- if PasswdAttrs == None:
- raise "No Users";
for x in PasswdAttrs:
Pass = '*'
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;
continue
if not GroupIDMap.has_key(group):
- print "Group does not exist ",group,"but",uid,"is in it"
+ print "Group", group, "does not exist but", uid, "is in it"
continue
existingGroups.append(group)
if SubGroupMap.has_key(group):
- addGroups(existingGroups, SubGroupMap[group])
+ addGroups(existingGroups, SubGroupMap[group], uid)
# Generate the group list
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:
# Fetch all the users
global PasswdAttrs;
- if PasswdAttrs == None:
- raise "No Users";
# Write out the email address for each user
for x in PasswdAttrs:
# Fetch all the users
global PasswdAttrs;
- if PasswdAttrs == None:
- raise "No Users";
# Write out the email address for each user
for x in PasswdAttrs:
# Fetch all the users
global PasswdAttrs;
- if PasswdAttrs == None:
- raise "No Users";
# Write out the position for each user
for x in PasswdAttrs:
# 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;
# Fetch all the users
global PasswdAttrs;
- if PasswdAttrs == None:
- raise "No Users";
+ global DisabledUsers
I = 0;
for x in PasswdAttrs:
if Line != "":
F.write(Sanitize(Line) + "\n")
+ DisabledUsers.append(x)
+
# Oops, something unspeakable happened.
except:
Die(File,F,None);
# Fetch all the users
global PasswdAttrs;
- if PasswdAttrs == None:
- raise "No Users";
for x in PasswdAttrs:
Reason = None
# Fetch all the users
global PasswdAttrs;
- if PasswdAttrs == None:
- raise "No Users";
for x in PasswdAttrs:
Reason = None
# Fetch all the users
global PasswdAttrs;
- if PasswdAttrs == None:
- raise "No Users";
for x in PasswdAttrs:
Reason = 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(l,File,HomePrefix):
F = None;
# 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:
continue;
# If the account has no PGP key, do not write it
- if x[1].has_key("keyFingerPrint") == 0:
+ if x[1].has_key("keyFingerPrint") == 0 and not isRoleAccount(x[1]):
continue;
try:
F.write("; %s\n"%(EmailAddress(x)));
# 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 \
# 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:
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]
global HostAttrs
if HostAttrs == None:
- raise "No Hosts";
+ raise UDEmptyList, "No Hosts"
for x in HostAttrs:
if x[1].has_key("hostname") == 0 or \
# Generate the debianhosts file (list of all IP addresses)
def GenHosts(l,File):
- F = None;
+ 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 == None:
- raise "No Hosts";
-
- for x in HostNames:
- if x[1].has_key("hostname") == 0:
- continue;
- Host = GetAttr(x,"hostname");
- try:
- Addr = socket.gethostbyname(Host);
- F.write(Addr + "\n");
- except:
- pass
+ 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 == 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);
+ Die(File,F,None)
+ raise
+ Done(File,F,None)
def GenKeyrings(l,OutDir):
for k in Keyrings:
"allowedHost","sshRSAAuthKey","dnsZoneEntry","cn","sn",\
"keyFingerPrint","privateSub","mailDisableMessage",\
"mailGreylisting","mailCallout","mailRBL","mailRHSBL",\
- "mailWhitelist", "sudoPassword"]);
+ "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"]);
# 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");
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");
# Compatibility.
GenForward(l,GlobalDir+"forward-alias");
+PasswdAttrs = filter(lambda x: not x in DisabledUsers, PasswdAttrs)
+
while(1):
Line = F.readline();
if Line == "":