X-Git-Url: https://git.adam-barratt.org.uk/?a=blobdiff_plain;f=ud-generate;h=792383e870750ef58c8b244f366ce38e17c36c61;hb=2525bf73603cb6487cfcea096e2dc347ad360394;hp=d1773ff2337d1530132d26c80d2c201d5acba0f6;hpb=9faf24404f56567aba452ea8263d6194bc594002;p=mirror%2Fuserdir-ldap.git diff --git a/ud-generate b/ud-generate index d1773ff..792383e 100755 --- a/ud-generate +++ b/ud-generate @@ -2,18 +2,33 @@ # -*- mode: python -*- # Generates passwd, shadow and group files from the ldap directory. -import string, re, time, ldap, getopt, sys, os, posix, pwd; +import string, re, time, ldap, getopt, sys, os, pwd; from userdir_ldap import *; PasswdAttrs = None; GroupIDMap = {}; +Allowed = None; +CurrentHost = ""; + +def Sanitize(Str): + return string.translate(Str,string.maketrans("\n\r\t","$$$")); # See if this user is in the group list -def IsInGroup(DnRecord,Allowed): +def IsInGroup(DnRecord): + global Allowed,CurrentHost; + if Allowed == None: + return 1; + # See if the primary group is in the list if Allowed.has_key(GetAttr(DnRecord,"gidnumber")) != 0: return 1; + # Check the host based ACL + if DnRecord[1].has_key("allowedhosts") != 0: + for I in DnRecord[1]["allowedhosts"]: + if CurrentHost == I: + return 1; + # See if there are supplementary groups if DnRecord[1].has_key("supplementarygid") == 0: return 0; @@ -43,7 +58,7 @@ def Done(File,F,Fdb): os.rename(File + ".tdb.tmp",File+".tdb"); # Generate the password list -def GenPasswd(l,File,HomePrefix,Allowed): +def GenPasswd(l,File,HomePrefix): F = None; Fdb = None; try: @@ -57,9 +72,13 @@ def GenPasswd(l,File,HomePrefix,Allowed): I = 0; for x in PasswdAttrs: - if x[1].has_key("uidnumber") == 0 or IsInGroup(x,Allowed) == 0: + if x[1].has_key("uidnumber") == 0 or IsInGroup(x) == 0: continue; - + + # Do not let people try to buffer overflow some busted passwd parser. + if len(GetAttr(x,"gecos")) > 100 or len(GetAttr(x,"loginshell")) > 50: + continue; + Line = "%s:x:%s:%s:%s:%s%s:%s\n" % (GetAttr(x,"uid"),\ GetAttr(x,"uidnumber"),GetAttr(x,"gidnumber"),\ GetAttr(x,"gecos"),HomePrefix,GetAttr(x,"uid"),\ @@ -77,7 +96,7 @@ def GenPasswd(l,File,HomePrefix,Allowed): Done(File,F,Fdb); # Generate the shadow list -def GenShadow(l,File,Allowed): +def GenShadow(l,File): F = None; Fdb = None; try: @@ -93,19 +112,20 @@ def GenShadow(l,File,Allowed): I = 0; for x in PasswdAttrs: - if x[1].has_key("uidnumber") == 0 or IsInGroup(x,Allowed) == 0: + if x[1].has_key("uidnumber") == 0 or IsInGroup(x) == 0: continue; Pass = GetAttr(x,"userpassword"); - if Pass[0:7] != "{crypt}": + if Pass[0:7] != "{crypt}" or len(Pass) > 50: Pass = '*'; else: Pass = Pass[7:]; - Line = "%s:%s:%s:%s:%s:%s:%s:%s:\n" % (GetAttr(x,"uid"),\ + Line = "%s:%s:%s:%s:%s:%s:%s:%s:" % (GetAttr(x,"uid"),\ Pass,GetAttr(x,"shadowlastchange"),\ GetAttr(x,"shadowmin"),GetAttr(x,"shadowmax"),\ GetAttr(x,"shadowwarning"),GetAttr(x,"shadowinactive"),\ GetAttr(x,"shadowexpire")); + Line = Sanitize(Line) + "\n"; F.write(Line); Fdb.write("0%u %s" % (I,Line)); Fdb.write(".%s %s" % (GetAttr(x,"uid"),Line)); @@ -117,8 +137,39 @@ def GenShadow(l,File,Allowed): raise; Done(File,F,Fdb); +# Generate the shadow list +def GenSSHShadow(l,File): + F = None; + Fdb = None; + try: + OldMask = os.umask(0077); + F = open(File + ".tmp","w",0600); + Fdb = None; + os.umask(OldMask); + + # 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 or IsInGroup(x) == 0 or \ + x[1].has_key("sshrsaauthkey") == 0: + continue; + for I in x[1]["sshrsaauthkey"]: + Line = "%s: %s" %(GetAttr(x,"uid"),I); + Line = Sanitize(Line) + "\n"; + F.write(Line); + + # Oops, something unspeakable happened. + except: + Die(F,Fdb); + raise; + Done(File,F,Fdb); + # Generate the group list -def GenGroup(l,File,Allowed): +def GenGroup(l,File): F = None; Fdb = None; try: @@ -137,7 +188,7 @@ def GenGroup(l,File,Allowed): # Sort them into a list of groups having a set of users for x in PasswdAttrs: - if x[1].has_key("uidnumber") == 0 or IsInGroup(x,Allowed) == 0: + if x[1].has_key("uidnumber") == 0 or IsInGroup(x) == 0: continue; if x[1].has_key("supplementarygid") == 0: continue; @@ -151,12 +202,14 @@ def GenGroup(l,File,Allowed): # Output the group file. Counter = 0; for x in GroupMap.keys(): + if GroupIDMap.has_key(x) == 0: + continue; Line = "%s:x:%u:" % (x,GroupIDMap[x]); Comma = ''; for I in GroupMap[x]: Line = Line + ("%s%s" % (Comma,I)); Comma = ','; - Line = Line + '\n'; + Line = Sanitize(Line) + "\n"; F.write(Line); Fdb.write("0%u %s" % (Counter,Line)); Fdb.write(".%s %s" % (x,Line)); @@ -170,7 +223,7 @@ def GenGroup(l,File,Allowed): Done(File,F,Fdb); # Generate the email forwarding list -def GenForward(l,File,Allowed): +def GenForward(l,File): F = None; Fdb = None; try: @@ -186,9 +239,15 @@ def GenForward(l,File,Allowed): # Write out the email address for each user for x in PasswdAttrs: - if x[1].has_key("emailforward") == 0 or IsInGroup(x,Allowed) == 0: + if x[1].has_key("emailforward") == 0 or IsInGroup(x) == 0: + continue; + + # Do not allow people to try to buffer overflow busted parsers + if len(GetAttr(x,"emailforward")) > 200: continue; - Line = "%s: %s\n" % (GetAttr(x,"uid"),GetAttr(x,"emailforward")); + + Line = "%s: %s" % (GetAttr(x,"uid"),GetAttr(x,"emailforward")); + Line = Sanitize(Line) + "\n"; F.write(Line); # Oops, something unspeakable happened. @@ -210,12 +269,14 @@ def GenMarkers(l,File): if PasswdAttrs == None: raise "No Users"; - # Write out the email address for each user + # 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: - F.write("%8s %8s \"\"\n"%(DecDegree(x,"latitude",1),DecDegree(x,"longitude",1))); + Line = "%8s %8s \"\""%(DecDegree(GetAttr(x,"latitude"),1),DecDegree(GetAttr(x,"longitude"),1)); + Line = Sanitize(Line) + "\n"; + F.write(Line); except: pass; @@ -225,9 +286,57 @@ def GenMarkers(l,File): raise; Done(File,F,Fdb); +# Generate the DNS Zone file +def GenDNS(l,File): + F = None; + Fdb = None; + try: + F = open(File + ".tmp","w"); + Fdb = 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: + if x[1].has_key("dnszoneentry") == 0: + continue; + try: + F.write("; %s\n"%(EmailAddress(x))); + for z in x[1]["dnszoneentry"]: + Split = string.split(string.lower(z)); + if string.lower(Split[1]) == 'in': + for y in range(0,len(Split)): + if Split[y] == "$": + Split[y] = "\n\t"; + Line = string.join(Split," ") + "\n"; + F.write(Line); + + # Write some identication information + if string.lower(Split[2]) != "cname": + 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: + pass; + + # Oops, something unspeakable happened. + except: + Die(F,Fdb); + raise; + Done(File,F,Fdb); + # Connect to the ldap server l = ldap.open(LDAPServer); -F = open(PassDir+"/pass-"+pwd.getpwuid(posix.getuid())[0],"r"); +F = open(PassDir+"/pass-"+pwd.getpwuid(os.getuid())[0],"r"); Pass = string.split(string.strip(F.readline())," "); F.close(); l.simple_bind_s("uid="+Pass[0]+","+BaseDn,Pass[1]); @@ -248,7 +357,9 @@ PasswdAttrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"uid=*",\ ["uid","uidnumber","gidnumber","supplementarygid",\ "gecos","loginshell","userpassword","shadowlastchange",\ "shadowmin","shadowmax","shadowwarning","shadowinactive", - "shadowexpire","emailforward","latitude","longitude"]); + "shadowexpire","emailforward","latitude","longitude",\ + "allowedhosts","sshrsaauthkey","dnszoneentry","cn","sn",\ + "keyfingerprint"]); # Open the control file if len(sys.argv) == 1: @@ -272,14 +383,26 @@ while(1): # Get the group list and convert any named groups to numerics GroupList = {}; + 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; - GenPasswd(l,OutDir+"passwd",Split[1],GroupList); - GenGroup(l,OutDir+"group",GroupList); - GenShadow(l,OutDir+"shadow",GroupList); - GenForward(l,OutDir+"forward-alias",GroupList); + global Allowed,CurrentHost; + Allowed = GroupList; + CurrentHost = Split[0]; + + GenPasswd(l,OutDir+"passwd",Split[1]); + GenGroup(l,OutDir+"group"); + GenShadow(l,OutDir+"shadow"); + GenSSHShadow(l,OutDir+"ssh-rsa-shadow"); + GenForward(l,OutDir+"forward-alias"); GenMarkers(l,OutDir+"markers"); + if ExtraList.has_key("[DNS]"): + GenDNS(l,OutDir+"dns-zone"); +