global CurrentHost
PasswdAttrs = None
+DebianUsers = None
DisabledUsers = []
GroupIDMap = {}
SubGroupMap = {}
UUID_FORMAT = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
EmailCheck = re.compile("^([^ <>@]+@[^ ,<>@]+)?$")
-BSMTPCheck = re.compile(".*mx 0 (gluck)\.debian\.org\..*",re.DOTALL)
-PurposeHostField = re.compile(r"\[\[([\*\-]?[a-z0-9.\-]*)(?:\|.*)?\]\]")
+BSMTPCheck = re.compile(".*mx 0 (master)\.debian\.org\..*",re.DOTALL)
+PurposeHostField = re.compile(r".*\[\[([\*\-]?[a-z0-9.\-]*)(?:\|.*)?\]\]")
DNSZone = ".debian.net"
Keyrings = ConfModule.sync_keyrings.split(":")
# 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
+ return (time.time() - time.mktime(time.strptime(line[1], "%Y-%m-%d"))) > age
except IndexError:
return False
+ except ValueError:
+ return False
return False
# See if this user is in the group list
def IsInGroup(DnRecord):
- if Allowed == None:
- return 1
+ if Allowed is None:
+ return True
# See if the primary group is in the list
if Allowed.has_key(GetAttr(DnRecord, "gidNumber")) != 0:
- return 1
+ return True
# Check the host based ACL
if DnRecord[1].has_key("allowedHost") != 0:
- for I in DnRecord[1]["allowedHost"]:
- if CurrentHost == I:
- return 1
+ if CurrentHost in DnRecord[1]["allowedHost"]:
+ return True
# See if there are supplementary groups
if DnRecord[1].has_key("supplementaryGid") == 0:
- return 0
+ return False
supgroups=[]
addGroups(supgroups, DnRecord[1]["supplementaryGid"], GetAttr(DnRecord, "uid"))
for g in supgroups:
if Allowed.has_key(g):
- return 1
- return 0
+ return True
+ return False
def Die(File, F, Fdb):
if F != None:
I = 0
for x in PasswdAttrs:
- if x[1].has_key("uidNumber") == 0 or IsInGroup(x) == 0:
+ if x[1].has_key("uidNumber") == 0 or not IsInGroup(x):
continue
# Do not let people try to buffer overflow some busted passwd parser.
I = 0
for x in PasswdAttrs:
- if x[1].has_key("uidNumber") == 0 or IsInGroup(x) == 0:
+ if x[1].has_key("uidNumber") == 0 or not IsInGroup(x):
continue
Pass = GetAttr(x, "userPassword")
for x in PasswdAttrs:
Pass = '*'
- if x[1].has_key("uidNumber") == 0 or IsInGroup(x) == 0:
+ if x[1].has_key("uidNumber") == 0 or not IsInGroup(x):
continue
if x[1].has_key('sudoPassword'):
continue
Pass = cryptedpass
if for_this_host: # this makes sure we take a per-host entry over the for-all entry
- break
+ break
if len(Pass) > 50:
Pass = '*'
# Oops, something unspeakable happened.
except IOError:
- Die(File, F, None)
- Die(masterFileName, masterFile, None)
- raise
+ Die(File, F, None)
+ Die(masterFileName, masterFile, None)
+ raise
return userfiles
# let's see if we handled this group already
if group in existingGroups:
- continue
+ continue
if not GroupIDMap.has_key(group):
print "Group", group, "does not exist but", uid, "is in it"
# Sort them into a list of groups having a set of users
for x in PasswdAttrs:
uid = GetAttr(x, "uid")
- if x[1].has_key("uidNumber") == 0 or IsInGroup(x) == 0:
+ if x[1].has_key("uidNumber") == 0 or not IsInGroup(x):
continue
if x[1].has_key("supplementaryGid") == 0:
continue
Line = "%s:x:%u:" % (x, GroupIDMap[x])
Comma = ''
for I in GroupMap[x]:
- Line = Line + ("%s%s" % (Comma, I))
- Comma = ','
+ Line = Line + ("%s%s" % (Comma, I))
+ Comma = ','
Line = Sanitize(Line) + "\n"
F.write("0%u %s" % (J, Line))
F.write(".%s %s" % (x, Line))
if x[1].has_key("emailForward") == 0:
continue
- if IsInGroup(x) == 0:
+ if not IsInGroup(x):
x[1].pop("emailForward")
continue
raise
Done(File, F, None)
-def GenAllForward(File):
+def GenCDB(File, Key):
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 DebianUsers
-
+
# Write out the email address for each user
for x in DebianUsers:
- if x[1].has_key("emailForward") == 0:
+ if not Key in x[1]:
continue
-
- # Do not allow people to try to buffer overflow busted parsers
- Forward = GetAttr(x, "emailForward")
-
+ Value = GetAttr(x, Key)
User = GetAttr(x, "uid")
- Fdb.write("+%d,%d:%s->%s\n" % (len(User), len(Forward), User, Forward))
-
+ Fdb.write("+%d,%d:%s->%s\n" % (len(User), len(Value), User, Value))
+
Fdb.write("\n")
# Oops, something unspeakable happened.
except:
if Pass.find("*LK*") != -1 or Pass.startswith("!"):
# Format is <login>:<reason>
Line = "%s:%s" % (GetAttr(x, "uid"), "Account is locked")
+ DisabledUsers.append(x)
if Line != "":
F.write(Sanitize(Line) + "\n")
- DisabledUsers.append(x)
# Oops, something unspeakable happened.
except:
Line = None
for z in x[1][Key]:
if Key == "mailWhitelist":
- if re.match('^[-\w.]+(/[\d]+)?$', z) == None:
- continue
+ if re.match('^[-\w.]+(/[\d]+)?$', z) == None:
+ continue
else:
- if re.match('^[-\w.]+$', z) == None:
- continue
+ if re.match('^[-\w.]+$', z) == None:
+ continue
if found == 0:
- found = 1
- Line = GetAttr(x, "uid")
+ found = 1
+ Line = GetAttr(x, "uid")
else:
Line += " "
Line += ": " + z
if Key == "mailRHSBL":
- Line += "/$sender_address_domain"
+ Line += "/$sender_address_domain"
if Line != None:
- Line = Sanitize(Line) + "\n"
- F.write(Line)
+ Line = Sanitize(Line) + "\n"
+ F.write(Line)
except:
pass
return False
# Generate the DNS Zone file
-def GenDNS(File, HomePrefix):
+def GenDNS(File):
F = None
try:
F = open(File + ".tmp", "w")
Host = Split[0] + DNSZone
if BSMTPCheck.match(Line) != None:
- F.write("; Has BSMTP\n")
+ F.write("; Has BSMTP\n")
# Write some identification information
if Split[2].lower() == "a":
Done(File, F, None)
# Generate the DNS SSHFP records
-def GenSSHFP(File, HomePrefix):
+def GenSSHFP(File):
F = None
try:
F = open(File + ".tmp", "w")
os.umask(OldMask)
global HostAttrs
- if HostAttrs == None:
+ if HostAttrs is None:
raise UDEmptyList, "No Hosts"
for x in HostAttrs:
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)
+ 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"
hostnames = l.search_s(HostBaseDn, ldap.SCOPE_ONELEVEL, "hostname=*",
["hostname"])
- if hostnames == None:
+ if hostnames is None:
raise UDEmptyList, "No Hosts"
seen = set()
seen.add(addr)
# Oops, something unspeakable happened.
except:
- Die(File, F, None)
- raise
+ Die(File, F, None)
+ raise
Done(File, F, None)
def GenKeyrings(OutDir):
for k in Keyrings:
shutil.copy(k, OutDir)
-
# Connect to the ldap server
l = connectLDAP()
F = open(PassDir + "/pass-" + pwd.getpwuid(os.getuid())[0], "r")
"allowedHost", "sshRSAAuthKey", "dnsZoneEntry", "cn", "sn",\
"keyFingerPrint", "privateSub", "mailDisableMessage",\
"mailGreylisting", "mailCallout", "mailRBL", "mailRHSBL",\
- "mailWhitelist", "sudoPassword", "objectClass", "accountStatus"])
+ "mailWhitelist", "sudoPassword", "objectClass", "accountStatus",\
+ "mailContentInspectionAction"])
if PasswdAttrs is None:
raise UDEmptyList, "No Users"
# Fetch all the hosts
-HostAttrs = l.search_s(HostBaseDn, ldap.SCOPE_ONELEVEL, "sshRSAHostKey=*",\
- ["hostname", "sshRSAHostKey", "purpose"])
-
-# Open the control file
-if len(sys.argv) == 1:
- F = open(GenerateConf, "r")
-else:
- F = open(sys.argv[1], "r")
+HostAttrs = l.search_s(HostBaseDn, ldap.SCOPE_ONELEVEL, "objectClass=debianServer",\
+ ["hostname", "sshRSAHostKey", "purpose", "allowedGroups", "exportOptions"])
# Generate global things
GlobalDir = GenerateDir + "/"
GenDisabledAccounts(GlobalDir + "disabled-accounts")
-PasswdAttrs = filter(not IsRetired, PasswdAttrs)
-DebianUsers = filter(IsGidDebian, PasswdAttrs)
+PasswdAttrs = filter(lambda x: not IsRetired(x), PasswdAttrs)
+#DebianUsers = filter(lambda x: IsGidDebian(x), PasswdAttrs)
+DebianUsers = PasswdAttrs
CheckForward()
GenMailDisable(GlobalDir + "mail-disable")
-GenAllForward(GlobalDir + "mail-forward.cdb")
+GenCDB(GlobalDir + "mail-forward.cdb", 'emailForward')
+GenCDB(GlobalDir + "mail-contentinspectionaction.cdb", 'mailContentInspectionAction')
GenPrivate(GlobalDir + "debian-private")
-#GenSSHKnown(l,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")
GenSSHKnown(GlobalDir + "ssh_known_hosts")
GenHosts(l, GlobalDir + "debianhosts")
-while(1):
- Line = F.readline()
- if Line == "":
- break
- Line = Line.strip()
- if Line == "":
- continue
- if Line[0] == '#':
+for host in HostAttrs:
+ if not "hostname" in host[1]:
continue
- Split = Line.split(" ")
- OutDir = GenerateDir + '/' + Split[0] + '/'
+ CurrentHost = host[1]['hostname'][0]
+ OutDir = GenerateDir + '/' + CurrentHost + '/'
try:
os.mkdir(OutDir)
except:
# Get the group list and convert any named groups to numerics
GroupList = {}
+ for groupname in AllowedGroupsPreload.strip().split(" "):
+ GroupList[groupname] = True
+ if 'allowedGroups' in host[1]:
+ for groupname in host[1]['allowedGroups']:
+ GroupList[groupname] = True
+ for groupname in GroupList.keys():
+ if groupname in GroupIDMap:
+ GroupList[str(GroupIDMap[groupname])] = True
+
ExtraList = {}
- for I in Split[2:]:
- if I[0] == '[':
- ExtraList[I] = None
- continue
- GroupList[I] = None
- if GroupIDMap.has_key(I):
- GroupList[str(GroupIDMap[I])] = None
+ if 'exportOptions' in host[1]:
+ for extra in host[1]['exportOptions']:
+ ExtraList[extra.upper()] = True
Allowed = GroupList
if Allowed == {}:
- Allowed = None
- CurrentHost = Split[0]
+ Allowed = None
DoLink(GlobalDir, OutDir, "debianhosts")
DoLink(GlobalDir, OutDir, "ssh_known_hosts")
DoLink(GlobalDir, OutDir, "disabled-accounts")
sys.stdout.flush()
- if ExtraList.has_key("[NOPASSWD]"):
- userlist = GenPasswd(OutDir + "passwd", Split[1], "*")
+ if 'NOPASSWD' in ExtraList:
+ userlist = GenPasswd(OutDir + "passwd", HomePrefix, "*")
else:
- userlist = GenPasswd(OutDir + "passwd", Split[1], "x")
+ userlist = GenPasswd(OutDir + "passwd", HomePrefix, "x")
sys.stdout.flush()
grouprevmap = GenGroup(OutDir + "group")
- GenShadowSudo(OutDir + "sudo-passwd", ExtraList.has_key("[UNTRUSTED]") or ExtraList.has_key("[NOPASSWD]"))
+ GenShadowSudo(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 ExtraList.has_key("[UNTRUSTED]"):
- print "[UNTRUSTED] tag is obsolete and may be removed in the future."
- continue
- if not ExtraList.has_key("[NOPASSWD]"):
+ if not 'NOPASSWD' in ExtraList:
GenShadow(OutDir + "shadow")
# Link in global things
- if not ExtraList.has_key("[NOMARKERS]"):
+ if not 'NOMARKERS' in ExtraList:
DoLink(GlobalDir, OutDir, "markers")
DoLink(GlobalDir, OutDir, "mail-forward.cdb")
+ DoLink(GlobalDir, OutDir, "mail-contentinspectionaction.cdb")
DoLink(GlobalDir, OutDir, "mail-disable")
DoLink(GlobalDir, OutDir, "mail-greylist")
DoLink(GlobalDir, OutDir, "mail-callout")
# Compatibility.
DoLink(GlobalDir, OutDir, "forward-alias")
- if ExtraList.has_key("[DNS]"):
- GenDNS(OutDir + "dns-zone", Split[1])
- GenSSHFP(OutDir + "dns-sshfp", Split[1])
+ if 'DNS' in ExtraList:
+ GenDNS(OutDir + "dns-zone")
+ GenSSHFP(OutDir + "dns-sshfp")
+
+ if 'AUTHKEYS' in ExtraList:
+ DoLink(GlobalDir, OutDir, "authorized_keys")
- if ExtraList.has_key("[BSMTP]"):
- GenBSMTP(OutDir + "bsmtp", Split[1])
+ if 'BSMTP' in ExtraList:
+ GenBSMTP(OutDir + "bsmtp", HomePrefix)
- if ExtraList.has_key("[PRIVATE]"):
+ if 'PRIVATE' in ExtraList:
DoLink(GlobalDir, OutDir, "debian-private")
- if ExtraList.has_key("[KEYRING]"):
+ if 'KEYRING' in ExtraList:
for k in Keyrings:
DoLink(GlobalDir, OutDir, os.path.basename(k))
else: