--- /dev/null
+#!/usr/bin/python
+
+# Copyright (c) 2008 Peter Palfrader <peter@palfrader.org>
+#
+# 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.
+
+# ud-ldap 0.3.46 changed the format of the sudopasswd lines so that
+# the hmac also includes purpose ("sudo") and userid that owns the
+# entry. This little script updates an ldap from old to new.
+
+import string, re, time, ldap, getopt, sys, os, pwd, posix, socket, base64, sha, shutil, errno, tarfile, grp
+from userdir_ldap import *;
+
+UUID_FORMAT = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
+
+# Connect to the ldap server
+l = connectLDAP()
+F = open(PassDir+"/pass-"+pwd.getpwuid(os.getuid())[0],"r");
+Pass = F.readline().strip().split(" ")
+F.close();
+l.simple_bind_s("uid="+Pass[0]+","+BaseDn,Pass[1]);
+
+PasswdAttrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"sudoPassword=*", ["uid","sudoPassword"]);
+if PasswdAttrs == None:
+ raise "No Users";
+
+for x in PasswdAttrs:
+ if not x[1].has_key('sudoPassword'):
+ continue
+
+ uid = x[1]['uid'][0]
+ Rec = []
+ for entry in x[1]['sudoPassword']:
+ Match = re.compile('^('+UUID_FORMAT+') (confirmed:[0-9a-f]{40}|unconfirmed) ([a-z0-9.,*]+) ([^ ]+)$').match(entry)
+ if Match == None:
+ continue
+ uuid = Match.group(1)
+ status = Match.group(2)
+ hosts = Match.group(3)
+ cryptedpass = Match.group(4)
+
+ # ok old format
+ oldformat = 'confirmed:'+make_hmac(':'.join(['password-is-confirmed', uuid, hosts, cryptedpass]))
+ newformat = 'confirmed:'+make_passwd_hmac('password-is-confirmed', 'sudo', x[1]['uid'][0], uuid, hosts, cryptedpass);
+
+ if status == oldformat:
+ print "Updating sudo password entry for %s."%(uid)
+ status = newformat
+ elif status == newformat:
+ print "not updating sudo password entry for %s, it's already up to date."%(uid)
+ else:
+ print "NOT Updating sudo password entry for %s, failed check."%(uid)
+
+ line = ' '.join([uuid, status, hosts, cryptedpass])
+ if len(Rec) == 0:
+ Rec.append((ldap.MOD_REPLACE, 'sudoPassword', line))
+ else:
+ Rec.append((ldap.MOD_ADD, 'sudoPassword', line))
+
+ Dn = "uid=" + uid + "," + BaseDn;
+ l.modify_s(Dn,Rec);
+
confirmedHosts = SudoPasswd[uuid][0]
confirmedHmac = SudoPasswd[uuid][1]
if status.startswith('confirmed:'):
- if status == 'confirmed:'+make_sudopasswd_hmac('password-is-confirmed', uuid, hosts, cryptedpass):
+ if status == 'confirmed:'+make_passwd_hmac('password-is-confirmed', 'sudo', uid, ,uuid, hosts, cryptedpass):
result = result + "Entry %s for sudo password on hosts %s already confirmed.\n"%(uuid, hosts)
else:
result = result + "Entry %s for sudo password on hosts %s is listed as confirmed, but HMAC does not verify.\n"%(uuid, hosts)
elif confirmedHosts != hosts:
result = result + "Entry %s hostlist mismatch (%s vs. %s).\n"%(uuid, hosts, confirmedHosts)
- elif make_sudopasswd_hmac('confirm-new-password', uuid, hosts, cryptedpass) == confirmedHmac:
+ elif make_passwd_hmac('confirm-new-password', 'sudo', uid, uuid, hosts, cryptedpass) == confirmedHmac:
result = result + "Entry %s for sudo password on hosts %s now confirmed.\n"%(uuid, hosts)
- status = 'confirmed:'+make_sudopasswd_hmac('password-is-confirmed', uuid, hosts, cryptedpass)
+ status = 'confirmed:'+make_passwd_hmac('password-is-confirmed', 'sudo', uid, uuid, hosts, cryptedpass)
else:
result = result + "Entry %s for sudo password on hosts %s HMAC verify failed.\n"%(uuid, hosts)
del SudoPasswd[uuid]
File.close();
return hmac.new(HmacKey, str, sha1_module).hexdigest()
-def make_sudopasswd_hmac(purpose, uuid, hosts, cryptedpass):
- return make_hmac(':'.join([purpose, uuid, hosts, cryptedpass]))
+def make_passwd_hmac(status, purpose, uid, uuid, hosts, cryptedpass):
+ return make_hmac(':'.join([status, purpose, uid, uuid, hosts, cryptedpass]))