Change the hmac that protect sudopassword entries to also hash the purpose
[mirror/userdir-ldap.git] / misc / ud-update-sudopasswords
diff --git a/misc/ud-update-sudopasswords b/misc/ud-update-sudopasswords
new file mode 100755 (executable)
index 0000000..8e7fea8
--- /dev/null
@@ -0,0 +1,74 @@
+#!/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);
+