X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=dak%2Fimport_keyring.py;h=4c6a2eaa73dcbfad787cdb87e4bbe0d74a19c917;hb=41b3a0f5299909f022bff054542c6676a1ed1b93;hp=63c0724177fec1f49b690d64b4790576213ba9f7;hpb=06b17e68fd4a76e7a12f741f26654e55bff05c79;p=dak.git diff --git a/dak/import_keyring.py b/dak/import_keyring.py old mode 100644 new mode 100755 index 63c07241..4c6a2eaa --- a/dak/import_keyring.py +++ b/dak/import_keyring.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Imports a keyring into the database +""" Imports a keyring into the database """ # Copyright (C) 2007 Anthony Towns # This program is free software; you can redistribute it and/or modify @@ -19,31 +19,32 @@ ################################################################################ -import daklib.database, daklib.logging import sys, os, re -import apt_pkg, pg, ldap, email.Utils +import apt_pkg, ldap, email.Utils + +from daklib.config import Config +from daklib.dbconn import * +from daklib import utils + # Globals -Cnf = None Options = None -projectB = None -Logger = None ################################################################################ -def get_uid_info(): +def get_uid_info(session): byname = {} byid = {} - q = projectB.query("SELECT id, uid, name FROM uid") - for (id, uid, name) in q.getresult(): - byname[uid] = (id, name) - byid[id] = (uid, name) + q = session.execute("SELECT id, uid, name FROM uid") + for (keyid, uid, name) in q.fetchall(): + byname[uid] = (keyid, name) + byid[keyid] = (uid, name) return (byname, byid) -def get_fingerprint_info(): +def get_fingerprint_info(session): fins = {} - q = projectB.query("SELECT f.fingerprint, f.id, f.uid, f.keyring FROM fingerprint f") - for (fingerprint, fingerprint_id, uid, keyring) in q.getresult(): + q = session.execute("SELECT f.fingerprint, f.id, f.uid, f.keyring FROM fingerprint f") + for (fingerprint, fingerprint_id, uid, keyring) in q.fetchall(): fins[fingerprint] = (uid, fingerprint_id, keyring) return fins @@ -59,7 +60,7 @@ def get_ldap_name(entry): ################################################################################ -class Keyring: +class Keyring(object): gpg_invocation = "gpg --no-default-keyring --keyring %s" +\ " --with-colons --fingerprint --fingerprint" keys = {} @@ -72,6 +73,7 @@ class Keyring: return "".join(esclist) def __init__(self, keyring): + self.cnf = Config() k = os.popen(self.gpg_invocation % keyring, "r") keys = self.keys key = None @@ -111,12 +113,12 @@ class Keyring: return ({}, {}) def import_users_from_ldap(self): - LDAPDn = Cnf["Import-LDAP-Fingerprints::LDAPDn"] - LDAPServer = Cnf["Import-LDAP-Fingerprints::LDAPServer"] + LDAPDn = self.cnf["Import-LDAP-Fingerprints::LDAPDn"] + LDAPServer = self.cnf["Import-LDAP-Fingerprints::LDAPServer"] l = ldap.open(LDAPServer) l.simple_bind_s("","") Attrs = l.search_s(LDAPDn, ldap.SCOPE_ONELEVEL, - "(&(keyfingerprint=*)(gidnumber=%s))" % (Cnf["Import-Users-From-Passwd::ValidGID"]), + "(&(keyfingerprint=*)(gidnumber=%s))" % (self.cnf["Import-Users-From-Passwd::ValidGID"]), ["uid", "keyfingerprint", "cn", "mn", "sn"]) ldap_fin_uid_id = {} @@ -131,16 +133,16 @@ class Keyring: uid = entry["uid"][0] name = get_ldap_name(entry) fingerprints = entry["keyFingerPrint"] - id = None + keyid = None for f in fingerprints: key = fpr_lookup.get(f, None) if key not in keys: continue keys[key]["uid"] = uid - if id != None: continue - id = daklib.database.get_or_set_uid_id(uid) - byuid[id] = (uid, name) - byname[uid] = (id, name) + if keyid != None: continue + keyid = database.get_or_set_uid_id(uid) + byuid[keyid] = (uid, name) + byname[uid] = (keyid, name) return (byname, byuid) @@ -155,15 +157,15 @@ class Keyring: keys[x]["uid"] = format % "invalid-uid" else: uid = format % keys[x]["email"] - id = daklib.database.get_or_set_uid_id(uid) - byuid[id] = (uid, keys[x]["name"]) - byname[uid] = (id, keys[x]["name"]) + keyid = database.get_or_set_uid_id(uid) + byuid[keyid] = (uid, keys[x]["name"]) + byname[uid] = (keyid, keys[x]["name"]) keys[x]["uid"] = uid if any_invalid: uid = format % "invalid-uid" - id = daklib.database.get_or_set_uid_id(uid) - byuid[id] = (uid, "ungeneratable user id") - byname[uid] = (id, "ungeneratable user id") + keyid = database.get_or_set_uid_id(uid) + byuid[keyid] = (uid, "ungeneratable user id") + byname[uid] = (keyid, "ungeneratable user id") return (byname, byuid) ################################################################################ @@ -179,23 +181,23 @@ def usage (exit_code=0): ################################################################################ def main(): - global Cnf, projectB, Options + global Options - Cnf = daklib.utils.get_conf() + cnf = Config() Arguments = [('h',"help","Import-Keyring::Options::Help"), ('L',"import-ldap-users","Import-Keyring::Options::Import-Ldap-Users"), ('U',"generate-users","Import-Keyring::Options::Generate-Users", "HasArg"), ] for i in [ "help", "report-changes", "generate-users", "import-ldap-users" ]: - if not Cnf.has_key("Import-Keyring::Options::%s" % (i)): - Cnf["Import-Keyring::Options::%s" % (i)] = "" + if not cnf.has_key("Import-Keyring::Options::%s" % (i)): + cnf["Import-Keyring::Options::%s" % (i)] = "" - keyring_names = apt_pkg.ParseCommandLine(Cnf, Arguments, sys.argv) + keyring_names = apt_pkg.ParseCommandLine(cnf.Cnf, Arguments, sys.argv) ### Parse options - Options = Cnf.SubTree("Import-Keyring::Options") + Options = cnf.SubTree("Import-Keyring::Options") if Options["Help"]: usage() @@ -207,39 +209,42 @@ def main(): changes = [] # (uid, changes strings) ### Initialise - - projectB = pg.connect(Cnf["DB::Name"], Cnf["DB::Host"], int(Cnf["DB::Port"])) - daklib.database.init(Cnf, projectB) - - projectB.query("BEGIN WORK") + session = DBConn().session() ### Cache all the existing fingerprint entries - - db_fin_info = get_fingerprint_info() + db_fin_info = get_fingerprint_info(session) ### Parse the keyring keyringname = keyring_names[0] keyring = Keyring(keyringname) - keyring_id = daklib.database.get_or_set_keyring_id( + is_dm = "false" + if cnf.has_key("Import-Keyring::"+keyringname+"::Debian-Maintainer"): + session.execute("UPDATE keyrings SET debian_maintainer = :dm WHERE name = :name", + {'dm': cnf["Import-Keyring::"+keyringname+"::Debian-Maintainer"], + 'name': keyringname.split("/")[-1]}) + + is_dm = cnf["Import-Keyring::"+keyringname+"::Debian-Maintainer"] + + keyring_id = database.get_or_set_keyring_id( keyringname.split("/")[-1]) ### Generate new uid entries if they're needed (from LDAP or the keyring) (desuid_byname, desuid_byid) = keyring.generate_desired_users() ### Cache all the existing uid entries - (db_uid_byname, db_uid_byid) = get_uid_info() + (db_uid_byname, db_uid_byid) = get_uid_info(session) ### Update full names of applicable users - for id in desuid_byid.keys(): - uid = (id, desuid_byid[id][0]) - name = desuid_byid[id][1] - oname = db_uid_byid[id][1] + for keyid in desuid_byid.keys(): + uid = (keyid, desuid_byid[keyid][0]) + name = desuid_byid[keyid][1] + oname = db_uid_byid[keyid][1] if name and oname != name: changes.append((uid[1], "Full name: %s" % (name))) - projectB.query("UPDATE uid SET name = '%s' WHERE id = %s" % - (pg.escape_string(name), id)) + session.execute("UPDATE uid SET name = :name WHERE id = :keyid", + {'name': name, 'keyid': keyid}) # The fingerprint table (fpr) points to a uid and a keyring. # If the uid is being decided here (ldap/generate) we set it to it. @@ -249,11 +254,11 @@ def main(): fpr = {} for z in keyring.keys.keys(): - id = db_uid_byname.get(keyring.keys[z].get("uid", None), [None])[0] - if id == None: - id = db_fin_info.get(keyring.keys[z]["fingerprints"][0], [None])[0] + keyid = db_uid_byname.get(keyring.keys[z].get("uid", None), [None])[0] + if keyid == None: + keyid = db_fin_info.get(keyring.keys[z]["fingerprints"][0], [None])[0] for y in keyring.keys[z]["fingerprints"]: - fpr[y] = (id,keyring_id) + fpr[y] = (keyid,keyring_id) # For any keys that used to be in this keyring, disassociate them. # We don't change the uid, leaving that for historical info; if @@ -263,7 +268,7 @@ def main(): if kr != keyring_id: continue if f in fpr: continue changes.append((db_uid_byid.get(u, [None])[0], "Removed key: %s" % (f))) - projectB.query("UPDATE fingerprint SET keyring = NULL WHERE id = %d" % (fid)) + session.execute("UPDATE fingerprint SET keyring = NULL WHERE id = :fprid", {'fprid': fid}) # For the keys in this keyring, add/update any fingerprints that've # changed. @@ -277,9 +282,13 @@ def main(): if oldfid == -1: changes.append((newuiduid, "Added key: %s" % (f))) if newuid: - projectB.query("INSERT INTO fingerprint (fingerprint, uid, keyring) VALUES ('%s', %d, %d)" % (f, newuid, keyring_id)) + session.execute("""INSERT INTO fingerprint (fingerprint, uid, keyring) + VALUES (:fpr, :uid, :keyring)""", + {'fpr': f, 'uid': uid, 'keyring': keyring_id}) else: - projectB.query("INSERT INTO fingerprint (fingerprint, keyring) VALUES ('%s', %d)" % (f, keyring_id)) + session.execute("""INSERT INTO fingerprint (fingerprint, keyring) + VALUES (:fpr, :keyring)""", + {'fpr': f, 'keyring': keyring_id}) else: if newuid and olduid != newuid: if olduid != -1: @@ -288,14 +297,21 @@ def main(): else: changes.append((newuiduid, "Linked key: %s" % f)) changes.append((newuiduid, " (formerly unowned)")) - projectB.query("UPDATE fingerprint SET uid = %d WHERE id = %d" % (newuid, oldfid)) + session.execute("UPDATE fingerprint SET uid = :uid WHERE id = :fpr", + {'uid': newuid, 'fpr': oldfid}) if oldkid != keyring_id: - projectB.query("UPDATE fingerprint SET keyring = %d WHERE id = %d" % (keyring_id, oldfid)) + # Only change the keyring if it won't result in a loss of permissions + q = session.execute("SELECT debian_maintainer FROM keyrings WHERE id = :keyring", + {'keyring': keyring_id}) + if is_dm == "false" and not q.fetchall()[0][0]: + session.execute("UPDATE fingerprint SET keyring = :keyring WHERE id = :fpr", + {'keyring': keyring_id, 'fpr': oldfid}) + else: + print "Key %s exists in both DM and DD keyrings. Not demoting." % (f) # All done! - - projectB.query("COMMIT WORK") + session.commit() changesd = {} for (k, v) in changes: