X-Git-Url: https://git.adam-barratt.org.uk/?p=mirror%2Fuserdir-ldap.git;a=blobdiff_plain;f=ud-host;h=e186e9a796d6f32560159d2be770d2f58854830f;hp=a2e870808b8c5c25cec9d15f9aa2563eb5534e0e;hb=a6fb69805c3999a85c064a96c93417bb1c284c5c;hpb=a2359d81607b9fdbcf0a91126258077dd189e2c9 diff --git a/ud-host b/ud-host index a2e8708..e186e9a 100755 --- a/ud-host +++ b/ud-host @@ -1,16 +1,40 @@ #!/usr/bin/env python # -*- mode: python -*- + +# Copyright (c) 2000-2001 Jason Gunthorpe +# Copyright (c) 2001 Ryan Murray +# Copyright (c) 2003 James Troup +# Copyright (c) 2004-2005 Joey Schulze +# +# 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. + # This script is an interactive way to manipulate fields in the LDAP directory. # When run it connects to the directory using the current users ID and fetches -# all the attributes for the first machine. It then formats them nicely and +# all the attributes for the first machine. It then formats them nicely and # allows the user to change them. # # Usage: userinfo -a -u -c -r -# -a Set the authentication user (the user whose password you are +# -a Set the authentication user (the user whose password you are # going to enter) # -h Set the host to display +# -l list all hosts and their status +# -f list all SSH fingerprints -import string, time, os, pwd, sys, getopt, ldap, crypt, whrandom, readline, copy; +import time, os, pwd, sys, getopt, ldap, crypt, readline, copy; +from tempfile import mktemp +from os import O_CREAT, O_EXCL, O_WRONLY from userdir_ldap import *; RootMode = 0; @@ -26,7 +50,10 @@ AttrInfo = {"description": ["Machine Descr.", 1], "machine": ["Machine Hardware", 10], "memory": ["Memory", 11], "disk": ["Disk", 12], - "bandwidth": ["Bandwidth", 13]}; + "physicalHost": ["Physical Host", 13], + "sshRSAHostKey": ["SSH Host Keys", 14], + "bandwidth": ["Bandwidth", 15], + "purpose": ["Purposes", 16],}; AttrPrompt = {"description": ["Purpose of the machine"], "hostname": ["The hostnames for the box (ipv4/ipv6)"], @@ -36,11 +63,14 @@ AttrPrompt = {"description": ["Purpose of the machine"], "distribution": ["The distribution version"], "access": ["all, developer only, restricted"], "admin": ["Admin email address"], - "architecture": ["Debian Arhitecture string"], + "architecture": ["Debian Architecture string"], "machine": ["Hardware description"], "memory": ["Installed RAM"], "disk": ["Disk Space, RAID levels, etc"], - "bandwidth": ["Available outbound"]}; + "physicalHost": ["The box hosting this virtual server"], + "sshRSAHostKey": ["A copy of /etc/ssh/ssh_*host_key.pub"], + "bandwidth": ["Available outbound"], + "purpose": ["The purposes of this host"],}; # Create a map of IDs to desc,value,attr OrderedIndex = {}; @@ -51,14 +81,14 @@ OrigOrderedIndex = copy.deepcopy(OrderedIndex); # Print out the automatic time stamp information def PrintModTime(Attrs): - Stamp = GetAttr(Attrs,"modifytimestamp",""); + Stamp = GetAttr(Attrs,"modifyTimestamp",""); if len(Stamp) >= 13: Time = (int(Stamp[0:4]),int(Stamp[4:6]),int(Stamp[6:8]), int(Stamp[8:10]),int(Stamp[10:12]),int(Stamp[12:14]),0,0,-1); print "%-24s:" % ("Record last modified on"), time.strftime("%a %d/%m/%Y %X UTC",Time), - print "by",ldap.explode_dn(GetAttr(Attrs,"modifiersname"),1)[0]; + print "by",ldap.explode_dn(GetAttr(Attrs,"modifiersName"),1)[0]; - Stamp = GetAttr(Attrs,"createtimestamp",""); + Stamp = GetAttr(Attrs,"createTimestamp",""); if len(Stamp) >= 13: Time = (int(Stamp[0:4]),int(Stamp[4:6]),int(Stamp[6:8]), int(Stamp[8:10]),int(Stamp[10:12]),int(Stamp[12:14]),0,0,-1); @@ -78,7 +108,7 @@ def ShowAttrs(Attrs): print; else: OrderedIndex[AttrInfo[at][1]][1] = Attrs[1][at]; - + Keys = OrderedIndex.keys(); Keys.sort(); for at in Keys: @@ -88,15 +118,27 @@ def ShowAttrs(Attrs): print "'%s'" % (re.sub('[\n\r]','?',x)), print; +def Overview(Attrs): + """Display a one-line overview for a given host""" + for i in ['host','architecture','distribution','access','status']: + if i not in Attrs[1].keys(): + Attrs[1][i] = [''] + print "%-12s %-10s %-38s %-25s %s" % (\ + Attrs[1]['host'][0], \ + Attrs[1]['architecture'][0], \ + Attrs[1]['distribution'][0], \ + Attrs[1]['access'][0], \ + Attrs[1]['status'][0]) + # Change a single attribute def ChangeAttr(Attrs,Attr): - if (Attr == "sponsor" or Attr == "hostname"): + if (Attr in ["sponsor", "sshRSAHostKey", "purpose"]): return MultiChangeAttr(Attrs,Attr); print "Old value: '%s'" % (GetAttr(Attrs,Attr,"")); print "Press enter to leave unchanged and a single space to set to empty"; NewValue = raw_input("New? "); - + # Empty string if (NewValue == ""): print "Leaving unchanged."; @@ -128,7 +170,7 @@ def MultiChangeAttr(Attrs,Attr): Attrs[1][Attr].sort(); print "Old values: ",Attrs[1][Attr]; - Mode = string.upper(raw_input("[D]elete or [A]dd? ")); + Mode = raw_input("[D]elete or [A]dd? ").upper() if (Mode != 'D' and Mode != 'A'): return; @@ -137,8 +179,8 @@ def MultiChangeAttr(Attrs,Attr): if (NewValue == ""): print "Leaving unchanged."; return; - - # Delete + + # Delete if (Mode == "D"): print "Deleting.",; try: @@ -156,11 +198,32 @@ def MultiChangeAttr(Attrs,Attr): Attrs[1][Attr].append(NewValue); print; +def CalcTempFile(): + unique = 0 + while unique == 0: + name = mktemp() + try: + fd = os.open(name, O_CREAT | O_EXCL | O_WRONLY, 0600) + except OSError: + continue + os.close(fd) + unique = 1 + return name + + # Main program starts here User = pwd.getpwuid(os.getuid())[0]; BindUser = User; +ListMode = 0 +FingerPrints = 0 +Host = None # Process options -(options, arguments) = getopt.getopt(sys.argv[1:], "nh:a:r") +try: + (options, arguments) = getopt.getopt(sys.argv[1:], "nh:a:rlf") +except getopt.GetoptError, data: + print data + sys.exit(1) + for (switch, val) in options: if (switch == '-h'): Host = val; @@ -170,33 +233,67 @@ for (switch, val) in options: RootMode = 1; elif (switch == '-n'): BindUser = ""; + elif (switch == '-l'): + BindUser = ""; + ListMode = 1 + elif (switch == '-f'): + BindUser = ""; + FingerPrints = 1 if (BindUser != ""): - print "Accessing LDAP entry", -if (BindUser != User): - if (BindUser != ""): - print "as '" + BindUser + "'"; + l = passwdAccessLDAP(LDAPServer, BaseDn, BindUser) else: - print; -if (BindUser != ""): - Password = getpass(BindUser + "'s password: "); + l = ldap.open(LDAPServer); + l.simple_bind_s("","") -# Connect to the ldap server -l = ldap.open(LDAPServer); -UserDn = "uid=" + BindUser + "," + BaseDn; -if (BindUser != ""): - l.simple_bind_s(UserDn,Password); -else: - l.simple_bind_s("",""); - -HBaseDn = "ou=hosts,dc=debian,dc=org"; -HostDn = "host=" + Host + "," + HBaseDn; +if ListMode == 1: + Attrs = l.search_s(HostBaseDn,ldap.SCOPE_ONELEVEL,"host=*") + hosts = [] + for hAttrs in Attrs: + hosts.append(hAttrs[1]['host'][0]) + hosts.sort() + + print "%-12s %-10s %-38s %-25s %s" % ("Host name","Arch","Distribution","Access","Status") + print "-"*115 + for host in hosts: + for hAttrs in Attrs: + if host == hAttrs[1]['host'][0]: + Overview(hAttrs) + sys.exit(0) +elif FingerPrints == 1: + if Host is not None: + Attrs = l.search_s(HostBaseDn,ldap.SCOPE_ONELEVEL,"host=" + Host) + else: + Attrs = l.search_s(HostBaseDn,ldap.SCOPE_ONELEVEL,"host=*") + hosts = [] + for hAttrs in Attrs: + hosts.append(hAttrs[1]['host'][0]) + hosts.sort() + + tmpfile = CalcTempFile() + for host in hosts: + for hAttrs in Attrs: + if host == hAttrs[1]['host'][0]: + if 'sshRSAHostKey' in hAttrs[1].keys(): + for key in hAttrs[1]['sshRSAHostKey']: + tmp = open(tmpfile, 'w') + tmp.write(key + '\n') + tmp.close() + fp = os.popen('/usr/bin/ssh-keygen -l -f ' + tmpfile, "r") + input = fp.readline() + fp.close() + fingerprint = input.split(' ') + print "%s %s root@%s" % (fingerprint[0], fingerprint[1], host) + os.unlink(tmpfile) + sys.exit(0) + +HostDn = "host=" + Host + "," + HostBaseDn; # Query the server for all of the attributes -Attrs = l.search_s(HBaseDn,ldap.SCOPE_ONELEVEL,"host=" + Host); +Attrs = l.search_s(HostBaseDn,ldap.SCOPE_ONELEVEL,"host=" + Host); if len(Attrs) == 0: print "Host",Host,"was not found."; - sys.exit(0); + sys.exit(0); # repeatedly show the account configuration while(1): @@ -207,12 +304,13 @@ while(1): if RootMode == 1: print " a) Arbitary Change"; print " n) New Host"; + print " d) Delete Host"; print " u) Switch Hosts"; print " x) Exit"; - + # Prompt Response = raw_input("Change? "); - if (Response == "x" or Response == "X" or Response == "q" or + if (Response == "x" or Response == "X" or Response == "q" or Response == "quit" or Response == "exit"): break; @@ -221,13 +319,13 @@ while(1): NewHost = raw_input("Host? "); if NewHost == "": continue; - NAttrs = l.search_s(HBaseDn,ldap.SCOPE_ONELEVEL,"host=" + NewHost); + NAttrs = l.search_s(HostBaseDn,ldap.SCOPE_ONELEVEL,"host=" + NewHost); if len(NAttrs) == 0: print "Host",NewHost,"was not found."; continue; Attrs = NAttrs; Host = NewHost; - HostDn = "host=" + Host + "," + HBaseDn; + HostDn = "host=" + Host + "," + HostBaseDn; OrderedIndex = copy.deepcopy(OrigOrderedIndex); continue; @@ -236,31 +334,43 @@ while(1): NewHost = raw_input("Host? "); if NewHost == "": continue; - NAttrs = l.search_s(HBaseDn,ldap.SCOPE_ONELEVEL,"host=" + NewHost); + NAttrs = l.search_s(HostBaseDn,ldap.SCOPE_ONELEVEL,"host=" + NewHost); if len(NAttrs) != 0: print "Host",NewHost,"already exists."; continue; - Dn = "host=" + NewHost + "," + HBaseDn; - l.add_s(Dn,[("host",NewHost), - ("objectclass","top")]); - - # Switch - NAttrs = l.search_s(HBaseDn,ldap.SCOPE_ONELEVEL,"host=" + NewHost); + NewHostName = raw_input("Hostname? "); + if NewHost == "": + continue; + Dn = "host=" + NewHost + "," + HostBaseDn; + l.add_s(Dn,[("host", NewHost), + ("hostname", NewHostName), + ("objectClass", ("top", "debianServer"))]); + + # Switch + NAttrs = l.search_s(HostBaseDn,ldap.SCOPE_ONELEVEL,"host=" + NewHost); if len(NAttrs) == 0: print "Host",NewHost,"was not found."; continue; Attrs = NAttrs; Host = NewHost; - HostDn = "host=" + Host + "," + HBaseDn; + HostDn = "host=" + Host + "," + HostBaseDn; OrderedIndex = copy.deepcopy(OrigOrderedIndex); continue; - + # Handle changing an arbitary value if (Response == "a"): Attr = raw_input("Attr? "); ChangeAttr(Attrs[0],Attr); continue; + if (Response == 'd'): + Really = raw_input("Really (type yes)? "); + if Really != 'yes': + continue; + print "Deleting",HostDn; + l.delete_s(HostDn); + continue; + # Convert the integer response try: ID = int(Response);