X-Git-Url: https://git.adam-barratt.org.uk/?p=mirror%2Fuserdir-ldap.git;a=blobdiff_plain;f=ud-info;h=3db064800f8eb03d51f6642d81af4f3bb8690d00;hp=8fde99a39343a85b00ff285fcb217882a56b5337;hb=HEAD;hpb=a6fb69805c3999a85c064a96c93417bb1c284c5c diff --git a/ud-info b/ud-info index 8fde99a..3db0648 100755 --- a/ud-info +++ b/ud-info @@ -17,7 +17,30 @@ # -r Enable 'root' functions, do this if your uid has access to # restricted variables. -import time, os, pwd, sys, getopt, ldap, crypt, readline, copy; +# Copyright (c) 1999-2001 Jason Gunthorpe +# Copyright (c) 2004-2005,7,8 Joey Schulze +# Copyright (c) 2001-2006 Ryan Murray +# Copyright (c) 2008,2009 Peter Palfrader +# Copyright (c) 2008 Martin Zobel-Helas +# Copyright (c) 2008 Marc 'HE' Brockschmidt +# Copyright (c) 2008 Mark Hymers +# Copyright (c) 2008 Thomas Viehmann +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +import time, os, pwd, sys, getopt, ldap, crypt, readline, copy, getpass from userdir_ldap import *; RootMode = 0; @@ -45,7 +68,6 @@ AttrInfo = {"cn": ["First Name", 101], "icqUin": ["ICQ UIN",14], "jabberJID": ["Jabber ID",15], "privateSub": ["Debian-Private",16], - "gender": ["Gender",17], "birthDate": ["Date of Birth",18], "mailDisableMessage": ["Mail Disabled",19], "mailGreylisting": ["Mail Greylisting",20], @@ -53,9 +75,14 @@ AttrInfo = {"cn": ["First Name", 101], "mailRBL": ["Mail RBLs",22], "mailRHSBL": ["Mail RHSBLs",23], "mailWhitelist": ["Mail Whitelist",24], + "mailContentInspectionAction": ["mail C-I Action",25], + "VoIP": ["VoIP Address",26], "comment": ["Comment",116], "userPassword": ["Crypted Password",117], - "dnsZoneEntry": ["d.net Entry",118]}; + "dnsZoneEntry": ["d.net Entry",118], + "accountStatus": ["DD status",301], + "accountComment": ["DD status comment",302], + }; AttrPrompt = {"cn": ["Common name or first name"], "mn": ["Middle name (or initial if it ends in a dot)"], @@ -75,7 +102,6 @@ AttrPrompt = {"cn": ["Common name or first name"], "supplementaryGid": ["Groups the user is in"], "allowedHost": ["Grant access to certain hosts"], "privateSub": ["Debian-Private mailing list subscription"], - "gender": ["ISO5218 Gender code (1=male,2=female,9=unspecified)"], "birthDate": ["Date of Birth (YYYYMMDD)"], "mailDisableMessage": ["Error message to return via SMTP"], "mailGreylisting": ["SMTP Greylisting (TRUE/FALSE)"], @@ -83,13 +109,18 @@ AttrPrompt = {"cn": ["Common name or first name"], "mailRBL": ["SMTP time RBL lists"], "mailRHSBL": ["SMTP time RHSBL lists"], "mailWhitelist": ["SMTP time whitelist from other checks"], + "mailContentInspectionAction": ["Content Inspection Action (reject, blackhole, markup)"], "member": ["LDAP Group Member for slapd ACLs"], "latitude": ["XEarth latitude in ISO 6709 format - see /usr/share/zoneinfo/zone.tab or etak.com"], "longitude": ["XEarth latitude in ISO 6709 format - see /usr/share/zoneinfo/zone.tab or etak.com"], "dnsZoneEntry": ["DNS Zone fragment associated this this user"], "labeledURI": ["Web home page"], "jabberJID": ["Jabber ID"], - "icqUin": ["ICQ UIN Number"]}; + "icqUin": ["ICQ UIN Number"], + "VoIP": ["VoIP Address"], + "accountStatus": ["DD status"], + "accountComment": ["DD status comment"], + }; # Create a map of IDs to desc,value,attr OrderedIndex = {}; @@ -98,14 +129,18 @@ for at in AttrInfo.keys(): OrderedIndex[AttrInfo[at][1]] = [AttrInfo[at][0], "", at]; OrigOrderedIndex = copy.deepcopy(OrderedIndex); +for id in OrderedIndex: + if not AttrPrompt.has_key( OrderedIndex[id][2] ): + print "Warning: no AttrPrompt for %s"%(id) + # Show shadow information def PrintShadow(Attrs): Changed = int(GetAttr(Attrs,"shadowLastChange","0")); MinDays = int(GetAttr(Attrs,"shadowMin","0")); MaxDays = int(GetAttr(Attrs,"shadowMax","0")); WarnDays = int(GetAttr(Attrs,"shadowWarning","0")); - InactDays = int(GetAttr(Attrs,"shadowinactive","0")); - Expire = int(GetAttr(Attrs,"shadowexpire","0")); + InactDays = int(GetAttr(Attrs,"shadowInactive","0")); + Expire = int(GetAttr(Attrs,"shadowExpire","0")); print "%-24s:" % ("Password last changed"), print time.strftime("%a %d/%m/%Y %Z",time.localtime(Changed*24*60*60)); @@ -182,7 +217,7 @@ def ShowAttrs(Attrs): Keys.sort(); for at in Keys: if at < 100 or RootMode != 0: - print " %3u) %-18s: " % (at,OrderedIndex[at][0]), + print " %3u) %-19s: " % (at,OrderedIndex[at][0]), for x in OrderedIndex[at][1]: print "'%s'" % (re.sub('[\n\r]','?',x)), print; @@ -215,6 +250,16 @@ def ChangeAttr(Attrs,Attr): Attrs[1][Attr] = [""]; return; + if (Attr == "mailGreylisting" or Attr == "mailCallout"): + if (NewValue.lower() != "true" and NewValue.lower() != "false"): + if (NewValue == "1"): NewValue = "true" + else: + if (NewValue == "0"): NewValue = "false" + else: + print "Need a boolean value" + return + NewValue = NewValue.upper() + # Set a new value print "Setting.",; l.modify_s(UserDn,[(ldap.MOD_REPLACE,Attr,NewValue)]); @@ -257,6 +302,20 @@ def MultiChangeAttr(Attrs,Attr): Attrs[1][Attr].append(NewValue); print; +def Lock(UserDn, Attrs, DisableMail=True): + shadowLast = str(int(time.time()/24/60/60)); + recs = [ + (ldap.MOD_REPLACE,"userPassword","{crypt}*LK*"), + (ldap.MOD_REPLACE,"shadowLastChange",shadowLast), + (ldap.MOD_REPLACE,"shadowExpire","1")]; + if DisableMail: + recs.append( (ldap.MOD_REPLACE,"mailDisableMessage","account locked") ) + Attrs[0][1]["mailDisableMessage"] = ["account locked"]; + l.modify_s(UserDn,recs); + Attrs[0][1]["userPassword"] = ["{crypt}*LK*"]; + Attrs[0][1]["shadowLastChange"] = [shadowLast]; + Attrs[0][1]["shadowExpire"] = ["1"]; + # Main program starts here User = pwd.getpwuid(os.getuid())[0]; BindUser = User; @@ -287,17 +346,22 @@ if (BindUser != User): print "as '" + BindUser + "'"; else: print; -if (BindUser != ""): - Password = getpass(BindUser + "'s password: "); # Connect to the ldap server -l = ldap.open(LDAPServer); -UserDn = "uid=" + BindUser + "," + BaseDn; +l = connectLDAP() +UserDn = "uid=" + User + "," + BaseDn if (BindUser != ""): - l.simple_bind_s(UserDn,Password); + Password = getpass.getpass(BindUser + "'s password: ") + BindUserDn = "uid=" + BindUser + "," + BaseDn else: - l.simple_bind_s("",""); -UserDn = "uid=" + User + "," + BaseDn; + Password = "" + BindUserDn = "" +try: + l.simple_bind_s(BindUserDn,Password) +except ldap.LDAPError,e: + print >> sys.stderr, "LDAP error:", e.args[0]['desc'] + print >> sys.stderr, " ", e.args[0]['info'] + sys.exit(1) # Enable changing of supplementary gid's if (RootMode == 1): @@ -324,7 +388,9 @@ while(1): if RootMode == 1: print " a) Arbitary Change"; + print " r) retire developer"; print " R) Randomize Password"; + print " L) Lock account and disable mail"; print " p) Change Password"; print " u) Switch Users"; print " x) Exit"; @@ -356,8 +422,8 @@ while(1): print "contain spaces and other special characters. No checking is done on the"; print "strength of the passwords so pick good ones please!"; - Pass1 = getpass(User + "'s new password: "); - Pass2 = getpass(User + "'s new password again: "); + Pass1 = getpass.getpass(User + "'s new password: ") + Pass2 = getpass.getpass(User + "'s new password again: ") if Pass1 != Pass2: print "Passwords did not match"; raw_input("Press a key"); @@ -372,10 +438,60 @@ while(1): print "Setting password.."; Pass = "{crypt}" + Pass; - l.modify_s(UserDn,[(ldap.MOD_REPLACE,"userPassword",Pass)]); + shadowLast = str(int(time.time()/24/60/60)); + l.modify_s(UserDn,[(ldap.MOD_REPLACE,"userPassword",Pass), + (ldap.MOD_REPLACE,"shadowLastChange",shadowLast)]); Attrs[0][1]["userPassword"] = [Pass]; + Attrs[0][1]["shadowLastChange"] = [shadowLast]; + continue; + + # retire DD + if Response == 'r' and RootMode == 1: + if Attrs[0][1].has_key("accountStatus") == 0: + curStatus = "" + else: + curStatus = Attrs[0][1]["accountStatus"][0] + if Attrs[0][1].has_key("accountComment") == 0: + curComment = "" + else: + curComment = Attrs[0][1]["accountComment"][0] + print "\n\nCurrent status is %s"%curStatus + print "Current comment is %s\n"%curComment + + print "Set account to:" + print " 1) retiring (lock account but do not disable mail):" + print " 2) inactive (removed/emeritus/... - lock account and disable mail):" + print " 3) memorial (lock account and disable mail):" + print " 4) active (do not change other settings, you will have to deal with them)" + print " q) return (no change)" + Resp = raw_input("Action? ") + if Resp == "1" or Resp == "2": + Lock(UserDn, Attrs, Resp == "2") + if Resp == "1": + newstatus = "retiring %s"%(time.strftime("%Y-%m-%d")) + else: + newstatus = "inactive %s"%(time.strftime("%Y-%m-%d")) + l.modify_s(UserDn,[(ldap.MOD_REPLACE,"accountStatus",newstatus)]) + Attrs[0][1]["accountStatus"] = [newstatus] + + Resp2 = raw_input("Optional RT ticket number? ") + if (Resp2 != ''): + comment = "RT#%s"%(Resp2) + l.modify_s(UserDn,[(ldap.MOD_REPLACE,"accountComment",comment)]) + Attrs[0][1]["accountComment"] = [comment] + elif Resp == "3": + Lock(UserDn, Attrs) + newstatus = "memorial" + l.modify_s(UserDn,[(ldap.MOD_REPLACE,"accountStatus",newstatus)]) + Attrs[0][1]["accountStatus"] = [newstatus] + elif Resp == "4": + newstatus = "active" + l.modify_s(UserDn,[(ldap.MOD_REPLACE,"accountStatus",newstatus)]) + Attrs[0][1]["accountStatus"] = [newstatus] + continue; + # Randomize password if Response == 'R' and RootMode == 1: Resp = raw_input("Randomize Users Password? [no/yes]"); @@ -393,8 +509,21 @@ while(1): print "Setting password.."; Pass = "{crypt}" + Pass; - l.modify_s(UserDn,[(ldap.MOD_REPLACE,"userPassword",Pass)]); + shadowLast = str(int(time.time()/24/60/60)); + l.modify_s(UserDn,[(ldap.MOD_REPLACE,"userPassword",Pass), + (ldap.MOD_REPLACE,"shadowLastChange",shadowLast)]); Attrs[0][1]["userPassword"] = [Pass]; + Attrs[0][1]["shadowLastChange"] = [shadowLast]; + continue; + + # Lock account + if Response == 'L' and RootMode == 1: + Resp = raw_input("Really lock account? [no/yes]"); + if Resp != "yes": + continue; + + print "Setting password.."; + Lock(UserDn, Attrs) continue; # Handle changing an arbitary value