3 # This script is an interactive way to manipulate fields in the LDAP directory.
4 # When run it connects to the directory using the current users ID and fetches
5 # all the attributes for the first machine. It then formats them nicely and
6 # allows the user to change them.
8 # Usage: userinfo -a <user> -u <user> -c <user> -r
9 # -a Set the authentication user (the user whose password you are
11 # -h Set the host to display
13 import string, time, os, pwd, sys, getopt, ldap, crypt, whrandom, readline, copy;
14 from userdir_ldap import *;
17 AttrInfo = {"description": ["Machine Descr.", 1],
18 "hostname": ["Host names", 2],
19 "status": ["Status", 3],
21 "sponsor": ["Sponsors", 5],
22 "distribution": ["Distribution", 6],
23 "access": ["Access", 7],
24 "admin": ["Admin", 8],
25 "architecture": ["Architecture", 9],
26 "machine": ["Machine Hardware", 10],
27 "memory": ["Memory", 11],
29 "sshRSAHostKey": ["SSH Host Keys", 14],
30 "bandwidth": ["Bandwidth", 15]};
32 AttrPrompt = {"description": ["Purpose of the machine"],
33 "hostname": ["The hostnames for the box (ipv4/ipv6)"],
34 "status": ["Blank if Up, explaination if not"],
35 "l": ["Physical location"],
36 "sponsor": ["Sponsors and their URLs"],
37 "distribution": ["The distribution version"],
38 "access": ["all, developer only, restricted"],
39 "admin": ["Admin email address"],
40 "architecture": ["Debian Architecture string"],
41 "machine": ["Hardware description"],
42 "memory": ["Installed RAM"],
43 "disk": ["Disk Space, RAID levels, etc"],
44 "sshRSAHostKey": ["A copy of /etc/ssh/ssh_*host_key.pub"],
45 "bandwidth": ["Available outbound"]};
47 # Create a map of IDs to desc,value,attr
49 for at in AttrInfo.keys():
50 if (AttrInfo[at][1] != 0):
51 OrderedIndex[AttrInfo[at][1]] = [AttrInfo[at][0], "", at];
52 OrigOrderedIndex = copy.deepcopy(OrderedIndex);
54 # Print out the automatic time stamp information
55 def PrintModTime(Attrs):
56 Stamp = GetAttr(Attrs,"modifyTimestamp","");
58 Time = (int(Stamp[0:4]),int(Stamp[4:6]),int(Stamp[6:8]),
59 int(Stamp[8:10]),int(Stamp[10:12]),int(Stamp[12:14]),0,0,-1);
60 print "%-24s:" % ("Record last modified on"), time.strftime("%a %d/%m/%Y %X UTC",Time),
61 print "by",ldap.explode_dn(GetAttr(Attrs,"modifiersName"),1)[0];
63 Stamp = GetAttr(Attrs,"createTimestamp","");
65 Time = (int(Stamp[0:4]),int(Stamp[4:6]),int(Stamp[6:8]),
66 int(Stamp[8:10]),int(Stamp[10:12]),int(Stamp[12:14]),0,0,-1);
67 print "%-24s:" % ("Record created on"), time.strftime("%a %d/%m/%Y %X UTC",Time);
69 # Display all of the attributes in a numbered list
74 for at in Attrs[1].keys():
75 if AttrInfo.has_key(at):
76 if AttrInfo[at][1] == 0:
77 print " %-18s:" % (AttrInfo[at][0]),
78 for x in Attrs[1][at]:
82 OrderedIndex[AttrInfo[at][1]][1] = Attrs[1][at];
84 Keys = OrderedIndex.keys();
87 if at < 100 or RootMode != 0:
88 print " %3u) %-18s: " % (at,OrderedIndex[at][0]),
89 for x in OrderedIndex[at][1]:
90 print "'%s'" % (re.sub('[\n\r]','?',x)),
93 # Change a single attribute
94 def ChangeAttr(Attrs,Attr):
95 if (Attr == "sponsor" or Attr == "hostname" or Attr == "sshRSAHostKey"):
96 return MultiChangeAttr(Attrs,Attr);
98 print "Old value: '%s'" % (GetAttr(Attrs,Attr,""));
99 print "Press enter to leave unchanged and a single space to set to empty";
100 NewValue = raw_input("New? ");
104 print "Leaving unchanged.";
107 # Single space designates delete, trap the delete error
108 if (NewValue == " "):
111 l.modify_s(HostDn,[(ldap.MOD_DELETE,Attr,None)]);
112 except ldap.NO_SUCH_ATTRIBUTE:
116 Attrs[1][Attr] = [""];
121 l.modify_s(HostDn,[(ldap.MOD_REPLACE,Attr,NewValue)]);
122 Attrs[1][Attr] = [NewValue];
125 def MultiChangeAttr(Attrs,Attr):
126 # Make sure that we have an entry
127 if not Attrs[1].has_key(Attr):
130 Attrs[1][Attr].sort();
131 print "Old values: ",Attrs[1][Attr];
133 Mode = string.upper(raw_input("[D]elete or [A]dd? "));
134 if (Mode != 'D' and Mode != 'A'):
137 NewValue = raw_input("Value? ");
140 print "Leaving unchanged.";
147 l.modify_s(HostDn,[(ldap.MOD_DELETE,Attr,NewValue)]);
148 except ldap.NO_SUCH_ATTRIBUTE:
152 Attrs[1][Attr].remove(NewValue);
157 l.modify_s(HostDn,[(ldap.MOD_ADD,Attr,NewValue)]);
158 Attrs[1][Attr].append(NewValue);
161 # Main program starts here
162 User = pwd.getpwuid(os.getuid())[0];
165 (options, arguments) = getopt.getopt(sys.argv[1:], "nh:a:r")
166 for (switch, val) in options:
169 elif (switch == '-a'):
171 elif (switch == '-r'):
173 elif (switch == '-n'):
177 print "Accessing LDAP entry",
178 if (BindUser != User):
180 print "as '" + BindUser + "'";
184 Password = getpass(BindUser + "'s password: ");
186 # Connect to the ldap server
187 l = ldap.open(LDAPServer);
188 UserDn = "uid=" + BindUser + "," + BaseDn;
190 l.simple_bind_s(UserDn,Password);
192 l.simple_bind_s("","");
194 HBaseDn = "ou=hosts,dc=debian,dc=org";
195 HostDn = "host=" + Host + "," + HBaseDn;
197 # Query the server for all of the attributes
198 Attrs = l.search_s(HBaseDn,ldap.SCOPE_ONELEVEL,"host=" + Host);
200 print "Host",Host,"was not found.";
203 # repeatedly show the account configuration
210 print " a) Arbitary Change";
211 print " n) New Host";
212 print " d) Delete Host";
213 print " u) Switch Hosts";
217 Response = raw_input("Change? ");
218 if (Response == "x" or Response == "X" or Response == "q" or
219 Response == "quit" or Response == "exit"):
222 # Change who we are looking at
223 if (Response == 'u' or Response == 'U'):
224 NewHost = raw_input("Host? ");
227 NAttrs = l.search_s(HBaseDn,ldap.SCOPE_ONELEVEL,"host=" + NewHost);
229 print "Host",NewHost,"was not found.";
233 HostDn = "host=" + Host + "," + HBaseDn;
234 OrderedIndex = copy.deepcopy(OrigOrderedIndex);
237 # Create a new entry and change to it Change who we are looking at
238 if (Response == 'n' or Response == 'N'):
239 NewHost = raw_input("Host? ");
242 NAttrs = l.search_s(HBaseDn,ldap.SCOPE_ONELEVEL,"host=" + NewHost);
244 print "Host",NewHost,"already exists.";
246 NewHostName = raw_input("Hostname? ");
249 Dn = "host=" + NewHost + "," + HBaseDn;
250 l.add_s(Dn,[("host",NewHost),
251 ("hostname", NewHostName),
252 ("objectClass", ("top", "debianServer"))]);
255 NAttrs = l.search_s(HBaseDn,ldap.SCOPE_ONELEVEL,"host=" + NewHost);
257 print "Host",NewHost,"was not found.";
261 HostDn = "host=" + Host + "," + HBaseDn;
262 OrderedIndex = copy.deepcopy(OrigOrderedIndex);
265 # Handle changing an arbitary value
266 if (Response == "a"):
267 Attr = raw_input("Attr? ");
268 ChangeAttr(Attrs[0],Attr);
271 if (Response == 'd'):
272 Really = raw_input("Really (type yes)? ");
275 print "Deleting",HostDn;
279 # Convert the integer response
282 if (not OrderedIndex.has_key(ID) or (ID > 100 and RootMode == 0)):
288 # Print the what to do prompt
289 print "Changing LDAP entry '%s' (%s)" % (OrderedIndex[ID][0],OrderedIndex[ID][2]);
290 print AttrPrompt[OrderedIndex[ID][2]][0];
291 ChangeAttr(Attrs[0],OrderedIndex[ID][2]);