diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..61533df --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +SOURCES/krb5-1.15.1-pdfs.tar +SOURCES/krb5-1.15.1.tar.gz +SOURCES/nss_wrapper-0.0-20140204195100.git3d58327.tar.xz +SOURCES/socket_wrapper-0.0-20140204194748.gitf3b2ece.tar.xz diff --git a/.krb5.metadata b/.krb5.metadata new file mode 100644 index 0000000..22193ae --- /dev/null +++ b/.krb5.metadata @@ -0,0 +1,4 @@ +0feda2b6393a4ac9ecc449fc7b4215da5ca6860d SOURCES/krb5-1.15.1-pdfs.tar +810210a61070ea371014ac514d191bbe5cdac2e2 SOURCES/krb5-1.15.1.tar.gz +7e2c80565c726a6be9a62615752196710e2e2faa SOURCES/nss_wrapper-0.0-20140204195100.git3d58327.tar.xz +ca7b62bd60d45817a059063bb0efd68cd1ecc889 SOURCES/socket_wrapper-0.0-20140204194748.gitf3b2ece.tar.xz diff --git a/SOURCES/Add-German-translation.patch b/SOURCES/Add-German-translation.patch new file mode 100644 index 0000000..98c6404 --- /dev/null +++ b/SOURCES/Add-German-translation.patch @@ -0,0 +1,9333 @@ +From eb32be474036aa25a14aca5f457d09ce1f2804ec Mon Sep 17 00:00:00 2001 +From: Chris Leick +Date: Wed, 6 Apr 2016 18:14:40 -0400 +Subject: [PATCH] Add German translation + +ticket: 8515 (new) +(cherry picked from commit 0c9a4d9734c29a77d3c7ac267e8e885a75f44b4f) +--- + src/po/Makefile.in | 2 +- + src/po/de.po | 9301 ++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 9302 insertions(+), 1 deletion(-) + create mode 100644 src/po/de.po + +diff --git a/src/po/Makefile.in b/src/po/Makefile.in +index fdaf872a1..6753447dc 100644 +--- a/src/po/Makefile.in ++++ b/src/po/Makefile.in +@@ -18,7 +18,7 @@ ETSRCS= $(BUILDTOP)/lib/gssapi/generic/gssapi_err_generic.c \ + $(BUILDTOP)/lib/krb5/error_tables/kv5m_err.c \ + $(BUILDTOP)/lib/krb5/error_tables/krb524_err.c + # This is a placeholder until we have an actual translation. +-CATALOGS=en_US.mo ++CATALOGS=en_US.mo de.mo + + .SUFFIXES: .po .mo + .po.mo: +diff --git a/src/po/de.po b/src/po/de.po +new file mode 100644 +index 000000000..2144d7833 +--- /dev/null ++++ b/src/po/de.po +@@ -0,0 +1,9301 @@ ++# German translation of mit-krb5. ++# This file is distributed under the same license as the mit-krb5 package. ++# Copyright (C) 1985-2013 by the Massachusetts Institute of Technology. ++# Copyright (C) of this file 2014-2016 Chris Leick . ++# ++msgid "" ++msgstr "" ++"Project-Id-Version: mit-krb5 13.2\n" ++"Report-Msgid-Bugs-To: krbdev@mit.edu\n" ++"POT-Creation-Date: 2015-05-06 14:59-0400\n" ++"PO-Revision-Date: 2016-04-07 08:15+0200\n" ++"Last-Translator: Chris Leick \n" ++"Language-Team: German \n" ++"Language: de\n" ++"MIME-Version: 1.0\n" ++"Content-Type: text/plain; charset=UTF-8\n" ++"Content-Transfer-Encoding: 8bit\n" ++"Plural-Forms: nplurals=2; plural=n != 1;\n" ++ ++#: ../../src/clients/kdestroy/kdestroy.c:62 ++#, c-format ++msgid "Usage: %s [-A] [-q] [-c cache_name]\n" ++msgstr "Aufruf: %s [-A] [-q] [-c Zwischenspeichername]\n" ++ ++#: ../../src/clients/kdestroy/kdestroy.c:63 ++#, c-format ++msgid "\t-A destroy all credential caches in collection\n" ++msgstr "\t-A vernichtet alle Anmeldedatenzwischenspeicher in der Sammlung.\n" ++ ++#: ../../src/clients/kdestroy/kdestroy.c:64 ++#, c-format ++msgid "\t-q quiet mode\n" ++msgstr "\t-q stiller Modus\n" ++ ++#: ../../src/clients/kdestroy/kdestroy.c:65 ++#: ../../src/clients/kswitch/kswitch.c:45 ++#, c-format ++msgid "\t-c specify name of credentials cache\n" ++msgstr "\t-c gibt den Namen des Zwischenspeichers für Anmeldedaten an.\n" ++ ++#: ../../src/clients/kdestroy/kdestroy.c:98 ++#: ../../src/clients/kinit/kinit.c:383 ../../src/clients/ksu/main.c:284 ++#, c-format ++msgid "Only one -c option allowed\n" ++msgstr "Nur eine »-c«-Option ist erlaubt.\n" ++ ++#: ../../src/clients/kdestroy/kdestroy.c:105 ++#: ../../src/clients/kinit/kinit.c:412 ../../src/clients/klist/klist.c:182 ++#, c-format ++msgid "Kerberos 4 is no longer supported\n" ++msgstr "Kerberos 4 wird nicht mehr unterstützt.\n" ++ ++#: ../../src/clients/kdestroy/kdestroy.c:126 ++#: ../../src/clients/klist/klist.c:253 ../../src/clients/ksu/main.c:131 ++#: ../../src/clients/ksu/main.c:137 ../../src/clients/kswitch/kswitch.c:97 ++#: ../../src/kadmin/ktutil/ktutil.c:52 ../../src/kdc/main.c:926 ++#: ../../src/slave/kprop.c:102 ../../src/slave/kpropd.c:1052 ++msgid "while initializing krb5" ++msgstr "beim Initialisieren von Krb5" ++ ++#: ../../src/clients/kdestroy/kdestroy.c:133 ++msgid "while listing credential caches" ++msgstr "beim Auflisten der Anmeldedatenzwischenspeicher" ++ ++#: ../../src/clients/kdestroy/kdestroy.c:140 ++msgid "composing ccache name" ++msgstr "Ccache-Name wird zusammengesetzt." ++ ++#: ../../src/clients/kdestroy/kdestroy.c:145 ++#, c-format ++msgid "while destroying cache %s" ++msgstr "beim Zerstören des Zwischenspeichers %s" ++ ++#: ../../src/clients/kdestroy/kdestroy.c:157 ++#: ../../src/clients/kswitch/kswitch.c:104 ++#, c-format ++msgid "while resolving %s" ++msgstr "beim Auflösen von %s" ++ ++#: ../../src/clients/kdestroy/kdestroy.c:163 ++#: ../../src/clients/kinit/kinit.c:501 ../../src/clients/klist/klist.c:460 ++msgid "while getting default ccache" ++msgstr "beim Holen des Standard-Ccaches" ++ ++#: ../../src/clients/kdestroy/kdestroy.c:170 ../../src/clients/ksu/main.c:986 ++msgid "while destroying cache" ++msgstr "beim Zerstören des Zwischenspeichers" ++ ++#: ../../src/clients/kdestroy/kdestroy.c:173 ++#, c-format ++msgid "Ticket cache NOT destroyed!\n" ++msgstr "Ticketzwischenspeicher NICHT vernichtet!\n" ++ ++#: ../../src/clients/kdestroy/kdestroy.c:175 ++#, c-format ++msgid "Ticket cache %cNOT%c destroyed!\n" ++msgstr "Ticketzwischenspeicher %cNICHT%c vernichtet!\n" ++ ++#: ../../src/clients/kinit/kinit.c:213 ++#, c-format ++msgid "\t-V verbose\n" ++msgstr "\t-V detaillierte Ausgabe\n" ++ ++#: ../../src/clients/kinit/kinit.c:214 ++#, c-format ++msgid "\t-l lifetime\n" ++msgstr "\t-l Lebensdauer\n" ++ ++#: ../../src/clients/kinit/kinit.c:215 ++#, c-format ++msgid "\t-s start time\n" ++msgstr "\t-s Startzeit\n" ++ ++#: ../../src/clients/kinit/kinit.c:216 ++#, c-format ++msgid "\t-r renewable lifetime\n" ++msgstr "\t-r verlängerbare Lebensdauer\n" ++ ++#: ../../src/clients/kinit/kinit.c:217 ++#, c-format ++msgid "\t-f forwardable\n" ++msgstr "\t-f weiterleitbar\n" ++ ++#: ../../src/clients/kinit/kinit.c:218 ++#, c-format ++msgid "\t-F not forwardable\n" ++msgstr "\t-F nicht weiterleitbar\n" ++ ++#: ../../src/clients/kinit/kinit.c:219 ++#, c-format ++msgid "\t-p proxiable\n" ++msgstr "\t-p Proxy nutzbar\n" ++ ++#: ../../src/clients/kinit/kinit.c:220 ++#, c-format ++msgid "\t-P not proxiable\n" ++msgstr "\t-P Proxy nicht nutzbar\n" ++ ++#: ../../src/clients/kinit/kinit.c:221 ++#, c-format ++msgid "\t-n anonymous\n" ++msgstr "\t-n anonym\n" ++ ++#: ../../src/clients/kinit/kinit.c:222 ++#, c-format ++msgid "\t-a include addresses\n" ++msgstr "\t-a bezieht Adressen ein.\n" ++ ++#: ../../src/clients/kinit/kinit.c:223 ++#, c-format ++msgid "\t-A do not include addresses\n" ++msgstr "\t-a bezieht Adressen nicht ein.\n" ++ ++#: ../../src/clients/kinit/kinit.c:224 ++#, c-format ++msgid "\t-v validate\n" ++msgstr "\t-v überprüft\n" ++ ++#: ../../src/clients/kinit/kinit.c:225 ++#, c-format ++msgid "\t-R renew\n" ++msgstr "\t-R erneuert\n" ++ ++#: ../../src/clients/kinit/kinit.c:226 ++#, c-format ++msgid "\t-C canonicalize\n" ++msgstr "\t-C bringt in Normalform\n" ++ ++#: ../../src/clients/kinit/kinit.c:227 ++#, c-format ++msgid "\t-E client is enterprise principal name\n" ++msgstr "\t-E Client ist der Principal-Name des Unternehmens\n" ++ ++#: ../../src/clients/kinit/kinit.c:228 ++#, c-format ++msgid "\t-k use keytab\n" ++msgstr "\t-k verwendet Schlüsseltabelle\n" ++ ++#: ../../src/clients/kinit/kinit.c:229 ++#, c-format ++msgid "\t-i use default client keytab (with -k)\n" ++msgstr "\t-i verwendet die Standardschlüsseltabelle des Clients (mit -k).\n" ++ ++#: ../../src/clients/kinit/kinit.c:230 ++#, c-format ++msgid "\t-t filename of keytab to use\n" ++msgstr "\t-t Dateiname der zu verwendenden Schlüsseltabelle\n" ++ ++#: ../../src/clients/kinit/kinit.c:231 ++#, c-format ++msgid "\t-c Kerberos 5 cache name\n" ++msgstr "\t-c Kerberos-5-Zwischenspeichername\n" ++ ++#: ../../src/clients/kinit/kinit.c:232 ++#, c-format ++msgid "\t-S service\n" ++msgstr "\t-S Dienst\n" ++ ++#: ../../src/clients/kinit/kinit.c:233 ++#, c-format ++msgid "\t-T armor credential cache\n" ++msgstr "\t-T gehärteter Anmeldedatenzwischenspeicher\n" ++ ++#: ../../src/clients/kinit/kinit.c:234 ++#, c-format ++msgid "\t-X [=]\n" ++msgstr "\t-X [=]\n" ++ ++#: ../../src/clients/kinit/kinit.c:301 ../../src/clients/kinit/kinit.c:309 ++#, c-format ++msgid "Bad lifetime value %s\n" ++msgstr "falscher Wert für die Lebensdauer %s\n" ++ ++#: ../../src/clients/kinit/kinit.c:343 ++#, c-format ++msgid "Bad start time value %s\n" ++msgstr "falscher Wert für die Startzeit %s\n" ++ ++#: ../../src/clients/kinit/kinit.c:362 ++#, c-format ++msgid "Only one -t option allowed.\n" ++msgstr "Nur eine -t-Option ist erlaubt.\n" ++ ++#: ../../src/clients/kinit/kinit.c:370 ++#, c-format ++msgid "Only one armor_ccache\n" ++msgstr "nur ein gehärteter Ccache\n" ++ ++#: ../../src/clients/kinit/kinit.c:391 ++#, c-format ++msgid "Only one -I option allowed\n" ++msgstr "Nur eine -I-Option ist erlaubt.\n" ++ ++#: ../../src/clients/kinit/kinit.c:401 ++msgid "while adding preauth option" ++msgstr "beim Hinzufügen der Option »preauth«" ++ ++#: ../../src/clients/kinit/kinit.c:425 ++#, c-format ++msgid "Only one of -f and -F allowed\n" ++msgstr "Nur eine der Optionen -f und -F ist erlaubt.\n" ++ ++#: ../../src/clients/kinit/kinit.c:430 ++#, c-format ++msgid "Only one of -p and -P allowed\n" ++msgstr "Nur eine der Optionen -p und -P ist erlaubt.\n" ++ ++#: ../../src/clients/kinit/kinit.c:435 ++#, c-format ++msgid "Only one of -a and -A allowed\n" ++msgstr "Nur eine der Optionen -a und -A ist erlaubt.\n" ++ ++#: ../../src/clients/kinit/kinit.c:440 ++#, c-format ++msgid "Only one of -t and -i allowed\n" ++msgstr "Nur eine der Optionen -t und-i ist erlaubt.\n" ++ ++#: ../../src/clients/kinit/kinit.c:447 ++#, c-format ++msgid "keytab specified, forcing -k\n" ++msgstr "Schlüsseltabelle angegeben, -k wird erzwungen\n" ++ ++#: ../../src/clients/kinit/kinit.c:451 ../../src/clients/klist/klist.c:221 ++#, c-format ++msgid "Extra arguments (starting with \"%s\").\n" ++msgstr "zusätzliche Argumente (beginnend mit »%s«)\n" ++ ++#: ../../src/clients/kinit/kinit.c:480 ++msgid "while initializing Kerberos 5 library" ++msgstr "beim Initialisieren der Kerberos-5-Bibliothek" ++ ++#: ../../src/clients/kinit/kinit.c:488 ../../src/clients/kinit/kinit.c:644 ++#, c-format ++msgid "resolving ccache %s" ++msgstr "Ccache %s wird ermittelt" ++ ++#: ../../src/clients/kinit/kinit.c:493 ++#, c-format ++msgid "Using specified cache: %s\n" ++msgstr "Angegebener Zwischenspeicher wird verwendet: %s\n" ++ ++#: ../../src/clients/kinit/kinit.c:515 ../../src/clients/kinit/kinit.c:595 ++#: ../../src/clients/kpasswd/kpasswd.c:28 ../../src/clients/ksu/main.c:238 ++#, c-format ++msgid "when parsing name %s" ++msgstr "wenn der Name %s ausgewertet wird" ++ ++#: ../../src/clients/kinit/kinit.c:523 ../../src/kadmin/dbutil/kdb5_util.c:307 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:391 ++#: ../../src/slave/kprop.c:203 ++msgid "while getting default realm" ++msgstr "beim Holen des Standard-Realms" ++ ++#: ../../src/clients/kinit/kinit.c:535 ++msgid "while building principal" ++msgstr "beim Erstellen des Principals" ++ ++#: ../../src/clients/kinit/kinit.c:543 ++msgid "When resolving the default client keytab" ++msgstr "beim Auflösen der Standardschlüsseltabelle des Clients" ++ ++#: ../../src/clients/kinit/kinit.c:550 ++msgid "When determining client principal name from keytab" ++msgstr "beim Bestimmen des Dienst-Principal-Namens anhand der Schlüsseltabelle" ++ ++#: ../../src/clients/kinit/kinit.c:559 ++msgid "when creating default server principal name" ++msgstr "wenn der Standard-Principal-Name des Servers erstellt wird" ++ ++#: ../../src/clients/kinit/kinit.c:566 ++#, c-format ++msgid "(principal %s)" ++msgstr "(Principal %s)" ++ ++#: ../../src/clients/kinit/kinit.c:569 ++msgid "for local services" ++msgstr "für lokale Dienste" ++ ++#: ../../src/clients/kinit/kinit.c:590 ../../src/clients/kpasswd/kpasswd.c:42 ++#, c-format ++msgid "Unable to identify user\n" ++msgstr "Benutzer kann nicht identifiziert werden\n" ++ ++#: ../../src/clients/kinit/kinit.c:605 ../../src/clients/kswitch/kswitch.c:116 ++#, c-format ++msgid "while searching for ccache for %s" ++msgstr "beim Suchen nach Ccache für %s" ++ ++#: ../../src/clients/kinit/kinit.c:611 ++#, c-format ++msgid "Using existing cache: %s\n" ++msgstr "Existierender Zwischenspeicher wird verwendet: %s\n" ++ ++#: ../../src/clients/kinit/kinit.c:620 ++msgid "while generating new ccache" ++msgstr "beim Erstellen von neuem Ccache" ++ ++#: ../../src/clients/kinit/kinit.c:624 ++#, c-format ++msgid "Using new cache: %s\n" ++msgstr "Neuer Zwischenspeicher wird verwendet: %s\n" ++ ++#: ../../src/clients/kinit/kinit.c:636 ++#, c-format ++msgid "Using default cache: %s\n" ++msgstr "Standardzwischenspeicher wird verwendet: %s\n" ++ ++#: ../../src/clients/kinit/kinit.c:649 ++#, c-format ++msgid "Using specified input cache: %s\n" ++msgstr "Angegebener Eingabezwischenspeicher wird verwendet: %s\n" ++ ++#: ../../src/clients/kinit/kinit.c:657 ../../src/clients/ksu/krb_auth_su.c:160 ++msgid "when unparsing name" ++msgstr "beim Rückgängigmachen der Auswertung des Namens" ++ ++#: ../../src/clients/kinit/kinit.c:661 ++#, c-format ++msgid "Using principal: %s\n" ++msgstr "verwendeter Principal: %s\n" ++ ++#: ../../src/clients/kinit/kinit.c:752 ++msgid "getting local addresses" ++msgstr "Lokale Adressen werden geholt." ++ ++#: ../../src/clients/kinit/kinit.c:771 ++#, c-format ++msgid "while setting up KDB keytab for realm %s" ++msgstr "beim Einrichten der KDB-Schlüsseltabelle für Realm %s" ++ ++#: ../../src/clients/kinit/kinit.c:780 ../../src/clients/kvno/kvno.c:201 ++#, c-format ++msgid "resolving keytab %s" ++msgstr "Schlüsseltabelle wird ermittelt: %s" ++ ++#: ../../src/clients/kinit/kinit.c:785 ++#, c-format ++msgid "Using keytab: %s\n" ++msgstr "Schlüsseltabelle wird verwendet: %s\n" ++ ++#: ../../src/clients/kinit/kinit.c:789 ++msgid "resolving default client keytab" ++msgstr "Standardschlüsseltabelle des Clients wird ermittelt." ++ ++#: ../../src/clients/kinit/kinit.c:799 ++#, c-format ++msgid "while setting '%s'='%s'" ++msgstr "beim Setzen von »%s«=»%s«" ++ ++#: ../../src/clients/kinit/kinit.c:804 ++#, c-format ++msgid "PA Option %s = %s\n" ++msgstr "PA-Option %s = %s\n" ++ ++#: ../../src/clients/kinit/kinit.c:849 ++msgid "getting initial credentials" ++msgstr "Anfängliche Anmeldedaten werden geholt." ++ ++#: ../../src/clients/kinit/kinit.c:852 ++msgid "validating credentials" ++msgstr "Anmeldedaten werden geprüft." ++ ++#: ../../src/clients/kinit/kinit.c:855 ++msgid "renewing credentials" ++msgstr "Anmeldedaten werden erneuert." ++ ++#: ../../src/clients/kinit/kinit.c:860 ++#, c-format ++msgid "%s: Password incorrect while %s\n" ++msgstr "%s: Passwort bei %s falsch\n" ++ ++#: ../../src/clients/kinit/kinit.c:863 ++#, c-format ++msgid "while %s" ++msgstr "bei %s" ++ ++#: ../../src/clients/kinit/kinit.c:871 ../../src/slave/kprop.c:224 ++#, c-format ++msgid "when initializing cache %s" ++msgstr "beim Initialisieren des Zwischenspeichers %s" ++ ++#: ../../src/clients/kinit/kinit.c:876 ++#, c-format ++msgid "Initialized cache\n" ++msgstr "initialisierter Zwischenspeicher\n" ++ ++#: ../../src/clients/kinit/kinit.c:880 ++msgid "while storing credentials" ++msgstr "beim Speichern der Anmeldedaten" ++ ++#: ../../src/clients/kinit/kinit.c:884 ++#, c-format ++msgid "Stored credentials\n" ++msgstr "gespeicherte Anmeldedaten\n" ++ ++#: ../../src/clients/kinit/kinit.c:891 ++msgid "while switching to new ccache" ++msgstr "beim Wechsel zum neuen Ccache" ++ ++#: ../../src/clients/kinit/kinit.c:946 ++#, c-format ++msgid "Authenticated to Kerberos v5\n" ++msgstr "Authentifiziert für Kerberos v5\n" ++ ++#: ../../src/clients/klist/klist.c:91 ++#, c-format ++msgid "" ++"Usage: %s [-e] [-V] [[-c] [-l] [-A] [-d] [-f] [-s] [-a [-n]]] [-k [-t] [-K]] " ++"[name]\n" ++msgstr "" ++"Aufruf: %s [-e] [-V] [[-c] [-l] [-A] [-d] [-f] [-s] [-a [-n]]] [-k [-t] [-" ++"K]] [Name]\n" ++ ++#: ../../src/clients/klist/klist.c:93 ++#, c-format ++msgid "\t-c specifies credentials cache\n" ++msgstr "\t-c gibt den Anmeldedatenzwischenspeicher an\n" ++ ++#: ../../src/clients/klist/klist.c:94 ++#, c-format ++msgid "\t-k specifies keytab\n" ++msgstr "\t-k gibt die Schlüsseltabelle an.\n" ++ ++#: ../../src/clients/klist/klist.c:95 ++#, c-format ++msgid "\t (Default is credentials cache)\n" ++msgstr "\t (Voreinstellung ist Anmeldedatenzwischenspeicher)\n" ++ ++#: ../../src/clients/klist/klist.c:96 ++#, c-format ++msgid "\t-i uses default client keytab if no name given\n" ++msgstr "" ++"\t-i verwendet die Standardschlüsseltabelle des Clients, falls kein Name " ++"angegeben wurde.\n" ++ ++#: ../../src/clients/klist/klist.c:97 ++#, c-format ++msgid "\t-l lists credential caches in collection\n" ++msgstr "\t-l listet gesammelte Anmeldedatenzwischenspeicher auf.\n" ++ ++#: ../../src/clients/klist/klist.c:98 ++#, c-format ++msgid "\t-A shows content of all credential caches\n" ++msgstr "\t-A zeigt den Inhalt aller Anmeldedatenzwischenspeicher an.\n" ++ ++#: ../../src/clients/klist/klist.c:99 ++#, c-format ++msgid "\t-e shows the encryption type\n" ++msgstr "\t-e zeigt den Verschlüsselungstyp.\n" ++ ++#: ../../src/clients/klist/klist.c:100 ++#, c-format ++msgid "\t-V shows the Kerberos version and exits\n" ++msgstr "\t-V zeigt die Kerberos-Version und wird beendet.\n" ++ ++#: ../../src/clients/klist/klist.c:101 ++#, c-format ++msgid "\toptions for credential caches:\n" ++msgstr "\tOptionen für Anmeldedatenzwischenspeicher:\n" ++ ++#: ../../src/clients/klist/klist.c:102 ++#, c-format ++msgid "\t\t-d shows the submitted authorization data types\n" ++msgstr "\t\t-d zeigt die übertragenen Autorisierungsdatentypen.\n" ++ ++#: ../../src/clients/klist/klist.c:104 ++#, c-format ++msgid "\t\t-f shows credentials flags\n" ++msgstr "t\t-f zeigt die Anmeldedatenschalter.\n" ++ ++#: ../../src/clients/klist/klist.c:105 ++#, c-format ++msgid "\t\t-s sets exit status based on valid tgt existence\n" ++msgstr "" ++"\t\t-s setzt den Exit-Status auf Basis der Existenz eines gültigen TGTs.\n" ++ ++#: ../../src/clients/klist/klist.c:107 ++#, c-format ++msgid "\t\t-a displays the address list\n" ++msgstr "\t\t-a zeigt die Adressliste.\n" ++ ++#: ../../src/clients/klist/klist.c:108 ++#, c-format ++msgid "\t\t\t-n do not reverse-resolve\n" ++msgstr "\t\t\t-n löst nicht rückwärts auf.\n" ++ ++#: ../../src/clients/klist/klist.c:109 ++#, c-format ++msgid "\toptions for keytabs:\n" ++msgstr "\tOptionen für Schlüsseltabellen:\n" ++ ++#: ../../src/clients/klist/klist.c:110 ++#, c-format ++msgid "\t\t-t shows keytab entry timestamps\n" ++msgstr "\t\t-t zeigt die Zeitstempel der Schlüsseltabelleneinträge.\n" ++ ++#: ../../src/clients/klist/klist.c:111 ++#, c-format ++msgid "\t\t-K shows keytab entry keys\n" ++msgstr "\t\t-K zeigt die Schlüssel der Schlüsseltabelleneinträge.\n" ++ ++#: ../../src/clients/klist/klist.c:230 ++#, c-format ++msgid "%s version %s\n" ++msgstr "%s Version %s\n" ++ ++#: ../../src/clients/klist/klist.c:282 ++msgid "while getting default client keytab" ++msgstr "beim Holen der Standardschlüsseltabelle des Clients" ++ ++#: ../../src/clients/klist/klist.c:287 ++msgid "while getting default keytab" ++msgstr "beim Holen der Standardschlüsseltabelle" ++ ++#: ../../src/clients/klist/klist.c:292 ../../src/kadmin/cli/keytab.c:108 ++#, c-format ++msgid "while resolving keytab %s" ++msgstr "beim Ermitteln der Schlüsseltabelle %s" ++ ++#: ../../src/clients/klist/klist.c:298 ../../src/kadmin/cli/keytab.c:92 ++msgid "while getting keytab name" ++msgstr "beim Holen des Schlüsseltabellennamens" ++ ++#: ../../src/clients/klist/klist.c:305 ../../src/kadmin/cli/keytab.c:399 ++msgid "while starting keytab scan" ++msgstr "beim Start des Schlüsseltabellen-Scans" ++ ++#: ../../src/clients/klist/klist.c:326 ../../src/clients/klist/klist.c:500 ++#: ../../src/clients/ksu/ccache.c:465 ../../src/kadmin/dbutil/dump.c:550 ++msgid "while unparsing principal name" ++msgstr "beim Rückgängigmachen des Auswertens des Principal-Namens" ++ ++#: ../../src/clients/klist/klist.c:350 ../../src/kadmin/cli/keytab.c:443 ++msgid "while scanning keytab" ++msgstr "beim Scannen der Schlüsseltabelle" ++ ++#: ../../src/clients/klist/klist.c:354 ../../src/kadmin/cli/keytab.c:448 ++msgid "while ending keytab scan" ++msgstr "beim Beenden des Schlüsseltabellen-Scans" ++ ++#: ../../src/clients/klist/klist.c:371 ../../src/clients/klist/klist.c:434 ++msgid "while listing ccache collection" ++msgstr "beim Aufführen der Ccache-Sammlung" ++ ++#: ../../src/clients/klist/klist.c:411 ++msgid "(Expired)" ++msgstr "(abgelaufen)" ++ ++#: ../../src/clients/klist/klist.c:466 ++#, c-format ++msgid "while resolving ccache %s" ++msgstr "beim Ermitteln des Ccaches %s" ++ ++#: ../../src/clients/klist/klist.c:504 ++#, c-format ++msgid "" ++"Ticket cache: %s:%s\n" ++"Default principal: %s\n" ++"\n" ++msgstr "" ++"Ticketzwischenspeicher: %s:%s\n" ++"Standard-Principal: %s\n" ++"\n" ++ ++#: ../../src/clients/klist/klist.c:518 ++msgid "while starting to retrieve tickets" ++msgstr "während das Abfragen der Tickets beginnt" ++ ++#: ../../src/clients/klist/klist.c:539 ++msgid "while finishing ticket retrieval" ++msgstr "während das Abfragem der Tickets endet" ++ ++#: ../../src/clients/klist/klist.c:545 ++msgid "while closing ccache" ++msgstr "beim Schließen des Ccaches" ++ ++#: ../../src/clients/klist/klist.c:555 ++msgid "while retrieving a ticket" ++msgstr "beim Abfragen eines Tickets" ++ ++#: ../../src/clients/klist/klist.c:667 ../../src/clients/ksu/ccache.c:450 ++#: ../../src/slave/kpropd.c:1225 ../../src/slave/kpropd.c:1285 ++msgid "while unparsing client name" ++msgstr "beim Rückgängigmachen des Auswertens des Client-Namens" ++ ++#: ../../src/clients/klist/klist.c:672 ../../src/clients/ksu/ccache.c:455 ++#: ../../src/slave/kprop.c:240 ++msgid "while unparsing server name" ++msgstr "beim Rückgängigmachen des Auswertens des Server-Namens" ++ ++#: ../../src/clients/klist/klist.c:701 ../../src/clients/ksu/ccache.c:480 ++#, c-format ++msgid "\tfor client %s" ++msgstr "\tfür Client %s" ++ ++#: ../../src/clients/klist/klist.c:713 ../../src/clients/ksu/ccache.c:489 ++msgid "renew until " ++msgstr "erneuern bis " ++ ++#: ../../src/clients/klist/klist.c:730 ../../src/clients/ksu/ccache.c:499 ++#, c-format ++msgid "Flags: %s" ++msgstr "Schalter: %s" ++ ++#: ../../src/clients/klist/klist.c:749 ++#, c-format ++msgid "Etype (skey, tkt): %s, " ++msgstr "Etype (Skey, TKT): %s, " ++ ++#: ../../src/clients/klist/klist.c:766 ++#, c-format ++msgid "AD types: " ++msgstr "AD-Typen" ++ ++#: ../../src/clients/klist/klist.c:783 ++#, c-format ++msgid "\tAddresses: (none)\n" ++msgstr "\tAdressen: (keine)\n" ++ ++#: ../../src/clients/klist/klist.c:785 ++#, c-format ++msgid "\tAddresses: " ++msgstr "\tAdressen: " ++ ++#: ../../src/clients/klist/klist.c:818 ++#, c-format ++msgid "broken address (type %d length %d)" ++msgstr "kaputte Adresse (Typ %d Länge %d)" ++ ++#: ../../src/clients/klist/klist.c:838 ++#, c-format ++msgid "unknown addrtype %d" ++msgstr "unbekannter »addrtype« %d" ++ ++#: ../../src/clients/klist/klist.c:847 ++#, c-format ++msgid "unprintable address (type %d, error %d %s)" ++msgstr "nicht druckbare Adresse (Typ %d Fehler %d %s)" ++ ++#: ../../src/clients/kpasswd/kpasswd.c:12 ../../src/lib/krb5/krb/gic_pwd.c:396 ++msgid "Enter new password" ++msgstr "Geben Sie ein neues Passwort ein." ++ ++#: ../../src/clients/kpasswd/kpasswd.c:13 ../../src/lib/krb5/krb/gic_pwd.c:404 ++msgid "Enter it again" ++msgstr "Geben Sie es erneut ein." ++ ++#: ../../src/clients/kpasswd/kpasswd.c:33 ++#, c-format ++msgid "Unable to identify user from password file\n" ++msgstr "" ++"Der Benutzer kann nicht anhand der Passwortdatei identifiziert werden.\n" ++ ++#: ../../src/clients/kpasswd/kpasswd.c:65 ++#, c-format ++msgid "usage: %s [principal]\n" ++msgstr "Aufruf: %s [Principal]\n" ++ ++#: ../../src/clients/kpasswd/kpasswd.c:73 ++msgid "initializing kerberos library" ++msgstr "Kerberos-Bibliothek wird initialisiert." ++ ++#: ../../src/clients/kpasswd/kpasswd.c:77 ++msgid "allocating krb5_get_init_creds_opt" ++msgstr "krb5_get_init_creds_opt wird reserviert." ++ ++#: ../../src/clients/kpasswd/kpasswd.c:92 ++msgid "opening default ccache" ++msgstr "Standard-Ccache wird geöffnet." ++ ++#: ../../src/clients/kpasswd/kpasswd.c:97 ++msgid "getting principal from ccache" ++msgstr "Principal wird vom Ccache geholt." ++ ++#: ../../src/clients/kpasswd/kpasswd.c:104 ++msgid "while setting FAST ccache" ++msgstr "beim Setzen des FAST-Ccaches" ++ ++#: ../../src/clients/kpasswd/kpasswd.c:111 ++msgid "closing ccache" ++msgstr "Ccache wird geschlossen." ++ ++#: ../../src/clients/kpasswd/kpasswd.c:118 ++msgid "parsing client name" ++msgstr "Client-Name wird ausgewertet." ++ ++#: ../../src/clients/kpasswd/kpasswd.c:135 ++msgid "Password incorrect while getting initial ticket" ++msgstr "Passwort beim Holen des anfänglichen Tickets falsch" ++ ++#: ../../src/clients/kpasswd/kpasswd.c:137 ++msgid "getting initial ticket" ++msgstr "Anfängliches Ticket wird geholt." ++ ++#: ../../src/clients/kpasswd/kpasswd.c:144 ++msgid "while reading password" ++msgstr "beim Lesen des Passworts" ++ ++#: ../../src/clients/kpasswd/kpasswd.c:152 ++msgid "changing password" ++msgstr "Passwort wird geändert." ++ ++#: ../../src/clients/kpasswd/kpasswd.c:174 ++#: ../lib/kadm5/chpass_util_strings.c:30 ++#, c-format ++msgid "Password changed.\n" ++msgstr "Passwort geändert\n" ++ ++#: ../../src/clients/ksu/authorization.c:369 ++#, c-format ++msgid "" ++"Error: bad entry - %s in %s file, must be either full path or just the cmd " ++"name\n" ++msgstr "" ++"Fehler: falscher Eintrag – %s in Datei %s muss entweder ein vollständiger " ++"Pfad oder nur ein Befehlsname sein.\n" ++ ++#: ../../src/clients/ksu/authorization.c:377 ++#, c-format ++msgid "" ++"Error: bad entry - %s in %s file, since %s is just the cmd name, CMD_PATH " ++"must be defined \n" ++msgstr "" ++"Fehler: falscher Eintrag – %s in Datei %s. Da %s nur ein Befehlsname ist, " ++"muss CMD_PATH definiert sein.\n" ++ ++#: ../../src/clients/ksu/authorization.c:392 ++#, c-format ++msgid "Error: bad entry - %s in %s file, CMD_PATH contains no paths \n" ++msgstr "" ++"Fehler: falscher Eintrag – %s in Datei %s. CMD_PATH enthält keine Pfade.\n" ++ ++#: ../../src/clients/ksu/authorization.c:401 ++#, c-format ++msgid "Error: bad path %s in CMD_PATH for %s must start with '/' \n" ++msgstr "Fehler: falscher Pfad %s in CMD_PATH für %s muss mit »/« beginnen\n" ++ ++#: ../../src/clients/ksu/authorization.c:517 ++msgid "Error: not found -> " ++msgstr "Fehler: nicht gefunden -> " ++ ++#: ../../src/clients/ksu/authorization.c:723 ++#, c-format ++msgid "home directory name `%s' too long, can't search for .k5login\n" ++msgstr "" ++"Name des Home-Verzeichnisses »%s« ist zu lang, Suche nach .k5login nicht " ++"möglich\n" ++ ++#: ../../src/clients/ksu/ccache.c:368 ++#, c-format ++msgid "home directory path for %s too long\n" ++msgstr "Home-Verzeichnispfad für %s zu lang\n" ++ ++#: ../../src/clients/ksu/ccache.c:461 ++msgid "while retrieving principal name" ++msgstr "beim Abfragen des Principal-Namens" ++ ++#: ../../src/clients/ksu/krb_auth_su.c:57 ++#: ../../src/clients/ksu/krb_auth_su.c:62 ../../src/slave/kprop.c:247 ++msgid "while copying client principal" ++msgstr "beim Kopieren des Client-Principals" ++ ++#: ../../src/clients/ksu/krb_auth_su.c:69 ++msgid "while creating tgt for local realm" ++msgstr "beim Erstellen des TGTs für lokalen Realm" ++ ++#: ../../src/clients/ksu/krb_auth_su.c:84 ++msgid "while retrieving creds from cache" ++msgstr "beim Abfragen der Anmeldedaten aus dem Zwischenspeicher" ++ ++#: ../../src/clients/ksu/krb_auth_su.c:95 ++msgid "while switching to target uid" ++msgstr "beim Umschalten auf die Ziel-UID" ++ ++#: ../../src/clients/ksu/krb_auth_su.c:100 ++#, c-format ++msgid "" ++"WARNING: Your password may be exposed if you enter it here and are logged \n" ++msgstr "" ++"WARNUNG: Ihr Passwort könnte offengelegt werden, falls Sie es hier eingeben " ++"und\n" ++ ++#: ../../src/clients/ksu/krb_auth_su.c:102 ++#, c-format ++msgid " in remotely using an unsecure (non-encrypted) channel. \n" ++msgstr "" ++" in der Ferne mittels eines unsicheren (unverschlüsselten) Kanals\n" ++" angemeldet sind.\n" ++ ++#: ../../src/clients/ksu/krb_auth_su.c:114 ../../src/clients/ksu/main.c:464 ++msgid "while reclaiming root uid" ++msgstr "beim erneuten Beanspruchen der Root-UID" ++ ++#: ../../src/clients/ksu/krb_auth_su.c:121 ++#, c-format ++msgid "does not have any appropriate tickets in the cache.\n" ++msgstr "hat keine geeigneten Tickets im Zwischenspeicher.\n" ++ ++#: ../../src/clients/ksu/krb_auth_su.c:133 ++msgid "while verifying ticket for server" ++msgstr "beim Prüfen des Tickets für Server" ++ ++#: ../../src/clients/ksu/krb_auth_su.c:167 ++msgid "while getting time of day" ++msgstr "beim Holen der Tageszeit" ++ ++#: ../../src/clients/ksu/krb_auth_su.c:171 ++#, c-format ++msgid "Kerberos password for %s: " ++msgstr "Kerberos-Passwort für %s: " ++ ++#: ../../src/clients/ksu/krb_auth_su.c:175 ++#, c-format ++msgid "principal name %s too long for internal buffer space\n" ++msgstr "Principal-Name %s für den internen Pufferbereich zu groß\n" ++ ++#: ../../src/clients/ksu/krb_auth_su.c:184 ++#, c-format ++msgid "while reading password for '%s'\n" ++msgstr "beim Lesen des Passworts für »%s«\n" ++ ++#: ../../src/clients/ksu/krb_auth_su.c:191 ++#, c-format ++msgid "No password given\n" ++msgstr "kein Passwort angegeben\n" ++ ++#: ../../src/clients/ksu/krb_auth_su.c:204 ++#, c-format ++msgid "%s: Password incorrect\n" ++msgstr "%s: Passwort falsch\n" ++ ++#: ../../src/clients/ksu/krb_auth_su.c:206 ++msgid "while getting initial credentials" ++msgstr "beim Holen der Anfangsanmeldedaten" ++ ++#: ../../src/clients/ksu/krb_auth_su.c:226 ++#: ../../src/clients/ksu/krb_auth_su.c:240 ++#, c-format ++msgid " %s while unparsing name\n" ++msgstr "%s beim Rückgängigmachen der Namensauswertung\n" ++ ++#: ../../src/clients/ksu/main.c:68 ++#, c-format ++msgid "" ++"Usage: %s [target user] [-n principal] [-c source cachename] [-k] [-D] [-r " ++"time] [-pf] [-l lifetime] [-zZ] [-q] [-e command [args... ] ] [-a " ++"[args... ] ]\n" ++msgstr "" ++"Aufruf: %s [Zielbenutzer] [-n Principal] [-c Quellenzwischenspeichername] [-" ++"k] [-D] [-r Zeit] [-pf] [-l Lebensdauer] [-zZ] [-q] [-e Befehl [Argumente " ++"…] ] [-a [Argumente …] ]\n" ++ ++#: ../../src/clients/ksu/main.c:147 ++msgid "" ++"program name too long - quitting to avoid triggering system logging bugs" ++msgstr "" ++"Programmname zu lang – wird beendet, um das Auslösen von " ++"Systemprotokollierungsfehlern zu vermeiden" ++ ++#: ../../src/clients/ksu/main.c:173 ++msgid "while allocating memory" ++msgstr "bei Reservieren von Speicher" ++ ++#: ../../src/clients/ksu/main.c:186 ++msgid "while setting euid to source user" ++msgstr "beim Setzen der EUID auf dem Quellbenutzer" ++ ++#: ../../src/clients/ksu/main.c:196 ../../src/clients/ksu/main.c:231 ++#, c-format ++msgid "Bad lifetime value (%s hours?)\n" ++msgstr "falscher Wert für Lebensdauer (%s Stunden?)\n" ++ ++#: ../../src/clients/ksu/main.c:208 ../../src/clients/ksu/main.c:292 ++msgid "when gathering parameters" ++msgstr "beim Zusammenstellen der Parameter" ++ ++#: ../../src/clients/ksu/main.c:251 ++#, c-format ++msgid "-z option is mutually exclusive with -Z.\n" ++msgstr "Die Optionen -z und -Z schließen sich gegenseitig aus.\n" ++ ++#: ../../src/clients/ksu/main.c:259 ++#, c-format ++msgid "-Z option is mutually exclusive with -z.\n" ++msgstr "Die Optionen -Z und -z schließen sich gegenseitig aus.\n" ++ ++#: ../../src/clients/ksu/main.c:272 ++#, c-format ++msgid "while looking for credentials cache %s" ++msgstr "beim Suchen nach dem Anmeldedatenzwischenspeicher %s" ++ ++#: ../../src/clients/ksu/main.c:278 ++#, c-format ++msgid "malformed credential cache name %s\n" ++msgstr "falsch gebildeter Anmeldedatenzwischenspeichername %s\n" ++ ++# ksu ist eine Kerberos-Variante von su ++#: ../../src/clients/ksu/main.c:336 ++#, c-format ++msgid "ksu: who are you?\n" ++msgstr "ksu: Wer sind Sie?\n" ++ ++#: ../../src/clients/ksu/main.c:340 ++#, c-format ++msgid "Your uid doesn't match your passwd entry?!\n" ++msgstr "Ihre UID passt nicht zu Ihrem Passworteintrag.\n" ++ ++#: ../../src/clients/ksu/main.c:355 ++#, c-format ++msgid "ksu: unknown login %s\n" ++msgstr "ksu: unbekannter Anmeldename %s\n" ++ ++#: ../../src/clients/ksu/main.c:375 ++msgid "while getting source cache" ++msgstr "beim Holen des Quellenzwischenspeichers" ++ ++#: ../../src/clients/ksu/main.c:381 ../../src/clients/kvno/kvno.c:194 ++msgid "while opening ccache" ++msgstr "beim Öffnen des Ccaches" ++ ++#: ../../src/clients/ksu/main.c:389 ++msgid "while selecting the best principal" ++msgstr "beim Auswählen des besten Principals" ++ ++#: ../../src/clients/ksu/main.c:397 ++msgid "while returning to source uid after finding best principal" ++msgstr "" ++"bei der Rückkehr zur Quell-UID, nachdem der beste Principal gefunden wurde" ++ ++#: ../../src/clients/ksu/main.c:417 ++#, c-format ++msgid "account %s: authorization failed\n" ++msgstr "Konto %s: Autorisierung fehlgeschlagen\n" ++ ++#: ../../src/clients/ksu/main.c:442 ++msgid "while parsing temporary name" ++msgstr "beim Auswertens des temporären Namens" ++ ++#: ../../src/clients/ksu/main.c:447 ++msgid "while creating temporary cache" ++msgstr "bei Erstellen des temporären Zwischenspeichers" ++ ++#: ../../src/clients/ksu/main.c:453 ../../src/clients/ksu/main.c:693 ++#, c-format ++msgid "while copying cache %s to %s" ++msgstr "beim Kopieren des Zwischenspeichers %s nach %s" ++ ++#: ../../src/clients/ksu/main.c:471 ++#, c-format ++msgid "" ++"WARNING: Your password may be exposed if you enter it here and are logged\n" ++msgstr "" ++"WARNUNG: Ihr Passwort könnte offengelegt werden, falls Sie es hier eingeben " ++"und\n" ++ ++#: ../../src/clients/ksu/main.c:473 ++#, c-format ++msgid " in remotely using an unsecure (non-encrypted) channel.\n" ++msgstr "" ++" in der Ferne über einen unsicheren (unverschlüsselten) Kanal " ++"angemeldet\n" ++"sind.\n" ++ ++#: ../../src/clients/ksu/main.c:479 ++#, c-format ++msgid "Goodbye\n" ++msgstr "Auf Wiedersehen\n" ++ ++#: ../../src/clients/ksu/main.c:483 ++#, c-format ++msgid "Could not get a tgt for " ++msgstr "Es konnte kein TGT geholt werden für " ++ ++#: ../../src/clients/ksu/main.c:505 ++#, c-format ++msgid "Authentication failed.\n" ++msgstr "Authentifizierung fehlgeschlagen.\n" ++ ++#: ../../src/clients/ksu/main.c:513 ++msgid "When unparsing name" ++msgstr "beim Rückgängigmachen der Namensauswertung" ++ ++#: ../../src/clients/ksu/main.c:517 ++#, c-format ++msgid "Authenticated %s\n" ++msgstr "Authentifiziert %s\n" ++ ++#: ../../src/clients/ksu/main.c:524 ++msgid "while switching to target for authorization check" ++msgstr "beim Wechsel des Ziels der Autorisierungsprüfung" ++ ++#: ../../src/clients/ksu/main.c:531 ++msgid "while checking authorization" ++msgstr "beim Prüfen der Autorisierung" ++ ++#: ../../src/clients/ksu/main.c:537 ++msgid "while switching back from target after authorization check" ++msgstr "beim Zurückwechsel vom Ziel nach der Autorisierungsprüfung" ++ ++#: ../../src/clients/ksu/main.c:544 ++#, c-format ++msgid "Account %s: authorization for %s for execution of\n" ++msgstr "Konto %s: Autorisierung für %s zum Ausführen von\n" ++ ++#: ../../src/clients/ksu/main.c:546 ++#, c-format ++msgid " %s successful\n" ++msgstr " %s erfolgreich\n" ++ ++#: ../../src/clients/ksu/main.c:552 ++#, c-format ++msgid "Account %s: authorization for %s successful\n" ++msgstr "Konto %s: Autorisierung für %s erfolgreich\n" ++ ++#: ../../src/clients/ksu/main.c:564 ++#, c-format ++msgid "Account %s: authorization for %s for execution of %s failed\n" ++msgstr "Konto %s: Autorisierung für %s zum Ausführen von %s fehlgeschlagen\n" ++ ++#: ../../src/clients/ksu/main.c:572 ++#, c-format ++msgid "Account %s: authorization of %s failed\n" ++msgstr "Konto %s: Autorisierung von %s fehlgeschlagen\n" ++ ++#: ../../src/clients/ksu/main.c:587 ++msgid "while calling cc_filter" ++msgstr "beim Aufruf von »cc_filter«" ++ ++#: ../../src/clients/ksu/main.c:595 ++msgid "while erasing target cache" ++msgstr "bei Löschen des Zielzwischenspeichers" ++ ++#: ../../src/clients/ksu/main.c:615 ++#, c-format ++msgid "ksu: permission denied (shell).\n" ++msgstr "ksu: Zugriff verweigert (Shell)\n" ++ ++#: ../../src/clients/ksu/main.c:624 ++#, c-format ++msgid "ksu: couldn't set environment variable USER\n" ++msgstr "ksu: Umgebungsvariable USER kann nicht gesetzt werden\n" ++ ++#: ../../src/clients/ksu/main.c:630 ++#, c-format ++msgid "ksu: couldn't set environment variable HOME\n" ++msgstr "ksu: Umgebungsvariable HOME kann nicht gesetzt werden\n" ++ ++#: ../../src/clients/ksu/main.c:635 ++#, c-format ++msgid "ksu: couldn't set environment variable SHELL\n" ++msgstr "ksu: Umgebungsvariable SHELL kann nicht gesetzt werden\n" ++ ++#: ../../src/clients/ksu/main.c:646 ++#, c-format ++msgid "ksu: initgroups failed.\n" ++msgstr "ksu: »initgroups« fehlgeschlagen\n" ++ ++#: ../../src/clients/ksu/main.c:651 ++#, c-format ++msgid "Leaving uid as %s (%ld)\n" ++msgstr "UID bleibt %s (%ld)\n" ++ ++#: ../../src/clients/ksu/main.c:654 ++#, c-format ++msgid "Changing uid to %s (%ld)\n" ++msgstr "UID wird zu %s (%ld) geändert\n" ++ ++#: ../../src/clients/ksu/main.c:680 ++msgid "while getting name of target ccache" ++msgstr "beim Holen des Ziel-Ccache-Namens" ++ ++#: ../../src/clients/ksu/main.c:700 ++#, c-format ++msgid "%s does not have correct permissions for %s, %s aborted" ++msgstr "%s hat nicht die korrekten Rechte für %s, %s wird abgebrochen." ++ ++#: ../../src/clients/ksu/main.c:721 ++#, c-format ++msgid "Internal error: command %s did not get resolved\n" ++msgstr "Interner Fehler: Befehl %s wurde nicht aufgelöst\n" ++ ++#: ../../src/clients/ksu/main.c:738 ../../src/clients/ksu/main.c:774 ++#, c-format ++msgid "while trying to execv %s" ++msgstr "beim Versuch von »execv %s«" ++ ++#: ../../src/clients/ksu/main.c:764 ++msgid "while calling waitpid" ++msgstr "beim Aufruf von »waitpid«" ++ ++#: ../../src/clients/ksu/main.c:769 ++msgid "while trying to fork." ++msgstr "beim Versuch zu verzweigen." ++ ++#: ../../src/clients/ksu/main.c:791 ++msgid "while reading cache name from ccache" ++msgstr "beim Lesen des Zwischenspeichernamens aus dem Ccache" ++ ++#: ../../src/clients/ksu/main.c:797 ++#, c-format ++msgid "ksu: couldn't set environment variable %s\n" ++msgstr "ksu: Umgebungsvariable %s kann nicht gesetzt werden\n" ++ ++#: ../../src/clients/ksu/main.c:820 ++#, c-format ++msgid "while clearing the value of %s" ++msgstr "beim Leeren des Werts von %s" ++ ++#: ../../src/clients/ksu/main.c:828 ++msgid "while resetting target ccache name" ++msgstr "beim Zurücksetzen des Ziel-Ccache-Namens" ++ ++#: ../../src/clients/ksu/main.c:842 ++msgid "while determining target ccache name" ++msgstr "beim Bestimmen des Ziel-Ccache-Namens" ++ ++#: ../../src/clients/ksu/main.c:881 ++msgid "while generating part of the target ccache name" ++msgstr "beim Erzeugen eines Teils des Ziel-Ccache-Namens" ++ ++#: ../../src/clients/ksu/main.c:887 ++msgid "while allocating memory for the target ccache name" ++msgstr "beim Reservieren von Speicher für den Ziel-Ccache-Namen" ++ ++#: ../../src/clients/ksu/main.c:906 ++msgid "while creating new target ccache" ++msgstr "bei Erstellen von neuem Ziel-Ccache" ++ ++#: ../../src/clients/ksu/main.c:912 ++msgid "while initializing target cache" ++msgstr "beim Initialisieren des Zielzwischenspeichers" ++ ++#: ../../src/clients/ksu/main.c:952 ++#, c-format ++msgid "terminal name %s too long\n" ++msgstr "Terminal-Name %s ist zu lang.\n" ++ ++#: ../../src/clients/ksu/main.c:980 ++msgid "while changing to target uid for destroying ccache" ++msgstr "beim Ändern der Ziel-UID für das Zerstören von Ccache" ++ ++#: ../../src/clients/kswitch/kswitch.c:44 ++#, c-format ++msgid "Usage: %s {-c cache_name | -p principal}\n" ++msgstr "Aufruf: %s {-c Zwischenspeichername | -p Principal}\n" ++ ++#: ../../src/clients/kswitch/kswitch.c:46 ++#, c-format ++msgid "\t-p specify name of principal\n" ++msgstr "\t-p gibt den Namen des Principals an.\n" ++ ++#: ../../src/clients/kswitch/kswitch.c:69 ++#, c-format ++msgid "Only one -c or -p option allowed\n" ++msgstr "Nur eine der Optionen -c oder -p ist erlaubt.\n" ++ ++#: ../../src/clients/kswitch/kswitch.c:88 ++#, c-format ++msgid "One of -c or -p must be specified\n" ++msgstr "Entweder -c oder -p muss angegeben werden.\n" ++ ++#: ../../src/clients/kswitch/kswitch.c:110 ../../src/clients/kvno/kvno.c:211 ++#: ../../src/clients/kvno/kvno.c:245 ../../src/kadmin/cli/keytab.c:350 ++#: ../../src/kadmin/dbutil/kdb5_util.c:576 ++#, c-format ++msgid "while parsing principal name %s" ++msgstr "beim Auswerten des Principal-Namens %s" ++ ++#: ../../src/clients/kswitch/kswitch.c:124 ++msgid "while switching to credential cache" ++msgstr "beim Wechsel auf den Anmeldedatenzwischenspeicher" ++ ++#: ../../src/clients/kvno/kvno.c:46 ++#, c-format ++msgid "usage: %s [-C] [-u] [-c ccache] [-e etype]\n" ++msgstr "Aufruf: %s [-C] [-u] [-c Ccache] [-e Etype]\n" ++ ++#: ../../src/clients/kvno/kvno.c:47 ++#, c-format ++msgid "\t[-k keytab] [-S sname] [-U for_user [-P]]\n" ++msgstr "\t[-k Schlüsseltabelle] [-S Sname] [-U für_Benutzer [-P]]\n" ++ ++#: ../../src/clients/kvno/kvno.c:48 ++#, c-format ++msgid "\tservice1 service2 ...\n" ++msgstr "\tDienst1 Dienst2 …\n" ++ ++#: ../../src/clients/kvno/kvno.c:103 ../../src/clients/kvno/kvno.c:111 ++#, c-format ++msgid "Options -u and -S are mutually exclusive\n" ++msgstr "Die Optionen -u und -S schließen sich gegenseitig aus.\n" ++ ++#: ../../src/clients/kvno/kvno.c:126 ++#, c-format ++msgid "Option -P (constrained delegation) requires keytab to be specified\n" ++msgstr "" ++"Die Option -P (eingeschränkte Abtretung) erfordert zur Angabe eine " ++"Schlüsseltabelle.\n" ++ ++#: ../../src/clients/kvno/kvno.c:130 ++#, c-format ++msgid "" ++"Option -P (constrained delegation) requires option -U (protocol transition)\n" ++msgstr "" ++"Die Option -P (eingeschränkte Abtretung) erfordert die Option -U " ++"(Protokollübergang)\n" ++ ++#: ../../src/clients/kvno/kvno.c:175 ../../src/kadmin/cli/kadmin.c:280 ++msgid "while initializing krb5 library" ++msgstr "beim Initialisieren der Krb5-Bibliothek" ++ ++#: ../../src/clients/kvno/kvno.c:182 ++msgid "while converting etype" ++msgstr "bei der Etype-Umwandlung" ++ ++#: ../../src/clients/kvno/kvno.c:218 ++msgid "while getting client principal name" ++msgstr "beim Holen des Client-Principal-Namens" ++ ++#: ../../src/clients/kvno/kvno.c:256 ++#, c-format ++msgid "while formatting parsed principal name for '%s'" ++msgstr "beim Formatieren des ausgewerteten Principal-Namens für »%s«" ++ ++#: ../../src/clients/kvno/kvno.c:267 ++msgid "client and server principal names must match" ++msgstr "Die Principal-Namen von Client und Server müssen übereinstimmen." ++ ++#: ../../src/clients/kvno/kvno.c:284 ++#, c-format ++msgid "while getting credentials for %s" ++msgstr "beim Holen der Anmeldedaten für %s" ++ ++#: ../../src/clients/kvno/kvno.c:291 ++#, c-format ++msgid "while decoding ticket for %s" ++msgstr "beim Dekodieren des Tickets für %s" ++ ++#: ../../src/clients/kvno/kvno.c:302 ++#, c-format ++msgid "while decrypting ticket for %s" ++msgstr "beim Entschlüsseln des Tickets für %s" ++ ++#: ../../src/clients/kvno/kvno.c:306 ++#, c-format ++msgid "%s: kvno = %d, keytab entry valid\n" ++msgstr "%s: KVNO = %d, Schlüsseltabelleneintrag gültig\n" ++ ++#: ../../src/clients/kvno/kvno.c:324 ++#, c-format ++msgid "%s: constrained delegation failed" ++msgstr "%s: eingeschränkte Abtretung fehlgeschlagen" ++ ++#: ../../src/clients/kvno/kvno.c:330 ++#, c-format ++msgid "%s: kvno = %d\n" ++msgstr "%s: KVNO = %d\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:118 ++#, c-format ++msgid "" ++"Usage: %s [-r realm] [-p principal] [-q query] [clnt|local args]\n" ++"\tclnt args: [-s admin_server[:port]] [[-c ccache]|[-k [-t keytab]]]|[-n]\n" ++"\tlocal args: [-x db_args]* [-d dbname] [-e \"enc:salt ...\"] [-m]\n" ++"where,\n" ++"\t[-x db_args]* - any number of database specific arguments.\n" ++"\t\t\tLook at each database documentation for supported arguments\n" ++msgstr "" ++"Aufruf: %s [-r Realm] [-p Principal] [-q Abfrage] [clnt|lokale Argumente]\n" ++"\tclnt Argumente: [-s Admin-Server[:Port]] [[-c Ccache]|\n" ++"\t[-k [-t Schlüsseltabelle]]]|[-n] lokale Argumente: [-x DB-Argumente]*\n" ++"\t[-d Datenbankname] [-e \"enc:Salt …\"] [-m]\n" ++"wobei\n" ++"\t[-x DB-Argumente]* - eine beliebige Anzahl datenbankspezifischer " ++"Argumente\n" ++"\tist. Die unterstützten Argumente finden Sie in den jeweiligen " ++"\tDatenbankdokumentationen\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:292 ../../src/kadmin/cli/kadmin.c:333 ++#, c-format ++msgid "%s: Cannot initialize. Not enough memory\n" ++msgstr "%s: Zu wenig Speicher zum Initialisieren\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:353 ../../src/kadmin/cli/kadmin.c:804 ++#: ../../src/kadmin/cli/kadmin.c:1084 ../../src/kadmin/cli/kadmin.c:1634 ++#: ../../src/kadmin/cli/keytab.c:159 ../../src/kadmin/dbutil/kdb5_util.c:591 ++#, c-format ++msgid "while parsing keysalts %s" ++msgstr "beim Auswerten der Schlüssel-Salts %s" ++ ++#: ../../src/kadmin/cli/kadmin.c:376 ++#, c-format ++msgid "%s: unable to get default realm\n" ++msgstr "%s: Standard-Realm kann nicht geholt werden\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:396 ++msgid "while opening default credentials cache" ++msgstr "beim Öffnen des Standardanmeldedatenzwischenspeichers" ++ ++#: ../../src/kadmin/cli/kadmin.c:402 ++#, c-format ++msgid "while opening credentials cache %s" ++msgstr "beim Öffnen des Anmeldedatenzwischenspeichers %s" ++ ++#: ../../src/kadmin/cli/kadmin.c:424 ../../src/kadmin/cli/kadmin.c:479 ++#: ../../src/kadmin/cli/kadmin.c:487 ../../src/kadmin/cli/kadmin.c:494 ++#, c-format ++msgid "%s: out of memory\n" ++msgstr "%s: Speicherplatz reicht nicht aus\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:433 ../../src/kadmin/cli/kadmin.c:448 ++#: ../../src/slave/kpropd.c:681 ++msgid "while canonicalizing principal name" ++msgstr "während der Principal-Name in die normale Form gebracht wird" ++ ++#: ../../src/kadmin/cli/kadmin.c:442 ++msgid "creating host service principal" ++msgstr "Principal des Rechnerdienstes wird erstellt" ++ ++#: ../../src/kadmin/cli/kadmin.c:455 ++#, c-format ++msgid "%s: unable to canonicalize principal\n" ++msgstr "%s: Principal kann nicht in die normale Form gebracht werden\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:499 ++#, c-format ++msgid "%s: unable to figure out a principal name\n" ++msgstr "%s: Es kann kein Principal-Name herausgefunden werden.\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:507 ++msgid "while setting up logging" ++msgstr "beim Einrichten der Protokollierung" ++ ++#: ../../src/kadmin/cli/kadmin.c:516 ++#, c-format ++msgid "Authenticating as principal %s with existing credentials.\n" ++msgstr "Authentifizierung als Principal %s mit existierenden Anmeldedaten\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:522 ++#, c-format ++msgid "Authenticating as principal %s with password; anonymous requested.\n" ++msgstr "" ++"Authentifizierung als Principal %s mit Passwort; Anonymität erwünscht\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:529 ++#, c-format ++msgid "Authenticating as principal %s with keytab %s.\n" ++msgstr "Authentifizierung als Principal %s mit Schlüsseltabelle %s\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:532 ++#, c-format ++msgid "Authenticating as principal %s with default keytab.\n" ++msgstr "Authentifizierung als Principal %s mit Standardschlüsseltabelle\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:538 ++#, c-format ++msgid "Authenticating as principal %s with password.\n" ++msgstr "Authentifizierung als Principal %s mit Passwort\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:546 ../../src/slave/kpropd.c:728 ++#, c-format ++msgid "while initializing %s interface" ++msgstr "beim Initialisieren der Schnittstelle %s" ++ ++#: ../../src/kadmin/cli/kadmin.c:560 ++#, c-format ++msgid "while closing ccache %s" ++msgstr "beim Schließen von Ccache %s" ++ ++#: ../../src/kadmin/cli/kadmin.c:566 ++msgid "while mapping update log" ++msgstr "beim Abbilden des Aktualisierungsprotokolls" ++ ++#: ../../src/kadmin/cli/kadmin.c:581 ++msgid "while unlocking locked database" ++msgstr "beim Entsperren der Datenbank" ++ ++#: ../../src/kadmin/cli/kadmin.c:590 ++msgid "Administration credentials NOT DESTROYED.\n" ++msgstr "Verwaltungsanmeldedaten NICHT VERNICHTET\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:639 ++#, c-format ++msgid "usage: delete_principal [-force] principal\n" ++msgstr "Aufruf: delete_principal [-force] Principal\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:644 ../../src/kadmin/cli/kadmin.c:819 ++msgid "while parsing principal name" ++msgstr "beim Auswerten des Principal-Namens" ++ ++#: ../../src/kadmin/cli/kadmin.c:650 ../../src/kadmin/cli/kadmin.c:825 ++#: ../../src/kadmin/cli/kadmin.c:1217 ../../src/kadmin/cli/kadmin.c:1339 ++#: ../../src/kadmin/cli/kadmin.c:1409 ../../src/kadmin/cli/kadmin.c:1858 ++#: ../../src/kadmin/cli/kadmin.c:1902 ../../src/kadmin/cli/kadmin.c:1948 ++#: ../../src/kadmin/cli/kadmin.c:1988 ++msgid "while canonicalizing principal" ++msgstr "während der Principal in die normale Form gebracht wird" ++ ++#: ../../src/kadmin/cli/kadmin.c:654 ++#, c-format ++msgid "Are you sure you want to delete the principal \"%s\"? (yes/no): " ++msgstr "" ++"Sind Sie sicher, dass Sie den Principal »%s« löschen möchten? (yes/no): " ++ ++#: ../../src/kadmin/cli/kadmin.c:658 ++#, c-format ++msgid "Principal \"%s\" not deleted\n" ++msgstr "Principal »%s« nicht gelöscht\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:665 ++#, c-format ++msgid "while deleting principal \"%s\"" ++msgstr "beim Löschen von Principal »%s«" ++ ++#: ../../src/kadmin/cli/kadmin.c:668 ++#, c-format ++msgid "Principal \"%s\" deleted.\n" ++msgstr "Principal »%s« gelöscht\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:669 ++#, c-format ++msgid "" ++"Make sure that you have removed this principal from all ACLs before " ++"reusing.\n" ++msgstr "" ++"Stellen Sie sicher, dass Sie diesen Principal aus allen ACLs entfernt haben, " ++"bevor Sie ihn erneut benutzen.\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:686 ++#, c-format ++msgid "usage: rename_principal [-force] old_principal new_principal\n" ++msgstr "Aufruf: rename_principal [-force] alter_Principal neuer_Principal\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:693 ++msgid "while parsing old principal name" ++msgstr "beim Auswerten des alten Principal-Namens" ++ ++#: ../../src/kadmin/cli/kadmin.c:699 ++msgid "while parsing new principal name" ++msgstr "beim Auswerten des neuen Principal-Namens" ++ ++#: ../../src/kadmin/cli/kadmin.c:705 ++msgid "while canonicalizing old principal" ++msgstr "während der alte Principal in die normale Form gebracht wird" ++ ++#: ../../src/kadmin/cli/kadmin.c:711 ++msgid "while canonicalizing new principal" ++msgstr "während der neue Principal in die normale Form gebracht wird" ++ ++#: ../../src/kadmin/cli/kadmin.c:715 ++#, c-format ++msgid "" ++"Are you sure you want to rename the principal \"%s\" to \"%s\"? (yes/no): " ++msgstr "" ++"Sind Sie sicher, dass Sie den Principal »%s« in »%s« umbenennen möchten? " ++"(yes/no): " ++ ++#: ../../src/kadmin/cli/kadmin.c:719 ++#, c-format ++msgid "Principal \"%s\" not renamed\n" ++msgstr "Principal »%s« wurde nicht umbenannt.\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:726 ++#, c-format ++msgid "while renaming principal \"%s\" to \"%s\"" ++msgstr "beim Umbenennen von Principal »%s« in »%s«" ++ ++#: ../../src/kadmin/cli/kadmin.c:730 ++#, c-format ++msgid "Principal \"%s\" renamed to \"%s\".\n" ++msgstr "Principal »%s« wurde in »%s« umbenannt.\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:731 ++#, c-format ++msgid "" ++"Make sure that you have removed the old principal from all ACLs before " ++"reusing.\n" ++msgstr "" ++"Stellen Sie sicher, dass Sie den alten Principal aus allen ACLs entfernt " ++"haben, bevor Sie ihn erneut benutzen.\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:746 ++#, c-format ++msgid "" ++"usage: change_password [-randkey] [-keepold] [-e keysaltlist] [-pw password] " ++"principal\n" ++msgstr "" ++"Aufruf: change_password [-randkey] [-keepold] [-e Schlüssel-Salt-Liste] [-pw " ++"Passwort] Principal\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:772 ++msgid "change_password: missing db argument" ++msgstr "change_password: fehlendes Datenbankargument" ++ ++#: ../../src/kadmin/cli/kadmin.c:778 ++#, c-format ++msgid "change_password: Not enough memory\n" ++msgstr "change_password: zu wenig Speicher\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:786 ++msgid "change_password: missing password arg" ++msgstr "change_password: fehlendes Passwortargument" ++ ++#: ../../src/kadmin/cli/kadmin.c:797 ++msgid "change_password: missing keysaltlist arg" ++msgstr "change_password: fehlendes Schlüssel-Salt-Listenargument" ++ ++#: ../../src/kadmin/cli/kadmin.c:813 ++msgid "missing principal name" ++msgstr "fehlender Principal-Name" ++ ++#: ../../src/kadmin/cli/kadmin.c:837 ../../src/kadmin/cli/kadmin.c:874 ++#, c-format ++msgid "while changing password for \"%s\"." ++msgstr "beim Ändern des Passworts von »%s«." ++ ++#: ../../src/kadmin/cli/kadmin.c:840 ../../src/kadmin/cli/kadmin.c:877 ++#, c-format ++msgid "Password for \"%s\" changed.\n" ++msgstr "Passwort von »%s« geändert\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:846 ../../src/kadmin/cli/kadmin.c:1290 ++#, c-format ++msgid "while randomizing key for \"%s\"." ++msgstr "beim Erzeugen eines zufälligen Schlüssels für »%s«." ++ ++#: ../../src/kadmin/cli/kadmin.c:849 ++#, c-format ++msgid "Key for \"%s\" randomized.\n" ++msgstr "Es wurde ein zufälliger Schlüssel für %s erzeugt\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:854 ../../src/kadmin/cli/kadmin.c:1250 ++#, c-format ++msgid "Enter password for principal \"%s\"" ++msgstr "Geben Sie das Passwort für Principal »%s« ein." ++ ++#: ../../src/kadmin/cli/kadmin.c:856 ../../src/kadmin/cli/kadmin.c:1252 ++#, c-format ++msgid "Re-enter password for principal \"%s\"" ++msgstr "Geben Sie das Passwort für Principal »%s« erneut ein." ++ ++#: ../../src/kadmin/cli/kadmin.c:861 ../../src/kadmin/cli/kadmin.c:1256 ++#, c-format ++msgid "while reading password for \"%s\"." ++msgstr "beim Lesen des Passworts von »%s«." ++ ++#: ../../src/kadmin/cli/kadmin.c:915 ++#, c-format ++msgid "Not enough memory\n" ++msgstr "Speicher reicht nicht aus\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:945 ../../src/kadmin/dbutil/kdb5_util.c:623 ++msgid "while getting time" ++msgstr "beim Holen der Zeit" ++ ++#: ../../src/kadmin/cli/kadmin.c:994 ../../src/kadmin/cli/kadmin.c:1007 ++#: ../../src/kadmin/cli/kadmin.c:1020 ../../src/kadmin/cli/kadmin.c:1033 ++#: ../../src/kadmin/cli/kadmin.c:1546 ../../src/kadmin/cli/kadmin.c:1558 ++#: ../../src/kadmin/cli/kadmin.c:1601 ../../src/kadmin/cli/kadmin.c:1618 ++#, c-format ++msgid "Invalid date specification \"%s\".\n" ++msgstr "ungültige Datumsangabe »%s«\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1118 ../../src/kadmin/cli/kadmin.c:1333 ++#: ../../src/kadmin/cli/kadmin.c:1404 ../../src/kadmin/cli/kadmin.c:1852 ++#: ../../src/kadmin/cli/kadmin.c:1896 ../../src/kadmin/cli/kadmin.c:1942 ++#: ../../src/kadmin/cli/kadmin.c:1982 ++msgid "while parsing principal" ++msgstr "beim Auswerten des Principals" ++ ++#: ../../src/kadmin/cli/kadmin.c:1127 ++#, c-format ++msgid "usage: add_principal [options] principal\n" ++msgstr "Aufruf: add_principal [Optionen] Principal\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1128 ../../src/kadmin/cli/kadmin.c:1155 ++#: ../../src/kadmin/cli/kadmin.c:1657 ++#, c-format ++msgid "\toptions are:\n" ++msgstr "\tEs gibt folgende Optionen:\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1130 ++#, c-format ++msgid "" ++"\t\t[-randkey|-nokey] [-x db_princ_args]* [-expire expdate] [-pwexpire " ++"pwexpdate] [-maxlife maxtixlife]\n" ++"\t\t[-kvno kvno] [-policy policy] [-clearpolicy]\n" ++"\t\t[-pw password] [-maxrenewlife maxrenewlife]\n" ++"\t\t[-e keysaltlist]\n" ++"\t\t[{+|-}attribute]\n" ++msgstr "" ++"\t\t[-randkey|-nokey] [-x DB-Principal-Argumente]* [-expire Ablaufdatum] [-" ++"pwexpire Passwortablaufdatum] [-maxlife maximale_Ticketlebensdauer]\n" ++"\t\t[-kvno KVNO] [-policy Richtlinie] [-clearpolicy]\n" ++"\t\t[-pw Passwort] [-maxrenewlife maximale_Dauer_bis_zum_Erneuern]\n" ++"\t\t[-e Schlüssel-Salt-Liste]\n" ++"\t\t[{+|-}Attribut]\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1136 ++#, c-format ++msgid "\tattributes are:\n" ++msgstr "\tEs gibt folgende Attribute:\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1138 ../../src/kadmin/cli/kadmin.c:1164 ++#, c-format ++msgid "" ++"\t\tallow_postdated allow_forwardable allow_tgs_req allow_renewable\n" ++"\t\tallow_proxiable allow_dup_skey allow_tix requires_preauth\n" ++"\t\trequires_hwauth needchange allow_svr password_changing_service\n" ++"\t\tok_as_delegate ok_to_auth_as_delegate no_auth_data_required\n" ++"\n" ++"where,\n" ++"\t[-x db_princ_args]* - any number of database specific arguments.\n" ++"\t\t\tLook at each database documentation for supported arguments\n" ++msgstr "" ++"\t\tallow_postdated allow_forwardable allow_tgs_req allow_renewable\n" ++"\t\tallow_proxiable allow_dup_skey allow_tix requires_preauth\n" ++"\t\trequires_hwauth needchange allow_svr password_changing_service\n" ++"\t\tok_as_delegate ok_to_auth_as_delegate no_auth_data_required\n" ++"\n" ++"wobei\n" ++"\t[-x DB-Principal-Argumente]* - eine beliebige Zahl\n" ++"\tdatenbankspezifischer Argumente ist.\n" ++"\t\t\tDie unterstützten Argumente finden Sie in der jeweiligen\n" ++"Datenbankdokumentation.\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1154 ++#, c-format ++msgid "usage: modify_principal [options] principal\n" ++msgstr "Aufruf: modify_principal [Optionen] Principal\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1157 ++#, c-format ++msgid "" ++"\t\t[-x db_princ_args]* [-expire expdate] [-pwexpire pwexpdate] [-maxlife " ++"maxtixlife]\n" ++"\t\t[-kvno kvno] [-policy policy] [-clearpolicy]\n" ++"\t\t[-maxrenewlife maxrenewlife] [-unlock] [{+|-}attribute]\n" ++msgstr "" ++"\t\t[-x DB-Principal-Argumente]* [-expire Ablaufdatum] [-pwexpire " ++"Passwortablaufdatum] [-maxlife maximale_Ticketlebensdauer]\n" ++"\t\t[-kvno KVNO] [-policy Richtlinie] [-clearpolicy]\n" ++"\t\t[-maxrenewlife maximale_Dauer_bis_zum_Erneuern] [-unlock] [{+|-}" ++"Attribut]\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1224 ../../src/kadmin/cli/kadmin.c:1362 ++#, c-format ++msgid "WARNING: policy \"%s\" does not exist\n" ++msgstr "WARNUNG: Richtlinie »%s« existiert nicht.\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1230 ++#, c-format ++msgid "NOTICE: no policy specified for %s; assigning \"default\"\n" ++msgstr "" ++"HINWEIS: Für %s wurde keine Richtlinie angegeben, es wird »default« " ++"zugewiesen\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1235 ++#, c-format ++msgid "WARNING: no policy specified for %s; defaulting to no policy\n" ++msgstr "" ++"WARNUNG: Für %s wurde keine Richtlinie angegeben, es wird die Vorgabe " ++"»keine\n" ++"Richtlinie« verwandt.\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1276 ++#, c-format ++msgid "Admin server does not support -nokey while creating \"%s\"\n" ++msgstr "" ++"Der Administrationsrechner unterstützt beim Erstellen von »%s« kein -nokey\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1298 ++#, c-format ++msgid "while clearing DISALLOW_ALL_TIX for \"%s\"." ++msgstr "beim Löschen von DISALLOW_ALL_TIX für »%s«." ++ ++#: ../../src/kadmin/cli/kadmin.c:1345 ++#, c-format ++msgid "while getting \"%s\"." ++msgstr "beim Holen von »%s«." ++ ++#: ../../src/kadmin/cli/kadmin.c:1371 ++#, c-format ++msgid "while modifying \"%s\"." ++msgstr "beim Ändern von »%s«." ++ ++#: ../../src/kadmin/cli/kadmin.c:1375 ++#, c-format ++msgid "Principal \"%s\" modified.\n" ++msgstr "Principal »%s« wurde geändert.\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1396 ++#, c-format ++msgid "usage: get_principal [-terse] principal\n" ++msgstr "Aufruf: get_principal [-terse] Principal\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1415 ++#, c-format ++msgid "while retrieving \"%s\"." ++msgstr "beim Abfragen von »%s«." ++ ++#: ../../src/kadmin/cli/kadmin.c:1420 ../../src/kadmin/cli/kadmin.c:1425 ++msgid "while unparsing principal" ++msgstr "beim Rückgängigmachen der Auswertung des Principals" ++ ++#: ../../src/kadmin/cli/kadmin.c:1429 ++#, c-format ++msgid "Principal: %s\n" ++msgstr "Principal: %s\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1430 ++#, c-format ++msgid "Expiration date: %s\n" ++msgstr "Ablaufdatum: %s\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1431 ../../src/kadmin/cli/kadmin.c:1433 ++#: ../../src/kadmin/cli/kadmin.c:1444 ++msgid "[never]" ++msgstr "[niemals]" ++ ++#: ../../src/kadmin/cli/kadmin.c:1432 ++#, c-format ++msgid "Last password change: %s\n" ++msgstr "Letzte Passwortänderung: %s\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1434 ++#, c-format ++msgid "Password expiration date: %s\n" ++msgstr "Passwortablaufdatum: %s\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1436 ../../src/kadmin/cli/kadmin.c:1478 ++msgid "[none]" ++msgstr "[keins]" ++ ++#: ../../src/kadmin/cli/kadmin.c:1437 ++#, c-format ++msgid "Maximum ticket life: %s\n" ++msgstr "maximale Ticketlebensdauer: %s\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1438 ++#, c-format ++msgid "Maximum renewable life: %s\n" ++msgstr "maximale verlängerbare Lebensdauer: %s\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1440 ++#, c-format ++msgid "Last modified: %s (%s)\n" ++msgstr "zuletzt geändert: %s (%s)\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1442 ++#, c-format ++msgid "Last successful authentication: %s\n" ++msgstr "letzte erfolgreiche Authentifizierung: %s\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1448 ++#, c-format ++msgid "Failed password attempts: %d\n" ++msgstr "Fehlgeschlagene Anmeldeversuche: %d\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1450 ++#, c-format ++msgid "Number of keys: %d\n" ++msgstr "Anzahl der Schlüssel: %d\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1457 ++#, c-format ++msgid "" ++msgstr "" ++ ++#: ../../src/kadmin/cli/kadmin.c:1464 ++#, c-format ++msgid "" ++msgstr "" ++ ++#: ../../src/kadmin/cli/kadmin.c:1470 ++#, c-format ++msgid "MKey: vno %d\n" ++msgstr "MKey: vno %d\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1472 ++#, c-format ++msgid "Attributes:" ++msgstr "Attribute:" ++ ++#: ../../src/kadmin/cli/kadmin.c:1480 ++msgid " [does not exist]" ++msgstr " [existiert nicht]" ++ ++#: ../../src/kadmin/cli/kadmin.c:1481 ++#, c-format ++msgid "Policy: %s%s\n" ++msgstr "Richtlinie: %s%s\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1517 ++#, c-format ++msgid "usage: get_principals [expression]\n" ++msgstr "Aufruf: get_principals [Ausdruck]\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1522 ../../src/kadmin/cli/kadmin.c:1794 ++msgid "while retrieving list." ++msgstr "beim Abfragen der Liste." ++ ++#: ../../src/kadmin/cli/kadmin.c:1647 ++#, c-format ++msgid "%s: parser lost count!\n" ++msgstr "%s: Auswertungsprogramm verlor Anzahl!\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1656 ++#, c-format ++msgid "usage; %s [options] policy\n" ++msgstr "Aufruf: %s [Optionen] Richtlinie\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1659 ++#, c-format ++msgid "" ++"\t\t[-maxlife time] [-minlife time] [-minlength length]\n" ++"\t\t[-minclasses number] [-history number]\n" ++"\t\t[-maxfailure number] [-failurecountinterval time]\n" ++"\t\t[-allowedkeysalts keysalts]\n" ++msgstr "" ++"\t\t[-maxlife Zeit] [-minlife Zeit] [-minlength Länge]\n" ++"\t\t[-minclasses Anzahl] [-history Nummer]\n" ++"\t\t[-maxfailure Anzahl] [-failurecountinterval Zeit]\n" ++"\t\t[-allowedkeysalts Schlüssel-Salts]\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1663 ++#, c-format ++msgid "\t\t[-lockoutduration time]\n" ++msgstr "\t\t[-lockoutduration Dauer]\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1682 ++#, c-format ++msgid "while creating policy \"%s\"." ++msgstr "beim Erstellen der Richtlinie »%s«" ++ ++#: ../../src/kadmin/cli/kadmin.c:1703 ++#, c-format ++msgid "while modifying policy \"%s\"." ++msgstr "beim Ändern der Richtlinie »%s«" ++ ++#: ../../src/kadmin/cli/kadmin.c:1715 ++#, c-format ++msgid "usage: delete_policy [-force] policy\n" ++msgstr "Aufruf: delete_policy [-force] Richtlinie\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1719 ++#, c-format ++msgid "Are you sure you want to delete the policy \"%s\"? (yes/no): " ++msgstr "" ++"Sind Sie sicher, dass Sie die Richtlinie »%s« löschen möchten? (yes/no): " ++ ++#: ../../src/kadmin/cli/kadmin.c:1723 ++#, c-format ++msgid "Policy \"%s\" not deleted.\n" ++msgstr "Richtlinie »%s« nicht gelöscht\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1729 ++#, c-format ++msgid "while deleting policy \"%s\"" ++msgstr "bei Löschen der Richtlinie »%s«" ++ ++#: ../../src/kadmin/cli/kadmin.c:1741 ++#, c-format ++msgid "usage: get_policy [-terse] policy\n" ++msgstr "Aufruf: get_policy [-terse] Richtlinie\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1746 ++#, c-format ++msgid "while retrieving policy \"%s\"." ++msgstr "beim Abfragen der Richtlinie »%s«." ++ ++#: ../../src/kadmin/cli/kadmin.c:1751 ++#, c-format ++msgid "Policy: %s\n" ++msgstr "Richtlinie: »%s«\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1752 ++#, c-format ++msgid "Maximum password life: %ld\n" ++msgstr "maximale Passwortlebensdauer: %ld\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1753 ++#, c-format ++msgid "Minimum password life: %ld\n" ++msgstr "minimale Passwortlebensdauer: %ld\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1754 ++#, c-format ++msgid "Minimum password length: %ld\n" ++msgstr "minimale Passwortlänge: %ld\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1755 ++#, c-format ++msgid "Minimum number of password character classes: %ld\n" ++msgstr "minimale Anzahl von Passwortzeichenklassen: %ld\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1757 ++#, c-format ++msgid "Number of old keys kept: %ld\n" ++msgstr "Anzahl aufbewahrter alter Schlüssel: %ld\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1758 ++#, c-format ++msgid "Maximum password failures before lockout: %lu\n" ++msgstr "maximale Anzahl falscher Passworteingaben vor dem Sperren: %lu\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1760 ++#, c-format ++msgid "Password failure count reset interval: %s\n" ++msgstr "Rücksetzintervall für zu viele falsch eingebene Passwörter: %s\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1762 ++#, c-format ++msgid "Password lockout duration: %s\n" ++msgstr "Passwortsperrdauer: %s\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1765 ++#, c-format ++msgid "Allowed key/salt types: %s\n" ++msgstr "erlaubte Schlüssel-/Salt-Typen: %s\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1789 ++#, c-format ++msgid "usage: get_policies [expression]\n" ++msgstr "Aufruf: get_policies [Ausdruck]\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1811 ++#, c-format ++msgid "usage: get_privs\n" ++msgstr "Aufruf: get_privs\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1816 ++msgid "while retrieving privileges" ++msgstr "beim Abfragen von Rechten" ++ ++#: ../../src/kadmin/cli/kadmin.c:1819 ++#, c-format ++msgid "current privileges:" ++msgstr "aktuelle Rechte:" ++ ++#: ../../src/kadmin/cli/kadmin.c:1845 ++#, c-format ++msgid "usage: purgekeys [-all|-keepkvno oldest_kvno_to_keep] principal\n" ++msgstr "" ++"Aufruf: purgekeys [-all|-keepkvno älteste_KVNO_die_behalten_wird] Principal\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1865 ++#, c-format ++msgid "while purging keys for principal \"%s\"" ++msgstr "beim vollständigen Löschen der Schlüssel für Principal »%s«" ++ ++#: ../../src/kadmin/cli/kadmin.c:1870 ++#, c-format ++msgid "All keys for principal \"%s\" removed.\n" ++msgstr "Alle Schlüssel für Principal »%s« wurden entfernt.\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1872 ++#, c-format ++msgid "Old keys for principal \"%s\" purged.\n" ++msgstr "Alte Schlüssel für Principal »%s« wurden entfernt.\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1889 ++#, c-format ++msgid "usage: get_strings principal\n" ++msgstr "Aufruf: get_strings Principal\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1909 ++#, c-format ++msgid "while getting attributes for principal \"%s\"" ++msgstr "beim Holen von Attributen für Principal »%s«" ++ ++#: ../../src/kadmin/cli/kadmin.c:1914 ++#, c-format ++msgid "(No string attributes.)\n" ++msgstr "(keine Zeichenkettenattribute)\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1933 ++#, c-format ++msgid "usage: set_string principal key value\n" ++msgstr "Aufruf: set_string Principal Schlüssel Wert\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1955 ++#, c-format ++msgid "while setting attribute on principal \"%s\"" ++msgstr "beim Setzen eines Attributes für Principal »%s«" ++ ++#: ../../src/kadmin/cli/kadmin.c:1959 ++#, c-format ++msgid "Attribute set for principal \"%s\".\n" ++msgstr "Attribute für Principal »%s« wurden gesetzt.\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1974 ++#, c-format ++msgid "usage: del_string principal key\n" ++msgstr "Aufruf: del_string Principal Schlüssel\n" ++ ++#: ../../src/kadmin/cli/kadmin.c:1995 ++#, c-format ++msgid "while deleting attribute from principal \"%s\"" ++msgstr "beim Löschen eines Attributs von Principal »%s«" ++ ++#: ../../src/kadmin/cli/kadmin.c:1999 ++#, c-format ++msgid "Attribute removed from principal \"%s\".\n" ++msgstr "Attribut von Principal »%s« wurde gelöscht.\n" ++ ++#: ../../src/kadmin/cli/keytab.c:56 ++#, c-format ++msgid "" ++"Usage: ktadd [-k[eytab] keytab] [-q] [-e keysaltlist] [-norandkey] " ++"[principal | -glob princ-exp] [...]\n" ++msgstr "" ++"Aufruf: ktadd [-k[eytab] Schlüsseltabelle] [-q] [-e Schlüssel-Salt-Liste] [-" ++"norandkey] [Principal | -glob Principal-Ausdruck] […]\n" ++ ++#: ../../src/kadmin/cli/keytab.c:59 ++#, c-format ++msgid "" ++"Usage: ktadd [-k[eytab] keytab] [-q] [-e keysaltlist] [principal | -glob " ++"princ-exp] [...]\n" ++msgstr "" ++"Aufruf: ktadd [-k[eytab] Schlüsseltabelle] [-q] [-e Schlüssel-Salt-Liste] " ++"[Principal | -glob Principal-Ausdruck] […]\n" ++ ++#: ../../src/kadmin/cli/keytab.c:67 ++#, c-format ++msgid "" ++"Usage: ktremove [-k[eytab] keytab] [-q] principal [kvno|\"all\"|\"old\"]\n" ++msgstr "" ++"Aufruf: ktremove [-k[eytab] Schlüsseltabelle] [-q] Principal " ++"[kvno|»all«|»old«]\n" ++ ++#: ../../src/kadmin/cli/keytab.c:81 ../../src/kadmin/cli/keytab.c:102 ++msgid "while creating keytab name" ++msgstr "beim Erstellen des Schlüsseltabellennamens" ++ ++#: ../../src/kadmin/cli/keytab.c:86 ++msgid "while opening default keytab" ++msgstr "beim Öffnen der Standardschlüsseltabelle" ++ ++#: ../../src/kadmin/cli/keytab.c:147 ++#, c-format ++msgid "-norandkey option only valid for kadmin.local\n" ++msgstr "Die Option »-norandkey« ist nur für »kadmin.local« gültig.\n" ++ ++#: ../../src/kadmin/cli/keytab.c:176 ++#, c-format ++msgid "cannot specify keysaltlist when not changing key\n" ++msgstr "" ++"Schlüssel-Salt-Liste kann nicht angegeben werden, wenn der Schlüssel nicht " ++"geändert wird\n" ++ ++#: ../../src/kadmin/cli/keytab.c:192 ++#, c-format ++msgid "while expanding expression \"%s\"." ++msgstr "beim Expandieren des Ausdrucks »%s«." ++ ++#: ../../src/kadmin/cli/keytab.c:211 ../../src/kadmin/cli/keytab.c:251 ++msgid "while closing keytab" ++msgstr "beim Schließen der Schlüsseltabelle" ++ ++#: ../../src/kadmin/cli/keytab.c:275 ++#, c-format ++msgid "while parsing -add principal name %s" ++msgstr "beim Auswerten von »-add Principal-Name %s«" ++ ++#: ../../src/kadmin/cli/keytab.c:289 ++#, c-format ++msgid "%s: Principal %s does not exist.\n" ++msgstr "%s: Principal %s existiert nicht.\n" ++ ++#: ../../src/kadmin/cli/keytab.c:292 ++#, c-format ++msgid "while changing %s's key" ++msgstr "beim Ändern des Schlüssels von %s" ++ ++#: ../../src/kadmin/cli/keytab.c:299 ++msgid "while retrieving principal" ++msgstr "beim Abfragen des Principals" ++ ++#: ../../src/kadmin/cli/keytab.c:311 ++msgid "while adding key to keytab" ++msgstr "beim Hinzufügen des Schlüssels zur Schlüsseltabelle" ++ ++#: ../../src/kadmin/cli/keytab.c:317 ++#, c-format ++msgid "" ++"Entry for principal %s with kvno %d, encryption type %s added to keytab %s.\n" ++msgstr "" ++"Der Eintrag für Principal %s mit KVNO %d und Verschlüsselungstyp %s wurde " ++"der Schlüsseltabelle %s hinzugefügt.\n" ++ ++#: ../../src/kadmin/cli/keytab.c:326 ++msgid "while freeing principal entry" ++msgstr "beim Freigeben des Principal-Eintrags" ++ ++#: ../../src/kadmin/cli/keytab.c:373 ++#, c-format ++msgid "%s: Keytab %s does not exist.\n" ++msgstr "%s: Schlüsseltabelle %s existiert nicht.\n" ++ ++#: ../../src/kadmin/cli/keytab.c:377 ++#, c-format ++msgid "%s: No entry for principal %s exists in keytab %s\n" ++msgstr "" ++"%s: Für Principal %s existiert kein Eintrag in der Schlüsseltabelle %s.\n" ++ ++#: ../../src/kadmin/cli/keytab.c:381 ++#, c-format ++msgid "%s: No entry for principal %s with kvno %d exists in keytab %s\n" ++msgstr "" ++"%s: Für den Principal %s mit der KVNO %d existiert kein Eintrag in der " ++"Schlüsseltabelle %s.\n" ++ ++#: ../../src/kadmin/cli/keytab.c:387 ++msgid "while retrieving highest kvno from keytab" ++msgstr "beim Abfragen der höchsten KVNO der Schlüsseltabelle" ++ ++#: ../../src/kadmin/cli/keytab.c:420 ++msgid "while temporarily ending keytab scan" ++msgstr "beim Unterbrechen des Schlüsseltabellen-Scans" ++ ++#: ../../src/kadmin/cli/keytab.c:425 ++msgid "while deleting entry from keytab" ++msgstr "beim Löschen eines Eintrags aus der Schlüsseltabelle" ++ ++#: ../../src/kadmin/cli/keytab.c:430 ++msgid "while restarting keytab scan" ++msgstr "bei der Wiederaufnahme des Schlüsseltabellen-Scans" ++ ++#: ../../src/kadmin/cli/keytab.c:436 ++#, c-format ++msgid "Entry for principal %s with kvno %d removed from keytab %s.\n" ++msgstr "" ++"Der Eintrag für Principal %s mit KVNO %d wurde aus der Schlüsseltabelle %s " ++"entfernt.\n" ++ ++#: ../../src/kadmin/cli/keytab.c:458 ++#, c-format ++msgid "%s: There is only one entry for principal %s in keytab %s\n" ++msgstr "" ++"%s: Es gibt nur einen Eintrag für Principal %s in der Schlüsseltabelle %s.\n" ++ ++#: ../../src/kadmin/cli/ss_wrapper.c:49 ../../src/kadmin/ktutil/ktutil.c:58 ++msgid "creating invocation" ++msgstr "Aufruf wird erstellt" ++ ++#: ../../src/kadmin/dbutil/dump.c:165 ++msgid "while allocating temporary filename dump" ++msgstr "beim Reservieren des temporären Dateinamenspeicherauszugs" ++ ++#: ../../src/kadmin/dbutil/dump.c:176 ++msgid "while renaming dump file into place" ++msgstr "während das Umbenennen der Auszugsdateien Gestalt annimmt" ++ ++#: ../../src/kadmin/dbutil/dump.c:192 ++msgid "while allocating dump_ok filename" ++msgstr "beim Reservieren des »dump_ok«-Dateinamens" ++ ++#: ../../src/kadmin/dbutil/dump.c:199 ++#, c-format ++msgid "while creating 'ok' file, '%s'" ++msgstr "beim Erstellen der Datei »ok«, »%s«" ++ ++#: ../../src/kadmin/dbutil/dump.c:206 ++#, c-format ++msgid "while locking 'ok' file, '%s'" ++msgstr "beim Sperren der Datei »ok«, »%s«" ++ ++#: ../../src/kadmin/dbutil/dump.c:248 ../../src/kadmin/dbutil/dump.c:277 ++#, c-format ++msgid "%s: regular expression error: %s\n" ++msgstr "%s: Fehler im regulären Ausdruck: %s\n" ++ ++#: ../../src/kadmin/dbutil/dump.c:260 ++#, c-format ++msgid "%s: regular expression match error: %s\n" ++msgstr "%s: Fehler beim Abgleich mit regulärem Ausdruck: %s\n" ++ ++#: ../../src/kadmin/dbutil/dump.c:361 ++#, c-format ++msgid "%s: tagged data list inconsistency for %s (counted %d, stored %d)\n" ++msgstr "" ++"%s: Unstimmigkeit in der markierten Datenliste für %s (%d gezählt, %d " ++"gespeichert)\n" ++ ++#: ../../src/kadmin/dbutil/dump.c:519 ++#, c-format ++msgid "" ++"Warning! Multiple DES-CBC-CRC keys for principal %s; skipping duplicates.\n" ++msgstr "" ++"Warnung! Mehrere DES-CBC-CRC-Schlüssel für Principal %s, Duplikate werden " ++"übersprungen.\n" ++ ++#: ../../src/kadmin/dbutil/dump.c:530 ++#, c-format ++msgid "" ++"Warning! No DES-CBC-CRC key for principal %s, cannot generate OV-compatible " ++"record; skipping\n" ++msgstr "" ++"Warnung! Kein DES-CBC-CRC-Schlüssel für Principal %s, es kann kein OV-" ++"kompatibler Datensatz erzeugt werden, wird übersprungen\n" ++ ++#: ../../src/kadmin/dbutil/dump.c:558 ++#, c-format ++msgid "while converting %s to new master key" ++msgstr "beim Umwandeln von %s in den neuen Hauptschlüssel" ++ ++#: ../../src/kadmin/dbutil/dump.c:579 ++#, c-format ++msgid "%s(%d): %s\n" ++msgstr "%s(%d): %s\n" ++ ++#: ../../src/kadmin/dbutil/dump.c:622 ++#, c-format ++msgid "%s(%d): ignoring trash at end of line: " ++msgstr "%s(%d): Müll am Zeilenende wird ignoriert: " ++ ++#: ../../src/kadmin/dbutil/dump.c:685 ++msgid "cannot read tagged data type and length" ++msgstr "Markierter Datentyp und Länge können nicht gelesen werden." ++ ++#: ../../src/kadmin/dbutil/dump.c:692 ++msgid "cannot read tagged data contents" ++msgstr "Inhalt der markierten Daten kann nicht gelesen werden." ++ ++#: ../../src/kadmin/dbutil/dump.c:726 ++msgid "cannot match size tokens" ++msgstr "Größenmerkmale können nicht zugeordnet werden." ++ ++#: ../../src/kadmin/dbutil/dump.c:755 ++msgid "cannot read name string" ++msgstr "Namenszeichenkette kann nicht gelesen werden." ++ ++#: ../../src/kadmin/dbutil/dump.c:760 ++#, c-format ++msgid "while parsing name %s" ++msgstr "beim Auswerten des Namens %s" ++ ++#: ../../src/kadmin/dbutil/dump.c:768 ++msgid "cannot read principal attributes" ++msgstr "Principal-Attribute können nicht gelesen werden." ++ ++#: ../../src/kadmin/dbutil/dump.c:821 ++msgid "cannot read key size and version" ++msgstr "Schlüssellänge und -version können nicht gelesen werden." ++ ++#: ../../src/kadmin/dbutil/dump.c:832 ++msgid "cannot read key type and length" ++msgstr "Schlüsseltyp und -länge können nicht gelesen werden." ++ ++#: ../../src/kadmin/dbutil/dump.c:838 ++msgid "cannot read key data" ++msgstr "Schlüsseldaten können nicht gelesen werden." ++ ++#: ../../src/kadmin/dbutil/dump.c:848 ++msgid "cannot read extra data" ++msgstr "Zusätzliche Daten können nicht gelesen werden." ++ ++#: ../../src/kadmin/dbutil/dump.c:857 ++#, c-format ++msgid "while storing %s" ++msgstr "beim Speichern von %s" ++ ++#: ../../src/kadmin/dbutil/dump.c:896 ../../src/kadmin/dbutil/dump.c:935 ++#: ../../src/kadmin/dbutil/dump.c:981 ++#, c-format ++msgid "cannot parse policy (%d read)\n" ++msgstr "Richtlinie kann nicht ausgewertet werden (%d gelesen)\n" ++ ++#: ../../src/kadmin/dbutil/dump.c:904 ../../src/kadmin/dbutil/dump.c:943 ++#: ../../src/kadmin/dbutil/dump.c:1001 ++msgid "while creating policy" ++msgstr "beim Erstellen der Richtlinie" ++ ++#: ../../src/kadmin/dbutil/dump.c:908 ++#, c-format ++msgid "created policy %s\n" ++msgstr "erstellte Richtlinie %s\n" ++ ++#: ../../src/kadmin/dbutil/dump.c:1038 ++#, c-format ++msgid "unknown record type \"%s\"\n" ++msgstr "unbekannter Datensatztyp »%s«\n" ++ ++#: ../../src/kadmin/dbutil/dump.c:1167 ++#, c-format ++msgid "%s: Unknown iprop dump version %d\n" ++msgstr "%s: unbekannte Iprop-Auszugsversion %d\n" ++ ++#: ../../src/kadmin/dbutil/dump.c:1270 ../../src/kadmin/dbutil/dump.c:1498 ++#, c-format ++msgid "Iprop not enabled\n" ++msgstr "Iprop nicht aktiviert\n" ++ ++#: ../../src/kadmin/dbutil/dump.c:1308 ++msgid "Conditional dump is an undocumented option for use only for iprop dumps" ++msgstr "" ++"Bedingter Auszug ist eine nicht dokumentierte Option, die nur für Iprop-" ++"Auszüge benutzt wird." ++ ++#: ../../src/kadmin/dbutil/dump.c:1321 ++msgid "Database not currently opened!" ++msgstr "Die Datenbank ist zur Zeit nicht geöffnet!" ++ ++#: ../../src/kadmin/dbutil/dump.c:1335 ++#: ../../src/kadmin/dbutil/kdb5_stash.c:116 ++#: ../../src/kadmin/dbutil/kdb5_util.c:479 ++msgid "while reading master key" ++msgstr "beim Lesen des Hauptschlüssels" ++ ++#: ../../src/kadmin/dbutil/dump.c:1341 ++msgid "while verifying master key" ++msgstr "beim Prüfen des Hauptschlüssels" ++ ++#: ../../src/kadmin/dbutil/dump.c:1360 ../../src/kadmin/dbutil/dump.c:1370 ++msgid "while reading new master key" ++msgstr "beim Lesen des neuen Hauptschlüssels" ++ ++#: ../../src/kadmin/dbutil/dump.c:1364 ++#, c-format ++msgid "Please enter new master key....\n" ++msgstr "Bitte geben Sie den neuen Hauptschlüssel ein …\n" ++ ++#: ../../src/kadmin/dbutil/dump.c:1388 ++#, c-format ++msgid "while opening %s for writing" ++msgstr "beim Öffnen von %s zum Schreiben" ++ ++#: ../../src/kadmin/dbutil/dump.c:1403 ++msgid "while reading update log header" ++msgstr "beim Lesen der Aktualisierungsprotokollkopfzeilen" ++ ++#: ../../src/kadmin/dbutil/dump.c:1418 ../../src/kadmin/dbutil/dump.c:1425 ++#, c-format ++msgid "performing %s dump" ++msgstr "Auszug von %s wird durchgeführt" ++ ++#: ../../src/kadmin/dbutil/dump.c:1455 ++#, c-format ++msgid "%s: error processing line %d of %s\n" ++msgstr "%s: Fehler beim Verarbeiten von Zeile %d von %s\n" ++ ++#: ../../src/kadmin/dbutil/dump.c:1507 ++msgid "while parsing options" ++msgstr "beim Auswerten der Optionen" ++ ++#: ../../src/kadmin/dbutil/dump.c:1522 ++#, c-format ++msgid "while opening %s" ++msgstr "beim Öffnen von %s" ++ ++#: ../../src/kadmin/dbutil/dump.c:1527 ../../src/kadmin/dbutil/dump.c:1626 ++msgid "standard input" ++msgstr "Standardeingabe" ++ ++#: ../../src/kadmin/dbutil/dump.c:1532 ++#, c-format ++msgid "%s: can't read dump header in %s\n" ++msgstr "%s: Kopfzeilen des Auszugs in %s können nicht gelesen werden.\n" ++ ++#: ../../src/kadmin/dbutil/dump.c:1540 ../../src/kadmin/dbutil/dump.c:1557 ++#, c-format ++msgid "%s: dump header bad in %s\n" ++msgstr "%s: falsche Kopfzeilen des Auszugs in %s\n" ++ ++#: ../../src/kadmin/dbutil/dump.c:1566 ++#, c-format ++msgid "Could not open iprop ulog\n" ++msgstr "Iprop-Ulog kann nicht geöffnet werden.\n" ++ ++#: ../../src/kadmin/dbutil/dump.c:1571 ++#, c-format ++msgid "%s: dump version %s can only be loaded with the -update flag\n" ++msgstr "" ++"%s: Die Auszugsversion %s kann nur mit dem Schalter -update geladen werden.\n" ++ ++#: ../../src/kadmin/dbutil/dump.c:1580 ../../src/kadmin/dbutil/dump.c:1585 ++msgid "computing parameters for database" ++msgstr "Parameter für die Datenbank werden berechnet." ++ ++#: ../../src/kadmin/dbutil/dump.c:1591 ++msgid "while creating database" ++msgstr "beim Erstellen der Datenbank" ++ ++#: ../../src/kadmin/dbutil/dump.c:1600 ++msgid "while opening database" ++msgstr "beim Öffnen der Datenbank" ++ ++#: ../../src/kadmin/dbutil/dump.c:1610 ++msgid "while permanently locking database" ++msgstr "beim dauerhaften Sperren der Datenbank" ++ ++#: ../../src/kadmin/dbutil/dump.c:1628 ++#, c-format ++msgid "%s: %s restore failed\n" ++msgstr "%s: Wiederherstellen von %s fehlgeschlagen\n" ++ ++#: ../../src/kadmin/dbutil/dump.c:1633 ++msgid "while unlocking database" ++msgstr "beim Aufheben der Datenbanksperre" ++ ++#: ../../src/kadmin/dbutil/dump.c:1643 ../../src/kadmin/dbutil/dump.c:1662 ++msgid "while reinitializing update log" ++msgstr "beim erneuten Initialisieren des Aktualisierungsprotokolls" ++ ++#: ../../src/kadmin/dbutil/dump.c:1653 ++msgid "while making newly loaded database live" ++msgstr "beim Aktivieren der neu geladenen Datenbank" ++ ++#: ../../src/kadmin/dbutil/dump.c:1669 ++msgid "while writing update log header" ++msgstr "beim Schreiben der Aktualisierungsprotokollkopfzeilen" ++ ++#: ../../src/kadmin/dbutil/dump.c:1683 ++#, c-format ++msgid "while deleting bad database %s" ++msgstr "beim Löschen der falschen Datenbank %s" ++ ++#: ../../src/kadmin/dbutil/kadm5_create.c:84 ++msgid "while looking up the Kerberos configuration" ++msgstr "beim Nachschlagen der Kerberos-Konfiguration" ++ ++#: ../../src/kadmin/dbutil/kadm5_create.c:111 ++msgid "while initializing the Kerberos admin interface" ++msgstr "beim Initialisieren der Kerberos-Administrationsoberfläche" ++ ++#: ../../src/kadmin/dbutil/kadm5_create.c:169 ++#, c-format ++msgid "getaddrinfo(%s): Cannot determine canonical hostname.\n" ++msgstr "" ++"getaddrinfo(%s): Die Normalform des Rechnernamens kann nicht bestimmt " ++"werden.\n" ++ ++#: ../../src/kadmin/dbutil/kadm5_create.c:190 ++#: ../../src/kadmin/dbutil/kadm5_create.c:196 ++#, c-format ++msgid "Out of memory\n" ++msgstr "Speicherplatz reicht nicht aus.\n" ++ ++#: ../../src/kadmin/dbutil/kadm5_create.c:270 ++msgid "while appending realm to principal" ++msgstr "beim Anhängen des Realms an den Principal" ++ ++#: ../../src/kadmin/dbutil/kadm5_create.c:275 ++msgid "while parsing admin principal name" ++msgstr "beim Auswerten des Principal-Namens des Administrators" ++ ++#: ../../src/kadmin/dbutil/kadm5_create.c:286 ++#, c-format ++msgid "while creating principal %s" ++msgstr "beim Erstellen des Principals %s" ++ ++#: ../../src/kadmin/dbutil/kdb5_create.c:175 ++#: ../../src/kadmin/dbutil/kdb5_util.c:241 ++#: ../../src/kadmin/dbutil/kdb5_util.c:248 ++msgid "while parsing command arguments\n" ++msgstr "beim Auswerten der Befehlsargumente\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_create.c:198 ++#, c-format ++msgid "Loading random data\n" ++msgstr "Zufällige Daten werden geladen.\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_create.c:201 ++msgid "Loading random data" ++msgstr "Zufällige Daten werden geladen." ++ ++#: ../../src/kadmin/dbutil/kdb5_create.c:211 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:242 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:435 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:591 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1149 ++#: ../../src/kadmin/dbutil/kdb5_util.c:423 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:606 ++msgid "while setting up master key name" ++msgstr "beim Einrichten des Hauptschlüsselnamens" ++ ++#: ../../src/kadmin/dbutil/kdb5_create.c:222 ++#, c-format ++msgid "" ++"Initializing database '%s' for realm '%s',\n" ++"master key name '%s'\n" ++msgstr "" ++"Datenbank »%s« für Realm »%s« wird initialisiert,\n" ++"Hauptschlüsselname »%s«\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_create.c:227 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:516 ++#, c-format ++msgid "You will be prompted for the database Master Password.\n" ++msgstr "Sie werden nach dem Master-Passwort der Datenbank gefragt.\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_create.c:228 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:260 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:517 ++#, c-format ++msgid "It is important that you NOT FORGET this password.\n" ++msgstr "Es ist wichtig, dass Sie dieses Passwort NICHT VERGESSEN.\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_create.c:234 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:266 ++msgid "while creating new master key" ++msgstr "beim Erstellen des neuen Hauptschlüssels" ++ ++#: ../../src/kadmin/dbutil/kdb5_create.c:242 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:527 ++msgid "while reading master key from keyboard" ++msgstr "beim Lesen des Hauptschlüssels von der Tastatur" ++ ++#: ../../src/kadmin/dbutil/kdb5_create.c:252 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:285 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:618 ++msgid "while calculating master key salt" ++msgstr "beim Berechnen des Hauptschlüssel-Salts" ++ ++#: ../../src/kadmin/dbutil/kdb5_create.c:260 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:294 ++#: ../../src/kadmin/dbutil/kdb5_util.c:465 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:630 ++msgid "while transforming master key from password" ++msgstr "beim Umwandeln des Hauptschlüssels vom Passwort" ++ ++#: ../../src/kadmin/dbutil/kdb5_create.c:270 ++msgid "while initializing random key generator" ++msgstr "beim Initialisieren des Zufallsschlüsselgenerators" ++ ++#: ../../src/kadmin/dbutil/kdb5_create.c:275 ++#, c-format ++msgid "while creating database '%s'" ++msgstr "beim Erstellen der Datenbank »%s«" ++ ++#: ../../src/kadmin/dbutil/kdb5_create.c:293 ++msgid "while creating update log" ++msgstr "beim Erstellen des Aktualisierungsprotokolls" ++ ++#: ../../src/kadmin/dbutil/kdb5_create.c:304 ++msgid "while initializing update log" ++msgstr "beim Initialisieren des Aktualisierungsprotokolls" ++ ++#: ../../src/kadmin/dbutil/kdb5_create.c:320 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:642 ++msgid "while adding entries to the database" ++msgstr "beim Hinzufügen von Einträgen in die Datenbank" ++ ++#: ../../src/kadmin/dbutil/kdb5_create.c:348 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:339 ++#: ../../src/kadmin/dbutil/kdb5_stash.c:133 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:667 ++msgid "while storing key" ++msgstr "beim Speichern des Schlüssels" ++ ++#: ../../src/kadmin/dbutil/kdb5_create.c:349 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:340 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:668 ++#, c-format ++msgid "Warning: couldn't stash master key.\n" ++msgstr "Warnung: Hauptschlüssel kann nicht gelagert werden.\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_destroy.c:57 ++msgid "while initializing krb5_context" ++msgstr "beim Initialisieren von »krb5_context«" ++ ++#: ../../src/kadmin/dbutil/kdb5_destroy.c:63 ++#: ../../src/kadmin/dbutil/kdb5_util.c:259 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:291 ++msgid "while setting default realm name" ++msgstr "beim Einstellen des Standard-Realm-Namens" ++ ++#: ../../src/kadmin/dbutil/kdb5_destroy.c:83 ++#, c-format ++msgid "Deleting KDC database stored in '%s', are you sure?\n" ++msgstr "" ++"Die in »%s« gespeicherte KDC-Datenbank wird gelöscht. Sind Sie sicher?\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_destroy.c:85 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1166 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c:360 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:1482 ++#, c-format ++msgid "(type 'yes' to confirm)? " ++msgstr "(Geben Sie als Bestätigung »yes« ein)? " ++ ++#: ../../src/kadmin/dbutil/kdb5_destroy.c:92 ++#, c-format ++msgid "OK, deleting database '%s'...\n" ++msgstr "OK, Datenbank »%s« wird gelöscht …\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_destroy.c:97 ++#, c-format ++msgid "deleting database '%s'" ++msgstr "Datenbank »%s« wird gelöscht." ++ ++#: ../../src/kadmin/dbutil/kdb5_destroy.c:106 ++#, c-format ++msgid "** Database '%s' destroyed.\n" ++msgstr "** Datenbank »%s« vernichtet\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:218 ++#, c-format ++msgid "%s is an invalid enctype" ++msgstr "%s ist ein ungültiger Verschlüsselungstyp" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:250 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:443 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:599 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:986 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1157 ++#, c-format ++msgid "while getting master key principal %s" ++msgstr "beim Holen des Hauptschlüssels von Principal %s" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:256 ++#, c-format ++msgid "Creating new master key for master key principal '%s'\n" ++msgstr "" ++"Es wird ein neuer Hauptschlüssel für den Hauptschlüssel-Principal »%s« " ++"erstellt.\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:259 ++#, c-format ++msgid "You will be prompted for a new database Master Password.\n" ++msgstr "Sie werden nach einem neuen Datenbank-Master-Passwort gefragt.\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:275 ++msgid "while reading new master key from keyboard" ++msgstr "beim Lesen des neuen Hauptschlüssels von der Tastatur" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:304 ++msgid "adding new master key to master principal" ++msgstr "dem Haupt-Principal wird ein neuer Hauptschlüssel hinzugefügt" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:310 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:402 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:843 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1356 ++msgid "while getting current time" ++msgstr "beim Holen der aktuellen Zeit" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:317 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:544 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1363 ++msgid "while updating the master key principal modification time" ++msgstr "beim Aktulisieren der Änderungszeit des Hauptschlüssel-Principals" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:325 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:553 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1374 ++msgid "while adding master key entry to the database" ++msgstr "beim Hinzufügen des Hauptschlüsseleintrags zur Datenbank" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:383 ++msgid "0 is an invalid KVNO value" ++msgstr "0 ist kein gültiger KVNO-Wert" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:394 ++#, c-format ++msgid "%d is an invalid KVNO value" ++msgstr "%d ist kein gültiger KVNO-Wert" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:410 ++#, c-format ++msgid "could not parse date-time string '%s'" ++msgstr "»date-time«-Zeichenkette »%s« konnte nicht ausgewertet werden" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:452 ++msgid "while looking up active version of master key" ++msgstr "beim Nachschlagen der aktiven Version des Hauptschlüssels" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:491 ++msgid "while adding new master key" ++msgstr "beim Hinzufügen eines neuen Hauptschlüssels" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:529 ++msgid "there must be one master key currently active" ++msgstr "ein Hauptschlüssel muss derzeit aktiv sein" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:537 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1342 ++msgid "while updating actkvno data for master principal entry" ++msgstr "beim Aktualisieren der Actkvno-Daten für den Haupt-Principal-Eintrag" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:581 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:948 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1116 ++msgid "master keylist not initialized" ++msgstr "Hauptschlüsselliste ist nicht initialisiert" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:607 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:994 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1254 ++msgid "while looking up active kvno list" ++msgstr "beim Nachschlagen der Liste aktiver KVNOs" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:615 ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1002 ++msgid "while looking up active master key" ++msgstr "beim Nachschlagen des aktiven Hauptschlüssels" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:627 ++msgid "while getting enctype description" ++msgstr "beim Holen des Verschlüsselungsbeschreibung" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:644 ++#, c-format ++msgid "KVNO: %d, Enctype: %s, Active on: %s *\n" ++msgstr "KVNO: %d, Verschlüsselungstyp: %s, aktiviert auf: %s *\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:649 ++#, c-format ++msgid "KVNO: %d, Enctype: %s, Active on: %s\n" ++msgstr "KVNO: %d, Verschlüsselungstyp: %s, aktiviert auf: %s\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:653 ++#, c-format ++msgid "KVNO: %d, Enctype: %s, No activate time set\n" ++msgstr "KVNO: %d, Verschlüsselungstyp: %s, keine Aktivierungszeit gesetzt\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:658 ++msgid "asprintf could not allocate enough memory to hold output" ++msgstr "" ++"Asprintf konnte nicht genug Speicher reservieren, um die Ausgabe " ++"bereitzuhalten" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:793 ++msgid "getting string representation of principal name" ++msgstr "Principal-Name wird im Klartext geholt" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:817 ++#, c-format ++msgid "determining master key used for principal '%s'" ++msgstr "Hauptschlüssel, der für Principal »%s« benutzt wird, wird bestimmt" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:823 ++#, c-format ++msgid "would skip: %s\n" ++msgstr "würde übersprungen: %s\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:825 ++#, c-format ++msgid "skipping: %s\n" ++msgstr "wird übersprungen: %s\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:831 ++#, c-format ++msgid "would update: %s\n" ++msgstr "würde aktualisiert: %s\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:835 ++#, c-format ++msgid "updating: %s\n" ++msgstr "wird aktualisiert: %s\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:839 ++#, c-format ++msgid "error re-encrypting key for principal '%s'" ++msgstr "Fehler beim erneuten Verschlüsseln des Schlüssels für Principal »%s«" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:850 ++#, c-format ++msgid "while updating principal '%s' modification time" ++msgstr "beim Aktualisieren der Änderungszeit von Principal »%s«" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:857 ++#, c-format ++msgid "while updating principal '%s' key data in the database" ++msgstr "" ++"beim Aktualisieren der Schlüsseldaten von Principal »%s« in der Datenbank" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:889 ++#, c-format ++msgid "" ++"\n" ++"(type 'yes' to confirm)? " ++msgstr "" ++"\n" ++"(Geben Sie als Bestätigung »yes« ein) " ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:942 ++msgid "while formatting master principal name" ++msgstr "beim Formatieren des Haupt-Principal-Namens" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:959 ++#, c-format ++msgid "converting glob pattern '%s' to regular expression" ++msgstr "Platzhalter »%s« wird in einen regulären Ausdruck umgewandelt" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:977 ++#, c-format ++msgid "error compiling converted regexp '%s'" ++msgstr "Fehler beim Kompilieren des umgewandelten regulären Ausdrucks »%s«" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1010 ++#, c-format ++msgid "Re-encrypt all keys not using master key vno %u?" ++msgstr "" ++"Sollen alle Schlüssel neu verschlüsselt werden, die nicht die Hauptschlüssel-" ++"VNO %u verwenden?" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1012 ++#, c-format ++msgid "OK, doing nothing.\n" ++msgstr "Ok, es wird nichts getan.\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1018 ++#, c-format ++msgid "Principals whose keys WOULD BE re-encrypted to master key vno %u:\n" ++msgstr "" ++"Principals, deren Schlüssel mit dem Hauptschlüssel VNO %u neu verschlüsselt " ++"WÜRDEN:\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1021 ++#, c-format ++msgid "" ++"Principals whose keys are being re-encrypted to master key vno %u if " ++"necessary:\n" ++msgstr "" ++"Principals, deren Schlüssel mit dem Hauptschlüssel VNO %u neu verschlüsselt " ++"werden, falls nötig:\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1037 ++msgid "trying to process principal database" ++msgstr "es wird versucht, die Principal-Datenbank zu verarbeiten" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1042 ++#, c-format ++msgid "%u principals processed: %u would be updated, %u already current\n" ++msgstr "" ++"%u Principals verarbeitet: %u würden aktualisiert, %u bereits aktuell\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1046 ++#, c-format ++msgid "%u principals processed: %u updated, %u already current\n" ++msgstr "%u Principals verarbeitet: %u aktualisiert, %u bereits aktuell\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1164 ++#, c-format ++msgid "" ++"Will purge all unused master keys stored in the '%s' principal, are you " ++"sure?\n" ++msgstr "" ++"Sind Sie sicher, dass alle nicht verwendeten Hauptschlüssel, die für " ++"Principal »%s« gespeichert sind, vollständig entfernt werden sollen?\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1175 ++#, c-format ++msgid "OK, purging unused master keys from '%s'...\n" ++msgstr "" ++"Ok, die nicht verwendeten Hauptschlüssel von »%s« werden vollständig " ++"entfernt …\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1183 ++#, c-format ++msgid "There is only one master key which can not be purged.\n" ++msgstr "" ++"Es gibt nur einen einzigen Hauptschlüssel, der nicht vollständig entfernt " ++"werden kann.\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1192 ++msgid "while allocating args.kvnos" ++msgstr "beim Reservieren von »args.kvnos«" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1208 ++msgid "while finding master keys in use" ++msgstr "bei der Suche nach den gerade verwendeten Hauptschlüsseln" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1217 ++#, c-format ++msgid "Would purge the following master key(s) from %s:\n" ++msgstr "" ++"Der/Die folgende(n) Hauptschlüssel würden/würde von %s vollständig " ++"entfernt:\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1220 ++#, c-format ++msgid "Purging the following master key(s) from %s:\n" ++msgstr "" ++"Der/Die folgende(n) Hauptschlüssel werden/wird von %s vollständig entfernt:\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1232 ++msgid "master key stash file needs updating, command aborting" ++msgstr "" ++"Ablagedatei des Hauptschlüssels erfordert Aktualisierung, Befehl abgebrochen" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1238 ++#, c-format ++msgid "KVNO: %d\n" ++msgstr "KVNO: %d\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1243 ++#, c-format ++msgid "All keys in use, nothing purged.\n" ++msgstr "Alle Schlüssel sind in Gebrauch, keiner wurde vollständig entfernt.\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1248 ++#, c-format ++msgid "%d key(s) would be purged.\n" ++msgstr "%d Schlüssel würde(n) vollständig entfernt.\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1261 ++msgid "while looking up mkey aux data list" ++msgstr "beim Nachschlagen der Mkey-Aux-Datenliste" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1269 ++msgid "while allocating key_data" ++msgstr "beim Reservieren von »key_data«" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1350 ++msgid "while updating mkey_aux data for master principal entry" ++msgstr "beim Aktualisieren der Mkey-Aux-Daten für den Haupt-Principal-Eintrag" ++ ++#: ../../src/kadmin/dbutil/kdb5_mkey.c:1378 ++#, c-format ++msgid "%d key(s) purged.\n" ++msgstr "%d Schlüssel vollständig entfernt\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_stash.c:97 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:538 ++#, c-format ++msgid "while setting up enctype %d" ++msgstr "beim Einrichten des Verschlüsselungstyps %d" ++ ++#: ../../src/kadmin/dbutil/kdb5_stash.c:123 ++msgid "while getting master key list" ++msgstr "beim Holen der Hauptschlüsselliste" ++ ++#: ../../src/kadmin/dbutil/kdb5_stash.c:127 ++#, c-format ++msgid "Using existing stashed keys to update stash file.\n" ++msgstr "" ++"Zur Aktualisierung der Ablagedatei werden existierende gelagert Schlüssel " ++"verwendet.\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:80 ++#, c-format ++msgid "" ++"Usage: kdb5_util [-x db_args]* [-r realm] [-d dbname] [-k mkeytype] [-M " ++"mkeyname]\n" ++"\t [-kv mkeyVNO] [-sf stashfilename] [-m] cmd [cmd_options]\n" ++"\tcreate [-s]\n" ++"\tdestroy [-f]\n" ++"\tstash [-f keyfile]\n" ++"\tdump [-old|-ov|-b6|-b7|-r13|-r18] [-verbose]\n" ++"\t [-mkey_convert] [-new_mkey_file mkey_file]\n" ++"\t [-rev] [-recurse] [filename [princs...]]\n" ++"\tload [-old|-ov|-b6|-b7|-r13|-r18] [-verbose] [-update] filename\n" ++"\tark [-e etype_list] principal\n" ++"\tadd_mkey [-e etype] [-s]\n" ++"\tuse_mkey kvno [time]\n" ++"\tlist_mkeys\n" ++msgstr "" ++"Aufruf: kdb5_util [-x Datenbankargumente]* [-r Realm] [-d Datenbankname] [-k " ++"Mkeytype] [-M Mkeyname]\n" ++"\t [-kv MkeyVNO] [-sf Ablagedateiname] [-m] Befehl [Befehlsoptionen]\n" ++"\tcreate [-s]\n" ++"\tdestroy [-f]\n" ++"\tstash [-f Schlüsseldatei]\n" ++"\tdump [-old|-ov|-b6|-b7|-r13|-r18] [-verbose]\n" ++"\t [-mkey_convert] [-new_mkey_file mkey-Datei]\n" ++"\t [-rev] [-recurse] [Dateiname [Principals …]]\n" ++"\tload [-old|-ov|-b6|-b7|-r13|-r18] [-verbose] [-update] Dateiname\n" ++"\tark [-e Etype-Liste] Principal\n" ++"\tadd_mkey [-e Etype] [-s]\n" ++"\tuse_mkey kvno [Zeit]\n" ++"\tlist_mkeys\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:98 ++#, c-format ++msgid "" ++"\tupdate_princ_encryption [-f] [-n] [-v] [princ-pattern]\n" ++"\tpurge_mkeys [-f] [-n] [-v]\n" ++"\n" ++"where,\n" ++"\t[-x db_args]* - any number of database specific arguments.\n" ++"\t\t\tLook at each database documentation for supported arguments\n" ++msgstr "" ++"\tupdate_princ_encryption [-f] [-n] [-v] [Principal-Muster]\n" ++"\tpurge_mkeys [-f] [-n] [-v]\n" ++"\n" ++"dabei sind\n" ++"\t[-x Datenbankargumente]* - eine beliebige Anzahl datenbankspezifischer " ++"Argumente.\n" ++"\t\t\tWelche Argumente unterstützt werden, finden Sie in der Dokumentation " ++"der jeweiligen Datenbank.\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:211 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:260 ++msgid "while initializing Kerberos code" ++msgstr "beim Initialisieren von Kerberos-Code" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:217 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:267 ++msgid "while creating sub-command arguments" ++msgstr "beim Erstellen von Unterbefehlsargumenten" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:235 ++msgid "while parsing command arguments" ++msgstr "beim Auswerten von Befehlsargumenten" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:264 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:298 ++#, c-format ++msgid ": %s is an invalid enctype" ++msgstr ": %s ist kein gültiger Verschlüsselungstyp" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:272 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:307 ++#, c-format ++msgid ": %s is an invalid mkeyVNO" ++msgstr ": %s ist kein gültiger MkeyVNO" ++ ++# FIXME s/retreiving/retrieving/ ++#: ../../src/kadmin/dbutil/kdb5_util.c:317 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:431 ++msgid "while retreiving configuration parameters" ++msgstr "beim Abfragen der Konfigurationsparameter" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:368 ++msgid "Too few arguments" ++msgstr "zu wenige Argumente" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:369 ++#, c-format ++msgid "Usage: %s dbpathname realmname" ++msgstr "Aufruf: %s Datenbankpfadname Realm-Name" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:375 ++msgid "while closing previous database" ++msgstr "beim Schließen der vorherigen Datenbank" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:412 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:877 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:1497 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:564 ++msgid "while initializing database" ++msgstr "beim Initialisieren der Datenbank" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:429 ++msgid "while retrieving master entry" ++msgstr "beim Abfragen des Haupteintrags" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:448 ++msgid "while calculated master key salt" ++msgstr "beim Berechnen des Hauptschlüssel-Salts" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:480 ++msgid "Warning: proceeding without master key" ++msgstr "Warnung: Es wird ohne Hauptschlüssel fortgefahren" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:498 ++msgid "while seeding random number generator" ++msgstr "beim Erzeugen des Startwerts des Zufallszahlengenerators" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:508 ++#, c-format ++msgid "%s: Could not map log\n" ++msgstr "%s: Protokolldatei konnte nicht abgebildet werden\n" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:535 ++msgid "while closing database" ++msgstr "beim Schließen der Datenbank" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:582 ++#, c-format ++msgid "while fetching principal %s" ++msgstr "beim Abrufen von Principal %s" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:605 ++msgid "while finding mkey" ++msgstr "beim Suchen nach Mkey" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:630 ++msgid "while setting changetime" ++msgstr "beim Setzen der Änderungszeit der Datei" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:638 ++#, c-format ++msgid "while saving principal %s" ++msgstr "beim Speichern von Principal %s" ++ ++#: ../../src/kadmin/dbutil/kdb5_util.c:642 ++#, c-format ++msgid "%s changed\n" ++msgstr "%s geändert\n" ++ ++#: ../../src/kadmin/ktutil/ktutil.c:73 ++#, c-format ++msgid "%s: invalid arguments\n" ++msgstr "%s: ungültige Argumente\n" ++ ++#: ../../src/kadmin/ktutil/ktutil.c:78 ++msgid "while freeing ktlist" ++msgstr "beim Freigeben von »ktlist«" ++ ++#: ../../src/kadmin/ktutil/ktutil.c:89 ++#, c-format ++msgid "%s: must specify keytab to read\n" ++msgstr "" ++"%s: Die Schlüsseltabelle, die gelesen werden soll, muss angegeben werden.\n" ++ ++#: ../../src/kadmin/ktutil/ktutil.c:94 ++#, c-format ++msgid "while reading keytab \"%s\"" ++msgstr "beim Lesen der Schlüsseltabelle »%s«" ++ ++#: ../../src/kadmin/ktutil/ktutil.c:104 ++#, c-format ++msgid "%s: must specify the srvtab to read\n" ++msgstr "%s: Die zu lesende Dienstschlüsseltabelle muss angegeben werden.\n" ++ ++#: ../../src/kadmin/ktutil/ktutil.c:109 ++#, c-format ++msgid "while reading srvtab \"%s\"" ++msgstr "beim Lesen der Dienstschlüsseltabelle »%s«" ++ ++#: ../../src/kadmin/ktutil/ktutil.c:119 ++#, c-format ++msgid "%s: must specify keytab to write\n" ++msgstr "%s: Die zu schreibende Schlüsseltabelle muss angegeben werden.\n" ++ ++#: ../../src/kadmin/ktutil/ktutil.c:124 ++#, c-format ++msgid "while writing keytab \"%s\"" ++msgstr "beim Schreiben der Schlüsseltabelle »%s«" ++ ++#: ../../src/kadmin/ktutil/ktutil.c:131 ++#, c-format ++msgid "%s: writing srvtabs is no longer supported\n" ++msgstr "" ++"%s: Schreiben der Dienstschlüsseltabelle wird nicht länger unterstützt\n" ++ ++#: ../../src/kadmin/ktutil/ktutil.c:169 ++#, c-format ++msgid "usage: %s (-key | -password) -p principal -k kvno -e enctype\n" ++msgstr "" ++"Aufruf: %s (-key | -password) -p Principal -k KVNO -e Verschlüsselungstyp\n" ++ ++#: ../../src/kadmin/ktutil/ktutil.c:176 ++msgid "while adding new entry" ++msgstr "beim Hinzufügen eines neuen Eintrags" ++ ++#: ../../src/kadmin/ktutil/ktutil.c:186 ++#, c-format ++msgid "%s: must specify entry to delete\n" ++msgstr "%s: zu löschender Eintrag muss angegeben werden\n" ++ ++#: ../../src/kadmin/ktutil/ktutil.c:191 ++#, c-format ++msgid "while deleting entry %d" ++msgstr "beim Löschen von Eintrag %d" ++ ++#: ../../src/kadmin/ktutil/ktutil.c:219 ++#, c-format ++msgid "%s: usage: %s [-t] [-k] [-e]\n" ++msgstr "%s: Aufruf: %s [-t] [-k] [-e]\n" ++ ++#: ../../src/kadmin/ktutil/ktutil.c:259 ++msgid "While converting enctype to string" ++msgstr "beim Umwandeln des Verschlüsselungstyps in eine Zeichenkette" ++ ++#: ../../src/kadmin/ktutil/ktutil_funcs.c:162 ++#, c-format ++msgid "Password for %.1000s" ++msgstr "Passwort für %.1000s" ++ ++#: ../../src/kadmin/ktutil/ktutil_funcs.c:179 ++#, c-format ++msgid "Key for %s (hex): " ++msgstr "Schlüssel für %s (hexadezimal): " ++ ++#: ../../src/kadmin/ktutil/ktutil_funcs.c:191 ++#, c-format ++msgid "addent: Error reading key.\n" ++msgstr "addent: Fehler beim Lesen des Schlüssels\n" ++ ++#: ../../src/kadmin/ktutil/ktutil_funcs.c:206 ++#, c-format ++msgid "addent: Illegal character in key.\n" ++msgstr "addent: unerlaubtes Zeichen im Schlüssel\n" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:48 ++#, c-format ++msgid "Unauthorized request: %s, client=%s, service=%s, addr=%s" ++msgstr "unberechtigte Anfrage: %s, Client=%s, Dienst=%s, Adresse=%s" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:49 ++#: ../../src/kadmin/server/ipropd_svc.c:212 ++#, c-format ++msgid "Request: %s, %s, %s, client=%s, service=%s, addr=%s" ++msgstr "Anfrage: %s, %s, %s, Client=%s, Dienst=%s, Adresse=%s" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:146 ++#: ../../src/kadmin/server/ipropd_svc.c:271 ++#, c-format ++msgid "%s: server handle is NULL" ++msgstr "%s: Server-Identifikator ist NULL" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:156 ++#: ../../src/kadmin/server/ipropd_svc.c:284 ++#, c-format ++msgid "%s: setup_gss_names failed" ++msgstr "%s: setup_gss_names fehlgeschlagen" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:166 ++#: ../../src/kadmin/server/ipropd_svc.c:295 ++#, c-format ++msgid "%s: out of memory recording principal names" ++msgstr "%s: Speicher reicht nicht zur Aufzeichnung der Principal-Namen aus" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:195 ++#, c-format ++msgid "%s; Incoming SerialNo=%lu; Outgoing SerialNo=%lu" ++msgstr "%s; eingehende Seriennummer=%lu; ausgehende Seriennummer=%lu" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:201 ++#, c-format ++msgid "%s; Incoming SerialNo=%lu; Outgoing SerialNo=N/A" ++msgstr "%s; eingehende Seriennummer=%lu; ausgehende Seriennummer=N/A" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:320 ++#, c-format ++msgid "%s: getclhoststr failed" ++msgstr "%s: getclhoststr fehlgeschlagen" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:342 ++#, c-format ++msgid "%s: cannot construct kdb5 util dump string too long; out of memory" ++msgstr "" ++"Ausgabenzeichenkette des KDB5-Hilfswerkzeugs nicht konstruierbar, da zu " ++"lang; Speicher reicht nicht aus.%s: Die Ausgabezeichenkette des KDB5-" ++"Hilfswerkzeugs kann nicht erstellt werden, weil sie zu lang ist. Der " ++"Speicherplatz reicht nicht aus." ++ ++#: ../../src/kadmin/server/ipropd_svc.c:362 ++#, c-format ++msgid "%s: fork failed: %s" ++msgstr "%s: Verzweigen fehlgeschlagen: %s" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:374 ++#, c-format ++msgid "%s: popen failed: %s" ++msgstr "%s: popen fehlgeschlagen: %s" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:388 ++#, c-format ++msgid "%s: pclose(popen) failed: %s" ++msgstr "%s: pclose(popen) fehlgeschlagen: %s" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:405 ++#, c-format ++msgid "%s: exec failed: %s" ++msgstr "%s: exec fehlgeschlagen: %s" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:421 ++#, c-format ++msgid "Request: %s, spawned resync process %d, client=%s, service=%s, addr=%s" ++msgstr "" ++"Anfrage: %s, hervorgebrachter Neusynchronisationsprozess %d, Client=%s, " ++"Dienst=%s, Adresse=%s" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:485 ++#: ../../src/kadmin/server/kadm_rpc_svc.c:275 ++#, c-format ++msgid "check_rpcsec_auth: failed inquire_context, stat=%u" ++msgstr "check_rpcsec_auth: inquire_context fehlgeschlagen, Stat=%u" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:515 ++#: ../../src/kadmin/server/kadm_rpc_svc.c:304 ++#, c-format ++msgid "bad service principal %.*s%s" ++msgstr "falscher Dienst-Principal %.*s%s" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:538 ++#, c-format ++msgid "authentication attempt failed: %s, RPC authentication flavor %d" ++msgstr "" ++"Authentifizierungsversuche gescheitert: %s, PRC-Authentifizierungsvariante %d" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:572 ++#, c-format ++msgid "RPC unknown request: %d (%s)" ++msgstr "unbekannte PRC-Anfrage: %d (%s)" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:580 ++#, c-format ++msgid "RPC svc_getargs failed (%s)" ++msgstr "RPC-»svc_getargs« fehlgeschlagen (%s)" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:590 ++#, c-format ++msgid "RPC svc_sendreply failed (%s)" ++msgstr "RPC-»svc_sendreply« fehlgeschlagen (%s)" ++ ++#: ../../src/kadmin/server/ipropd_svc.c:596 ++#, c-format ++msgid "RPC svc_freeargs failed (%s)" ++msgstr "RPC-»svc_freeargs« fehlgeschlagen (%s)" ++ ++#: ../../src/kadmin/server/kadm_rpc_svc.c:325 ++#, c-format ++msgid "gss_to_krb5_name: failed display_name status %d" ++msgstr "gss_to_krb5_name: display_name fehlgeschlagen, Status %d" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:86 ++#, c-format ++msgid "" ++"Usage: kadmind [-x db_args]* [-r realm] [-m] [-nofork] [-port port-number]\n" ++"\t\t[-proponly] [-p path-to-kdb5_util] [-F dump-file]\n" ++"\t\t[-K path-to-kprop] [-P pid_file]\n" ++"\n" ++"where,\n" ++"\t[-x db_args]* - any number of database specific arguments.\n" ++"\t\t\tLook at each database documentation for supported arguments\n" ++msgstr "" ++"Aufruf: kadmind [-x Datenbankargumente]* [-r Realm] [-m] [-nofork]\n" ++"\t\t[-port Portummer] [-p Pfad_zum_KDB5-Hilfswerkzeug] [-F Auszugsdatei]\n" ++"\t\t[-K Pfad_zu_Kprop] [-P PID-Datei]\n" ++"\n" ++"dabei sind\n" ++"\t[-x Datenbankargumente]* - eine beliebige Anzahl datenbankspezifischer " ++"Argumente.\n" ++"\t\t\tWelche Argumente unterstützt werden, finden Sie in der Dokumentation " ++"der jeweiligen Datenbank.\n" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:111 ++#, c-format ++msgid "%s: %s while %s, aborting\n" ++msgstr "%s: %s bei %s, wird abgebrochen\n" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:113 ++#, c-format ++msgid "%s while %s, aborting\n" ++msgstr "%s bei %s, wird abgebrochen\n" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:115 ++#, c-format ++msgid "%s: %s, aborting\n" ++msgstr "%s: %s, wird abgebrochen\n" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:116 ++#, c-format ++msgid "%s, aborting" ++msgstr "%s, wird abgebrochen" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:282 ++#, c-format ++msgid "" ++"WARNING! Forged/garbled request: %s, claimed client = %.*s%s, server = %.*s" ++"%s, addr = %s" ++msgstr "" ++"WARNUNG! Gefälschte/verstümmelte Anfrage: %s, geforderter Client = %.*s%s, " ++"Server = %.*s%s, Adresse = %s" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:288 ++#, c-format ++msgid "" ++"WARNING! Forged/garbled request: %d, claimed client = %.*s%s, server = %.*s" ++"%s, addr = %s" ++msgstr "" ++"WARNUNG! Gefälschte/verstümmelte Anfrage: %d, Client = %.*s%s, Server = " ++"%.*s%s, Adresse = %s" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:302 ++#, c-format ++msgid "Miscellaneous RPC error: %s, %s" ++msgstr "sonstiger PRC-Fehler: %s, %s" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:318 ++#, c-format ++msgid "%s Cannot decode status %d" ++msgstr "%s: Status %d kann nicht dekodiert werden" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:336 ++#, c-format ++msgid "Authentication attempt failed: %s, GSS-API error strings are:" ++msgstr "Authentifizierungsversuch fehlgeschlagen: %s, GSS-API-Fehlermeldungen:" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:341 ++msgid " GSS-API error strings complete." ++msgstr " GSS-API-Fehlermeldungen vollständig" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:378 ++#, c-format ++msgid "%s: cannot initialize. Not enough memory\n" ++msgstr "%s: kann nicht initialisiert werden: Speicher reicht nicht aus.\n" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:445 ++#, c-format ++msgid "%s: %s while initializing context, aborting\n" ++msgstr "%s: %s beim Initialisieren des Kontextes, wird abgebrochen\n" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:456 ++msgid "initializing" ++msgstr "wird initialisiert" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:460 ++msgid "getting config parameters" ++msgstr "beim Holen der Konfigurationsparameter" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:462 ++msgid "Missing required realm configuration" ++msgstr "erforderliche Realm-Konfiguration fehlt" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:464 ++msgid "Missing required ACL file configuration" ++msgstr "erforderliche ACL-Dateikonfiguration fehlt" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:468 ++msgid "initializing network" ++msgstr "Netzwerk wird initialisiert" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:473 ++msgid "Cannot build GSSAPI auth names" ++msgstr "GSS-API-Authentifizierungsnamen können nicht gebildet werden." ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:477 ++msgid "Cannot set up KDB keytab" ++msgstr "Die KDB-Schlüsseltabelle kann nicht eingerichtet werden." ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:480 ++msgid "Cannot set GSSAPI authentication names" ++msgstr "GSS-API-Authentifizierungsnamen können nicht gesetzt werden." ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:497 ++msgid "Cannot initialize GSSAPI service name" ++msgstr "GSSAPI-Dienstname kann nicht initialisiert werden" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:501 ++msgid "initializing ACL file" ++msgstr "ACL-Datei wird initialisiert" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:504 ++msgid "spawning daemon process" ++msgstr "Daemon-Prozess wird erzeugt" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:508 ++msgid "creating PID file" ++msgstr "PID-Datei wird erstellt" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:511 ++msgid "Seeding random number generator" ++msgstr "Startwert des Zufallszahlengenerators wird erzeugt" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:514 ++msgid "getting random seed" ++msgstr "Zufallsstartwert wird geholt" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:521 ++msgid "mapping update log" ++msgstr "Aktualisierungsprotokoll wird abgebildet" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:525 ++#, c-format ++msgid "%s: create IPROP svc (PROG=%d, VERS=%d)\n" ++msgstr "%s: IPROP-Dienst wird erstellt (PROG=%d, VERS=%d)\n" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:530 ++msgid "starting" ++msgstr "startet" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:532 ../../src/kdc/main.c:1061 ++#, c-format ++msgid "%s: starting...\n" ++msgstr "%s: startet …\n" ++ ++#: ../../src/kadmin/server/ovsec_kadmd.c:535 ++msgid "finished, exiting" ++msgstr "fertig, wird beendet" ++ ++#: ../../src/kadmin/server/schpw.c:282 ++#, c-format ++msgid "setpw request from %s by %.*s%s for %.*s%s: %s" ++msgstr "»setpw«-Anfrage von %s durch %.*s%s für %.*s%s: %s" ++ ++#: ../../src/kadmin/server/schpw.c:287 ++#, c-format ++msgid "chpw request from %s for %.*s%s: %s" ++msgstr "»chpw«-Anfrage von %s für %.*s%s: %s" ++ ++#: ../../src/kadmin/server/schpw.c:464 ++#, c-format ++msgid "chpw: Couldn't open admin keytab %s" ++msgstr "chpw«: Administratorschlüsseltabelle %s konnte nicht geöffnet werden" ++ ++#: ../../src/kadmin/server/server_stubs.c:293 ++#, c-format ++msgid "" ++"Unauthorized request: %s, %.*s%s, client=%.*s%s, service=%.*s%s, addr=%s" ++msgstr "" ++"Unauthorisierte Anfrage: %s, %.*s%s, Client=%.*s%s, Dienst=%.*s%s, Adresse=%s" ++ ++#: ../../src/kadmin/server/server_stubs.c:314 ++#: ../../src/kadmin/server/server_stubs.c:649 ++#: ../../src/kadmin/server/server_stubs.c:1792 ++msgid "success" ++msgstr "erfolgreich" ++ ++#: ../../src/kadmin/server/server_stubs.c:324 ++#, c-format ++msgid "Request: %s, %.*s%s, %s, client=%.*s%s, service=%.*s%s, addr=%s" ++msgstr "Anfrage: %s, %.*s%s, %s, Client=%.*s%s, Dienst=%.*s%s, Adresse=%s" ++ ++#: ../../src/kadmin/server/server_stubs.c:628 ++#, c-format ++msgid "" ++"Unauthorized request: kadm5_rename_principal, %.*s%s to %.*s%s, client=%.*s" ++"%s, service=%.*s%s, addr=%s" ++msgstr "" ++"Unauthorisierte Anfrage: kadm5_rename_principal, %.*s%s bis %.*s%s, Client=" ++"%.*s%s, Dienst=%.*s%s, Adresse=%s" ++ ++#: ../../src/kadmin/server/server_stubs.c:644 ++#, c-format ++msgid "" ++"Request: kadm5_rename_principal, %.*s%s to %.*s%s, %s, client=%.*s%s, " ++"service=%.*s%s, addr=%s" ++msgstr "" ++"Anfrage: kadm5_rename_principal, %.*s%s bis %.*s%s, %s, Client=%.*s%s, " ++"Dienst=%.*s%s, Adresse=%s" ++ ++#: ../../src/kadmin/server/server_stubs.c:1788 ++#, c-format ++msgid "" ++"Request: kadm5_init, %.*s%s, %s, client=%.*s%s, service=%.*s%s, addr=%s, " ++"vers=%d, flavor=%d" ++msgstr "" ++"Anfrage: kadm5_init, %.*s%s, %s, Client=%.*s%s, Dienst=%.*s%s, Adresse=%s, " ++"Version=%d, Variante=%d" ++ ++#: ../../src/kdc/do_as_req.c:273 ++#, c-format ++msgid "AS_REQ : handle_authdata (%d)" ++msgstr "AS_REQ: handle_authdata (%d)" ++ ++#: ../../src/kdc/do_tgs_req.c:593 ++#, c-format ++msgid "TGS_REQ : handle_authdata (%d)" ++msgstr "TGS_REQ: handle_authdata (%d)" ++ ++#: ../../src/kdc/do_tgs_req.c:655 ++msgid "not checking transit path" ++msgstr "Übergangspfad wird nicht geprüft" ++ ++#: ../../src/kdc/fast_util.c:62 ++#, c-format ++msgid "%s while handling ap-request armor" ++msgstr "%s bei der Handhabung des »ap-request«-Schutzes" ++ ++#: ../../src/kdc/fast_util.c:71 ++msgid "ap-request armor for something other than the local TGS" ++msgstr "»ap-request«-Schutz für etwas anderes als den lokalen TGS" ++ ++#: ../../src/kdc/fast_util.c:80 ++msgid "ap-request armor without subkey" ++msgstr "»ap-request«-Schutz ohne Unterschlüssel" ++ ++#: ../../src/kdc/fast_util.c:162 ++msgid "Ap-request armor not permitted with TGS" ++msgstr "»ap-request«-Schutz nicht mit TGS gestattet" ++ ++#: ../../src/kdc/fast_util.c:169 ++#, c-format ++msgid "Unknown FAST armor type %d" ++msgstr "unbekanntet FAST-Schutztyp %d" ++ ++#: ../../src/kdc/fast_util.c:183 ++msgid "No armor key but FAST armored request present" ++msgstr "Es gibt keinen Schutzschlüssel aber eine FAST-geschützte Anfrage" ++ ++#: ../../src/kdc/fast_util.c:219 ++msgid "FAST req_checksum invalid; request modified" ++msgstr "FAST-»req_checksum« ungültig; Anfrage geändert" ++ ++#: ../../src/kdc/fast_util.c:225 ++msgid "Unkeyed checksum used in fast_req" ++msgstr "in fast_req wurde eine Prüfsumme ohne Schlüssel benutzt" ++ ++#: ../../src/kdc/kdc_audit.c:110 ++#, c-format ++msgid "audit plugin %s failed to open. error=%i" ++msgstr "Öffnen der Audit-Erweiterung %s fehlgeschlagen. Fehler=%i" ++ ++#: ../../src/kdc/kdc_authdata.c:292 ../../src/kdc/kdc_authdata.c:328 ++#, c-format ++msgid "authdata %s failed to initialize: %s" ++msgstr "Initialisieren von »authdata« %s fehlgeschlagen: %s" ++ ++#: ../../src/kdc/kdc_authdata.c:779 ++#, c-format ++msgid "authdata (%s) handling failure: %s" ++msgstr "Handhabung von »authdata« %s fehlgeschlagen: %s" ++ ++#: ../../src/kdc/kdc_log.c:82 ++#, c-format ++msgid "AS_REQ (%s) %s: ISSUE: authtime %d, %s, %s for %s" ++msgstr "AS_REQ (%s) %s: PROBLEM: Authentifizierungszeit %d, %s, %s für %s" ++ ++#: ../../src/kdc/kdc_log.c:88 ++#, c-format ++msgid "AS_REQ (%s) %s: %s: %s for %s%s%s" ++msgstr "AS_REQ (%s) %s: %s: %s für %s%s%s" ++ ++#: ../../src/kdc/kdc_log.c:159 ++#, c-format ++msgid "TGS_REQ (%s) %s: %s: authtime %d, %s%s %s for %s%s%s" ++msgstr "TGS_REQ (%s) %s: %s: Authentifizierungszeit %d, %s%s %s für %s%s%s" ++ ++#: ../../src/kdc/kdc_log.c:166 ++#, c-format ++msgid "... PROTOCOL-TRANSITION s4u-client=%s" ++msgstr "… PROTOKOLLÜBERGANG s4u-client=%s" ++ ++#: ../../src/kdc/kdc_log.c:170 ++#, c-format ++msgid "... CONSTRAINED-DELEGATION s4u-client=%s" ++msgstr "… EINHESCHRÄNKTE DELEGIERUNG s4u-client=%s" ++ ++#: ../../src/kdc/kdc_log.c:174 ++#, c-format ++msgid "TGS_REQ %s: %s: authtime %d, %s for %s, 2nd tkt client %s" ++msgstr "TGS_REQ %s: %s: Authentifizierungszeit %d, %s für %s, 2. TKT-Client %s" ++ ++#: ../../src/kdc/kdc_log.c:208 ++#, c-format ++msgid "bad realm transit path from '%s' to '%s' via '%.*s%s'" ++msgstr "falscher Realm-Übergangspfad von »%s« zu »%s« über »%.*s%s«" ++ ++#: ../../src/kdc/kdc_log.c:214 ++#, c-format ++msgid "unexpected error checking transit from '%s' to '%s' via '%.*s%s': %s" ++msgstr "" ++"unerwarteter Fehler bei der Prüfung des Übergangs von »%s« zu »%s« über »%.*s" ++"%s«: %s" ++ ++#: ../../src/kdc/kdc_log.c:232 ++msgid "TGS_REQ: issuing alternate TGT" ++msgstr "TGS_REQ: alternativer TGT wird erstellt" ++ ++#: ../../src/kdc/kdc_log.c:235 ++#, c-format ++msgid "TGS_REQ: issuing TGT %s" ++msgstr "TGS_REQ: TGT %s wird erstellt" ++ ++#: ../../src/kdc/kdc_preauth.c:328 ++#, c-format ++msgid "preauth %s failed to initialize: %s" ++msgstr "Initialisieren von »preauth« %s fehlgeschlagen: %s" ++ ++#: ../../src/kdc/kdc_preauth.c:339 ++#, c-format ++msgid "preauth %s failed to setup loop: %s" ++msgstr "Einrichten der Schleife von »preauth« %s fehlgeschlagen: %s" ++ ++#: ../../src/kdc/kdc_preauth.c:760 ++#, c-format ++msgid "%spreauth required but hint list is empty" ++msgstr "%spreauth benötigt, aber Hinweisliste ist leer" ++ ++#: ../../src/kdc/kdc_preauth_ec.c:75 ++msgid "Encrypted Challenge used outside of FAST tunnel" ++msgstr "verschlüsselte Aufforderung wurde außerhalb des FAST-Tunnels verwendet" ++ ++#: ../../src/kdc/kdc_preauth_ec.c:110 ++msgid "Incorrect password in encrypted challenge" ++msgstr "falsches Passwort in verschlüsselter Aufforderung" ++ ++#: ../../src/kdc/kdc_util.c:236 ++msgid "TGS_REQ: SESSION KEY or MUTUAL" ++msgstr "TGS_REQ: SITZUNGSSCHLÜSSEL oder BEIDERSEITIG" ++ ++#: ../../src/kdc/kdc_util.c:314 ++msgid "PROCESS_TGS: failed lineage check" ++msgstr "PROCESS_TGS: Abstammungsprüfung fehlgeschlagen" ++ ++#: ../../src/kdc/kdc_util.c:468 ++#, c-format ++msgid "TGS_REQ: UNKNOWN SERVER: server='%s'" ++msgstr "TGS_REQ: UNBEKANNTER SERVER: Server=»%s«" ++ ++#: ../../src/kdc/main.c:231 ++#, c-format ++msgid "while getting context for realm %s" ++msgstr "beim Holen des Kontextes für Realm %s" ++ ++#: ../../src/kdc/main.c:329 ++#, c-format ++msgid "while setting default realm to %s" ++msgstr "beim Setzen des Standard-Realms auf %s" ++ ++#: ../../src/kdc/main.c:337 ++#, c-format ++msgid "while initializing database for realm %s" ++msgstr "beim Initialisieren der Datenbank für Realm %s" ++ ++#: ../../src/kdc/main.c:346 ++#, c-format ++msgid "while setting up master key name %s for realm %s" ++msgstr "beim Einrichten des Hauptschlüsselnamens %s für Realm %s" ++ ++#: ../../src/kdc/main.c:359 ++#, c-format ++msgid "while fetching master key %s for realm %s" ++msgstr "beim Abholen des Hauptschlüssels %s für Realm %s" ++ ++#: ../../src/kdc/main.c:367 ++#, c-format ++msgid "while fetching master keys list for realm %s" ++msgstr "beim Abholen der Hauptschlüsselliste für Realm %s" ++ ++#: ../../src/kdc/main.c:376 ++#, c-format ++msgid "while resolving kdb keytab for realm %s" ++msgstr "beim Ermitteln der KDB-Schlüsseltabelle für Realm %s" ++ ++#: ../../src/kdc/main.c:385 ++#, c-format ++msgid "while building TGS name for realm %s" ++msgstr "beim Bilden des TGS-Namens für Realm %s" ++ ++#: ../../src/kdc/main.c:503 ++#, c-format ++msgid "creating %d worker processes" ++msgstr "%d Arbeitsprozesse werden erzeugt" ++ ++#: ../../src/kdc/main.c:513 ++msgid "Unable to reinitialize main loop" ++msgstr "Hauptschleife konnte nicht neu initialisiert werden" ++ ++#: ../../src/kdc/main.c:518 ++#, c-format ++msgid "Unable to initialize signal handlers in pid %d" ++msgstr "" ++"Signalbehandlungsprogramme in PID %d konnten nicht initialisiert werden" ++ ++#: ../../src/kdc/main.c:548 ++#, c-format ++msgid "worker %ld exited with status %d" ++msgstr "Arbeitsprozess %ld endete mit Status %d" ++ ++#: ../../src/kdc/main.c:572 ++#, c-format ++msgid "signal %d received in supervisor" ++msgstr "Überwachungsprogramm empfing Signal %d" ++ ++#: ../../src/kdc/main.c:591 ++#, c-format ++msgid "" ++"usage: %s [-x db_args]* [-d dbpathname] [-r dbrealmname]\n" ++"\t\t[-R replaycachename] [-m] [-k masterenctype]\n" ++"\t\t[-M masterkeyname] [-p port] [-P pid_file]\n" ++"\t\t[-n] [-w numworkers] [/]\n" ++"\n" ++"where,\n" ++"\t[-x db_args]* - Any number of database specific arguments.\n" ++"\t\t\tLook at each database module documentation for \t\t\tsupported " ++"arguments\n" ++msgstr "" ++"Aufruf: %s [-x Datenbankargumente]* [-d Datenbankpfadname]\n" ++"\t\t[-r Datenbank-Realm-Name] [-m] [-k Hauptverschlüsselungstyp]\n" ++"\t\t[-M Hauptschlüsselname] [-p Port] [-P PID-Datei]\n" ++"\t\t[-n] [-w Arbeitsprozessanzahl] [/]\n" ++"\n" ++"dabei sind\n" ++"\t[-x Datenbankargumente]* - eine beliebige Anzahl datenbankspezifischer " ++"Argumente.\n" ++"\t\t\tWelche Argumente unterstützt werden, finden Sie in der Dokumentation " ++"der jeweiligen Datenbank.\n" ++ ++#: ../../src/kdc/main.c:653 ../../src/kdc/main.c:660 ../../src/kdc/main.c:774 ++#, c-format ++msgid " KDC cannot initialize. Not enough memory\n" ++msgstr "KDC kann nicht initialisiert werden. Speicher reicht nicht aus\n" ++ ++#: ../../src/kdc/main.c:679 ../../src/kdc/main.c:722 ../../src/kdc/main.c:733 ++#, c-format ++msgid "%s: KDC cannot initialize. Not enough memory\n" ++msgstr "%s: KDC kann nicht initialisiert werden. Speicher reicht nicht aus\n" ++ ++#: ../../src/kdc/main.c:699 ../../src/kdc/main.c:816 ++#, c-format ++msgid "%s: cannot initialize realm %s - see log file for details\n" ++msgstr "" ++"%s: Realm %s kann nicht initialisiert werden - Einzelheiten finden Sie in " ++"der Protokolldatei\n" ++ ++#: ../../src/kdc/main.c:710 ++#, c-format ++msgid "%s: cannot initialize realm %s. Not enough memory\n" ++msgstr "" ++"%s: Realm %s kann nicht initialisiert werden. Speicher reicht nicht aus\n" ++ ++#: ../../src/kdc/main.c:761 ++#, c-format ++msgid "invalid enctype %s" ++msgstr "ungültiger Verschlüsselungstyp %s" ++ ++#: ../../src/kdc/main.c:804 ++msgid "while attempting to retrieve default realm" ++msgstr "beim Versuch, den Standard-Realm abzufragen" ++ ++#: ../../src/kdc/main.c:806 ++#, c-format ++msgid "%s: %s, attempting to retrieve default realm\n" ++msgstr "%s: %s, es wird versucht, den Standard-Realm abzufragen\n" ++ ++#: ../../src/kdc/main.c:912 ++#, c-format ++msgid "%s: cannot get memory for realm list\n" ++msgstr "%s: Speicher für die Realm-Liste kann nicht erlangt werden\n" ++ ++# http://www.oreilly.de/german/freebooks/linuxdrive2ger/getcache.html ++#: ../../src/kdc/main.c:947 ++msgid "while initializing lookaside cache" ++msgstr "beim Initialisieren des Lookaside-Zwischenspeichers" ++ ++#: ../../src/kdc/main.c:955 ++msgid "while creating main loop" ++msgstr "beim Erzeugen der Hauptschleife" ++ ++# SAM=Security Accounts Manager ++#: ../../src/kdc/main.c:965 ++msgid "while initializing SAM" ++msgstr "beim Initialisieren des SAMs" ++ ++#: ../../src/kdc/main.c:1011 ++msgid "while initializing routing socket" ++msgstr "beim Initialisieren des Routing-Sockets" ++ ++#: ../../src/kdc/main.c:1017 ++msgid "while initializing signal handlers" ++msgstr "beim Initialisieren des Signalbehandlungsprogramms" ++ ++#: ../../src/kdc/main.c:1024 ++msgid "while initializing network" ++msgstr "beim Initialisieren des Netzwerks" ++ ++#: ../../src/kdc/main.c:1029 ++msgid "while detaching from tty" ++msgstr "beim Lösen vom Terminal" ++ ++#: ../../src/kdc/main.c:1036 ++msgid "while creating PID file" ++msgstr "beim Erstellen der PID-Datei" ++ ++#: ../../src/kdc/main.c:1045 ++msgid "creating worker processes" ++msgstr "Arbeitsprozesse werden erzeugt" ++ ++#: ../../src/kdc/main.c:1055 ++msgid "while loading audit plugin module(s)" ++msgstr "beim Laden des/der Auditerweiterungsmoduls/Auditerweiterungsmodule" ++ ++#: ../../src/kdc/main.c:1059 ++msgid "commencing operation" ++msgstr "Aktion wird begonnen" ++ ++#: ../../src/kdc/main.c:1067 ++msgid "shutting down" ++msgstr "wird heruntergefahren" ++ ++#: ../../src/lib/apputils/net-server.c:258 ++msgid "Got signal to request exit" ++msgstr "Signal zur Anfrage des Beendens empfangen" ++ ++#: ../../src/lib/apputils/net-server.c:272 ++msgid "Got signal to reset" ++msgstr "Signal zum Zurücksetzen empfangen" ++ ++#: ../../src/lib/apputils/net-server.c:429 ++#, c-format ++msgid "closing down fd %d" ++msgstr "Dateideskriptor %d wird geschlossen" ++ ++#: ../../src/lib/apputils/net-server.c:443 ++#, c-format ++msgid "descriptor %d closed but still in svc_fdset" ++msgstr "Deskriptor %d geschlossen, aber immer noch in »svc_fdset«" ++ ++#: ../../src/lib/apputils/net-server.c:469 ++msgid "cannot create io event" ++msgstr "E/A-Ereignis kann nicht erzeugt werden" ++ ++#: ../../src/lib/apputils/net-server.c:475 ++msgid "cannot save event" ++msgstr "Ereignis kann nicht gesichert werden" ++ ++#: ../../src/lib/apputils/net-server.c:495 ++#, c-format ++msgid "file descriptor number %d too high" ++msgstr "Dateideskriptornummer %d zu hoch" ++ ++#: ../../src/lib/apputils/net-server.c:503 ++msgid "cannot allocate storage for connection info" ++msgstr "Speicher für Verbindungsinformation kann nicht reserviert werden" ++ ++#: ../../src/lib/apputils/net-server.c:562 ++#, c-format ++msgid "Cannot create TCP server socket on %s" ++msgstr "Auf %s kann kein TCP-Server-Socket erstellt werden." ++ ++#: ../../src/lib/apputils/net-server.c:571 ++#, c-format ++msgid "TCP socket fd number %d (for %s) too high" ++msgstr "TCP-Socket-Deskriptornummer %d (für %s) zu hoch" ++ ++#: ../../src/lib/apputils/net-server.c:579 ++#, c-format ++msgid "Cannot enable SO_REUSEADDR on fd %d" ++msgstr "SO_REUSEADDR kann nicht für Dateideskriptor %d aktiviert werden" ++ ++#: ../../src/lib/apputils/net-server.c:586 ++#, c-format ++msgid "setsockopt(%d,IPV6_V6ONLY,1) failed" ++msgstr "setsockopt(%d,IPV6_V6ONLY,1) fehlgeschlagen" ++ ++#: ../../src/lib/apputils/net-server.c:588 ++#, c-format ++msgid "setsockopt(%d,IPV6_V6ONLY,1) worked" ++msgstr "setsockopt(%d,IPV6_V6ONLY,1) funktioniert" ++ ++#: ../../src/lib/apputils/net-server.c:591 ++msgid "no IPV6_V6ONLY socket option support" ++msgstr "keine Socket-Option für IPV6_V6ONLY unterstützt" ++ ++#: ../../src/lib/apputils/net-server.c:597 ++#, c-format ++msgid "Cannot bind server socket on %s" ++msgstr "Server-Socket kann nicht an %s gebunden werden" ++ ++#: ../../src/lib/apputils/net-server.c:624 ++#, c-format ++msgid "Cannot create RPC service: %s; continuing" ++msgstr "RPC-Dienst kann nicht erstellt werden: %s; es wird fortgefahren" ++ ++#: ../../src/lib/apputils/net-server.c:633 ++#, c-format ++msgid "Cannot register RPC service: %s; continuing" ++msgstr "RPC-Dienst kann nicht registriert werden: %s; es wird fortgefahren" ++ ++#: ../../src/lib/apputils/net-server.c:682 ++#, c-format ++msgid "Cannot listen on TCP server socket on %s" ++msgstr "" ++"Auf dem TCP-Server-Socket kann nicht auf eine Verbindung gewartet werden auf " ++"%s." ++ ++#: ../../src/lib/apputils/net-server.c:688 ++#, c-format ++msgid "cannot set listening tcp socket on %s non-blocking" ++msgstr "" ++"Das auf eine Verbindung wartende TCP-Socket kann nicht auf nicht-" ++"blockierendes %s gesetzt werden." ++ ++#: ../../src/lib/apputils/net-server.c:695 ++#, c-format ++msgid "disabling SO_LINGER on TCP socket on %s" ++msgstr "SO_LINGER auf dem TCP-Socket auf %s wird deaktiviert" ++ ++#: ../../src/lib/apputils/net-server.c:743 ++#: ../../src/lib/apputils/net-server.c:752 ++#, c-format ++msgid "listening on fd %d: tcp %s" ++msgstr "auf Dateideskriptor %d wird auf eine Verbindung gewartet: TCP %s" ++ ++#: ../../src/lib/apputils/net-server.c:757 ++msgid "assuming IPv6 socket accepts IPv4" ++msgstr "es wird davon ausgegangen, dass das IPv6-Socket IPv4 akzeptiert" ++ ++#: ../../src/lib/apputils/net-server.c:791 ++#: ../../src/lib/apputils/net-server.c:804 ++#, c-format ++msgid "listening on fd %d: rpc %s" ++msgstr "auf Dateideskriptor %d wird auf eine Verbindung gewartet: RPC %s" ++ ++#: ../../src/lib/apputils/net-server.c:883 ++#, c-format ++msgid "Cannot request packet info for udp socket address %s port %d" ++msgstr "" ++"Paketinformation für UDP-Socket-Adresse %s, Port %d, kann nicht abgefragt " ++"werden" ++ ++#: ../../src/lib/apputils/net-server.c:889 ++#, c-format ++msgid "listening on fd %d: udp %s%s" ++msgstr "auf Dateideskriptor %d wird auf eine Verbindung gewartet: UDP %s%s" ++ ++#: ../../src/lib/apputils/net-server.c:918 ++msgid "Failed to reconfigure network, exiting" ++msgstr "Neukonfiguration des Netzwerks fehlgeschlagen, wird beendet" ++ ++#: ../../src/lib/apputils/net-server.c:979 ++#, c-format ++msgid "" ++"unhandled routing message type %d, will reconfigure just for the fun of it" ++msgstr "" ++"nicht behandelter Routing-Meldungstyp %d, es wird es nur zum Spaß neu " ++"konfiguriert" ++ ++#: ../../src/lib/apputils/net-server.c:1013 ++#, c-format ++msgid "short read (%d/%d) from routing socket" ++msgstr "ungenügende Daten (%d/%d) vom Routing-Socket gelesen" ++ ++#: ../../src/lib/apputils/net-server.c:1023 ++#, c-format ++msgid "read %d from routing socket but msglen is %d" ++msgstr "%d vom Routing-Socket gelesen, Nachrichtenlänge ist jedoch %d" ++ ++#: ../../src/lib/apputils/net-server.c:1055 ++#, c-format ++msgid "couldn't set up routing socket: %s" ++msgstr "Routing-Socket konnte nicht eingerichtet werden: %s" ++ ++#: ../../src/lib/apputils/net-server.c:1058 ++#, c-format ++msgid "routing socket is fd %d" ++msgstr "Das Routing-Socket hat den Dateideskriptor %d." ++ ++#: ../../src/lib/apputils/net-server.c:1084 ++msgid "setting up network..." ++msgstr "Netzwerk wird eingerichtet …" ++ ++#: ../../src/lib/apputils/net-server.c:1101 ++#, c-format ++msgid "set up %d sockets" ++msgstr "%d Sockets werden eingerichtet" ++ ++#: ../../src/lib/apputils/net-server.c:1103 ++msgid "no sockets set up?" ++msgstr "keine Sockets eingerichtet?" ++ ++#: ../../src/lib/apputils/net-server.c:1351 ++#: ../../src/lib/apputils/net-server.c:1405 ++msgid "while dispatching (udp)" ++msgstr "beim Versenden (UDP)" ++ ++#: ../../src/lib/apputils/net-server.c:1380 ++#, c-format ++msgid "while sending reply to %s/%s from %s" ++msgstr "beim Senden der Antwort zu %s/%s von %s" ++ ++#: ../../src/lib/apputils/net-server.c:1385 ++#, c-format ++msgid "short reply write %d vs %d\n" ++msgstr "ungenügende Ausgabe der Antwort %d gegenüber %d\n" ++ ++#: ../../src/lib/apputils/net-server.c:1430 ++msgid "while receiving from network" ++msgstr "beim Empfangen vom Netzwerk" ++ ++#: ../../src/lib/apputils/net-server.c:1446 ++#, c-format ++msgid "pktinfo says local addr is %s" ++msgstr "Pktinfo sagt, die lokale Adresse sei %s" ++ ++#: ../../src/lib/apputils/net-server.c:1479 ++msgid "too many connections" ++msgstr "zu viele Verbindungen" ++ ++#: ../../src/lib/apputils/net-server.c:1502 ++#, c-format ++msgid "dropping %s fd %d from %s" ++msgstr "%s Dateideskriptor %d von %s wird verworfen" ++ ++#: ../../src/lib/apputils/net-server.c:1580 ++#, c-format ++msgid "allocating buffer for new TCP session from %s" ++msgstr "Puffer für neue TCP-Sitzung von %s wird reserviert" ++ ++#: ../../src/lib/apputils/net-server.c:1610 ++msgid "while dispatching (tcp)" ++msgstr "beim Versenden (TCP)" ++ ++#: ../../src/lib/apputils/net-server.c:1642 ++msgid "error allocating tcp dispatch private!" ++msgstr "Fehler beim Reservieren zum nicht öffentlichen TCP-Versand!" ++ ++#: ../../src/lib/apputils/net-server.c:1689 ++#, c-format ++msgid "TCP client %s wants %lu bytes, cap is %lu" ++msgstr "TCP-Client %s will %lu Byte, Cap ist %lu" ++ ++#: ../../src/lib/apputils/net-server.c:1697 ++#, c-format ++msgid "error constructing KRB_ERR_FIELD_TOOLONG error! %s" ++msgstr "Fehler beim Erzeugen des KRB_ERR_FIELD_TOOLONG-Fehlers! %s" ++ ++#: ../../src/lib/apputils/net-server.c:1876 ++#, c-format ++msgid "accepted RPC connection on socket %d from %s" ++msgstr "akzeptierte PRC-Verbindung auf Socket %d von %s" ++ ++# pseudo random function ++#: ../../src/lib/crypto/krb/cf2.c:114 ++#, c-format ++msgid "Enctype %d has no PRF" ++msgstr "Verschlüsselungstyp %d hat keine PRF" ++ ++#: ../../src/lib/crypto/krb/prng_fortuna.c:428 ++msgid "Random number generator could not be seeded" ++msgstr "Zufallszahlengenerator konnte kein Startwert zugewiesen werden" ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:43 ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:165 ++msgid "A required input parameter could not be read" ++msgstr "Ein benötigter Eingabeparameter konnte nicht gelesen werden." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:44 ++msgid "A required input parameter could not be written" ++msgstr "Ein benötigter Eingabeparameter konnte nicht geschrieben werden." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:45 ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:175 ++msgid "A parameter was malformed" ++msgstr "Ein Parameter hatte eine falsche Form" ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:48 ++msgid "calling error" ++msgstr "Aufruffehler" ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:59 ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:195 ++msgid "An unsupported mechanism was requested" ++msgstr "Ein nicht unterstützter Mechanismus wurde angefordert." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:60 ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:199 ++msgid "An invalid name was supplied" ++msgstr "Ein ungültiger Name wurde übergeben." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:61 ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:203 ++msgid "A supplied name was of an unsupported type" ++msgstr "Ein übergebener Name hatte einen nicht unterstützten Typ." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:62 ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:208 ++msgid "Incorrect channel bindings were supplied" ++msgstr "Falsche Kanalbindungen wurden übergeben." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:63 ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:179 ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:274 ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:334 ++msgid "An invalid status code was supplied" ++msgstr "Ein ungültiger Statuscode wurde übergeben." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:64 ++msgid "A token had an invalid signature" ++msgstr "Ein Merkmal hatte eine ungültige Signatur." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:65 ++msgid "No credentials were supplied" ++msgstr "Es wurden keine Anmeldedaten übergeben." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:66 ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:223 ++msgid "No context has been established" ++msgstr "Es wurde keine Kontext etabliert." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:67 ++msgid "A token was invalid" ++msgstr "Ein Merkmal war ungültig." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:68 ++msgid "A credential was invalid" ++msgstr "Eine der Anmeldedaten war ungültig." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:69 ++msgid "The referenced credentials have expired" ++msgstr "Die referenzierten Anmeldedaten sind abgelaufen." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:70 ++msgid "The context has expired" ++msgstr "Der Kontext ist abgelaufen." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:71 ++msgid "Miscellaneous failure" ++msgstr "sonstiger Fehlschlag" ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:72 ++msgid "The quality-of-protection requested could not be provided" ++msgstr "" ++"Die angeforderte Qualität des Schutzes konnte nicht bereitgestellt werden." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:73 ++msgid "The operation is forbidden by the local security policy" ++msgstr "Die Aktion wird durch die lokale Sicherheitsrichtinie verboten." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:74 ++msgid "The operation or option is not available" ++msgstr "Die Aktion oder Option ist nicht verfügbar." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:77 ++msgid "routine error" ++msgstr "Fehler in einer Routine" ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:89 ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:311 ++msgid "The routine must be called again to complete its function" ++msgstr "" ++"Die Routine muss erneut aufgerufen werden, um ihre Funktion zu " ++"vervollständigen." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:90 ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:316 ++msgid "The token was a duplicate of an earlier token" ++msgstr "Das Merkmal war ein Zweitexemplar eines früheren Merkmals." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:91 ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:321 ++msgid "The token's validity period has expired" ++msgstr "Die Gültigkeitsperiode des Merkmals ist abgelaufen." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:92 ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:325 ++msgid "A later token has already been processed" ++msgstr "Es wurde bereits ein neueres Merkmal verarbeitet." ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:95 ++msgid "supplementary info code" ++msgstr "zusätzlicher Informationscode" ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:106 ++#: ../lib/krb5/error_tables/krb5_err.c:23 ++msgid "No error" ++msgstr "kein Fehler" ++ ++#: ../../src/lib/gssapi/generic/disp_major_status.c:107 ++#, c-format ++msgid "Unknown %s (field = %d)" ++msgstr "%s unbekannt (Feld = %d)" ++ ++#: ../../src/lib/gssapi/krb5/acquire_cred.c:165 ++#, c-format ++msgid "No key table entry found matching %s" ++msgstr "Es wurde kein zu %s passender Schlüsseltabelleneintrag gefunden." ++ ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:161 ++msgid "The routine completed successfully" ++msgstr "Die Routine wurde erfolgreich abgeschlossen" ++ ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:170 ++msgid "A required output parameter could not be written" ++msgstr "Ein erforderlicher Ausgabeparameter konnte nicht geschrieben werden." ++ ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:212 ++msgid "A token had an invalid Message Integrity Check (MIC)" ++msgstr "" ++"Ein Merkmal hatte eine ungültige Meldungsintegritätsprüfung (Message " ++"Integrity Check/MIC)." ++ ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:217 ++msgid "" ++"No credentials were supplied, or the credentials were unavailable or " ++"inaccessible" ++msgstr "" ++"Es wurden keine Anmeldedaten übergeben oder die Anmeldedaten waren nicht " ++"verfügbar bzw. ein Zugriff darauf nicht möglich." ++ ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:227 ++msgid "Invalid token was supplied" ++msgstr "Es wurde ein ungültiges Token übergeben." ++ ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:231 ++msgid "Invalid credential was supplied" ++msgstr "ungültige Anmeldedaten wurden übergeben" ++ ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:235 ++msgid "The referenced credential has expired" ++msgstr "Die referenzierten Anmeldedaten sind abgelaufen." ++ ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:239 ++msgid "The referenced context has expired" ++msgstr "Der referenzierte Kontext ist abgelaufen." ++ ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:243 ++msgid "Unspecified GSS failure. Minor code may provide more information" ++msgstr "" ++"nicht spezifizierter GSS-Fehlschlag. Möglicherweise stellt der " ++"untergeordnete Code weitere Informationen bereit." ++ ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:248 ++msgid "The quality-of-protection (QOP) requested could not be provided" ++msgstr "" ++"Die Qualität des Schutzes (quality-of-protection/QOP) konnte nicht " ++"bereitgestellt werden." ++ ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:253 ++msgid "The operation is forbidden by local security policy" ++msgstr "Die Aktion wird durch die lokale Sicherheitsrichtinie verboten." ++ ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:258 ++msgid "The operation or option is not available or unsupported" ++msgstr "" ++"Die Aktion oder Option ist nicht verfügbar oder wird nicht unterstützt." ++ ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:263 ++msgid "The requested credential element already exists" ++msgstr "Das angeforderte Anmeldedatenelement existiert bereits." ++ ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:268 ++msgid "The provided name was not mechanism specific (MN)" ++msgstr "Der bereitgestellte Name war nicht mechanismusspezifisch (MN)." ++ ++#: ../../src/lib/gssapi/mechglue/g_dsp_status.c:329 ++msgid "An expected per-message token was not received" ++msgstr "Ein erwartetes nachrichtenspezifisches Token wurde nicht empfangen." ++ ++#: ../../src/lib/gssapi/spnego/spnego_mech.c:1860 ++msgid "SPNEGO cannot find mechanisms to negotiate" ++msgstr "SPNEGO kann keine Mechanismen zum Aushandeln finden." ++ ++#: ../../src/lib/gssapi/spnego/spnego_mech.c:1865 ++msgid "SPNEGO failed to acquire creds" ++msgstr "SPNEGO ist beim Beschaffen von Anmeldedaten gescheitert" ++ ++#: ../../src/lib/gssapi/spnego/spnego_mech.c:1870 ++msgid "SPNEGO acceptor did not select a mechanism" ++msgstr "SPNEGO-Abnehmer hat keinen Mechanismus ausgewählt" ++ ++#: ../../src/lib/gssapi/spnego/spnego_mech.c:1875 ++msgid "SPNEGO failed to negotiate a mechanism" ++msgstr "SPNEGO ist beim Aushandeln eines Mechanismus gescheitert." ++ ++#: ../../src/lib/gssapi/spnego/spnego_mech.c:1880 ++msgid "SPNEGO acceptor did not return a valid token" ++msgstr "SPNEGO-Abnehmer hat kein gültiges Token zurückgeliefert" ++ ++#: ../../src/lib/kadm5/alt_prof.c:854 ++#, c-format ++msgid "Cannot resolve address of admin server \"%s\" for realm \"%s\"" ++msgstr "" ++"Adresse des Admin-Servers »%s« für Realm »%s« kann nicht ermittelt werden" ++ ++#: ../../src/lib/kadm5/logger.c:56 ++#, c-format ++msgid "%s: cannot parse <%s>\n" ++msgstr "%s: <%s> kann nicht ausgewertet werden\n" ++ ++#: ../../src/lib/kadm5/logger.c:57 ++#, c-format ++msgid "%s: warning - logging entry syntax error\n" ++msgstr "%s: Warnung – Syntaxfehler bei Protokolleintrag\n" ++ ++#: ../../src/lib/kadm5/logger.c:58 ++#, c-format ++msgid "%s: error writing to %s\n" ++msgstr "%s: Fehler beim Schreiben auf %s\n" ++ ++#: ../../src/lib/kadm5/logger.c:59 ++#, c-format ++msgid "%s: error writing to %s device\n" ++msgstr "%s: Fehler beim Schreiben auf Gerät %s\n" ++ ++#: ../../src/lib/kadm5/logger.c:61 ++msgid "EMERGENCY" ++msgstr "NOTFALL" ++ ++#: ../../src/lib/kadm5/logger.c:62 ++msgid "ALERT" ++msgstr "ALARM" ++ ++#: ../../src/lib/kadm5/logger.c:63 ++msgid "CRITICAL" ++msgstr "KRITISCH" ++ ++#: ../../src/lib/kadm5/logger.c:64 ++msgid "Error" ++msgstr "Fehler" ++ ++#: ../../src/lib/kadm5/logger.c:65 ++msgid "Warning" ++msgstr "Warnung" ++ ++#: ../../src/lib/kadm5/logger.c:66 ++msgid "Notice" ++msgstr "Hinweis" ++ ++#: ../../src/lib/kadm5/logger.c:67 ++msgid "info" ++msgstr "Information" ++ ++#: ../../src/lib/kadm5/logger.c:68 ++msgid "debug" ++msgstr "Fehlersuchmeldung" ++ ++#: ../../src/lib/kadm5/logger.c:967 ++#, c-format ++msgid "Couldn't open log file %s: %s\n" ++msgstr "Protokolldatei %s konnte nicht geöffnet werden: %s\n" ++ ++#: ../../src/lib/kadm5/srv/kadm5_hook.c:119 ++#, c-format ++msgid "kadm5_hook %s failed postcommit %s: %s" ++msgstr "»kadm5_hook« %s ist beim Nach-Commit %s gescheitert: %s" ++ ++#: ../../src/lib/kadm5/srv/pwqual_dict.c:106 ++msgid "No dictionary file specified, continuing without one." ++msgstr "keine Wörterbuchdatei angegeben, es wird ohne fortgefahren" ++ ++#: ../../src/lib/kadm5/srv/pwqual_dict.c:113 ++#, c-format ++msgid "WARNING! Cannot find dictionary file %s, continuing without one." ++msgstr "" ++"WARNUNG! Wörterbuchdatei %s kann nicht gefunden werden, es wird ohne " ++"fortgefahren" ++ ++#: ../../src/lib/kadm5/srv/pwqual_empty.c:42 ++msgid "Empty passwords are not allowed" ++msgstr "Leere Passwörter sind nicht erlaubt." ++ ++#: ../../src/lib/kadm5/srv/pwqual_hesiod.c:114 ++msgid "Password may not match user information." ++msgstr "Das Passwort darf keinen Anwenderdaten entsprechen." ++ ++#: ../../src/lib/kadm5/srv/pwqual_princ.c:54 ++msgid "Password may not match principal name" ++msgstr "Das Passwort darf nicht mit dem Principal-Namen übereinstimmen." ++ ++#: ../../src/lib/kadm5/srv/server_acl.c:89 ++#, c-format ++msgid "%s: line %d too long, truncated" ++msgstr "%s: Zeile %d zu lang, wurde gekürzt" ++ ++#: ../../src/lib/kadm5/srv/server_acl.c:90 ++#, c-format ++msgid "Unrecognized ACL operation '%c' in %s" ++msgstr "unbekannte ACL-Aktion »%c« in %s" ++ ++#: ../../src/lib/kadm5/srv/server_acl.c:92 ++#, c-format ++msgid "%s: syntax error at line %d <%10s...>" ++msgstr "%s: Syntaxfehler in Zeile %d <%10s …>" ++ ++#: ../../src/lib/kadm5/srv/server_acl.c:94 ++#, c-format ++msgid "%s while opening ACL file %s" ++msgstr "%s beim Öffnen der ACL-Datei %s" ++ ++#: ../../src/lib/kadm5/srv/server_acl.c:353 ++#, c-format ++msgid "%s: invalid restrictions: %s" ++msgstr "%s: ungültige Beschränkung: %s" ++ ++#: ../../src/lib/kadm5/srv/server_kdb.c:192 ++msgid "History entry contains no key data" ++msgstr "Chronikeintrag enthält keine Schlüsseldaten" ++ ++#: ../../src/lib/kadm5/srv/server_misc.c:128 ++#, c-format ++msgid "password quality module %s rejected password for %s: %s" ++msgstr "" ++"Das Modul %s für Passwortqualität hat das Passwort für %s abgelehnt: %s" ++ ++#: ../../src/lib/kadm5/str_conv.c:80 ++msgid "Not Postdateable" ++msgstr "nicht vordatierbar" ++ ++#: ../../src/lib/kadm5/str_conv.c:81 ++msgid "Not Forwardable" ++msgstr "nicht weiterleitbar" ++ ++#: ../../src/lib/kadm5/str_conv.c:82 ++msgid "No TGT-based requests" ++msgstr "keine TGT-basierten Anfragen" ++ ++#: ../../src/lib/kadm5/str_conv.c:83 ++msgid "Not renewable" ++msgstr "nicht erneuerbar" ++ ++#: ../../src/lib/kadm5/str_conv.c:84 ++msgid "Not proxiable" ++msgstr "Proxy nicht nutzbar" ++ ++#: ../../src/lib/kadm5/str_conv.c:85 ++msgid "No DUP_SKEY requests" ++msgstr "keine DUP_SKEY-Anfragen" ++ ++#: ../../src/lib/kadm5/str_conv.c:86 ++msgid "All Tickets Disallowed" ++msgstr "keine Tickets erlaubt" ++ ++#: ../../src/lib/kadm5/str_conv.c:87 ++msgid "Preauthentication required" ++msgstr "Vorauthentifizierung erforderlich" ++ ++#: ../../src/lib/kadm5/str_conv.c:88 ++msgid "HW authentication required" ++msgstr "HW-Authentifizierung erforderlich" ++ ++#: ../../src/lib/kadm5/str_conv.c:89 ++msgid "OK as Delegate" ++msgstr "OK als Vertreter" ++ ++#: ../../src/lib/kadm5/str_conv.c:90 ++msgid "Password Change required" ++msgstr "Passwortänderung erforderlich" ++ ++#: ../../src/lib/kadm5/str_conv.c:91 ++msgid "Service Disabled" ++msgstr "Dienst deaktiviert" ++ ++#: ../../src/lib/kadm5/str_conv.c:92 ++msgid "Password Changing Service" ++msgstr "Passwortänderungsdienst" ++ ++#: ../../src/lib/kadm5/str_conv.c:93 ++msgid "RSA-MD5 supported" ++msgstr "RSA-MD5 unterstützt" ++ ++#: ../../src/lib/kadm5/str_conv.c:94 ++msgid "Protocol transition with delegation allowed" ++msgstr "Protokollübergang mit Vertretung erlaubt" ++ ++#: ../../src/lib/kadm5/str_conv.c:95 ++msgid "No authorization data required" ++msgstr "keine Autorisierungsdaten erforderlich" ++ ++#: ../../src/lib/kdb/kdb5.c:219 ++msgid "No default realm set; cannot initialize KDB" ++msgstr "kein Standard-Realm gesetzt; KDB kann nicht initialisiert werden" ++ ++#: ../../src/lib/kdb/kdb5.c:324 ../../src/lib/kdb/kdb5.c:406 ++#, c-format ++msgid "Unable to find requested database type: %s" ++msgstr "angeforderter Datenbanktyp kann nicht gefunden werden. %s" ++ ++#: ../../src/lib/kdb/kdb5.c:416 ++#, c-format ++msgid "plugin symbol 'kdb_function_table' lookup failed: %s" ++msgstr "" ++"Nachschlagen des Erweiterungssymbols »kdb_function_table« fehlgeschlagen: %s" ++ ++#: ../../src/lib/kdb/kdb5.c:426 ++#, c-format ++msgid "" ++"Unable to load requested database module '%s': plugin symbol " ++"'kdb_function_table' not found" ++msgstr "" ++"angefordertes Datenbankmodul »%s« kann nicht geladen werden: " ++"Erweiterungssymbol »kdb_function_table« nicht gefunden" ++ ++#: ../../src/lib/kdb/kdb5.c:1650 ++#, c-format ++msgid "Illegal version number for KRB5_TL_MKEY_AUX %d\n" ++msgstr "Ungültige Versionsnummer für KRB5_TL_MKEY_AUX %d\n" ++ ++#: ../../src/lib/kdb/kdb5.c:1819 ++#, c-format ++msgid "Illegal version number for KRB5_TL_ACTKVNO %d\n" ++msgstr "Ungültige Versionsnummer für KRB5_TL_ACTKVNO %d\n" ++ ++#: ../../src/lib/kdb/kdb_default.c:164 ++#, c-format ++msgid "keyfile (%s) is not a regular file: %s" ++msgstr "Schlüsseldatei (%s) ist keine normale Datei: %s" ++ ++#: ../../src/lib/kdb/kdb_default.c:177 ++msgid "Could not create temp keytab file name." ++msgstr "Temporärer Schlüsseltabellendateiname konnte nicht erstellt werden." ++ ++#: ../../src/lib/kdb/kdb_default.c:202 ++#, c-format ++msgid "Temporary stash file already exists: %s." ++msgstr "Temporäre Ablagedatei existiert bereits: %s." ++ ++#: ../../src/lib/kdb/kdb_default.c:230 ++#, c-format ++msgid "rename of temporary keyfile (%s) to (%s) failed: %s" ++msgstr "" ++"Umbenennen von temporärer Schlüsseldatei (%s) in (%s) fehlgeschlagen: %s" ++ ++#: ../../src/lib/kdb/kdb_default.c:419 ++#, c-format ++msgid "Can not fetch master key (error: %s)." ++msgstr "Hauptschlüssel kann nicht abgeholt werden (Fehler: %s)" ++ ++#: ../../src/lib/kdb/kdb_default.c:482 ++msgid "Unable to decrypt latest master key with the provided master key\n" ++msgstr "" ++"Letzter Hauptschlüssel kann nicht mit dem bereitgestellten Hauptschlüssel " ++"entschlüsselt werden.\n" ++ ++#: ../../src/lib/kdb/kdb_log.c:83 ++msgid "could not sync ulog header to disk" ++msgstr "Ulog-Kopfzeilen konnten nicht auf die Platte synchronisiert werden" ++ ++#: ../../src/lib/krb5/ccache/cc_dir.c:122 ++#, c-format ++msgid "Subsidiary cache path %s has no parent directory" ++msgstr "" ++"Ergänzender Zwischenspeicherpfad %s hat kein übergeordnetes Verzeichnis." ++ ++#: ../../src/lib/krb5/ccache/cc_dir.c:128 ++#, c-format ++msgid "Subsidiary cache path %s filename does not begin with \"tkt\"" ++msgstr "" ++"Dateiname des ergänzenden Zwischenspeicherpfads %s beginnt nicht mit »tkt«" ++ ++#: ../../src/lib/krb5/ccache/cc_dir.c:169 ++#, c-format ++msgid "%s contains invalid filename" ++msgstr "%s enthält einen ungültigen Dateinamen." ++ ++#: ../../src/lib/krb5/ccache/cc_dir.c:229 ++#, c-format ++msgid "Credential cache directory %s does not exist" ++msgstr "Anmeldedatenzwischenspeicherverzeichnis %s existiert nicht." ++ ++#: ../../src/lib/krb5/ccache/cc_dir.c:235 ++#, c-format ++msgid "Credential cache directory %s exists but is not a directory" ++msgstr "" ++"Anmeldedatenzwischenspeicherverzeichnis %s existiert, ist jedoch kein " ++"Verzeichnis" ++ ++#: ../../src/lib/krb5/ccache/cc_dir.c:400 ++msgid "" ++"Can't create new subsidiary cache because default cache is not a directory " ++"collection" ++msgstr "" ++"Der neue ergänzende Zwischenspeicher kann nicht erstellt werden, da der " ++"Standardzwischenspeicher keine Ansammlung von Verzeichnissen ist." ++ ++#: ../../src/lib/krb5/ccache/cc_file.c:569 ++#, c-format ++msgid "Credentials cache file '%s' not found" ++msgstr "Anmeldedatenzwischenspeicherdatei »%s« nicht gefunden" ++ ++#: ../../src/lib/krb5/ccache/cc_file.c:1575 ++#, c-format ++msgid "Credentials cache I/O operation failed (%s)" ++msgstr "Anmeldedatenzwischenspeicher-E/A-Aktion fehlgeschlagen (%s)" ++ ++#: ../../src/lib/krb5/ccache/cc_keyring.c:1151 ++msgid "" ++"Can't create new subsidiary cache because default cache is already a " ++"subsidiary" ++msgstr "" ++"Der neue ergänzende Zwischenspeicher kann nicht erstellt werden, da der " ++"Standardzwischenspeicher bereits eine Ergänzung ist." ++ ++#: ../../src/lib/krb5/ccache/cc_keyring.c:1219 ++#, c-format ++msgid "Credentials cache keyring '%s' not found" ++msgstr "Schlüsselbund %s des Anmeldedatenzwischenspeichers nicht gefunden" ++ ++#: ../../src/lib/krb5/ccache/cccursor.c:212 ++#, c-format ++msgid "Can't find client principal %s in cache collection" ++msgstr "" ++"Client-Principal %s kann nicht in der Zwischenspeicheransammlung gefunden " ++"werden" ++ ++#: ../../src/lib/krb5/ccache/cccursor.c:253 ++msgid "No Kerberos credentials available" ++msgstr "keine Kerberos-Anmeldedaten verfügbar" ++ ++#: ../../src/lib/krb5/keytab/kt_file.c:398 ++#, c-format ++msgid "No key table entry found for %s" ++msgstr "Für %s wurde kein Schlüsseltabelleneintrag gefunden." ++ ++#: ../../src/lib/krb5/keytab/kt_file.c:815 ++#: ../../src/lib/krb5/keytab/kt_file.c:848 ++msgid "Cannot change keytab with keytab iterators active" ++msgstr "" ++"Schlüsseltabelle mit aktiven Schlüsseltabelleniteratoren kann nicht geändert " ++"werden" ++ ++#: ../../src/lib/krb5/keytab/kt_file.c:1047 ++#, c-format ++msgid "Key table file '%s' not found" ++msgstr "Schlüsseltabellendatei »%s« nicht gefunden" ++ ++#: ../../src/lib/krb5/keytab/ktfns.c:127 ++#, c-format ++msgid "Keytab %s is nonexistent or empty" ++msgstr "Schlüsseltabelle %s existiert nicht oder ist leer" ++ ++#: ../../src/lib/krb5/krb/chpw.c:251 ++msgid "Malformed request error" ++msgstr "Fehler wegen Anfrage in falscher Form" ++ ++#: ../../src/lib/krb5/krb/chpw.c:254 ../lib/krb5/error_tables/kdb5_err.c:58 ++msgid "Server error" ++msgstr "Serverfehler" ++ ++#: ../../src/lib/krb5/krb/chpw.c:257 ++msgid "Authentication error" ++msgstr "Authentifizierungsfehler" ++ ++#: ../../src/lib/krb5/krb/chpw.c:260 ++msgid "Password change rejected" ++msgstr "Passwortänderung abgelehnt" ++ ++#: ../../src/lib/krb5/krb/chpw.c:263 ++msgid "Access denied" ++msgstr "Zugriff verweigert" ++ ++#: ../../src/lib/krb5/krb/chpw.c:266 ++msgid "Wrong protocol version" ++msgstr "falsche Protokollversion" ++ ++#: ../../src/lib/krb5/krb/chpw.c:269 ++msgid "Initial password required" ++msgstr "Erstpasswort erforderlich" ++ ++#: ../../src/lib/krb5/krb/chpw.c:272 ++msgid "Success" ++msgstr "Erfolg" ++ ++#: ../../src/lib/krb5/krb/chpw.c:275 ../lib/krb5/error_tables/krb5_err.c:257 ++msgid "Password change failed" ++msgstr "Ändern des Passworts fehlgeschlagen" ++ ++#: ../../src/lib/krb5/krb/chpw.c:433 ++msgid "" ++"The password must include numbers or symbols. Don't include any part of " ++"your name in the password." ++msgstr "" ++"Das Passwort muss Zahlen oder Symbole enthalten. Fügen Sie keinen Teil Ihres " ++"Namens in das Passwort ein." ++ ++#: ../../src/lib/krb5/krb/chpw.c:439 ++#, c-format ++msgid "The password must contain at least %d character." ++msgid_plural "The password must contain at least %d characters." ++msgstr[0] "Das Passwort muss mindestens %d Zeichen enthalten." ++msgstr[1] "Das Passwort muss mindestens %d Zeichen enthalten." ++ ++#: ../../src/lib/krb5/krb/chpw.c:448 ++#, c-format ++msgid "The password must be different from the previous password." ++msgid_plural "The password must be different from the previous %d passwords." ++msgstr[0] "Das Passwort muss sich vom vorhergehenden Passwort unterscheiden." ++msgstr[1] "" ++"Das Passwort muss sich von den vorhergehenden %d Passwörtern unterscheiden." ++ ++#: ../../src/lib/krb5/krb/chpw.c:460 ++#, c-format ++msgid "The password can only be changed once a day." ++msgid_plural "The password can only be changed every %d days." ++msgstr[0] "Das Passwort kann nur einmal täglich geändert werden." ++msgstr[1] "Das Passwort kann nur alle %d Tage geändert werden." ++ ++#: ../../src/lib/krb5/krb/chpw.c:506 ++msgid "Try a more complex password, or contact your administrator." ++msgstr "" ++"Versuchen Sie es mit einem etwas komplexeren Passwort oder wenden Sie sich " ++"an Ihren Administrator." ++ ++#: ../../src/lib/krb5/krb/fast.c:217 ++#, c-format ++msgid "%s constructing AP-REQ armor" ++msgstr "%s-Konstruktion von AP-REQ-Schutz" ++ ++#: ../../src/lib/krb5/krb/fast.c:399 ++#, c-format ++msgid "%s while decrypting FAST reply" ++msgstr "%s beim Entschlüsseln der FAST-Antwort" ++ ++#: ../../src/lib/krb5/krb/fast.c:408 ++msgid "nonce modified in FAST response: KDC response modified" ++msgstr "" ++"Nummer für einmaligen Gebrauch in der FAST-Anwort geändert: KDC-Anwort " ++"geändert" ++ ++#: ../../src/lib/krb5/krb/fast.c:474 ++msgid "Expecting FX_ERROR pa-data inside FAST container" ++msgstr "Innerhalb des FAST-Containers wird »FX_ERROR pa-data« erwartet." ++ ++#: ../../src/lib/krb5/krb/fast.c:545 ++msgid "FAST response missing finish message in KDC reply" ++msgstr "Der FAST-Anwort fehlt die Beendigungsnachricht in der KDC-Anwort" ++ ++#: ../../src/lib/krb5/krb/fast.c:558 ++msgid "Ticket modified in KDC reply" ++msgstr "Ticket in der KDC-Antwort verändert" ++ ++#: ../../src/lib/krb5/krb/gc_via_tkt.c:208 ++#, c-format ++msgid "KDC returned error string: %.*s" ++msgstr "KDC gab eine Fehlermeldung zurück: %.*s" ++ ++#: ../../src/lib/krb5/krb/gc_via_tkt.c:217 ++#, c-format ++msgid "Server %s not found in Kerberos database" ++msgstr "Server %s wurde nicht in der Kerberos-Datenbank gefunden" ++ ++#: ../../src/lib/krb5/krb/get_in_tkt.c:133 ++msgid "Reply has wrong form of session key for anonymous request" ++msgstr "" ++"Antwort hat die falsche Form des Sitzungschlüssels für eine anonyme Anfrage" ++ ++#: ../../src/lib/krb5/krb/get_in_tkt.c:1628 ++#, c-format ++msgid "%s while storing credentials" ++msgstr "%s beim Speichern der Anmeldedaten" ++ ++#: ../../src/lib/krb5/krb/get_in_tkt.c:1715 ++#, c-format ++msgid "Client '%s' not found in Kerberos database" ++msgstr "Client »%s« wurde nicht in der Kerberos-Datenbank gefunden" ++ ++#: ../../src/lib/krb5/krb/gic_keytab.c:207 ++#, c-format ++msgid "Keytab contains no suitable keys for %s" ++msgstr "Schlüsseltabelle enthält keine passenden Schlüssel für %s" ++ ++#: ../../src/lib/krb5/krb/gic_pwd.c:75 ++#, c-format ++msgid "Password for %s" ++msgstr "Passwort for %s" ++ ++#: ../../src/lib/krb5/krb/gic_pwd.c:227 ++#, c-format ++msgid "Warning: Your password will expire in less than one hour on %s" ++msgstr "" ++"Warnung: Ihr Passwort auf %s wird in weniger als einer Stunde ablaufen." ++ ++# FIXME in German impossible; plural without »s« ++#: ../../src/lib/krb5/krb/gic_pwd.c:231 ++#, c-format ++msgid "Warning: Your password will expire in %d hour%s on %s" ++msgstr "Warnung: Ihr Passwort wird in %d Stunden%s auf %s ablaufen." ++ ++#: ../../src/lib/krb5/krb/gic_pwd.c:235 ++#, c-format ++msgid "Warning: Your password will expire in %d days on %s" ++msgstr "Warnung: Ihr Passwort wird in %d Tagen auf %s ablaufen." ++ ++#: ../../src/lib/krb5/krb/gic_pwd.c:409 ++msgid "Password expired. You must change it now." ++msgstr "Passwort abgelaufen. Sie müssen es nun ändern." ++ ++#: ../../src/lib/krb5/krb/gic_pwd.c:428 ../../src/lib/krb5/krb/gic_pwd.c:432 ++#, c-format ++msgid "%s. Please try again." ++msgstr "%s. Bitte versuchen Sie es erneut." ++ ++#: ../../src/lib/krb5/krb/gic_pwd.c:471 ++#, c-format ++msgid "%.*s%s%s. Please try again.\n" ++msgstr "%.*s%s%s. Bitte versuchen Sie es erneut.\n" ++ ++#: ../../src/lib/krb5/krb/parse.c:203 ++#, c-format ++msgid "Principal %s is missing required realm" ++msgstr "Principal %s fehlt erforderlicher Realm" ++ ++#: ../../src/lib/krb5/krb/parse.c:215 ++#, c-format ++msgid "Principal %s has realm present" ++msgstr "Für Principal %s ist Realm vorhanden" ++ ++#: ../../src/lib/krb5/krb/plugin.c:165 ++#, c-format ++msgid "Invalid module specifier %s" ++msgstr "ungültiger Modulbezeichner %s" ++ ++#: ../../src/lib/krb5/krb/plugin.c:402 ++#, c-format ++msgid "Could not find %s plugin module named '%s'" ++msgstr "Das Erweiterungsmodul %s namens »%s« konnte nicht gefunden werden." ++ ++#: ../../src/lib/krb5/krb/preauth2.c:1018 ++msgid "Unable to initialize preauth context" ++msgstr "Vorauthentifizierungskontext konnte nicht initialisiert werden." ++ ++#: ../../src/lib/krb5/krb/preauth2.c:1032 ++#, c-format ++msgid "Preauth module %s: %s" ++msgstr "Vorauthentifizierungsmodul %s: %s" ++ ++#: ../../src/lib/krb5/krb/preauth_otp.c:510 ++msgid "Please choose from the following:\n" ++msgstr "Bitte wählen Sie aus dem Folgenden aus:\n" ++ ++#: ../../src/lib/krb5/krb/preauth_otp.c:511 ++msgid "Vendor:" ++msgstr "Anbieter:" ++ ++#: ../../src/lib/krb5/krb/preauth_otp.c:523 ++msgid "Enter #" ++msgstr "Geben Sie # ein" ++ ++#: ../../src/lib/krb5/krb/preauth_otp.c:559 ++msgid "OTP Challenge:" ++msgstr "Anforderung des Einwegpassworts:" ++ ++#: ../../src/lib/krb5/krb/preauth_otp.c:588 ++msgid "OTP Token PIN" ++msgstr "Einwegpasswort-Token-PIN" ++ ++#: ../../src/lib/krb5/krb/preauth_otp.c:702 ++msgid "OTP value doesn't match any token formats" ++msgstr "Wert des Einwegpassworts entspricht keinem Token-Format" ++ ++#: ../../src/lib/krb5/krb/preauth_otp.c:769 ++msgid "Enter OTP Token Value" ++msgstr "Geben Sie den Wert des Einwegpasswort-Tokens an" ++ ++#: ../../src/lib/krb5/krb/preauth_otp.c:914 ++msgid "No supported tokens" ++msgstr "keine unterstützten Token" ++ ++#: ../../src/lib/krb5/krb/preauth_sam2.c:49 ++msgid "Challenge for Enigma Logic mechanism" ++msgstr "Anforderung für Enigma-Logic-Mechanismus" ++ ++#: ../../src/lib/krb5/krb/preauth_sam2.c:53 ++msgid "Challenge for Digital Pathways mechanism" ++msgstr "Anforderung für Digital-Pathway-Mechanismus" ++ ++#: ../../src/lib/krb5/krb/preauth_sam2.c:57 ++msgid "Challenge for Activcard mechanism" ++msgstr "Anforderung für Activcard-Mechanismus" ++ ++#: ../../src/lib/krb5/krb/preauth_sam2.c:60 ++msgid "Challenge for Enhanced S/Key mechanism" ++msgstr "Anforderung für erweiterten S/Key-Mechanismus" ++ ++#: ../../src/lib/krb5/krb/preauth_sam2.c:63 ++msgid "Challenge for Traditional S/Key mechanism" ++msgstr "Anforderung für traditionellen S/Key-Mechanismus" ++ ++#: ../../src/lib/krb5/krb/preauth_sam2.c:66 ++#: ../../src/lib/krb5/krb/preauth_sam2.c:69 ++msgid "Challenge for Security Dynamics mechanism" ++msgstr "Anforderung für Security-Dynamics-Mechanismus" ++ ++#: ../../src/lib/krb5/krb/preauth_sam2.c:72 ++msgid "Challenge from authentication server" ++msgstr "Anforderung vom Authentifizierungsserver" ++ ++#: ../../src/lib/krb5/krb/preauth_sam2.c:166 ++msgid "SAM Authentication" ++msgstr "SAM-Authentifizierung" ++ ++#: ../../src/lib/krb5/krb/rd_req_dec.c:145 ++#, c-format ++msgid "Cannot find key for %s kvno %d in keytab" ++msgstr "" ++"Schlüssel für %s-KNVO %d kann nicht in der Schlüsseltabelle gefunden werden" ++ ++#: ../../src/lib/krb5/krb/rd_req_dec.c:150 ++#, c-format ++msgid "Cannot find key for %s kvno %d in keytab (request ticket server %s)" ++msgstr "" ++"Schlüssel für %s-KNVO %d kann nicht in der Schlüsseltabelle gefunden werden " ++"(angefragter Ticketserver %s)" ++ ++#: ../../src/lib/krb5/krb/rd_req_dec.c:175 ++#, c-format ++msgid "Cannot decrypt ticket for %s using keytab key for %s" ++msgstr "" ++"Ticket für %s kann nicht mittels des Schlüsseltabellenschlüssels für %s " ++"entschlüsselt werden" ++ ++#: ../../src/lib/krb5/krb/rd_req_dec.c:197 ++#, c-format ++msgid "Server principal %s does not match request ticket server %s" ++msgstr "Server-Principal %s passt nicht zum abgefragten Ticketserver %s" ++ ++#: ../../src/lib/krb5/krb/rd_req_dec.c:226 ++msgid "No keys in keytab" ++msgstr "keine Schlüssel in der Schlüsseltabelle" ++ ++#: ../../src/lib/krb5/krb/rd_req_dec.c:229 ++#, c-format ++msgid "Server principal %s does not match any keys in keytab" ++msgstr "" ++"Server-Principal %s hat keinen passenden Schlüssel in der Schlüsseltabelle" ++ ++#: ../../src/lib/krb5/krb/rd_req_dec.c:236 ++#, c-format ++msgid "" ++"Request ticket server %s found in keytab but does not match server principal " ++"%s" ++msgstr "" ++"abgefragter Ticketserver %s wurde in der Schlüsseltabelle gefunden, er passte " ++"jedoch nicht zu Server-Principal %s" ++ ++#: ../../src/lib/krb5/krb/rd_req_dec.c:241 ++#, c-format ++msgid "Request ticket server %s not found in keytab (ticket kvno %d)" ++msgstr "" ++"Abgefragter Ticketserver %s wurde nicht in der Schlüsseltabelle gefunden " ++"(Ticket KVNO %d)." ++ ++#: ../../src/lib/krb5/krb/rd_req_dec.c:247 ++#, c-format ++msgid "" ++"Request ticket server %s kvno %d not found in keytab; ticket is likely out " ++"of date" ++msgstr "" ++"Abgefragter Ticketserver %s KVNO %d wurde nicht in der Schlüsseltabelle " ++"gefunden; Ticket ist wahrscheinlich abgelaufen." ++ ++#: ../../src/lib/krb5/krb/rd_req_dec.c:252 ++#, c-format ++msgid "" ++"Request ticket server %s kvno %d not found in keytab; keytab is likely out " ++"of date" ++msgstr "" ++"Abgefragter Ticketserver %s KVNO %d wurde nicht in der Schlüsseltabelle " ++"gefunden; Schlüsseltabelle ist wahrscheinlich nicht mehr aktuell." ++ ++#: ../../src/lib/krb5/krb/rd_req_dec.c:261 ++#, c-format ++msgid "" ++"Request ticket server %s kvno %d found in keytab but not with enctype %s" ++msgstr "" ++"Abgefragter Ticketserver %s KVNO %d wurde in der Schlüsseltabelle gefunden, " ++"jedoch nicht mit Verschlüsselungstyp %s." ++ ++#: ../../src/lib/krb5/krb/rd_req_dec.c:266 ++#, c-format ++msgid "" ++"Request ticket server %s kvno %d enctype %s found in keytab but cannot " ++"decrypt ticket" ++msgstr "" ++"Abgefragter Ticketserver %s KVNO %d mit Verschlüsselungstyp %s in der " ++"Schlüsseltabelle gefunden, Ticket kann jedoch nicht entschlüsselt werden." ++ ++#: ../../src/lib/krb5/krb/rd_req_dec.c:897 ++#, c-format ++msgid "Encryption type %s not permitted" ++msgstr "Verschlüsselungstyp %s nicht erlaubt" ++ ++#: ../../src/lib/krb5/os/expand_path.c:316 ++#, c-format ++msgid "Can't find username for uid %lu" ++msgstr "Zu UID %lu kann kein Benutzername gefunden werden." ++ ++#: ../../src/lib/krb5/os/expand_path.c:405 ++#: ../../src/lib/krb5/os/expand_path.c:421 ++msgid "Invalid token" ++msgstr "ungültiges Token" ++ ++#: ../../src/lib/krb5/os/expand_path.c:506 ++msgid "variable missing }" ++msgstr "Variable fehlt }" ++ ++#: ../../src/lib/krb5/os/locate_kdc.c:660 ++#, c-format ++msgid "Cannot find KDC for realm \"%.*s\"" ++msgstr "KDC für Realm »%.*s« kann nicht gefunden werden" ++ ++#: ../../src/lib/krb5/os/sendto_kdc.c:475 ++#, c-format ++msgid "Cannot contact any KDC for realm '%.*s'" ++msgstr "für Realm »%.*s« kann nicht KDC kontaktiert werden" ++ ++#: ../../src/lib/krb5/rcache/rc_io.c:106 ++#, c-format ++msgid "Cannot fstat replay cache file %s: %s" ++msgstr "»fstat« für Antwortzwischenspeicherdatei %s nicht möglich: %s" ++ ++#: ../../src/lib/krb5/rcache/rc_io.c:112 ++#, c-format ++msgid "" ++"Insecure mkstemp() file mode for replay cache file %s; try running this " ++"program with umask 077" ++msgstr "" ++"unsicherer mkstemp()-Dateimodus für Antwortzwischenspeicherdatei %s; " ++"versuchen Sie, dieses Programm mit der Umask 077 auszuführen" ++ ++#: ../../src/lib/krb5/rcache/rc_io.c:144 ++#, c-format ++msgid "Cannot %s replay cache file %s: %s" ++msgstr "%s der Wiederholungszwischenspeicherdatei %s nicht möglich: %s" ++ ++#: ../../src/lib/krb5/rcache/rc_io.c:149 ++#, c-format ++msgid "Cannot %s replay cache: %s" ++msgstr "%s des Wiederholungszwischenspeichers nicht möglich: %s" ++ ++#: ../../src/lib/krb5/rcache/rc_io.c:272 ++#, c-format ++msgid "Insecure file mode for replay cache file %s" ++msgstr "unsicherer Dateimodus für Wiederholungszwischenspeicherdatei %s" ++ ++#: ../../src/lib/krb5/rcache/rc_io.c:278 ++#, c-format ++msgid "rcache not owned by %d" ++msgstr "Rcache gehört nicht %d" ++ ++#: ../../src/lib/krb5/rcache/rc_io.c:402 ../../src/lib/krb5/rcache/rc_io.c:406 ++#: ../../src/lib/krb5/rcache/rc_io.c:411 ++#, c-format ++msgid "Can't write to replay cache: %s" ++msgstr "" ++"in Wiederholungszwischenspeicherdatei kann nicht geschrieben werden: %s" ++ ++#: ../../src/lib/krb5/rcache/rc_io.c:432 ++#, c-format ++msgid "Cannot sync replay cache file: %s" ++msgstr "" ++"Wiederholungszwischenspeicherdatei kann nicht synchronisiert werden: %s" ++ ++#: ../../src/lib/krb5/rcache/rc_io.c:451 ++#, c-format ++msgid "Can't read from replay cache: %s" ++msgstr "aus dem Wiederholungszwischenspeicher kann nicht gelesen werden: %s" ++ ++#: ../../src/lib/krb5/rcache/rc_io.c:482 ../../src/lib/krb5/rcache/rc_io.c:488 ++#: ../../src/lib/krb5/rcache/rc_io.c:493 ++#, c-format ++msgid "Can't destroy replay cache: %s" ++msgstr "Wiederholungszwischenspeicher kann nicht vernichtet werden: %s" ++ ++#: ../../src/plugins/kdb/db2/kdb_db2.c:245 ++#: ../../src/plugins/kdb/db2/kdb_db2.c:830 ++#, c-format ++msgid "Unsupported argument \"%s\" for db2" ++msgstr "nicht unterstütztes Argument »%s« für DB2" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c:69 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:887 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:1088 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:1507 ++msgid "while reading kerberos container information" ++msgstr "beim Lesen der Kerberos-Container-Information" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c:129 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c:143 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c:504 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c:518 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:151 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:166 ++msgid "while providing time specification" ++msgstr "beim Bereitstellen der Zeitspezifikation" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c:268 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c:304 ++msgid "while creating policy object" ++msgstr "beim Erstellen des Richtlinienobjekts" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c:279 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:1515 ++msgid "while reading realm information" ++msgstr "beim Lesen der Realm-Information" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c:348 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c:407 ++msgid "while destroying policy object" ++msgstr "beim Zerstören des Richtlinienobjekts" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c:358 ++#, c-format ++msgid "This will delete the policy object '%s', are you sure?\n" ++msgstr "Dies wird das Richtlinienobjekt »%s« löschen, sind Sie sicher?\n" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c:473 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c:663 ++msgid "while modifying policy object" ++msgstr "beim Ändern des Richtlinienobjekts" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c:487 ++#, c-format ++msgid "while reading information of policy '%s'" ++msgstr "beim Lesen der Information der Richtlinie »%s«" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c:692 ++msgid "while viewing policy" ++msgstr "beim Betrachten der Richtlinie" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c:701 ++#, c-format ++msgid "while viewing policy '%s'" ++msgstr "beim Betrachten der Richtlinie »%s«" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c:835 ++msgid "while listing policy objects" ++msgstr "beim Auflisten der Richtlinienobjekte" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:453 ++#, c-format ++msgid "for subtree while creating realm '%s'" ++msgstr "für einen Teilbaum beim Erstellen von Realm »%s«" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:465 ++#, c-format ++msgid "for container reference while creating realm '%s'" ++msgstr "für Container-Bezug beim Erstellen von Realm »%s«" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:489 ++#, c-format ++msgid "invalid search scope while creating realm '%s'" ++msgstr "ungültiger Suchbereich beim Erstellen von Realm »%s«" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:504 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:823 ++#, c-format ++msgid "'%s' is an invalid option\n" ++msgstr "»%s« ist keine gültige Option\n" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:512 ++#, c-format ++msgid "Initializing database for realm '%s'\n" ++msgstr "Datenbank für Realm »%s« wird initialisiert\n" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:536 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:696 ++#, c-format ++msgid "while creating realm '%s'" ++msgstr "beim Erstellen von Realm »%s«" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:556 ++#, c-format ++msgid "Enter DN of Kerberos container: " ++msgstr "Geben Sie die den DN des Kerberos-Containers ein: " ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:591 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:894 ++#, c-format ++msgid "while reading information of realm '%s'" ++msgstr "beim Lesen der Information von Realm »%s«" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:733 ++msgid "while reading Kerberos container information" ++msgstr "beim Lesen der Kerberos-Container-Information" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:774 ++#, c-format ++msgid "for subtree while modifying realm '%s'" ++msgstr "für einen Teilbaum beim Ändern von Realm »%s«" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:785 ++#, c-format ++msgid "for container reference while modifying realm '%s'" ++msgstr "für Container-Bezug beim Ändern von Realm »%s«" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:812 ++#, c-format ++msgid "specified for search scope while modifying information of realm '%s'" ++msgstr "" ++"angegeben für Suchbereich, während die Information für Realm »%s« geändert " ++"wird" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:851 ++#, c-format ++msgid "while modifying information of realm '%s'" ++msgstr "beim Ändern der Information von Realm »%s«" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:940 ++msgid "Realm Name" ++msgstr "Realm-Name" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:943 ++msgid "Subtree" ++msgstr "Teilbaum" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:946 ++msgid "Principal Container Reference" ++msgstr "Principal-Container-Bezug" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:951 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:953 ++msgid "SearchScope" ++msgstr "Suchbereich" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:951 ++msgid "Invalid !" ++msgstr "ungültig!" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:958 ++msgid "KDC Services" ++msgstr "KDC-Dienste" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:973 ++msgid "Admin Services" ++msgstr "Administratordienste" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:988 ++msgid "Passwd Services" ++msgstr "Passwortdienste" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:1004 ++msgid "Maximum Ticket Life" ++msgstr "maximale Ticketlebensdauer" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:1009 ++msgid "Maximum Renewable Life" ++msgstr "maximale verlängerbare Lebensdauer" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:1016 ++msgid "Ticket flags" ++msgstr "Ticket-Flags" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:1095 ++msgid "while listing realms" ++msgstr "beim Auflisten der Realms" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:1439 ++msgid "while adding entries to database" ++msgstr "beim Hinzufügen von Einträgen zur Datenbank" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:1480 ++#, c-format ++msgid "Deleting KDC database of '%s', are you sure?\n" ++msgstr "" ++"Sind Sie sicher, dass die KDC-Datenbank von »%s« gelöscht werden soll?\n" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:1491 ++#, c-format ++msgid "OK, deleting database of '%s'...\n" ++msgstr "OK, die Datenbank von »%s« wird gelöscht …\n" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:1524 ++#, c-format ++msgid "deleting database of '%s'" ++msgstr "Die Datenbank von »%s« wird gelöscht." ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c:1529 ++#, c-format ++msgid "** Database of '%s' destroyed.\n" ++msgstr "** Datenbank von »%s« vernichtet\n" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c:81 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c:88 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c:96 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c:104 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c:120 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c:148 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c:227 ++msgid "while setting service object password" ++msgstr "beim Setzen des Passworts für das Dienstobjekt" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c:140 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:477 ++#, c-format ++msgid "Password for \"%s\"" ++msgstr "Passwort für »%s«" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c:143 ++#, c-format ++msgid "Re-enter password for \"%s\"" ++msgstr "Geben Sie das Passwort für »%s« erneut ein." ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c:154 ++#, c-format ++msgid "%s: Invalid password\n" ++msgstr "%s: ungültiges Passwort\n" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c:170 ++msgid "Failed to convert the password to hexadecimal" ++msgstr "Das Umwandeln des Passworts in Dezimalschreibweise ist fehlgeschlagen." ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c:183 ++#, c-format ++msgid "Failed to open file %s: %s" ++msgstr "Datei %s konnte nicht geöffnet werden: %s" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c:205 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c:247 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c:256 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c:283 ++msgid "Failed to write service object password to file" ++msgstr "" ++"Schreiben des Passworts für das Dienstobjekt in eine Datei fehlgeschlagen" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c:211 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c:268 ++msgid "Error reading service object password file" ++msgstr "Fehler beim Lesen der Passwortdatei für das Dienstobjekt" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c:236 ++#, c-format ++msgid "Error creating file %s" ++msgstr "Fehler beim Erstellen der Datei %s" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:105 ++#, c-format ++msgid "" ++"Usage: kdb5_ldap_util [-D user_dn [-w passwd]] [-H ldapuri]\n" ++"\tcmd [cmd_options]\n" ++"create [-subtrees subtree_dn_list] [-sscope search_scope] [-" ++"containerref container_reference_dn]\n" ++"\t\t[-m|-P password|-sf stashfilename] [-k mkeytype] [-kv mkeyVNO] [-s]\n" ++"\t\t[-maxtktlife max_ticket_life] [-maxrenewlife max_renewable_ticket_life]\n" ++"\t\t[ticket_flags] [-r realm]\n" ++"modify [-subtrees subtree_dn_list] [-sscope search_scope] [-" ++"containerref container_reference_dn]\n" ++"\t\t[-maxtktlife max_ticket_life] [-maxrenewlife max_renewable_ticket_life]\n" ++"\t\t[ticket_flags] [-r realm]\n" ++"view [-r realm]\n" ++"destroy [-f] [-r realm]\n" ++"list\n" ++"stashsrvpw [-f filename] service_dn\n" ++"create_policy [-r realm] [-maxtktlife max_ticket_life]\n" ++"\t\t[-maxrenewlife max_renewable_ticket_life] [ticket_flags] policy\n" ++"modify_policy [-r realm] [-maxtktlife max_ticket_life]\n" ++"\t\t[-maxrenewlife max_renewable_ticket_life] [ticket_flags] policy\n" ++"view_policy [-r realm] policy\n" ++"destroy_policy [-r realm] [-force] policy\n" ++"list_policy [-r realm]\n" ++msgstr "" ++"Aufruf: kdb5_ldap_util [-D Benutzer-DN [-w Passwort]] [-H LDAP-URI]\n" ++"\tcmd [Befehlsoptionen]\n" ++"create [-subtrees DN-Liste_Teilbäume] [-sscope Suchbereich] [-" ++"containerref Container-Bezug-DN]\n" ++"\t\t[-m|-P Passwort|-sf Ablagedateiname] [-k mkeytype] [-kv mkeyVNO] [-s]\n" ++"\t\t[-maxtktlife maximale_Ticketlebensdauer]\n" ++"\t\t[-maxrenewlife maximale_Dauer_bis_zum_Erneuern_des_Tickets]\n" ++"\t\t[Ticket_Flags] [-r Realm]\n" ++"modify [-subtrees DN-Liste_Teilbäume] [-sscope Suchbereich] [-" ++"containerref Container-Bezug-DN]\n" ++"\t\t[-maxtktlife maximale_Ticketlebensdauer]\n" ++"\t\t[-maxrenewlife maximale_Dauer_bis_zum_Erneuern_des_Tickets]\n" ++"\t\t[Ticket_Flags] [-r Realm]\n" ++"view [-r Realm]\n" ++"destroy [-f] [-r Realm]\n" ++"list\n" ++"stashsrvpw [-f Dateiname] Dienst-DN\n" ++"create_policy [-r Realm] [-maxtktlife maximale_Ticketlebensdauer]\n" ++"\t\t[-maxrenewlife maximale_Dauer_bis_zum_Erneuern_des_Tickets]\n" ++"\t\t[Ticket_Flags] Richtlinie\n" ++"modify_policy [-r Realm] [-maxtktlife maximale_Ticketlebensdauer]\n" ++"\t\t[-maxrenewlife maximale_Dauer_bis_zum_Erneuern_des_Tickets]\n" ++"\t\t[Ticket_Flags] Richtlinie\n" ++"view_policy [-r Realm] Richtlinie\n" ++"destroy_policy [-r Realm] [-force] Richtlinie\n" ++"list_policy [-r Realm]\n" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:325 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:333 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:341 ++msgid "while reading ldap parameters" ++msgstr "beim Lesen der LDAP-Parameter" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:439 ++msgid "while initializing error handling" ++msgstr "beim Initialisieren der Fehlerbehandlung" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:447 ++msgid "while initializing ldap handle" ++msgstr "beim Initialisieren des LDAP-Identifikators" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:461 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:470 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:483 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:525 ++msgid "while retrieving ldap configuration" ++msgstr "beim Abfragen der LDAP-Konfiguration" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:500 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:507 ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:516 ++msgid "while initializing server list" ++msgstr "beim Initialisieren der Serverliste" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:547 ++msgid "while setting up lib handle" ++msgstr "ein Einrichten der BibliotheksIdentifikators" ++ ++#: ../../src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c:556 ++msgid "while reading ldap configuration" ++msgstr "beim Lesen der LDAP-Konfiguration" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c:68 ++msgid "Unable to read Kerberos container" ++msgstr "Kerberos-Container kann nicht gelesen werden" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c:74 ++msgid "Unable to read Realm" ++msgstr "Realm kann nicht gelesen werden" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c:215 ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c:73 ++msgid "Error processing LDAP DB params:" ++msgstr "Fehler beim Verarbeiten der LDAP-Datenbankparameter:" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c:222 ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c:80 ++msgid "Error reading LDAP server params:" ++msgstr "Fehler beim Lesen der LDAP-Server-Parameters:" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c:64 ++msgid "LDAP bind dn value missing" ++msgstr "LDAP-Bindungs-DN-Wert fehlt" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c:69 ++msgid "LDAP bind password value missing" ++msgstr "LDAP-Bindungs-Passwortwert fehlt" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c:77 ++msgid "Error reading password from stash: " ++msgstr "Fehler beim Lesen des Passworts aus der Ablage: " ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c:85 ++msgid "Service password length is zero" ++msgstr "Länge des Dienstpassworts ist Null" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c:145 ++#, c-format ++msgid "Cannot bind to LDAP server '%s' with SASL mechanism '%s': %s" ++msgstr "" ++"mit LDAP-Server »%s« kann keine Verbindung mit SASL-Mechanismus »%s« " ++"hergestellt werden: %s" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c:158 ++#, c-format ++msgid "Cannot bind to LDAP server '%s' as '%s': %s" ++msgstr "" ++"mit LDAP-Server »%s« kann keine Verbindung als »%s« hergestellt werden: %s" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c:183 ++#, c-format ++msgid "Cannot create LDAP handle for '%s': %s" ++msgstr "LDAP-Identifikator für »%s« kann nicht erstellt werden: %s" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c:131 ++msgid "could not complete roll-back, error deleting Kerberos Container" ++msgstr "" ++"Zurücksetzen kann nicht abgeschlossen werden, Fehler beim Löschen des " ++"Kerberos-Containers" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_krbcontainer.c:56 ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_krbcontainer.c:67 ++msgid "Error reading kerberos container location from krb5.conf" ++msgstr "" ++"Fehler beim Lesen des Kerberos-Container-Speicherorts aus der »krb5.conf«." ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_krbcontainer.c:75 ++msgid "Kerberos container location not specified" ++msgstr "Kerberos-Container-Speicherort nicht angegeben" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c:55 ++#, c-format ++msgid "Error reading '%s' attribute: %s" ++msgstr "Fehler beim Lesen des Attributs »%s«: %s" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c:218 ++msgid "KDB module requires -update argument" ++msgstr "KDB-Modul benötigt Argument »-update«" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c:224 ++#, c-format ++msgid "'%s' value missing" ++msgstr "Wert »%s« fehlt" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c:282 ++#, c-format ++msgid "unknown option '%s'" ++msgstr "unbekannte Option »%s«" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c:342 ++msgid "Minimum connections required per server is 2" ++msgstr "Die benötigte Mindestanzahl von Verbindungen pro Server ist zwei" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c:159 ++msgid "Default realm not set" ++msgstr "Standard-Realm nicht gesetzt" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c:262 ++msgid "DN information missing" ++msgstr "DN-Information fehlt" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:108 ++msgid "Principal does not belong to realm" ++msgstr "Principal gehört nicht zum Realm" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:278 ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:287 ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:295 ++#, c-format ++msgid "%s option not supported" ++msgstr "Option %s wird nicht unterstützt" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:302 ++#, c-format ++msgid "unknown option: %s" ++msgstr "unbekannte Option: %s" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:309 ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:316 ++#, c-format ++msgid "%s option value missing" ++msgstr "Wert der Option %s fehlt" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:542 ++msgid "Principal does not belong to the default realm" ++msgstr "Principal gehört nicht zum Standard-Realm" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:610 ++#, c-format ++msgid "" ++"operation can not continue, more than one entry with principal name \"%s\" " ++"found" ++msgstr "" ++"Die Aktion kann nicht fortfahren, da mehr als ein Principal namens »%s« " ++"gefunden wurde." ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:673 ++#, c-format ++msgid "'%s' not found: " ++msgstr "»%s« nicht gefunden: " ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:751 ++msgid "DN is out of the realm subtree" ++msgstr "DN liegt außerhalb ders Teilbaums des Realms" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:807 ++#, c-format ++msgid "ldap object is already kerberized" ++msgstr "LDAP-Objekt ist bereits an Kerberos angepasst" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:827 ++#, c-format ++msgid "" ++"link information can not be set/updated as the kerberos principal belongs to " ++"an ldap object" ++msgstr "" ++"Verweisinformation kann nicht eingerichtet/aktualisiert werden, da der " ++"Kerberos-Principal zu einem LDAP-Objekt gehört." ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:842 ++#, c-format ++msgid "Failed getting object references" ++msgstr "Holen von Objektbezügen fehlgeschlagen" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:849 ++#, c-format ++msgid "kerberos principal is already linked to a ldap object" ++msgstr "Kerberos-Principal ist bereits mit einem LDAP-Objekt verknüpft" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:1167 ++msgid "ticket policy object value: " ++msgstr "Wert des Ticket-Richtlinienobjekts: " ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:1215 ++#, c-format ++msgid "Principal delete failed (trying to replace entry): %s" ++msgstr "" ++"Löschen des Principals fehlgeschlagen (es wird versucht, den Eintrag zu " ++"ersetzen): %s" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:1225 ++#, c-format ++msgid "Principal add failed: %s" ++msgstr "Hinzufügen des Principals fehlgeschlagen: %s" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:1263 ++#, c-format ++msgid "User modification failed: %s" ++msgstr "Änderung des Benutzers fehlgeschlagen: %s" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:1336 ++msgid "Error reading ticket policy. " ++msgstr "Fehler beim Lesen der Ticket-Richtlinie" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c:1402 ++#, c-format ++msgid "unable to decode stored principal key data (%s)" ++msgstr "" ++"Die gespeicherten Schlüsseldaten des Principals (%s) konnten nicht " ++"dekodiert werden." ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c:223 ++msgid "Realm information not available" ++msgstr "Realm-Information nicht verfügbar" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c:294 ++msgid "Error reading ticket policy: " ++msgstr "Fehler beim Lesen der Ticket-Richtlinie:" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c:307 ++#, c-format ++msgid "Realm Delete FAILED: %s" ++msgstr "Löschen des Realms FEHLGESCHLAGEN: %s" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c:387 ++msgid "subtree value: " ++msgstr "Wert des Teilbaums: " ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c:404 ++msgid "container reference value: " ++msgstr "Wert des Container-Bezugs: " ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c:487 ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c:550 ++msgid "Kerberos Container information is missing" ++msgstr "Kerberos-Container-Information fehlt" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c:499 ++msgid "Invalid Kerberos container DN" ++msgstr "ungültiger Kerberos-Container-DN" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c:515 ++#, c-format ++msgid "Kerberos Container create FAILED: %s" ++msgstr "Erstellen des Kerberos-Containers FEHLGESCHLAGEN: %s" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c:558 ++#, c-format ++msgid "Kerberos Container delete FAILED: %s" ++msgstr "Löschen des Kerberos-Containers FEHLGESCHLAGEN: %s" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c:634 ++msgid "realm object value: " ++msgstr "Wert des Realm-Objekts: " ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.c:48 ++msgid "Not a hexadecimal password" ++msgstr "kein hexadezimales Passwort" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.c:55 ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.c:66 ++msgid "Password corrupt" ++msgstr "Passwort beschädigt" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.c:93 ++#, c-format ++msgid "Cannot open LDAP password file '%s': %s" ++msgstr "LDAP-Passwortdatei »%s« kann nicht geöffnet werden: %s" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.c:123 ++#, c-format ++msgid "Bind DN entry '%s' missing in LDAP password file '%s'" ++msgstr "Bind-DN-Eintrag »%s« fehlt in der LDAP-Passwortdatei »%s«" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c:56 ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c:132 ++msgid "Ticket Policy Name missing" ++msgstr "Ticket-Richtlinienname fehlt" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c:144 ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c:221 ++msgid "ticket policy object: " ++msgstr "Ticket-Richtlinienobjekt: " ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c:209 ++msgid "Ticket Policy Object information missing" ++msgstr "Ticket-Richtlinienobjekt-Information fehlt" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c:300 ++msgid "Ticket Policy Object DN missing" ++msgstr "DN des Ticket-Richtlinienobjekts fehlt" ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c:327 ++msgid "Delete Failed: One or more Principals associated with the Ticket Policy" ++msgstr "" ++"Löschen fehlgeschlagen: Ein oder mehrere Principals gehören zur Ticket-" ++"Richtlinie." ++ ++#: ../../src/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c:435 ++msgid "Error reading container object: " ++msgstr "Fehler beim Lesen des Container-Objekts: " ++ ++#: ../../src/plugins/preauth/pkinit/pkinit_crypto_nss.c:667 ++#: ../../src/plugins/preauth/pkinit/pkinit_crypto_openssl.c:652 ++#: ../../src/plugins/preauth/pkinit/pkinit_crypto_openssl.c:4153 ++msgid "Pass phrase for" ++msgstr "Passphrase für" ++ ++#: ../../src/plugins/preauth/pkinit/pkinit_crypto_openssl.c:1081 ++#, c-format ++msgid "Cannot create cert chain: %s" ++msgstr "Zertifikatskette kann nicht erstellt werden: %s" ++ ++#: ../../src/plugins/preauth/pkinit/pkinit_crypto_openssl.c:1408 ++msgid "Invalid pkinit packet: octet string expected" ++msgstr "ungültiges Pkinit-Paket: Achtbit-Zeichenkette erwartet" ++ ++#: ../../src/plugins/preauth/pkinit/pkinit_crypto_openssl.c:1427 ++msgid "wrong oid\n" ++msgstr "falsche OID\n" ++ ++#: ../../src/plugins/preauth/pkinit/pkinit_crypto_openssl.c:5994 ++#, c-format ++msgid "unknown code 0x%x" ++msgstr "unbekannter Code 0x%x" ++ ++#: ../../src/plugins/preauth/pkinit/pkinit_identity.c:424 ++#, c-format ++msgid "Unsupported type while processing '%s'\n" ++msgstr "nicht unterstützter Typ bei der Verarbeitung von »%s«\n" ++ ++#: ../../src/plugins/preauth/pkinit/pkinit_identity.c:465 ++msgid "Internal error parsing X509_user_identity\n" ++msgstr "interner Fehler beim Auswerten von »X509_user_identity«\n" ++ ++#: ../../src/plugins/preauth/pkinit/pkinit_identity.c:560 ++msgid "No user identity options specified" ++msgstr "keine Optionen der Nutzeridentität angegeben" ++ ++#: ../../src/plugins/preauth/pkinit/pkinit_srv.c:414 ++msgid "Pkinit request not signed, but client not anonymous." ++msgstr "Pkinit-Anfrage nicht signiert, Client ist jedoch nicht anonym" ++ ++# DH = Diffie-Hellman ++#: ../../src/plugins/preauth/pkinit/pkinit_srv.c:447 ++msgid "Anonymous pkinit without DH public value not supported." ++msgstr "Anonymes Pkinit wird nicht ohne öffentlichen DH-Wert unterstützt." ++ ++#: ../../src/plugins/preauth/pkinit/pkinit_srv.c:1147 ++#, c-format ++msgid "No pkinit_identity supplied for realm %s" ++msgstr "Für Realm %s wird keine »pkinit_identity« bereitgestellt." ++ ++#: ../../src/plugins/preauth/pkinit/pkinit_srv.c:1158 ++#, c-format ++msgid "No pkinit_anchors supplied for realm %s" ++msgstr "Für Realm %s werden keine »pkinit_anchors« bereitgestellt." ++ ++#: ../../src/plugins/preauth/pkinit/pkinit_srv.c:1346 ++msgid "No realms configured correctly for pkinit support" ++msgstr "Für Pkinit-Unterstützung wurden keine Realms korrekt konfiguriert." ++ ++#: ../../src/slave/kprop.c:85 ++#, c-format ++msgid "" ++"\n" ++"Usage: %s [-r realm] [-f file] [-d] [-P port] [-s srvtab] slave_host\n" ++"\n" ++msgstr "" ++"\n" ++"Aufruf: %s [-r Realm] [-f Datei] [-d] [-P Port] [-s Dienstschlüsseltabelle] " ++"untergeordneter_Rechner\n" ++"\n" ++ ++#: ../../src/slave/kprop.c:114 ++#, c-format ++msgid "Database propagation to %s: SUCCEEDED\n" ++msgstr "Datenbankverbreitung auf %s: ERFOLGREICH\n" ++ ++#: ../../src/slave/kprop.c:187 ++msgid "while setting client principal name" ++msgstr "beim Setzen des Client-Principal-Namens" ++ ++#: ../../src/slave/kprop.c:194 ../../src/slave/kprop.c:209 ++msgid "while setting client principal realm" ++msgstr "beim Setzen des Client-Principal-Realms" ++ ++#: ../../src/slave/kprop.c:217 ++#, c-format ++msgid "while opening credential cache %s" ++msgstr "beim Öffnen des Anmeldedatenzwischenspeichers %s" ++ ++#: ../../src/slave/kprop.c:233 ++msgid "while setting server principal name" ++msgstr "beim Setzen des Server-Principal-Namens" ++ ++#: ../../src/slave/kprop.c:255 ++msgid "while resolving keytab" ++msgstr "beim Ermitteln der Schlüsseltabelle" ++ ++#: ../../src/slave/kprop.c:264 ++msgid "while getting initial credentials\n" ++msgstr "beim Holen der Anfangsanmeldedaten\n" ++ ++#: ../../src/slave/kprop.c:301 ++msgid "while creating socket" ++msgstr "beim Erstellen eines Sockets" ++ ++#: ../../src/slave/kprop.c:317 ++msgid "while converting server address" ++msgstr "beim Umwandeln der Server-Adresse" ++ ++#: ../../src/slave/kprop.c:327 ++msgid "while connecting to server" ++msgstr "beim Verbinden mit dem Server" ++ ++#: ../../src/slave/kprop.c:334 ../../src/slave/kpropd.c:1215 ++msgid "while getting local socket address" ++msgstr "beim Holen der lokalen Socket-Adresse" ++ ++#: ../../src/slave/kprop.c:339 ++msgid "while converting local address" ++msgstr "beim Umwandeln der lokalen Socket-Adresse" ++ ++#: ../../src/slave/kprop.c:362 ++msgid "in krb5_auth_con_setaddrs" ++msgstr "in »krb5_auth_con_setaddrs«" ++ ++#: ../../src/slave/kprop.c:370 ++msgid "while authenticating to server" ++msgstr "beim Authentifizieren am Server" ++ ++#: ../../src/slave/kprop.c:374 ../../src/slave/kprop.c:573 ++#: ../../src/slave/kpropd.c:1521 ++#, c-format ++msgid "Generic remote error: %s\n" ++msgstr "allgemeiner ferner Fehler: %s\n" ++ ++#: ../../src/slave/kprop.c:380 ../../src/slave/kprop.c:579 ++msgid "signalled from server" ++msgstr "signalisiert vom Server" ++ ++#: ../../src/slave/kprop.c:382 ../../src/slave/kprop.c:581 ++#, c-format ++msgid "Error text from server: %s\n" ++msgstr "Fehlermeldung vom Server: %s\n" ++ ++#: ../../src/slave/kprop.c:410 ++#, c-format ++msgid "allocating database file name '%s'" ++msgstr "Datenbankdateiname »%s« wird reserviert" ++ ++#: ../../src/slave/kprop.c:416 ++#, c-format ++msgid "while trying to open %s" ++msgstr "beim Versuch, %s zu öffnen" ++ ++#: ../../src/slave/kprop.c:423 ++msgid "database locked" ++msgstr "Datenbank gesperrt" ++ ++#: ../../src/slave/kprop.c:426 ../../src/slave/kpropd.c:525 ++#, c-format ++msgid "while trying to lock '%s'" ++msgstr "beim Versuch, »%s« zu sperren" ++ ++#: ../../src/slave/kprop.c:430 ../../src/slave/kprop.c:438 ++#, c-format ++msgid "while trying to stat %s" ++msgstr "beim Versuch, »stat« für %s auszuführen" ++ ++#: ../../src/slave/kprop.c:434 ++msgid "while trying to malloc data_ok_fn" ++msgstr "beim Versuch, Speicher für »data_ok_fn« zu reservieren" ++ ++#: ../../src/slave/kprop.c:443 ++#, c-format ++msgid "'%s' more recent than '%s'." ++msgstr "»%s« ist aktueller als »%s«." ++ ++#: ../../src/slave/kprop.c:459 ++#, c-format ++msgid "while unlocking database '%s'" ++msgstr "beim Entsperren von Datenbank »%s«" ++ ++#: ../../src/slave/kprop.c:492 ../../src/slave/kprop.c:493 ++msgid "while encoding database size" ++msgstr "beim Aufbereiten der Datenbankgröße" ++ ++#: ../../src/slave/kprop.c:501 ++msgid "while sending database size" ++msgstr "beim Senden der Datenbankgröße" ++ ++#: ../../src/slave/kprop.c:511 ++msgid "while allocating i_vector" ++msgstr "beim Reservieren von »i_vector«" ++ ++#: ../../src/slave/kprop.c:534 ++#, c-format ++msgid "while sending database block starting at %d" ++msgstr "beim Senden des Datenbankblocks, der bei %d beginnt" ++ ++#: ../../src/slave/kprop.c:544 ++msgid "Premature EOF found for database file!" ++msgstr "vorzeitiges EOF für Datenbankdatei gefunden!" ++ ++#: ../../src/slave/kprop.c:557 ++msgid "while reading response from server" ++msgstr "beim Lesen der Antwort vom Servers" ++ ++#: ../../src/slave/kprop.c:568 ++msgid "while decoding error response from server" ++msgstr "beim Aufschlüsseln der Fehlerantwort vom Server" ++ ++#: ../../src/slave/kprop.c:599 ++#, c-format ++msgid "Kpropd sent database size %d, expecting %d" ++msgstr "Kpropd sendet Datenbankgröße %d, erwartet wurde %d" ++ ++#: ../../src/slave/kprop.c:643 ++msgid "while allocating filename for update_last_prop_file" ++msgstr "beim Reservieren des Dateinamens für »update_last_prop_file«" ++ ++#: ../../src/slave/kprop.c:648 ++#, c-format ++msgid "while creating 'last_prop' file, '%s'" ++msgstr "beim Erstellen der Datei »last_prop«, »%s«" ++ ++#: ../../src/slave/kpropd.c:170 ++#, c-format ++msgid "" ++"\n" ++"Usage: %s [-r realm] [-s srvtab] [-dS] [-f slave_file]\n" ++msgstr "" ++"\n" ++"Aufruf: %s [-r Realm] [-s Dienstschlüsseltabelle] [-dS] [-f " ++"untergeordnete_Datei]\n" ++ ++#: ../../src/slave/kpropd.c:172 ++#, c-format ++msgid "\t[-F kerberos_db_file ] [-p kdb5_util_pathname]\n" ++msgstr "\t[-F Kerberos-Datenbankdatei ] [-p KDB5-Hilfswerkzeugpfadname]\n" ++ ++#: ../../src/slave/kpropd.c:173 ++#, c-format ++msgid "\t[-x db_args]* [-P port] [-a acl_file]\n" ++msgstr "\t[-x Datenbankargumente]* [-P Port] [-a ACL-Datei]\n" ++ ++#: ../../src/slave/kpropd.c:174 ++#, c-format ++msgid "\t[-A admin_server]\n" ++msgstr "\t[-A Serveradministrator]\n" ++ ++#: ../../src/slave/kpropd.c:215 ++#, c-format ++msgid "Killing fullprop child (%d)\n" ++msgstr "Beenden des Fullprop-Kindprozesses (%d) wird erzwungen\n" ++ ++#: ../../src/slave/kpropd.c:244 ++msgid "while checking if stdin is a socket" ++msgstr "beim Prüfen, ob die Standardeingabe ein Socket ist" ++ ++#: ../../src/slave/kpropd.c:262 ++#, c-format ++msgid "ready\n" ++msgstr "bereit\n" ++ ++#: ../../src/slave/kpropd.c:272 ++#, c-format ++msgid "Could not open /dev/null: %s" ++msgstr "/dev/null konnte nicht geöffnet werden: %s" ++ ++#: ../../src/slave/kpropd.c:279 ++#, c-format ++msgid "Could not dup the inetd socket: %s" ++msgstr "Das Inetd-Socket konnte nicht dupliziert werden: %s" ++ ++#: ../../src/slave/kpropd.c:314 ../../src/slave/kpropd.c:327 ++msgid "do_iprop failed.\n" ++msgstr "»do_iprop« fehlgeschlagen\n" ++ ++#: ../../src/slave/kpropd.c:366 ++#, c-format ++msgid "getaddrinfo: %s\n" ++msgstr "getaddrinfo: %s\n" ++ ++#: ../../src/slave/kpropd.c:372 ++msgid "while obtaining socket" ++msgstr "beim Erlangen des Sockets" ++ ++#: ../../src/slave/kpropd.c:378 ++msgid "while setting SO_REUSEADDR option" ++msgstr "beim Setzen der Option SO_REUSEADDR" ++ ++#: ../../src/slave/kpropd.c:386 ++msgid "while unsetting IPV6_V6ONLY option" ++msgstr "beim Entfernen der Option IPV6_V6ONLY" ++ ++#: ../../src/slave/kpropd.c:391 ++msgid "while binding listener socket" ++msgstr "beim Anbinden an das auf Verbindung wartende Socket" ++ ++#: ../../src/slave/kpropd.c:402 ++#, c-format ++msgid "waiting for a kprop connection\n" ++msgstr "warten auf Kprop-Verbindung\n" ++ ++#: ../../src/slave/kpropd.c:408 ++msgid "while accepting connection" ++msgstr "beim Akzeptieren der Verbindung" ++ ++#: ../../src/slave/kpropd.c:414 ++msgid "while forking" ++msgstr "beim Erzeugen eines Kindprozesses" ++ ++#: ../../src/slave/kpropd.c:429 ++#, c-format ++msgid "waitpid() failed to wait for doit() (%d %s)\n" ++msgstr "waitpid() schlug beim Warten auf doit() fehl (%d %s)\n" ++ ++#: ../../src/slave/kpropd.c:433 ++msgid "while waiting to receive database" ++msgstr "beim Warten auf den Erhalt der Datenbank" ++ ++#: ../../src/slave/kpropd.c:437 ++#, c-format ++msgid "Database load process for full propagation completed.\n" ++msgstr "" ++"Der Datenbankladeprozess für eine vollständige Verbreitung ist " ++"abgeschlossen.\n" ++ ++#: ../../src/slave/kpropd.c:471 ++#, c-format ++msgid "" ++"%s: Standard input does not appear to be a network socket.\n" ++"\t(Not run from inetd, and missing the -S option?)\n" ++msgstr "" ++"%s: Bei der Standardeingabe scheint es sich nicht um ein Netzwerk-Socket zu\n" ++"\thandeln (läuft nicht aus Inetd und die Option -S fehlt?).\n" ++ ++#: ../../src/slave/kpropd.c:485 ++msgid "while attempting setsockopt (SO_KEEPALIVE)" ++msgstr "beim Versuch, »setsockopt« auszuführen (SO_KEEPALIVE)" ++ ++#: ../../src/slave/kpropd.c:490 ++#, c-format ++msgid "Connection from %s" ++msgstr "Verbindung von %s" ++ ++#: ../../src/slave/kpropd.c:510 ++#, c-format ++msgid "Rejected connection from unauthorized principal %s\n" ++msgstr "Zurückgewiesene Verbindung von nicht autorisiertem Principal %s\n" ++ ++#: ../../src/slave/kpropd.c:514 ++#, c-format ++msgid "Rejected connection from unauthorized principal %s" ++msgstr "Zurückgewiesene Verbindung von nicht authorisiertem Principal %s" ++ ++#: ../../src/slave/kpropd.c:531 ++#, c-format ++msgid "while opening database file, '%s'" ++msgstr "beim Öffnen der Datenbankdatei, »%s«" ++ ++#: ../../src/slave/kpropd.c:537 ++#, c-format ++msgid "while renaming %s to %s" ++msgstr "beim Umbenennen von %s in %s" ++ ++#: ../../src/slave/kpropd.c:543 ++#, c-format ++msgid "while downgrading lock on '%s'" ++msgstr "beim Downgrade der Sperre auf »%s«" ++ ++#: ../../src/slave/kpropd.c:550 ++#, c-format ++msgid "while unlocking '%s'" ++msgstr "beim Aufheben der Sperre »%s«" ++ ++#: ../../src/slave/kpropd.c:562 ++msgid "while sending # of received bytes" ++msgstr "beim Senden n empfangener Byte" ++ ++#: ../../src/slave/kpropd.c:568 ++msgid "while trying to close database file" ++msgstr "beim Versuch, die Datenbankdatei zu schließen" ++ ++#: ../../src/slave/kpropd.c:624 ++#, c-format ++msgid "Incremental propagation enabled\n" ++msgstr "inkrementelle Verbreitung aktiviert\n" ++ ++#: ../../src/slave/kpropd.c:634 ++msgid "Unable to get default realm" ++msgstr "Standard-Realm kann nicht geholt werden" ++ ++#: ../../src/slave/kpropd.c:647 ++#, c-format ++msgid "%s: unable to get kiprop host based service name for realm %s\n" ++msgstr "" ++"%s: Kiprop-rechnerbasierter Dienstname für Realm %s kann nicht geholt " ++"werden\n" ++ ++#: ../../src/slave/kpropd.c:658 ++msgid "while trying to construct host service principal" ++msgstr "beim Versuch, den Rechnerdienst-Principal zu erstellen" ++ ++#: ../../src/slave/kpropd.c:672 ++msgid "while determining local service principal name" ++msgstr "beim Bestimmen des lokalen Dienst-Principal-Namens" ++ ++#: ../../src/slave/kpropd.c:692 ++#, c-format ++msgid "Initializing kadm5 as client %s\n" ++msgstr "Kadm5 wird als Client %s initialisiert\n" ++ ++#: ../../src/slave/kpropd.c:706 ++#, c-format ++msgid "kadm5 initialization failed!\n" ++msgstr "Initialisierung von Kadm5 fehlgeschlagen!\n" ++ ++#: ../../src/slave/kpropd.c:715 ++msgid "while attempting to connect to master KDC ... retrying" ++msgstr "" ++"beim Versuch, eine Verbindung zum Master-KDC aufzubauen … wird erneut " ++"versucht" ++ ++#: ../../src/slave/kpropd.c:719 ++#, c-format ++msgid "Sleeping %d seconds to re-initialize kadm5 (RPC ERROR)\n" ++msgstr "" ++"Um Kadm5 neu zu initialisieren, wird %d Sekunden gewartet (RPC-FEHLER).\n" ++ ++#: ../../src/slave/kpropd.c:735 ++#, c-format ++msgid "while initializing %s interface, retrying" ++msgstr "beim Initialisieren der Schnittstelle %s, wird erneut versucht" ++ ++#: ../../src/slave/kpropd.c:739 ++#, c-format ++msgid "Sleeping %d seconds to re-initialize kadm5 (krb5kdc not running?)\n" ++msgstr "" ++"Um Kadm5 neu zu initialisieren, wird %d Sekunden gewartet (läuft Krb5kdc " ++"nicht?).\n" ++ ++#: ../../src/slave/kpropd.c:749 ++#, c-format ++msgid "kadm5 initialization succeeded\n" ++msgstr "Initialisieren von Kadm5 erfolgreich\n" ++ ++#: ../../src/slave/kpropd.c:771 ++msgid "reading update log header" ++msgstr "Aktualisierungsprotokollkopfzeilen werden gelesen" ++ ++#: ../../src/slave/kpropd.c:782 ++#, c-format ++msgid "Calling iprop_get_updates_1 (sno=%u sec=%u usec=%u)\n" ++msgstr "»iprop_get_updates_1()« wird aufgerufen (sno=%u sec=%u usec=%u)\n" ++ ++#: ../../src/slave/kpropd.c:792 ++msgid "iprop_get_updates call failed" ++msgstr "Aufruf von »iprop_get_updates« fehlgeschlagen" ++ ++#: ../../src/slave/kpropd.c:798 ++#, c-format ++msgid "Reinitializing iprop because get updates failed\n" ++msgstr "" ++"Iprop wird neu initialisiert, da Aktualisierungen fehlgeschlagen sind\n" ++ ++#: ../../src/slave/kpropd.c:819 ++#, c-format ++msgid "Still waiting for full resync\n" ++msgstr "" ++"Es wird immer noch auf das vollständige erneute Synchronisieren gewartet.\n" ++ ++#: ../../src/slave/kpropd.c:824 ++#, c-format ++msgid "Full resync needed\n" ++msgstr "erneutes vollständiges Synchronisieren erforderlich\n" ++ ++#: ../../src/slave/kpropd.c:825 ++msgid "kpropd: Full resync needed." ++msgstr "Kpropd: erneutes vollständiges Synchronisieren erforderlich" ++ ++#: ../../src/slave/kpropd.c:830 ++msgid "iprop_full_resync call failed" ++msgstr "Aufruf von »iprop_full_resync« fehlgeschlagen" ++ ++#: ../../src/slave/kpropd.c:841 ++#, c-format ++msgid "Full resync request granted\n" ++msgstr "Anfrage nach vollständigem erneuten Synchronisieren genehmigt\n" ++ ++#: ../../src/slave/kpropd.c:842 ++msgid "Full resync request granted." ++msgstr "Anfrage nach vollständigem erneuten Synchronisieren genehmigt" ++ ++# FIXME s/backoff/back-off/ ++#: ../../src/slave/kpropd.c:851 ++#, c-format ++msgid "Exponential backoff\n" ++msgstr "exponentieller Wartezyklus\n" ++ ++#: ../../src/slave/kpropd.c:857 ++#, c-format ++msgid "Full resync permission denied\n" ++msgstr "vollständiges erneutes Synchronisieren nicht gestattet\n" ++ ++#: ../../src/slave/kpropd.c:858 ++msgid "Full resync, permission denied." ++msgstr "vollständiges erneutes Synchronisieren, nicht gestattet" ++ ++#: ../../src/slave/kpropd.c:863 ++#, c-format ++msgid "Full resync error from master\n" ++msgstr "Fehler beim vollständigen erneuten Synchronisieren vom Master\n" ++ ++#: ../../src/slave/kpropd.c:864 ++msgid " Full resync, error returned from master KDC." ++msgstr "" ++"vollständiges erneutes Synchronisieren, das Master-KDC gab einen Fehler " ++"zurück" ++ ++#: ../../src/slave/kpropd.c:872 ++#, c-format ++msgid "Full resync invalid result from master\n" ++msgstr "" ++"Beim vollständigen erneuten Synchronisieren gab der Master ein ungültiges " ++"Ergebnis zurück.\n" ++ ++#: ../../src/slave/kpropd.c:874 ++msgid "Full resync, invalid return from master KDC." ++msgstr "" ++"vollständiges erneutes Synchronisieren, ungültiger Rückgabewert vom Master-" ++"KDC" ++ ++#: ../../src/slave/kpropd.c:890 ++#, c-format ++msgid "Got incremental updates (sno=%u sec=%u usec=%u)\n" ++msgstr "" ++"inkrementelle Aktualisierungen erhalten (sno=%u sec=%u usec=%u)\n" ++ ++#: ../../src/slave/kpropd.c:902 ++#, c-format ++msgid "ulog_replay failed (%s), updates not registered\n" ++msgstr "" ++"»ulog_replay« fehlgeschlagen (%s), Aktualisierungen nicht registriert\n" ++ ++#: ../../src/slave/kpropd.c:905 ++#, c-format ++msgid "ulog_replay failed (%s), updates not registered." ++msgstr "»ulog_replay« fehlgeschlagen (%s), Aktualisierungen nicht registriert" ++ ++#: ../../src/slave/kpropd.c:914 ++#, c-format ++msgid "Incremental updates: %d updates / %lu us" ++msgstr "inkrementelle Aktualisierungen: %d Aktualisierungen / %lu us" ++ ++#: ../../src/slave/kpropd.c:917 ++#, c-format ++msgid "Incremental updates: %d updates / %lu us\n" ++msgstr "inkrementelle Aktualisierungen: %d Aktualisierungen / %lu us\n" ++ ++#: ../../src/slave/kpropd.c:925 ++#, c-format ++msgid "get_updates permission denied\n" ++msgstr "Zugriff bei »get_updates« verweigert\n" ++ ++#: ../../src/slave/kpropd.c:926 ++msgid "get_updates, permission denied." ++msgstr "»get_updates«, Zugriff verweigert" ++ ++#: ../../src/slave/kpropd.c:931 ++#, c-format ++msgid "get_updates error from master\n" ++msgstr "»get_updates«-Fehler vom Master\n" ++ ++#: ../../src/slave/kpropd.c:932 ++msgid "get_updates, error returned from master KDC." ++msgstr "Vom Master-KDC wurde ein »get_updates«-Fehler zurückgegeben." ++ ++# FIXME s/backoff/back-off/ ++#: ../../src/slave/kpropd.c:940 ++#, c-format ++msgid "get_updates master busy; backoff\n" ++msgstr "»get_updates«-Master ausgelastet; hält sich zurück\n" ++ ++#: ../../src/slave/kpropd.c:949 ++#, c-format ++msgid "KDC is synchronized with master.\n" ++msgstr "KDC wurde mit dem Master synchronisiert.\n" ++ ++#: ../../src/slave/kpropd.c:957 ++#, c-format ++msgid "get_updates invalid result from master\n" ++msgstr "ungültiges »get_updates«-Ergebnis vom Master\n" ++ ++#: ../../src/slave/kpropd.c:958 ++msgid "get_updates, invalid return from master KDC." ++msgstr "»get_updates«, ungültiger Rückgabewert vom Master-KDC" ++ ++# FIXME s/backoff/back-off/ ++#: ../../src/slave/kpropd.c:973 ++#, c-format ++msgid "Busy signal received from master, backoff for %d secs\n" ++msgstr "" ++"Vom Master wurde ein Signal empfangen, dass er ausgelastet ist, " ++"Zurückhaltung für %d Sekunden\n" ++ ++#: ../../src/slave/kpropd.c:980 ++#, c-format ++msgid "Waiting for %d seconds before checking for updates again\n" ++msgstr "" ++"vor der erneuten Prufung auf Aktualisierungen wird %d Sekunden gewartet\n" ++ ++#: ../../src/slave/kpropd.c:991 ++#, c-format ++msgid "ERROR returned by master, bailing\n" ++msgstr "FEHLER vom Master zurückgegeben, Ausstieg\n" ++ ++#: ../../src/slave/kpropd.c:992 ++msgid "ERROR returned by master KDC, bailing.\n" ++msgstr "FEHLER vom Master-KDC zurückgegeben, Ausstieg\n" ++ ++#: ../../src/slave/kpropd.c:1134 ++msgid "copying db args" ++msgstr "Datenbankargumente werden kopiert" ++ ++#: ../../src/slave/kpropd.c:1161 ++msgid "while trying to construct my service name" ++msgstr "beim Versuch, meinen Dienstnamen zu erstellen" ++ ++#: ../../src/slave/kpropd.c:1167 ++msgid "while constructing my service realm" ++msgstr "beim Erstellen meines Dienst-Realms" ++ ++#: ../../src/slave/kpropd.c:1175 ++msgid "while allocating filename for temp file" ++msgstr "beim Reservieren des Dateinamens für die temporäre Datei" ++ ++#: ../../src/slave/kpropd.c:1181 ++msgid "while initializing" ++msgstr "bei der Initialisierung" ++ ++#: ../../src/slave/kpropd.c:1189 ++msgid "Unable to map log!\n" ++msgstr "Protokoll kann nicht abgebildet werden!\n" ++ ++#: ../../src/slave/kpropd.c:1235 ++#, c-format ++msgid "Error in krb5_auth_con_ini: %s" ++msgstr "Fehler in »krb5_auth_con_ini«: %s" ++ ++#: ../../src/slave/kpropd.c:1243 ++#, c-format ++msgid "Error in krb5_auth_con_setflags: %s" ++msgstr "Fehler in »krb5_auth_con_setflags«: %s" ++ ++#: ../../src/slave/kpropd.c:1251 ++#, c-format ++msgid "Error in krb5_auth_con_setaddrs: %s" ++msgstr "Fehler in »krb5_auth_con_setaddrs«: %s" ++ ++#: ../../src/slave/kpropd.c:1259 ++#, c-format ++msgid "Error in krb5_kt_resolve: %s" ++msgstr "Fehler in »krb5_kt_resolve«: %s" ++ ++#: ../../src/slave/kpropd.c:1268 ++#, c-format ++msgid "Error in krb5_recvauth: %s" ++msgstr "Fehler in »krb5_recvauth«: %s" ++ ++#: ../../src/slave/kpropd.c:1275 ++#, c-format ++msgid "Error in krb5_copy_prinicpal: %s" ++msgstr "Fehler in »krb5_copy_prinicpal«: %s" ++ ++#: ../../src/slave/kpropd.c:1291 ++msgid "while unparsing ticket etype" ++msgstr "beim Rückgängigmachen der Auswertung des »etype«s des Tickets" ++ ++#: ../../src/slave/kpropd.c:1295 ++#, c-format ++msgid "authenticated client: %s (etype == %s)\n" ++msgstr "Authentifizierter Client: %s (etype == %s)\n" ++ ++#: ../../src/slave/kpropd.c:1374 ++msgid "while reading size of database from client" ++msgstr "beim Lesen der Datenbankgröße vom Client" ++ ++#: ../../src/slave/kpropd.c:1384 ++msgid "while decoding database size from client" ++msgstr "beim Dekodieren der Datenbankgröße vom Client" ++ ++#: ../../src/slave/kpropd.c:1397 ++msgid "while initializing i_vector" ++msgstr "beim Initialisieren von »i_vector«" ++ ++#: ../../src/slave/kpropd.c:1402 ++#, c-format ++msgid "Full propagation transfer started.\n" ++msgstr "vollständige Verbreitungsübertragung gestartet\n" ++ ++#: ../../src/slave/kpropd.c:1455 ++#, c-format ++msgid "Full propagation transfer finished.\n" ++msgstr "vollständige Verbreitungsübertragung beendet\n" ++ ++#: ../../src/slave/kpropd.c:1516 ++msgid "while decoding error packet from client" ++msgstr "beim Dekodieren des Fehlerpakets vom Client" ++ ++#: ../../src/slave/kpropd.c:1525 ++msgid "signaled from server" ++msgstr "signalisiert vom Server" ++ ++#: ../../src/slave/kpropd.c:1527 ++#, c-format ++msgid "Error text from client: %s\n" ++msgstr "Fehlermeldung vom Client: %s\n" ++ ++#: ../../src/slave/kpropd.c:1576 ++#, c-format ++msgid "while trying to fork %s" ++msgstr "beim Versuch, einen Kindprozess von %s zu erzeugen" ++ ++#: ../../src/slave/kpropd.c:1580 ++#, c-format ++msgid "while trying to exec %s" ++msgstr "beim Versuch, %s auszuführen" ++ ++#: ../../src/slave/kpropd.c:1587 ++#, c-format ++msgid "while waiting for %s" ++msgstr "beim Warten auf %s" ++ ++#: ../../src/slave/kpropd.c:1593 ++#, c-format ++msgid "%s load terminated" ++msgstr "Laden von %s beendet" ++ ++#: ../../src/slave/kpropd.c:1599 ++#, c-format ++msgid "%s returned a bad exit status (%d)" ++msgstr "%s gab einen falschen Exit-Status (%d) zurück" ++ ++#: ../../src/slave/kproplog.c:27 ++#, c-format ++msgid "" ++"\n" ++"Usage: %s [-h] [-v] [-v] [-e num]\n" ++"\t%s -R\n" ++"\n" ++msgstr "" ++"\n" ++"Aufruf: %s [-h] [-v] [-v] [-e Zahl]\n" ++"\t%s -R\n" ++"\n" ++ ++#: ../../src/slave/kproplog.c:129 ++#, c-format ++msgid "" ++"\n" ++"Couldn't allocate memory" ++msgstr "" ++"\n" ++"Speicher konnte nicht reserviert werden" ++ ++#: ../../src/slave/kproplog.c:223 ++#, c-format ++msgid "\t\tAttribute flags\n" ++msgstr "\t\tAttributschalter\n" ++ ++#: ../../src/slave/kproplog.c:228 ++#, c-format ++msgid "\t\tMaximum ticket life\n" ++msgstr "\t\tmaximale Ticketlebensdauer\n" ++ ++#: ../../src/slave/kproplog.c:233 ++#, c-format ++msgid "\t\tMaximum renewable life\n" ++msgstr "\t\tmaximale verlängerbare Lebensdauer\n" ++ ++#: ../../src/slave/kproplog.c:238 ++#, c-format ++msgid "\t\tPrincipal expiration\n" ++msgstr "\t\tAblauf des Principals\n" ++ ++#: ../../src/slave/kproplog.c:243 ++#, c-format ++msgid "\t\tPassword expiration\n" ++msgstr "\t\tAblauf des Passworts\n" ++ ++#: ../../src/slave/kproplog.c:248 ++#, c-format ++msgid "\t\tLast successful auth\n" ++msgstr "\t\tletzte erfolgreiche Authentifizierung\n" ++ ++#: ../../src/slave/kproplog.c:253 ++#, c-format ++msgid "\t\tLast failed auth\n" ++msgstr "\t\tletzte fehlgeschlagene Authentifizierung\n" ++ ++#: ../../src/slave/kproplog.c:258 ++#, c-format ++msgid "\t\tFailed passwd attempt\n" ++msgstr "\t\tfehlgeschlagener Passwortversuch\n" ++ ++#: ../../src/slave/kproplog.c:263 ++#, c-format ++msgid "\t\tPrincipal\n" ++msgstr "\t\tPrincipal\n" ++ ++#: ../../src/slave/kproplog.c:268 ++#, c-format ++msgid "\t\tKey data\n" ++msgstr "\t\tSchlüsseldaten\n" ++ ++#: ../../src/slave/kproplog.c:275 ++#, c-format ++msgid "\t\tTL data\n" ++msgstr "\t\tTL-Daten\n" ++ ++#: ../../src/slave/kproplog.c:282 ++#, c-format ++msgid "\t\tLength\n" ++msgstr "\t\tLänge\n" ++ ++#: ../../src/slave/kproplog.c:287 ++#, c-format ++msgid "\t\tPassword last changed\n" ++msgstr "\t\tletzte Passwortänderung\n" ++ ++#: ../../src/slave/kproplog.c:292 ++#, c-format ++msgid "\t\tModifying principal\n" ++msgstr "\t\ttPrincipal wird geändert\n" ++ ++#: ../../src/slave/kproplog.c:297 ++#, c-format ++msgid "\t\tModification time\n" ++msgstr "\t\tÄnderungszeit\n" ++ ++#: ../../src/slave/kproplog.c:302 ++#, c-format ++msgid "\t\tModified where\n" ++msgstr "\t\tGeändert wobei\n" ++ ++#: ../../src/slave/kproplog.c:307 ++#, c-format ++msgid "\t\tPassword policy\n" ++msgstr "\t\tPasswortrichtlinie\n" ++ ++#: ../../src/slave/kproplog.c:312 ++#, c-format ++msgid "\t\tPassword policy switch\n" ++msgstr "\t\tPasswortrichtlinienumschalter\n" ++ ++#: ../../src/slave/kproplog.c:317 ++#, c-format ++msgid "\t\tPassword history KVNO\n" ++msgstr "\t\tPasswortchronik KVNO\n" ++ ++#: ../../src/slave/kproplog.c:322 ++#, c-format ++msgid "\t\tPassword history\n" ++msgstr "\t\tPasswortchronik\n" ++ ++#: ../../src/slave/kproplog.c:356 ++#, c-format ++msgid "" ++"Corrupt update entry\n" ++"\n" ++msgstr "" ++"beschädigter Aktualisierungseintrag\n" ++"\n" ++ ++#: ../../src/slave/kproplog.c:364 ++#, c-format ++msgid "" ++"Entry data decode failure\n" ++"\n" ++msgstr "" ++"Dekodieren der eingetragenen Daten fehlgeschlagen\n" ++"\n" ++ ++#: ../../src/slave/kproplog.c:369 ++#, c-format ++msgid "Update Entry\n" ++msgstr "Aktualisierungseintrag\n" ++ ++#: ../../src/slave/kproplog.c:371 ++#, c-format ++msgid "\tUpdate serial # : %u\n" ++msgstr "\tAktualisierung der Seriennummer: %u\n" ++ ++#: ../../src/slave/kproplog.c:373 ++#, c-format ++msgid "\tUpdate operation : " ++msgstr "\tAktualisierungsaktion: " ++ ++#: ../../src/slave/kproplog.c:375 ++#, c-format ++msgid "Delete\n" ++msgstr "Löschen\n" ++ ++#: ../../src/slave/kproplog.c:377 ++#, c-format ++msgid "Add\n" ++msgstr "Hinzufügen\n" ++ ++#: ../../src/slave/kproplog.c:381 ++#, c-format ++msgid "" ++"Could not allocate principal name\n" ++"\n" ++msgstr "" ++"Der Principal-Name konnte nicht reserviert werden.\n" ++"\n" ++ ++#: ../../src/slave/kproplog.c:387 ++#, c-format ++msgid "\tUpdate principal : %s\n" ++msgstr "\tAktualisierung des Principals: %s\n" ++ ++#: ../../src/slave/kproplog.c:389 ++#, c-format ++msgid "\tUpdate size : %u\n" ++msgstr "\tGröße der Aktualisierung: %u\n" ++ ++#: ../../src/slave/kproplog.c:390 ++#, c-format ++msgid "\tUpdate committed : %s\n" ++msgstr "\tAktualisierung übergeben: %s\n" ++ ++#: ../../src/slave/kproplog.c:394 ++#, c-format ++msgid "\tUpdate time stamp : None\n" ++msgstr "\tZeitstempel der Aktualisierung: keiner\n" ++ ++#: ../../src/slave/kproplog.c:396 ++#, c-format ++msgid "\tUpdate time stamp : %s" ++msgstr "\tZeitstempel der Aktualisierung: %s" ++ ++#: ../../src/slave/kproplog.c:400 ++#, c-format ++msgid "\tAttributes changed : %d\n" ++msgstr "\tgeänderte Attribute: %d\n" ++ ++#: ../../src/slave/kproplog.c:465 ++#, c-format ++msgid "" ++"Unable to initialize Kerberos\n" ++"\n" ++msgstr "" ++"Kerberos kann nicht initialisiert werden\n" ++"\n" ++ ++#: ../../src/slave/kproplog.c:472 ++#, c-format ++msgid "" ++"Couldn't read database_name\n" ++"\n" ++msgstr "" ++"»database_name« kann nicht gelesen werden\n" ++"\n" ++ ++#: ../../src/slave/kproplog.c:476 ++#, c-format ++msgid "" ++"\n" ++"Kerberos update log (%s)\n" ++msgstr "" ++"\n" ++"Kerberos-Aktualisierungsprotokoll (%s)\n" ++ ++#: ../../src/slave/kproplog.c:480 ../../src/slave/kproplog.c:495 ++#, c-format ++msgid "" ++"Unable to map log file %s\n" ++"\n" ++msgstr "" ++"Protokolldatei %s kann nicht abgebildet werden\n" ++"\n" ++ ++#: ../../src/slave/kproplog.c:485 ++#, c-format ++msgid "" ++"Couldn't reinitialize ulog file %s\n" ++"\n" ++msgstr "" ++"Ulog-Datei %s konnte nicht neu initialisiert werden\n" ++"\n" ++ ++#: ../../src/slave/kproplog.c:489 ++#, c-format ++msgid "Reinitialized the ulog.\n" ++msgstr "Das Ulog wurde neu initialisiert.\n" ++ ++#: ../../src/slave/kproplog.c:501 ++#, c-format ++msgid "" ++"Corrupt header log, exiting\n" ++"\n" ++msgstr "" ++"beschädigtes Kopfzeilenprotokoll, wird beendet\n" ++"\n" ++ ++#: ../../src/slave/kproplog.c:505 ++#, c-format ++msgid "Update log dump :\n" ++msgstr "Aktualisierungsprotokollauszug :\n" ++ ++#: ../../src/slave/kproplog.c:506 ++#, c-format ++msgid "\tLog version # : %u\n" ++msgstr "\tProtokollversion #: %u\n" ++ ++#: ../../src/slave/kproplog.c:507 ++#, c-format ++msgid "\tLog state : " ++msgstr "\tProtokollstatus: " ++ ++#: ../../src/slave/kproplog.c:510 ++#, c-format ++msgid "Stable\n" ++msgstr "stabil\n" ++ ++#: ../../src/slave/kproplog.c:513 ++#, c-format ++msgid "Unstable\n" ++msgstr "instabil\n" ++ ++#: ../../src/slave/kproplog.c:516 ++#, c-format ++msgid "Corrupt\n" ++msgstr "beschädigt\n" ++ ++#: ../../src/slave/kproplog.c:519 ++#, c-format ++msgid "Unknown state: %d\n" ++msgstr "unbekannter Status: %d\n" ++ ++#: ../../src/slave/kproplog.c:522 ++#, c-format ++msgid "\tEntry block size : %u\n" ++msgstr "\tBlockgrößeneintrag: %u\n" ++ ++#: ../../src/slave/kproplog.c:523 ++#, c-format ++msgid "\tNumber of entries : %u\n" ++msgstr "\tAnzahl der Einträge: %u\n" ++ ++#: ../../src/slave/kproplog.c:526 ++#, c-format ++msgid "\tLast serial # : None\n" ++msgstr "\tletzte Seriennummer: keine\n" ++ ++#: ../../src/slave/kproplog.c:529 ++#, c-format ++msgid "\tFirst serial # : None\n" ++msgstr "\terste Seriennummer: keine\n" ++ ++#: ../../src/slave/kproplog.c:531 ++#, c-format ++msgid "\tFirst serial # : " ++msgstr "\terste Seriennummer: " ++ ++#: ../../src/slave/kproplog.c:535 ++#, c-format ++msgid "\tLast serial # : " ++msgstr "\tletzte Seriennummer: " ++ ++#: ../../src/slave/kproplog.c:540 ++#, c-format ++msgid "\tLast time stamp : None\n" ++msgstr "\tletzter Zeitstempel: keiner\n" ++ ++#: ../../src/slave/kproplog.c:543 ++#, c-format ++msgid "\tFirst time stamp : None\n" ++msgstr "\terster Zeitstempel: keiner\n" ++ ++#: ../../src/slave/kproplog.c:545 ++#, c-format ++msgid "\tFirst time stamp : %s" ++msgstr "\terster Zeitstempel: %s" ++ ++#: ../../src/slave/kproplog.c:549 ++#, c-format ++msgid "\tLast time stamp : %s\n" ++msgstr "\tletzter Zeitstempel: %s\n" ++ ++#: ../../src/util/support/errors.c:77 ++msgid "Kerberos library initialization failure" ++msgstr "Initialisieren der Kerberos-Bibliothek fehlgeschlagen" ++ ++#: ../../src/util/support/errors.c:93 ++#, c-format ++msgid "error %ld" ++msgstr "Fehler %ld" ++ ++#: ../../src/util/support/plugins.c:186 ++#, c-format ++msgid "unable to find plugin [%s]: %s" ++msgstr "Erweiterung [%s] konnte nicht gefunden werden: %s" ++ ++#: ../../src/util/support/plugins.c:274 ++msgid "unknown failure" ++msgstr "unbekannter Fehlschlag" ++ ++#: ../../src/util/support/plugins.c:277 ++#, c-format ++msgid "unable to load plugin [%s]: %s" ++msgstr "Erweiterung [%s] konnte nicht geladen werden: %s" ++ ++#: ../../src/util/support/plugins.c:300 ++#, c-format ++msgid "unable to load DLL [%s]" ++msgstr "DLL [%s] konnte nicht geladen werden" ++ ++#: ../../src/util/support/plugins.c:316 ++#, c-format ++msgid "plugin unavailable: %s" ++msgstr "Erweiterung nicht verfügbar: %s" ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:23 ++msgid "No @ in SERVICE-NAME name string" ++msgstr "keine @ in der Namenszeichenkette SERVICE-NAME" ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:24 ++msgid "STRING-UID-NAME contains nondigits" ++msgstr "STRING-UID-NAME enthält etwas anderes als Ziffern" ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:25 ++msgid "UID does not resolve to username" ++msgstr "UID lässt sich nicht zu Benutzernamen ermitteln" ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:26 ++msgid "Validation error" ++msgstr "Überprüfungsfehler" ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:27 ++msgid "Couldn't allocate gss_buffer_t data" ++msgstr "»gss_buffer_t«-Daten konnten reserviert werden" ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:28 ++msgid "Message context invalid" ++msgstr "Nachrichtenkontext ungültig" ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:29 ++msgid "Buffer is the wrong size" ++msgstr "Puffer hat die falsche Größe" ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:30 ++msgid "Credential usage type is unknown" ++msgstr "Typ des Anmeldedatenaufrufs ist unbekannt" ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:31 ++msgid "Unknown quality of protection specified" ++msgstr "unbekannte Schutzqualität angegeben" ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:32 ++msgid "Local host name could not be determined" ++msgstr "lokaler Rechnername konnte nicht bestimmt werden" ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:33 ++msgid "Hostname in SERVICE-NAME string could not be canonicalized" ++msgstr "" ++"Rechnername in der Zeichenkette »SERVICE-NAME« konnte nicht in Normalform " ++"gebracht werden" ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:34 ++msgid "Mechanism is incorrect" ++msgstr "Mechanismus ist nicht korrekt" ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:35 ++msgid "Token header is malformed or corrupt" ++msgstr "Token-Kopfzeilen haben die falsche Form oder sind beschädigt" ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:36 ++msgid "Packet was replayed in wrong direction" ++msgstr "Paket wurde in falscher Richtung erneut abgespielt" ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:37 ++msgid "Token is missing data" ++msgstr "dem Token fehlen Daten" ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:38 ++msgid "Token was reflected" ++msgstr "Token wurde zurückgeworfen" ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:39 ++msgid "Received token ID does not match expected token ID" ++msgstr "Die empfangene Token-Kennung passt nicht zur erwarteten Token-Kennung." ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:40 ++msgid "The given credential's usage does not match the requested usage" ++msgstr "" ++"Die Verwendung der angegebenen Anmeldedaten passt nicht zur angeforderten " ++"Verwendung." ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:41 ++msgid "Storing of acceptor credentials is not supported by the mechanism" ++msgstr "" ++"Das Speichern von Abnehmeranmeldedaten wird nicht durch den Mechanismus " ++"unterstützt." ++ ++#: ../lib/gssapi/generic/gssapi_err_generic.c:42 ++msgid "Storing of non-default credentials is not supported by the mechanism" ++msgstr "" ++"Das Speichern von Nichtstandardanmeldedaten wird nicht durch den Mechanismus " ++"unterstützt." ++ ++#: ../lib/gssapi/krb5/gssapi_err_krb5.c:23 ++msgid "Principal in credential cache does not match desired name" ++msgstr "" ++"Principal im Anmeldedatenzwischenspeicher entspricht nicht dem gewünschten " ++"Namen" ++ ++#: ../lib/gssapi/krb5/gssapi_err_krb5.c:24 ++msgid "No principal in keytab matches desired name" ++msgstr "Kein Principal in der Schlüsseltabelle passt zum gewünschten Namen." ++ ++#: ../lib/gssapi/krb5/gssapi_err_krb5.c:25 ++msgid "Credential cache has no TGT" ++msgstr "Anmeldedatenzwischenspeicher hat kein TGT" ++ ++#: ../lib/gssapi/krb5/gssapi_err_krb5.c:26 ++msgid "Authenticator has no subkey" ++msgstr "Schlüsselziffer hat keinen Unterschlüssel" ++ ++#: ../lib/gssapi/krb5/gssapi_err_krb5.c:27 ++msgid "Context is already fully established" ++msgstr "Kontext wurde bereits vollständig eingerichtet" ++ ++#: ../lib/gssapi/krb5/gssapi_err_krb5.c:28 ++msgid "Unknown signature type in token" ++msgstr "unbekannter Signaturtyp im Token" ++ ++#: ../lib/gssapi/krb5/gssapi_err_krb5.c:29 ++msgid "Invalid field length in token" ++msgstr "falsche Feldlänge im Token" ++ ++#: ../lib/gssapi/krb5/gssapi_err_krb5.c:30 ++msgid "Attempt to use incomplete security context" ++msgstr "" ++"Es wurde versucht, einen unvollständigen Sicherheitskontext zu verwenden." ++ ++#: ../lib/gssapi/krb5/gssapi_err_krb5.c:31 ++msgid "Bad magic number for krb5_gss_ctx_id_t" ++msgstr "falsche magische Zahl für »krb5_gss_ctx_id_t«" ++ ++#: ../lib/gssapi/krb5/gssapi_err_krb5.c:32 ++msgid "Bad magic number for krb5_gss_cred_id_t" ++msgstr "falsche magische Zahl für »krb5_gss_cred_id_t«" ++ ++#: ../lib/gssapi/krb5/gssapi_err_krb5.c:33 ++msgid "Bad magic number for krb5_gss_enc_desc" ++msgstr "falsche magische Zahl für »krb5_gss_enc_desc«" ++ ++#: ../lib/gssapi/krb5/gssapi_err_krb5.c:34 ++msgid "Sequence number in token is corrupt" ++msgstr "Sequnznummer im Token ist beschädigt" ++ ++#: ../lib/gssapi/krb5/gssapi_err_krb5.c:35 ++msgid "Credential cache is empty" ++msgstr "Anmeldedatenzwischenspeicher ist leer" ++ ++#: ../lib/gssapi/krb5/gssapi_err_krb5.c:36 ++msgid "Acceptor and Initiator share no checksum types" ++msgstr "Abnehmer und Initiator haben keinen gemeinsamen Prüfsummentyp" ++ ++#: ../lib/gssapi/krb5/gssapi_err_krb5.c:37 ++msgid "Requested lucid context version not supported" ++msgstr "angeforderte »lucid«-Kontextversion nicht unterstützt" ++ ++# PRF = Pseudo Random Function ++#: ../lib/gssapi/krb5/gssapi_err_krb5.c:38 ++msgid "PRF input too long" ++msgstr "PRF-Eingabe zu lang" ++ ++#: ../lib/gssapi/krb5/gssapi_err_krb5.c:39 ++msgid "Bad magic number for iakerb_ctx_id_t" ++msgstr "falsche magische Zahl für »iakerb_ctx_id_t«" ++ ++#: ../lib/kadm5/chpass_util_strings.c:23 ++msgid "while getting policy info." ++msgstr "beim Holen der Richtlinieninformation." ++ ++#: ../lib/kadm5/chpass_util_strings.c:24 ++msgid "while getting principal info." ++msgstr "beim Holen der Principal-Information." ++ ++#: ../lib/kadm5/chpass_util_strings.c:25 ++msgid "New passwords do not match - password not changed.\n" ++msgstr "neue Passwörter stimmen nicht überein – Passwort nicht geändert\n" ++ ++#: ../lib/kadm5/chpass_util_strings.c:26 ++msgid "New password" ++msgstr "neues Passwort" ++ ++#: ../lib/kadm5/chpass_util_strings.c:27 ++msgid "New password (again)" ++msgstr "neues Passwort (erneut)" ++ ++#: ../lib/kadm5/chpass_util_strings.c:28 ++msgid "" ++"You must type a password. Passwords must be at least one character long.\n" ++msgstr "" ++"Sie müssen ein Passwort eingeben. Passwörter müssen mindestens ein Zeichen " ++"lang sein.\n" ++ ++#: ../lib/kadm5/chpass_util_strings.c:29 ++msgid "yet no policy set! Contact your system security administrator." ++msgstr "" ++"noch keine Richtlinie gesetzt! Kontaktieren Sie Ihren " ++"Systemsicherheitsadministrator" ++ ++#: ../lib/kadm5/chpass_util_strings.c:31 ++msgid "" ++"New password was found in a dictionary of possible passwords and\n" ++"therefore may be easily guessed. Please choose another password.\n" ++"See the kpasswd man page for help in choosing a good password." ++msgstr "" ++"Das neue Passwort wurde in einem Wörterbuch mit möglichen Passwörtern " ++"gefunden\n" ++"und kann daher leicht erraten werden. Bitte wählen Sie ein anderes " ++"Passwort.\n" ++"Hilfe bei der Wahl guter Passwörter finden Sie in der Handbuchseite von\n" ++"»kpasswd«." ++ ++#: ../lib/kadm5/chpass_util_strings.c:32 ++msgid "Password not changed." ++msgstr "Passwort nicht geändert" ++ ++#: ../lib/kadm5/chpass_util_strings.c:33 ++#, c-format ++msgid "" ++"New password is too short.\n" ++"Please choose a password which is at least %d characters long." ++msgstr "" ++"Das neue Passwort ist zu kurz.\n" ++"Bitte wählen Sie ein Passwort, das mindestens %d Zeichen lang ist." ++ ++#: ../lib/kadm5/chpass_util_strings.c:34 ++#, c-format ++msgid "" ++"New password does not have enough character classes.\n" ++"The character classes are:\n" ++"\t- lower-case letters,\n" ++"\t- upper-case letters,\n" ++"\t- digits,\n" ++"\t- punctuation, and\n" ++"\t- all other characters (e.g., control characters).\n" ++"Please choose a password with at least %d character classes." ++msgstr "" ++"Das neue Passwort besteht aus zu wenigen Zeichenklassen.\n" ++"Die Zeichenklassen sind:\n" ++"\t- Kleinbuchstaben,\n" ++"\t- Großbuchstaben,\n" ++"\t- Ziffern,\n" ++"\t- Satzzeichen und\n" ++"\t- alle anderen Zeichen (z.B. Steuerzeichen).\n" ++"Bitte wählen Sie ein Passwort mit mindestens %d Zeichenklassen." ++ ++#: ../lib/kadm5/chpass_util_strings.c:35 ++#, c-format ++msgid "" ++"Password cannot be changed because it was changed too recently.\n" ++"Please wait until %s before you change it.\n" ++"If you need to change your password before then, contact your system\n" ++"security administrator." ++msgstr "" ++"Das Passwort kann nicht geändert werden, da es erst vor kurzem geändert " ++"wurde.\n" ++"Bitte warten Sie bis %s, ehe Sie es ändern.\n" ++"Falls Sie es vorher ändern müssen, kontaktieren Sie Ihren\n" ++"Systemsicherheitsadministrator." ++ ++#: ../lib/kadm5/chpass_util_strings.c:36 ++msgid "New password was used previously. Please choose a different password." ++msgstr "" ++"Das neue Passwort wurde zuvor schon benutzt. Bitte wählen Sie ein anderes " ++"Passwort." ++ ++#: ../lib/kadm5/chpass_util_strings.c:37 ++msgid "while trying to change password." ++msgstr "beim Versuch, das Passwort zu ändern." ++ ++#: ../lib/kadm5/chpass_util_strings.c:38 ++msgid "while reading new password." ++msgstr "beim Lesen des neuen Passworts." ++ ++#: ../lib/kadm5/kadm_err.c:23 ++msgid "Operation failed for unspecified reason" ++msgstr "Aktion aus nicht näher beschriebenem Grund fehlgeschlagen" ++ ++#: ../lib/kadm5/kadm_err.c:24 ++msgid "Operation requires ``get'' privilege" ++msgstr "Aktion erfordert »get«-Recht" ++ ++#: ../lib/kadm5/kadm_err.c:25 ++msgid "Operation requires ``add'' privilege" ++msgstr "Aktion erfordert »add«-Recht" ++ ++#: ../lib/kadm5/kadm_err.c:26 ++msgid "Operation requires ``modify'' privilege" ++msgstr "Aktion erfordert »modify«-Recht" ++ ++#: ../lib/kadm5/kadm_err.c:27 ++msgid "Operation requires ``delete'' privilege" ++msgstr "Aktion erfordert »delete«-Recht" ++ ++#: ../lib/kadm5/kadm_err.c:28 ++msgid "Insufficient authorization for operation" ++msgstr "unzureichende Berechtigung für diese Aktion" ++ ++#: ../lib/kadm5/kadm_err.c:29 ../lib/kdb/adb_err.c:29 ++msgid "Database inconsistency detected" ++msgstr "Datenbankinkonsistenz entdeckt" ++ ++#: ../lib/kadm5/kadm_err.c:30 ../lib/kdb/adb_err.c:24 ++msgid "Principal or policy already exists" ++msgstr "Principal oder Richtlinie existiert bereits" ++ ++#: ../lib/kadm5/kadm_err.c:31 ++msgid "Communication failure with server" ++msgstr "Kommunikation mit dem Server fehlgeschlagen" ++ ++#: ../lib/kadm5/kadm_err.c:32 ++msgid "No administration server found for realm" ++msgstr "kein Administrationsserver für den Realm gefunden" ++ ++#: ../lib/kadm5/kadm_err.c:33 ++msgid "Password history principal key version mismatch" ++msgstr "Die Passwortchronikschlüssel des Principals passen nicht zusammen." ++ ++#: ../lib/kadm5/kadm_err.c:34 ++msgid "Connection to server not initialized" ++msgstr "Verbindung zum Server nicht initialisiert" ++ ++#: ../lib/kadm5/kadm_err.c:35 ++msgid "Principal does not exist" ++msgstr "Principal existiert nicht" ++ ++#: ../lib/kadm5/kadm_err.c:36 ++msgid "Policy does not exist" ++msgstr "Richtlinie existiert nicht" ++ ++#: ../lib/kadm5/kadm_err.c:37 ++msgid "Invalid field mask for operation" ++msgstr "ungültige Feldmaske für Aktion" ++ ++#: ../lib/kadm5/kadm_err.c:38 ++msgid "Invalid number of character classes" ++msgstr "ungültige Anzahl von Zeichenklassen" ++ ++#: ../lib/kadm5/kadm_err.c:39 ++msgid "Invalid password length" ++msgstr "ungültige Passwortlänge" ++ ++#: ../lib/kadm5/kadm_err.c:40 ++msgid "Illegal policy name" ++msgstr "unzulässiger Richtlinienname" ++ ++#: ../lib/kadm5/kadm_err.c:41 ++msgid "Illegal principal name" ++msgstr "unzulässiger Principal-Name" ++ ++# FIXME s/auxillary/auxilary/ ++#: ../lib/kadm5/kadm_err.c:42 ++msgid "Invalid auxillary attributes" ++msgstr "ungültige Zusatzattribute" ++ ++#: ../lib/kadm5/kadm_err.c:43 ++msgid "Invalid password history count" ++msgstr "ungültige Passwortchronikanzahl" ++ ++#: ../lib/kadm5/kadm_err.c:44 ++msgid "Password minimum life is greater than password maximum life" ++msgstr "Die minimale Lebensdauer des Passworts ist größer als die maximale." ++ ++#: ../lib/kadm5/kadm_err.c:45 ++msgid "Password is too short" ++msgstr "Das Passwort ist zu kurz." ++ ++#: ../lib/kadm5/kadm_err.c:46 ++msgid "Password does not contain enough character classes" ++msgstr "Das Passwort enthält nicht genug Zeichenklassen." ++ ++#: ../lib/kadm5/kadm_err.c:47 ++msgid "Password is in the password dictionary" ++msgstr "Das Passwort steht im Passwortwörterbuch." ++ ++#: ../lib/kadm5/kadm_err.c:48 ++msgid "Cannot reuse password" ++msgstr "Das Passwort kann nicht erneut verwendet werden." ++ ++#: ../lib/kadm5/kadm_err.c:49 ++msgid "Current password's minimum life has not expired" ++msgstr "Die aktuell minimale Lebensdauer des Passworts ist nicht abgelaufen." ++ ++#: ../lib/kadm5/kadm_err.c:50 ../lib/krb5/error_tables/kdb5_err.c:67 ++msgid "Policy is in use" ++msgstr "Richtlinie ist in Benutzung" ++ ++#: ../lib/kadm5/kadm_err.c:51 ++msgid "Connection to server already initialized" ++msgstr "Verbindung zum Server ist bereits initialisiert" ++ ++#: ../lib/kadm5/kadm_err.c:52 ++msgid "Incorrect password" ++msgstr "falsches Passwort" ++ ++#: ../lib/kadm5/kadm_err.c:53 ++msgid "Cannot change protected principal" ++msgstr "geschützter Principal kann nicht geändert werden" ++ ++#: ../lib/kadm5/kadm_err.c:54 ++msgid "Programmer error! Bad Admin server handle" ++msgstr "Fehler des Programmierers! Falscher Admin-Server-Identifikator" ++ ++#: ../lib/kadm5/kadm_err.c:55 ++msgid "Programmer error! Bad API structure version" ++msgstr "Fehler des Programmierers! Falsche API-Strukturversion" ++ ++#: ../lib/kadm5/kadm_err.c:56 ++msgid "" ++"API structure version specified by application is no longer supported (to " ++"fix, recompile application against current KADM5 API header files and " ++"libraries)" ++msgstr "" ++"Die von der Anwendung angegebene Version der API-Struktur wird nicht länger " ++"unterstützt. (Kompilieren Sie die Anwendung mit den aktuellen KADM5-API-" ++"Header-Dateien und -Bibliotheken, um dies zu beheben.)" ++ ++#: ../lib/kadm5/kadm_err.c:57 ++msgid "" ++"API structure version specified by application is unknown to libraries (to " ++"fix, obtain current KADM5 API header files and libraries and recompile " ++"application)" ++msgstr "" ++"Die von der Anwendung angegebene Version der API-Struktur ist den " ++"Bibliotheken unbekannt. (Besorgen Sie sich die aktuellen KADM5-API-Header-" ++"Dateien und -Bibliotheken und kompilieren Sie die Anwendung neu, um dies zu " ++"beheben.)" ++ ++#: ../lib/kadm5/kadm_err.c:58 ++msgid "Programmer error! Bad API version" ++msgstr "Fehler des Programmierers! Falsche API-Version" ++ ++#: ../lib/kadm5/kadm_err.c:59 ++msgid "" ++"API version specified by application is no longer supported by libraries (to " ++"fix, update application to adhere to current API version and recompile)" ++msgstr "" ++"Die von der Anwendung angegebene Version der API-Struktur wird nicht länger " ++"von den Bibliotheken unterstützt. (Aktualisieren Sie die Anwendung, dass sie " ++"zu der aktuellen API-Version passt, und kompilieren Sie sie, um dies zu " ++"beheben.)" ++ ++#: ../lib/kadm5/kadm_err.c:60 ++msgid "" ++"API version specified by application is no longer supported by server (to " ++"fix, update application to adhere to current API version and recompile)" ++msgstr "" ++"Die von der Anwendung angegebene Version der API-Struktur wird nicht länger " ++"vom Server unterstützt. (Aktualisieren Sie die Anwendung, dass sie zu der " ++"aktuellen API-Version passt, und kompilieren Sie sie, um dies zu beheben.)" ++ ++#: ../lib/kadm5/kadm_err.c:61 ++msgid "" ++"API version specified by application is unknown to libraries (to fix, obtain " ++"current KADM5 API header files and libraries and recompile application)" ++msgstr "" ++"Die von der Anwendung angegebenene API-Version ist den Bibliotheken " ++"unbekannt. (Besorgen Sie sich die aktuellen KADM5-API-Header-Dateien und -" ++"Bibliotheken und kompilieren Sie die Anwendung neu, um dies zu beheben.)" ++ ++#: ../lib/kadm5/kadm_err.c:62 ++msgid "" ++"API version specified by application is unknown to server (to fix, obtain " ++"and install newest KADM5 Admin Server)" ++msgstr "" ++"Die von der Anwendung angegebene API-Version ist dem Server unbekannt. " ++"(Besorgen und installieren Sie sich den neuesten KADM5-Admin-Server, um dies " ++"zu beheben.)" ++ ++#: ../lib/kadm5/kadm_err.c:63 ++msgid "Database error! Required KADM5 principal missing" ++msgstr "Datenbankfehler! Erforderlicher KADM5-Principal fehlt" ++ ++#: ../lib/kadm5/kadm_err.c:64 ++msgid "The salt type of the specified principal does not support renaming" ++msgstr "Der Salt-Typ des angegebenen Principals unterstützt kein Umbenennen." ++ ++#: ../lib/kadm5/kadm_err.c:65 ++msgid "Illegal configuration parameter for remote KADM5 client" ++msgstr "widerrechtlicher Konfigurationsparameter für fernen KADM5-Client" ++ ++#: ../lib/kadm5/kadm_err.c:66 ++msgid "Illegal configuration parameter for local KADM5 client" ++msgstr "widerrechtlicher Konfigurationsparameter für lokalen KADM5-Client" ++ ++#: ../lib/kadm5/kadm_err.c:67 ++msgid "Operation requires ``list'' privilege" ++msgstr "Aktion erfordert das »list«-Recht" ++ ++#: ../lib/kadm5/kadm_err.c:68 ++msgid "Operation requires ``change-password'' privilege" ++msgstr "Aktion erfordert das »change-password«-Recht" ++ ++#: ../lib/kadm5/kadm_err.c:69 ++msgid "GSS-API (or Kerberos) error" ++msgstr "GSS-API- (oder Kerberos-) Fehler" ++ ++#: ../lib/kadm5/kadm_err.c:70 ++msgid "Programmer error! Illegal tagged data list type" ++msgstr "" ++"Fehler des Programmierers! Widerrechlicher Listentyp für gekennzeichnete " ++"Daten" ++ ++#: ../lib/kadm5/kadm_err.c:71 ++msgid "Required parameters in kdc.conf missing" ++msgstr "erforderliche Parameter in »kdc.conf« fehlen" ++ ++#: ../lib/kadm5/kadm_err.c:72 ++msgid "Bad krb5 admin server hostname" ++msgstr "falscher Rechnername des KRB5-Admin-Servers" ++ ++#: ../lib/kadm5/kadm_err.c:73 ++msgid "Operation requires ``set-key'' privilege" ++msgstr "Aktion erfordert das »set-key«-Recht" ++ ++#: ../lib/kadm5/kadm_err.c:74 ++msgid "Multiple values for single or folded enctype" ++msgstr "" ++"mehrere Werte für einzelnen Verschlüsselungstyp oder Verschlüsselungstyp mit " ++"Salt" ++ ++#: ../lib/kadm5/kadm_err.c:75 ++msgid "Invalid enctype for setv4key" ++msgstr "widerrechtlicher Verschlüsselungstyp für Setv4key" ++ ++#: ../lib/kadm5/kadm_err.c:76 ++msgid "Mismatched enctypes for setkey3" ++msgstr "nicht zusammenpassende Verschlüsselungstypen für Setkey3" ++ ++#: ../lib/kadm5/kadm_err.c:77 ++msgid "Missing parameters in krb5.conf required for kadmin client" ++msgstr "für Kadmin-Client benötigte Parameter fehlen in »krb5.conf«" ++ ++#: ../lib/kadm5/kadm_err.c:78 ../lib/kdb/adb_err.c:30 ++msgid "XDR encoding error" ++msgstr "XDR-Verschlüsselungsfehler" ++ ++#: ../lib/kadm5/kadm_err.c:79 ++msgid "Cannot resolve network address for admin server in requested realm" ++msgstr "" ++"Die Netzwerkadresse für den Admin-Server im angeforderten Realm kann nicht " ++"aufgelöst werden." ++ ++#: ../lib/kadm5/kadm_err.c:80 ++msgid "Unspecified password quality failure" ++msgstr "nicht näher angegebener Passwortqualitätsfehlschlag" ++ ++#: ../lib/kadm5/kadm_err.c:81 ++msgid "Invalid key/salt tuples" ++msgstr "ungültige Schlüssel-/Salt-Tupel" ++ ++#: ../lib/kdb/adb_err.c:23 ++msgid "No Error" ++msgstr "kein Fehler" ++ ++#: ../lib/kdb/adb_err.c:25 ++msgid "Principal or policy does not exist" ++msgstr "Principal oder Richtlinie existiert nicht" ++ ++#: ../lib/kdb/adb_err.c:26 ++msgid "Database not initialized" ++msgstr "Datenbank nicht initialisiert" ++ ++#: ../lib/kdb/adb_err.c:27 ++msgid "Invalid policy name" ++msgstr "ungültiger Richtlinienname" ++ ++#: ../lib/kdb/adb_err.c:28 ++msgid "Invalid principal name" ++msgstr "ungültiger Principal-Name" ++ ++#: ../lib/kdb/adb_err.c:31 ++msgid "Failure!" ++msgstr "Fehlschlag!" ++ ++#: ../lib/kdb/adb_err.c:32 ++msgid "Bad lock mode" ++msgstr "falscher Sperrmodus" ++ ++#: ../lib/kdb/adb_err.c:33 ++msgid "Cannot lock database" ++msgstr "Datenbank kann nicht gesperrt werden" ++ ++#: ../lib/kdb/adb_err.c:34 ++msgid "Database not locked" ++msgstr "Datenbank nicht gesperrt" ++ ++#: ../lib/kdb/adb_err.c:35 ++msgid "KADM5 administration database lock file missing" ++msgstr "Sperrdatei der KADM5-Verwaltungsdatenbank fehlt" ++ ++#: ../lib/kdb/adb_err.c:36 ++msgid "Insufficient permission to lock file" ++msgstr "keine ausreichenden Rechte zum Sperren der Datei" ++ ++#: ../lib/krb5/error_tables/k5e1_err.c:23 ++msgid "Plugin does not support interface version" ++msgstr "Erweiterung unterstützt nicht die Schnittstellenversion" ++ ++#: ../lib/krb5/error_tables/k5e1_err.c:24 ++msgid "Invalid module specifier" ++msgstr "ungültige Modulangabe" ++ ++#: ../lib/krb5/error_tables/k5e1_err.c:25 ++msgid "Plugin module name not found" ++msgstr "Erweiterungsmodulname nicht gefunden" ++ ++#: ../lib/krb5/error_tables/k5e1_err.c:26 ++msgid "The KDC should discard this request" ++msgstr "Das KDC sollte diese Anfrage verwerfen" ++ ++#: ../lib/krb5/error_tables/k5e1_err.c:27 ++msgid "Can't create new subsidiary cache" ++msgstr "Der neue ergänzende Zwischenspeicher kann nicht erzeugt werden" ++ ++#: ../lib/krb5/error_tables/k5e1_err.c:28 ++msgid "Invalid keyring anchor name" ++msgstr "ungültiger Schlüsselbundverankerungsname" ++ ++#: ../lib/krb5/error_tables/k5e1_err.c:29 ++msgid "Unknown keyring collection version" ++msgstr "unbekannte Schlüsselbundsammlungsversion" ++ ++#: ../lib/krb5/error_tables/k5e1_err.c:30 ++msgid "Invalid UID in persistent keyring name" ++msgstr "ungültige UID im beständigen Schlüsselbundnamen" ++ ++#: ../lib/krb5/error_tables/k5e1_err.c:31 ++msgid "Malformed reply from KCM daemon" ++msgstr "Antwort des KCM-Daemons hat die falsche Form" ++ ++#: ../lib/krb5/error_tables/k5e1_err.c:32 ++msgid "Mach RPC error communicating with KCM daemon" ++msgstr "Mach-RPC-Fehler beim der Kommunikation mit dem KCM-Daemon" ++ ++#: ../lib/krb5/error_tables/k5e1_err.c:33 ++msgid "KCM daemon reply too big" ++msgstr "Antwort des KCM-Daemons zu groß" ++ ++#: ../lib/krb5/error_tables/k5e1_err.c:34 ++msgid "No KCM server found" ++msgstr "Kein KCM-Server gefunden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:24 ++msgid "Client's entry in database has expired" ++msgstr "Eintrag des Clients in der Datenbank ist abgelaufen" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:25 ++msgid "Server's entry in database has expired" ++msgstr "Eintrag des Servers in der Datenbank ist abgelaufen" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:26 ++msgid "Requested protocol version not supported" ++msgstr "angeforderte Protokollversion nicht unterstützt" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:27 ++msgid "Client's key is encrypted in an old master key" ++msgstr "" ++"Der Schlüssel des Clients wurde mit einem alten Hauptschlüssel verschlüsselt." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:28 ++msgid "Server's key is encrypted in an old master key" ++msgstr "" ++"Der Schlüssel des Servers wurde mit einem alten Hauptschlüssel verschlüsselt." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:29 ++msgid "Client not found in Kerberos database" ++msgstr "Client nicht in der Kerberos-Datenbank gefunden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:30 ++msgid "Server not found in Kerberos database" ++msgstr "Server nicht in der Kerberos-Datenbank gefunden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:31 ++msgid "Principal has multiple entries in Kerberos database" ++msgstr "Principal hat in der Kerberos-Datenbank mehrere Einträge" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:32 ++msgid "Client or server has a null key" ++msgstr "Client oder Server hat einen Nullschlüssel" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:33 ++msgid "Ticket is ineligible for postdating" ++msgstr "Ticket ist zum Vordatieren ungeeignet" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:34 ++msgid "Requested effective lifetime is negative or too short" ++msgstr "Die angeforderte effektive Lebensdauer ist negativ oder zu kurz." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:35 ++msgid "KDC policy rejects request" ++msgstr "KDC-Richtlinie weist die Anfrage zurück" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:36 ++msgid "KDC can't fulfill requested option" ++msgstr "KDC kann erforderliche Option nicht erfüllen" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:37 ++msgid "KDC has no support for encryption type" ++msgstr "KDC unterstützt diesen Verschlüsselungstyp nicht" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:38 ++msgid "KDC has no support for checksum type" ++msgstr "KDC unterstützt diesen Prüfsummentyp nicht" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:39 ++msgid "KDC has no support for padata type" ++msgstr "KDC unterstützt diesen Padata-Typ nicht" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:40 ++msgid "KDC has no support for transited type" ++msgstr "KDC unterstützt diesen Übergangstyp nicht" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:41 ++msgid "Clients credentials have been revoked" ++msgstr "Anmeldedaten des Clients wurden widerrufen" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:42 ++msgid "Credentials for server have been revoked" ++msgstr "Anmeldedaten für den Server wurden widerrufen" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:43 ++msgid "TGT has been revoked" ++msgstr "TGT wurde widerrufen" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:44 ++msgid "Client not yet valid - try again later" ++msgstr "Client noch nicht gültig – versuchen Sie es später noch einmal" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:45 ++msgid "Server not yet valid - try again later" ++msgstr "Server noch nicht gültig – versuchen Sie es später noch einmal" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:46 ++msgid "Password has expired" ++msgstr "Passwort ist abgelaufen" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:47 ++msgid "Preauthentication failed" ++msgstr "Vorauthentifizierung fehlgeschlagen" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:48 ++msgid "Additional pre-authentication required" ++msgstr "zusätzlich Vorauthentifizierung erforderlich" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:49 ++msgid "Requested server and ticket don't match" ++msgstr "abgefragter Server und Ticket passen nicht zusammen" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:50 ++msgid "Server principal valid for user2user only" ++msgstr "Der Server-Principal ist nur für »user2user« gültig" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:51 ++msgid "KDC policy rejects transited path" ++msgstr "KDC-Richtlinie verwirft durchgereichten Pfad" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:52 ++msgid "A service is not available that is required to process the request" ++msgstr "" ++"Ein Dienst, der zum Verarbeiten der Abfrage erforderlich ist, ist nicht " ++"verfügbar." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:53 ++msgid "KRB5 error code 30" ++msgstr "KRB5-Fehlercode 30" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:54 ++msgid "Decrypt integrity check failed" ++msgstr "Entschlüsselungsintegritätsprüfung fehlgeschlagen" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:55 ++msgid "Ticket expired" ++msgstr "Ticket abgelaufen" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:56 ++msgid "Ticket not yet valid" ++msgstr "Ticket noch nicht gültig" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:57 ++msgid "Request is a replay" ++msgstr "Anfrage ist eine Wiederholung" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:58 ++msgid "The ticket isn't for us" ++msgstr "Das Ticket ist nicht für uns." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:59 ++msgid "Ticket/authenticator don't match" ++msgstr "Ticket/Schlüsselziffer passen nicht zueinander" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:60 ++msgid "Clock skew too great" ++msgstr "Uhrzeitabweichung zu groß" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:61 ++msgid "Incorrect net address" ++msgstr "falsche Netzwerkadresse" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:62 ++msgid "Protocol version mismatch" ++msgstr "Protokollversion passt nicht" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:63 ++msgid "Invalid message type" ++msgstr "ungültiger Nachrichtentyp" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:64 ++msgid "Message stream modified" ++msgstr "Nachrichtendatenstrom geändert" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:65 ++msgid "Message out of order" ++msgstr "Nachricht nicht in Ordnung" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:66 ++msgid "Illegal cross-realm ticket" ++msgstr "Widerrechliches Realm-übergreifendes Ticket" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:67 ++msgid "Key version is not available" ++msgstr "Schlüsselversion ist nicht verfügbar" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:68 ++msgid "Service key not available" ++msgstr "Dienstschlüssel nicht verfügbar" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:69 ++#: ../lib/krb5/error_tables/krb5_err.c:181 ++msgid "Mutual authentication failed" ++msgstr "gegenseitige Authentifizierung fehlgeschlagen" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:70 ++msgid "Incorrect message direction" ++msgstr "falsche Nachrichtenrichtung" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:71 ++msgid "Alternative authentication method required" ++msgstr "alternative Authentifizierungsmethode erforderlich" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:72 ++msgid "Incorrect sequence number in message" ++msgstr "falsche Sequenznummer in der Nachricht" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:73 ++msgid "Inappropriate type of checksum in message" ++msgstr "ungeeigneter Prüfsummentyp in der Nachricht" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:74 ++msgid "Policy rejects transited path" ++msgstr "Richtlinie verwirft durchgereichten Pfad" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:75 ++msgid "Response too big for UDP, retry with TCP" ++msgstr "Antwort für UDP zu groß, erneuter Versuch mit TCP" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:76 ++msgid "KRB5 error code 53" ++msgstr "KRB5-Fehlercode 53" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:77 ++msgid "KRB5 error code 54" ++msgstr "KRB5-Fehlercode 54" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:78 ++msgid "KRB5 error code 55" ++msgstr "KRB5-Fehlercode 55" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:79 ++msgid "KRB5 error code 56" ++msgstr "KRB5-Fehlercode 56" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:80 ++msgid "KRB5 error code 57" ++msgstr "KRB5-Fehlercode 57" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:81 ++msgid "KRB5 error code 58" ++msgstr "KRB5-Fehlercode 58" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:82 ++msgid "KRB5 error code 59" ++msgstr "KRB5-Fehlercode 59" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:83 ++msgid "Generic error (see e-text)" ++msgstr "allgemeiner Fehler (siehe E-Text)" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:84 ++msgid "Field is too long for this implementation" ++msgstr "Feld ist für diese Implementierung zu lang" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:85 ++msgid "Client not trusted" ++msgstr "Client nicht vertrauenswürdig" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:86 ++msgid "KDC not trusted" ++msgstr "KDC nicht vertrauenswürdig" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:87 ++msgid "Invalid signature" ++msgstr "ungültige Signatur" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:88 ++msgid "Key parameters not accepted" ++msgstr "Schlüsselparameter nicht akzeptiert" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:89 ++msgid "Certificate mismatch" ++msgstr "Zertifikat passt nicht" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:90 ++msgid "No ticket granting ticket" ++msgstr "kein ticketgewährendes Ticket" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:91 ++msgid "Realm not local to KDC" ++msgstr "Realm für KDC nicht lokal" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:92 ++msgid "User to user required" ++msgstr "Benutzer-zu-Benutzer erforderlich" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:93 ++msgid "Can't verify certificate" ++msgstr "Zertifikat kann nicht überprüft werden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:94 ++msgid "Invalid certificate" ++msgstr "ungültiges Zertifikat" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:95 ++msgid "Revoked certificate" ++msgstr "widerrufenes Zertifikat" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:96 ++msgid "Revocation status unknown" ++msgstr "Widerrufsstatus unbekannt" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:97 ++msgid "Revocation status unavailable" ++msgstr "Widerrufsstatus nicht verfügbar" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:98 ++msgid "Client name mismatch" ++msgstr "Client-Name passt nicht" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:99 ++msgid "KDC name mismatch" ++msgstr "KDC-Name passt nicht" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:100 ++msgid "Inconsistent key purpose" ++msgstr "inkonstistenter Schlüsselzweck" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:101 ++msgid "Digest in certificate not accepted" ++msgstr "Kurzfassung im Zertifikat nicht akzeptiert" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:102 ++msgid "Checksum must be included" ++msgstr "Prüfsumme muss enthalten sein" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:103 ++msgid "Digest in signed-data not accepted" ++msgstr "Kurzfassung in signierten Daten nicht akzeptiert" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:104 ++msgid "Public key encryption not supported" ++msgstr "Asymetrische Verschlüsselung nicht unterstützt" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:105 ++msgid "KRB5 error code 82" ++msgstr "KRB5-Fehlercode 82" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:106 ++msgid "KRB5 error code 83" ++msgstr "KRB5-Fehlercode 83" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:107 ++msgid "KRB5 error code 84" ++msgstr "KRB5-Fehlercode 84" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:108 ++msgid "The IAKERB proxy could not find a KDC" ++msgstr "Der IAKERB-Proxy konnte kein KDC finden." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:109 ++msgid "The KDC did not respond to the IAKERB proxy" ++msgstr "Das KDC anwortete dem IAKERB-Proxy nicht." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:110 ++msgid "KRB5 error code 87" ++msgstr "KRB5-Fehlercode 87" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:111 ++msgid "KRB5 error code 88" ++msgstr "KRB5-Fehlercode 88" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:112 ++msgid "KRB5 error code 89" ++msgstr "KRB5-Fehlercode 89" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:113 ++msgid "KRB5 error code 90" ++msgstr "KRB5-Fehlercode 90" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:114 ++msgid "KRB5 error code 91" ++msgstr "KRB5-Fehlercode 91" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:115 ++msgid "KRB5 error code 92" ++msgstr "KRB5-Fehlercode 92" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:116 ++msgid "An unsupported critical FAST option was requested" ++msgstr "Es wurde eine nicht unterstützte kritische FAST-Aktion angefordert." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:117 ++msgid "KRB5 error code 94" ++msgstr "KRB5-Fehlercode 94" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:118 ++msgid "KRB5 error code 95" ++msgstr "KRB5-Fehlercode 95" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:119 ++msgid "KRB5 error code 96" ++msgstr "KRB5-Fehlercode 96" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:120 ++msgid "KRB5 error code 97" ++msgstr "KRB5-Fehlercode 97" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:121 ++msgid "KRB5 error code 98" ++msgstr "KRB5-Fehlercode 98" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:122 ++msgid "KRB5 error code 99" ++msgstr "KRB5-Fehlercode 99" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:123 ++msgid "No acceptable KDF offered" ++msgstr "kein akzeptables KDF angeboten" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:124 ++msgid "KRB5 error code 101" ++msgstr "KRB5-Fehlercode 101" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:125 ++msgid "KRB5 error code 102" ++msgstr "KRB5-Fehlercode 102" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:126 ++msgid "KRB5 error code 103" ++msgstr "KRB5-Fehlercode 103" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:127 ++msgid "KRB5 error code 104" ++msgstr "KRB5-Fehlercode 104" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:128 ++msgid "KRB5 error code 105" ++msgstr "KRB5-Fehlercode 105" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:129 ++msgid "KRB5 error code 106" ++msgstr "KRB5-Fehlercode 106" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:130 ++msgid "KRB5 error code 107" ++msgstr "KRB5-Fehlercode 107" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:131 ++msgid "KRB5 error code 108" ++msgstr "KRB5-Fehlercode 108" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:132 ++msgid "KRB5 error code 109" ++msgstr "KRB5-Fehlercode 109" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:133 ++msgid "KRB5 error code 110" ++msgstr "KRB5-Fehlercode 110" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:134 ++msgid "KRB5 error code 111" ++msgstr "KRB5-Fehlercode 111" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:135 ++msgid "KRB5 error code 112" ++msgstr "KRB5-Fehlercode 112" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:136 ++msgid "KRB5 error code 113" ++msgstr "KRB5-Fehlercode 113" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:137 ++msgid "KRB5 error code 114" ++msgstr "KRB5-Fehlercode 114" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:138 ++msgid "KRB5 error code 115" ++msgstr "KRB5-Fehlercode 115" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:139 ++msgid "KRB5 error code 116" ++msgstr "KRB5-Fehlercode 116" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:140 ++msgid "KRB5 error code 117" ++msgstr "KRB5-Fehlercode 117" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:141 ++msgid "KRB5 error code 118" ++msgstr "KRB5-Fehlercode 118" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:142 ++msgid "KRB5 error code 119" ++msgstr "KRB5-Fehlercode 119" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:143 ++msgid "KRB5 error code 120" ++msgstr "KRB5-Fehlercode 120" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:144 ++msgid "KRB5 error code 121" ++msgstr "KRB5-Fehlercode 121" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:145 ++msgid "KRB5 error code 122" ++msgstr "KRB5-Fehlercode 122" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:146 ++msgid "KRB5 error code 123" ++msgstr "KRB5-Fehlercode 123" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:147 ++msgid "KRB5 error code 124" ++msgstr "KRB5-Fehlercode 124" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:148 ++msgid "KRB5 error code 125" ++msgstr "KRB5-Fehlercode 125" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:149 ++msgid "KRB5 error code 126" ++msgstr "KRB5-Fehlercode 126" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:150 ++msgid "KRB5 error code 127" ++msgstr "KRB5-Fehlercode 127" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:151 ++#: ../lib/krb5/error_tables/kdb5_err.c:23 ++msgid "$Id$" ++msgstr "$Id$" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:152 ++msgid "Invalid flag for file lock mode" ++msgstr "ungültiger Schalter für den Datei-Sperrmodus" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:153 ++msgid "Cannot read password" ++msgstr "Passwort kann nicht gelesen werden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:154 ++msgid "Password mismatch" ++msgstr "Passwort stimmt nicht überein" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:155 ++msgid "Password read interrupted" ++msgstr "Lesen des Passworts unterbrochen" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:156 ++msgid "Illegal character in component name" ++msgstr "ungültiges Zeichen in Komponentenname" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:157 ++msgid "Malformed representation of principal" ++msgstr "Darstellung des Principals in falscher Form" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:158 ++msgid "Can't open/find Kerberos configuration file" ++msgstr "Kerberos-Konfigurationsdatei kann nicht geöffnet/gefunden werden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:159 ++msgid "Improper format of Kerberos configuration file" ++msgstr "Format der Kerberos-Konfigurationsdatei ist ungeeignet" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:160 ++msgid "Insufficient space to return complete information" ++msgstr "Platz reicht nicht zur Rückgabe aller Informationen aus" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:161 ++msgid "Invalid message type specified for encoding" ++msgstr "der zum Kodieren angegebene Nachrichtentyp ist ungültig" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:162 ++msgid "Credential cache name malformed" ++msgstr "falsche Form des Anmeldedatenzwischenspeichernamens" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:163 ++msgid "Unknown credential cache type" ++msgstr "unbekannter Anmeldedatenzwischenspeichertyp" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:164 ++msgid "Matching credential not found" ++msgstr "keine passenden Anmeldedaten gefunden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:165 ++msgid "End of credential cache reached" ++msgstr "Ende des Anmeldedatenzwischenspeichers erreicht" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:166 ++msgid "Request did not supply a ticket" ++msgstr "Anfrage lieferte kein Ticket" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:167 ++msgid "Wrong principal in request" ++msgstr "falscher Principal in der Anfrage" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:168 ++msgid "Ticket has invalid flag set" ++msgstr "Das Ticket hat einen falsch gesetzten Schalter." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:169 ++msgid "Requested principal and ticket don't match" ++msgstr "angeforderter Principal und Ticket passen nicht zusammen" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:170 ++msgid "KDC reply did not match expectations" ++msgstr "KDC-Antwort entsprach nicht den Erwartungen" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:171 ++msgid "Clock skew too great in KDC reply" ++msgstr "Zeitversatz in der KDC-Antwort zu groß" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:172 ++msgid "Client/server realm mismatch in initial ticket request" ++msgstr "" ++"Client-/Server-Realm passen in der anfänglichen Ticketanfrage nicht zusammen." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:173 ++msgid "Program lacks support for encryption type" ++msgstr "" ++"Dem Programm fehlt es an der Unterstützung für den Verschlüsselungstyp." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:174 ++msgid "Program lacks support for key type" ++msgstr "Dem Programm fehlt es an der Unterstützung für den Schlüsseltyp." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:175 ++msgid "Requested encryption type not used in message" ++msgstr "" ++"Der angeforderte Verschlüsselungstyp wird in der Nachricht nicht verwendet." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:176 ++msgid "Program lacks support for checksum type" ++msgstr "Dem Programm fehlt es an der Unterstützung für den Prüfsummentyp." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:177 ++msgid "Cannot find KDC for requested realm" ++msgstr "KDC für angeforderten Realm kann nicht gefunden werden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:178 ++msgid "Kerberos service unknown" ++msgstr "Kerberos-Dienst unbekannt" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:179 ++msgid "Cannot contact any KDC for requested realm" ++msgstr "Für den angeforderten Realm kann kein KDC kontaktiert werden." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:180 ++msgid "No local name found for principal name" ++msgstr "Für den Principal-Namen wurde kein lokaler Name gefunden." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:182 ++msgid "Replay cache type is already registered" ++msgstr "Wiederholungszwischenspeichertyp ist bereits registriert" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:183 ++msgid "No more memory to allocate (in replay cache code)" ++msgstr "" ++"kein Speicher mehr zu reservieren (im Wiederholungszwischenspeichercode)" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:184 ++msgid "Replay cache type is unknown" ++msgstr "Wiederholungszwischenspeichertyp ist unbekannt" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:185 ++msgid "Generic unknown RC error" ++msgstr "allgemeiner unbekannter Wiederholungszwischenspeicherfehler" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:186 ++msgid "Message is a replay" ++msgstr "Nachricht ist eine Wiederholung" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:187 ++msgid "Replay cache I/O operation failed" ++msgstr "Wiederholungszwischenspeicher-E/A-Aktion fehlgeschlagen" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:188 ++msgid "Replay cache type does not support non-volatile storage" ++msgstr "" ++"Wiederholungszwischenspeichertyp unterstützt keinen beständigen Speicher" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:189 ++msgid "Replay cache name parse/format error" ++msgstr "Auswerte-/Formatfehler im Wiederholungszwischenspeichernamens" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:190 ++msgid "End-of-file on replay cache I/O" ++msgstr "Dateiende bei der E/A des Wiederholungszwischenspeichers" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:191 ++msgid "No more memory to allocate (in replay cache I/O code)" ++msgstr "" ++"kein weiterer Speicher reservierbar (im Wiederholungszwischenspeicher-E/A-" ++"Code)" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:192 ++msgid "Permission denied in replay cache code" ++msgstr "Zugriff im Wiederholungszwischenspeichercode verweigert" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:193 ++msgid "I/O error in replay cache i/o code" ++msgstr "E/A-Fehler im Wiederholungszwischenspeicher-E/A-Code" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:194 ++msgid "Generic unknown RC/IO error" ++msgstr "allgemeiner unbekannter Wiederholungszwischenspeicher-/E/A-Fehler" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:195 ++msgid "Insufficient system space to store replay information" ++msgstr "" ++"Platz im System reicht nicht zum Speichern der Wiederholungsinformationen" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:196 ++msgid "Can't open/find realm translation file" ++msgstr "Realm-Übersetzungsdatei kann nicht geöffnet/gefunden werden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:197 ++msgid "Improper format of realm translation file" ++msgstr "Format der Realm-Übersetzungsdatei ist ungeeignet" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:198 ++msgid "Can't open/find lname translation database" ++msgstr "die Lname-Übersetzungsdatenbank kann nicht geöffnet/gefunden werden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:199 ++msgid "No translation available for requested principal" ++msgstr "Für den angeforderten Principal ist keine Übersetzung verfügbar." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:200 ++msgid "Improper format of translation database entry" ++msgstr "Format des Eintrags der Übersetzungsdatenbank ist ungeeignet" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:201 ++msgid "Cryptosystem internal error" ++msgstr "interner Fehler des Verschlüsselungssystems" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:202 ++msgid "Key table name malformed" ++msgstr "falsche Form des Schlüsseltabellennamens" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:203 ++msgid "Unknown Key table type" ++msgstr "unbekannter Schlüsseltabellentyp" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:204 ++msgid "Key table entry not found" ++msgstr "Schlüsseltabelleneintrag nicht gefunden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:205 ++msgid "End of key table reached" ++msgstr "Ende der Schlüsseltabelle erreicht" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:206 ++msgid "Cannot write to specified key table" ++msgstr "in angegebene Schlüsseltabelle kann nicht geschrieben werden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:207 ++msgid "Error writing to key table" ++msgstr "Fehler beim Schreiben in Schlüsseltabelle" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:208 ++msgid "Cannot find ticket for requested realm" ++msgstr "Ticket für angeforderten Realm kann nicht gefunden werden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:209 ++msgid "DES key has bad parity" ++msgstr "DES-Schlüssel hat falsche Parität" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:210 ++msgid "DES key is a weak key" ++msgstr "DES-Schlüssel ist schwach" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:211 ++msgid "Bad encryption type" ++msgstr "falscher Verschlüsselungstyp" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:212 ++msgid "Key size is incompatible with encryption type" ++msgstr "Schlüssellänge ist nicht mit dem Verschlüsselungstyp kompatibel" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:213 ++msgid "Message size is incompatible with encryption type" ++msgstr "Nachrichtengröße ist nicht mit Verschlüsselungstyp kompatibel" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:214 ++msgid "Credentials cache type is already registered." ++msgstr "Anmeldedatenzwischenspeichertyp ist bereits registriert" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:215 ++msgid "Key table type is already registered." ++msgstr "Schlüsseltabellentyp ist bereits registriert" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:216 ++msgid "Credentials cache I/O operation failed XXX" ++msgstr "E/A-Aktion für Anmeldedatenzwischenspeicher fehlgeschlagen XXX" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:217 ++msgid "Credentials cache permissions incorrect" ++msgstr "Anmeldedatenzwischenspeicherrechte nicht korrekt" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:218 ++msgid "No credentials cache found" ++msgstr "kein Anmeldedatenzwischenspeicher gefunden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:219 ++msgid "Internal credentials cache error" ++msgstr "interner Anmeldedatenzwischenspeicherfehler" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:220 ++msgid "Error writing to credentials cache" ++msgstr "Fehler beim Schreiben in den Anmeldedatenzwischenspeicher" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:221 ++msgid "No more memory to allocate (in credentials cache code)" ++msgstr "" ++"kein weiterer Speicher zu reservieren (im Anmeldedatenzwischenspeichercode)" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:222 ++msgid "Bad format in credentials cache" ++msgstr "falsches Format im Anmeldedatenzwischenspeicher" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:223 ++msgid "No credentials found with supported encryption types" ++msgstr "keine Anmeldedaten mit unterstützten Verschlüsselungstypen gefunden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:224 ++msgid "Invalid KDC option combination (library internal error)" ++msgstr "ungültige Kombination von KDC-Optionen (interner Bibliotheksfehler)" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:225 ++msgid "Request missing second ticket" ++msgstr "Der Anfrage fehlt das zweite Ticket." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:226 ++msgid "No credentials supplied to library routine" ++msgstr "der Bibliotheks-Routine wurden keine Anmeldedaten geliefert" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:227 ++msgid "Bad sendauth version was sent" ++msgstr "Es wurde eine falsche Sendauth-Version verschickt" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:228 ++msgid "Bad application version was sent (via sendauth)" ++msgstr "Es wurde eine falsche Anwendungsversion (über Sendauth) verschickt" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:229 ++msgid "Bad response (during sendauth exchange)" ++msgstr "falsche Antwort (beim Sendauth-Austausch)" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:230 ++msgid "Server rejected authentication (during sendauth exchange)" ++msgstr "Server wies Authentifizierung (beim Sendauth-Austausch) zurück" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:231 ++msgid "Unsupported preauthentication type" ++msgstr "nicht unterstützter Vorauthentifizierungstyp" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:232 ++msgid "Required preauthentication key not supplied" ++msgstr "erforderlicher Vorauthentifizierungsschlüssel nicht bereitgestellt" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:233 ++msgid "Generic preauthentication failure" ++msgstr "allgemeiner Fehlschlag der Vorauthentifizierung" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:234 ++msgid "Unsupported replay cache format version number" ++msgstr "" ++"nicht unterstütztes Versionsnummernformat des Wiederholungszwischenspeichers" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:235 ++msgid "Unsupported credentials cache format version number" ++msgstr "" ++"nicht unterstütztes Versionsnummernformat des Anmeldedatenzwischenspeichers" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:236 ++msgid "Unsupported key table format version number" ++msgstr "nicht unterstütztes Versionsnummernformat der Schlüsseltabelle" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:237 ++msgid "Program lacks support for address type" ++msgstr "Dem Programm fehlt es an der Unterstützung des Adresstyps." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:238 ++msgid "Message replay detection requires rcache parameter" ++msgstr "Erkennung der Antwortnachricht erfordert den Parameter »rcache«" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:239 ++msgid "Hostname cannot be canonicalized" ++msgstr "Rechnername kann nicht in Normalform gebracht werden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:240 ++msgid "Cannot determine realm for host" ++msgstr "Realm für Rechner kann nicht bestimmt werden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:241 ++msgid "Conversion to service principal undefined for name type" ++msgstr "Umwandlung in Dienst-Principal für Namenstyp nicht definiert" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:242 ++msgid "Initial Ticket response appears to be Version 4 error" ++msgstr "anfängliche Ticket-Antwort scheint ein Fehler der Version 4 zu sein" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:243 ++msgid "Cannot resolve network address for KDC in requested realm" ++msgstr "" ++"Netzwerkadresse für KDC im angeforderten Realm kann nicht aufgelöst werden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:244 ++msgid "Requesting ticket can't get forwardable tickets" ++msgstr "anforderndes Ticket kann keine weiterleitbaren Tickets holen" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:245 ++msgid "Bad principal name while trying to forward credentials" ++msgstr "falscher Principal beim Versuch, Anmeldedaten weiterzuleiten" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:246 ++msgid "Looping detected inside krb5_get_in_tkt" ++msgstr "Schleife innerhalb von »krb5_get_in_tkt« entdeckt" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:247 ++msgid "Configuration file does not specify default realm" ++msgstr "Konfigurationsdatei gibt keinen Standard-Realm an" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:248 ++msgid "Bad SAM flags in obtain_sam_padata" ++msgstr "falsche SAM-Schalter in »obtain_sam_padata«" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:249 ++msgid "Invalid encryption type in SAM challenge" ++msgstr "ungültiger Verschlüsselungstyp in der SAM-Aufforderung" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:250 ++msgid "Missing checksum in SAM challenge" ++msgstr "fehlende Prüfsumme in der SAM-Aufforderung" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:251 ++msgid "Bad checksum in SAM challenge" ++msgstr "falsche Prüfsumme in der SAM-Aufforderung" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:252 ++msgid "Keytab name too long" ++msgstr "Schlüsseltabellennamen zu lang" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:253 ++msgid "Key version number for principal in key table is incorrect" ++msgstr "" ++"Schlüsselversionsnummer des Principals in der Schlüsseltabelle ist nicht " ++"korrekt" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:254 ++msgid "This application has expired" ++msgstr "Diese Anwendung ist abgelaufen." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:255 ++msgid "This Krb5 library has expired" ++msgstr "Diese Krb5-Bibliothek ist abgelaufen." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:256 ++msgid "New password cannot be zero length" ++msgstr "Das neue Passwort kann nicht die Länge Null haben." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:258 ++msgid "Bad format in keytab" ++msgstr "falsches Format in der Schlüsseltabelle" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:259 ++msgid "Encryption type not permitted" ++msgstr "Verschlüsselungstyp nicht erlaubt" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:260 ++msgid "No supported encryption types (config file error?)" ++msgstr "" ++"keine unterstützten Verschlüsselungstypen (Fehler in der " ++"Konfigurationsdatei?)" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:261 ++msgid "Program called an obsolete, deleted function" ++msgstr "Das Programm rief eine veraltete, gelöschte Funktion auf." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:262 ++msgid "unknown getaddrinfo failure" ++msgstr "unbekannter Getaddrinfo-Fehlschlag" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:263 ++msgid "no data available for host/domain name" ++msgstr "keine Daten für Rechner/Domain-Namen verfügbar" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:264 ++msgid "host/domain name not found" ++msgstr "Rechner/Domain-Name nicht gefunden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:265 ++msgid "service name unknown" ++msgstr "Dienstname unbekannt" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:266 ++msgid "Cannot determine realm for numeric host address" ++msgstr "Realm für numerische Rechneradresse kann nicht bestimmt werden" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:267 ++msgid "Invalid key generation parameters from KDC" ++msgstr "ungültige Parameter zum Erzeugen von Schlüsseln vom KDC" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:268 ++msgid "service not available" ++msgstr "Dienst nicht verfügbar" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:269 ++msgid "Ccache function not supported: read-only ccache type" ++msgstr "Ccache-Funktion nicht unterstützt: Ccache-Typ nur lesbar" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:270 ++msgid "Ccache function not supported: not implemented" ++msgstr "Ccache-Funktion nicht unterstützt: nicht implementiert" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:271 ++msgid "Invalid format of Kerberos lifetime or clock skew string" ++msgstr "" ++"ungültiges Format der Kerberos-Lebensdauer oder der Zeitversatzzeichenkette" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:272 ++msgid "Supplied data not handled by this plugin" ++msgstr "" ++"Die bereitgestellten Daten werden nicht von dieser Erweiterung behandelt." ++ ++#: ../lib/krb5/error_tables/krb5_err.c:273 ++msgid "Plugin does not support the operation" ++msgstr "Erweiterung unterstützt diese Aktion nicht" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:274 ++msgid "Invalid UTF-8 string" ++msgstr "ungültige UTF-8-Zeichenkette" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:275 ++msgid "FAST protected pre-authentication required but not supported by KDC" ++msgstr "" ++"FAST-geschützte Vorauthentifizierung erforderlich, aber nicht vom KDC " ++"unterstützt" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:276 ++msgid "Auth context must contain local address" ++msgstr "Authentifizierungskontext muss lokale Adresse enthalten" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:277 ++msgid "Auth context must contain remote address" ++msgstr "Authentifizierungskontext muss ferne Adresse enthalten" ++ ++#: ../lib/krb5/error_tables/krb5_err.c:278 ++msgid "Tracing unsupported" ++msgstr "Verfolgung nicht unterstützt" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:24 ++msgid "Entry already exists in database" ++msgstr "Eintrag existiert bereits in der Datenbank" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:25 ++msgid "Database store error" ++msgstr "Datenbank-Speicherfehler" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:26 ++msgid "Database read error" ++msgstr "Datenbank-Lesefehler" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:27 ++msgid "Insufficient access to perform requested operation" ++msgstr "Zugriffsrechte reichen nicht zur Durchführung der angeforderten Aktion" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:28 ++msgid "No such entry in the database" ++msgstr "kein derartiger Eintrag in der Datenbank" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:29 ++msgid "Illegal use of wildcard" ++msgstr "ungültige Verwendung eines Platzhalters" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:30 ++msgid "Database is locked or in use--try again later" ++msgstr "" ++"Datenbank ist gesperrt oder wird gerade benutzt – versuchen Sie es später " ++"wieder" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:31 ++msgid "Database was modified during read" ++msgstr "Datenbank wurde während des Lesens geändert" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:32 ++msgid "Database record is incomplete or corrupted" ++msgstr "Datensatz ist unvollständig oder beschädigt" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:33 ++msgid "Attempt to lock database twice" ++msgstr "Es wurde zweimal versucht, die Datenbank zu sperren." ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:34 ++msgid "Attempt to unlock database when not locked" ++msgstr "" ++"Es wurde versucht, die Datenbank zu entsperren, obwohl sie nicht gesperrt " ++"ist." ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:35 ++msgid "Invalid kdb lock mode" ++msgstr "ungültiger KDB-Sperrmodus" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:36 ++msgid "Database has not been initialized" ++msgstr "Datenbank wurde nicht initialisiert" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:37 ++msgid "Database has already been initialized" ++msgstr "Datenbank wurde bereits initialisiert" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:38 ++msgid "Bad direction for converting keys" ++msgstr "falsche Richtung zum Umwandeln von Schlüsseln" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:39 ++msgid "Cannot find master key record in database" ++msgstr "Hauptschlüsseldatensatz kann nicht in der Datenbank gefunden werden" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:40 ++msgid "Master key does not match database" ++msgstr "Hauptschlüssel passt nicht zur Datenbank" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:41 ++msgid "Key size in database is invalid" ++msgstr "Die Schlüssellänge in der Datenbank ist ungültig," ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:42 ++msgid "Cannot find/read stored master key" ++msgstr "Der gespeicherte Hauptschlüssel kann nicht gefunden/gelesen werden." ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:43 ++msgid "Stored master key is corrupted" ++msgstr "Der gespeicherte Hauptschlüssel ist beschädigt." ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:44 ++msgid "Cannot find active master key" ++msgstr "Der aktive Hauptschlüssel kann nicht gefunden werden." ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:45 ++msgid "KVNO of new master key does not match expected value" ++msgstr "KVNO des neuen Hauptschlüssels passt nicht zum erwarteten Wert" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:46 ++msgid "Stored master key is not current" ++msgstr "gespeicherter Hauptschlüssel ist nicht aktuell" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:47 ++msgid "Insufficient access to lock database" ++msgstr "keine ausreichenden Zugriffsrechte zum Sperren der Datenbank" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:48 ++msgid "Database format error" ++msgstr "fehlerhaftes Datenbankformat" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:49 ++msgid "Unsupported version in database entry" ++msgstr "nicht unterstützte Version im Datenbankeintrag" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:50 ++msgid "Unsupported salt type" ++msgstr "nicht unterstützter Salt-Typ" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:51 ++msgid "Unsupported encryption type" ++msgstr "nicht unterstützter Verschlüsselungstyp" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:52 ++msgid "Bad database creation flags" ++msgstr "falsche Schalter zum Erstellen der Datenbank" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:53 ++msgid "No matching key in entry having a permitted enctype" ++msgstr "" ++"kein passender Schlüssel in einem Eintrag mit erlaubtem Verschlüsselungstyp" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:54 ++msgid "No matching key in entry" ++msgstr "kein passender Schlüssel im Eintrag" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:55 ++msgid "Unable to find requested database type" ++msgstr "angeforderter Datenbanktyp kann nicht gefunden werden" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:56 ++msgid "Database type not supported" ++msgstr "Datenbanktyp nicht unterstützt" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:57 ++msgid "Database library failed to initialize" ++msgstr "Initialisieren der Datenbankbibliothek fehlgeschlagen" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:59 ++msgid "Unable to access Kerberos database" ++msgstr "auf die Kerberos-Datenbank kann nicht zugegriffen werden" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:60 ++msgid "Kerberos database internal error" ++msgstr "interner Kerberos-Datenbankfehler" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:61 ++msgid "Kerberos database constraints violated" ++msgstr "Kerberos-Datenbankbeschränkungen verletzt" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:62 ++msgid "Update log conversion error" ++msgstr "Fehler beim Umwandeln des Aktualisierungsprotokolls" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:63 ++msgid "Update log is unstable" ++msgstr "Aktualisierungsprotokoll ist instabil" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:64 ++msgid "Update log is corrupt" ++msgstr "Aktualisierungsprotokoll ist beschädigt" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:65 ++msgid "Generic update log error" ++msgstr "allgemeiner Aktualisierungsprotokollfehler" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:66 ++msgid "Database module does not match KDC version" ++msgstr "Datenbankmodul passt nicht zur KDC-Version" ++ ++#: ../lib/krb5/error_tables/kdb5_err.c:68 ++msgid "Too much string mapping data" ++msgstr "zu viele zeichenkettenabbildenden Daten" ++ ++#: ../lib/krb5/error_tables/asn1_err.c:23 ++msgid "ASN.1 failed call to system time library" ++msgstr "ASN.1 beim Aufruf der Systemzeitbibliothek gescheitert" ++ ++#: ../lib/krb5/error_tables/asn1_err.c:24 ++msgid "ASN.1 structure is missing a required field" ++msgstr "ein erforderliches Feld fehlt in der ASN.1-Struktur" ++ ++#: ../lib/krb5/error_tables/asn1_err.c:25 ++msgid "ASN.1 unexpected field number" ++msgstr "ASN.1 unerwartete Feldnummer" ++ ++#: ../lib/krb5/error_tables/asn1_err.c:26 ++msgid "ASN.1 type numbers are inconsistent" ++msgstr "ASN.1-Typnummern sind inkonsistent" ++ ++#: ../lib/krb5/error_tables/asn1_err.c:27 ++msgid "ASN.1 value too large" ++msgstr "ASN.1-Wert zu groß" ++ ++#: ../lib/krb5/error_tables/asn1_err.c:28 ++msgid "ASN.1 encoding ended unexpectedly" ++msgstr "ASN.1-Kodierung endete unerwartet" ++ ++#: ../lib/krb5/error_tables/asn1_err.c:29 ++msgid "ASN.1 identifier doesn't match expected value" ++msgstr "ASN.1-Bezeichner passt nicht zum erwarteten Wert" ++ ++#: ../lib/krb5/error_tables/asn1_err.c:30 ++msgid "ASN.1 length doesn't match expected value" ++msgstr "Länge von ASN.1 passt nicht zum erwarteten Wert" ++ ++#: ../lib/krb5/error_tables/asn1_err.c:31 ++msgid "ASN.1 badly-formatted encoding" ++msgstr "fehlerhaft formatierte ASN.1-Kodierung" ++ ++#: ../lib/krb5/error_tables/asn1_err.c:32 ++msgid "ASN.1 parse error" ++msgstr "ASN.1-Auswertungsfehler" ++ ++#: ../lib/krb5/error_tables/asn1_err.c:33 ++msgid "ASN.1 bad return from gmtime" ++msgstr "ASN.1 falscher Rückgabewert von Gmtime" ++ ++#: ../lib/krb5/error_tables/asn1_err.c:34 ++msgid "ASN.1 non-constructed indefinite encoding" ++msgstr "nicht konstruierte unbestimmte ASN.1-Kodierung" ++ ++#: ../lib/krb5/error_tables/asn1_err.c:35 ++msgid "ASN.1 missing expected EOC" ++msgstr "ASN.1 fehlt erwartetes EOC" ++ ++#: ../lib/krb5/error_tables/asn1_err.c:36 ++msgid "ASN.1 object omitted in sequence" ++msgstr "ASN.1-Objekt in Sequenz ausgelassen" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:23 ++msgid "Kerberos V5 magic number table" ++msgstr "Tabelle magischer Zahlen von Kerberos V5" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:24 ++msgid "Bad magic number for krb5_principal structure" ++msgstr "falsche magische Zahl für Krb5_principal-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:25 ++msgid "Bad magic number for krb5_data structure" ++msgstr "falsche magische Zahl für Krb5_data-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:26 ++msgid "Bad magic number for krb5_keyblock structure" ++msgstr "falsche magische Zahl für Krb5_krb5_keyblock-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:27 ++msgid "Bad magic number for krb5_checksum structure" ++msgstr "falsche magische Zahl für Krb5_krb5_checksum-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:28 ++msgid "Bad magic number for krb5_encrypt_block structure" ++msgstr "falsche magische Zahl für Krb5_encrypt_bloc-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:29 ++msgid "Bad magic number for krb5_enc_data structure" ++msgstr "falsche magische Zahl für Krb5_enc_data-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:30 ++msgid "Bad magic number for krb5_cryptosystem_entry structure" ++msgstr "falsche magische Zahl für Krb5_cryptosystem_entry-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:31 ++msgid "Bad magic number for krb5_cs_table_entry structure" ++msgstr "falsche magische Zahl für Krb5_cs_table_entry-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:32 ++msgid "Bad magic number for krb5_checksum_entry structure" ++msgstr "falsche magische Zahl für Krb5_checksum_entry-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:33 ++msgid "Bad magic number for krb5_authdata structure" ++msgstr "falsche magische Zahl für Krb5_authdata-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:34 ++msgid "Bad magic number for krb5_transited structure" ++msgstr "falsche magische Zahl für Krb5_transited-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:35 ++msgid "Bad magic number for krb5_enc_tkt_part structure" ++msgstr "falsche magische Zahl für Krb5_enc_tkt_part-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:36 ++msgid "Bad magic number for krb5_ticket structure" ++msgstr "falsche magische Zahl für Krb5_ticket-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:37 ++msgid "Bad magic number for krb5_authenticator structure" ++msgstr "falsche magische Zahl für Krb5_authenticator-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:38 ++msgid "Bad magic number for krb5_tkt_authent structure" ++msgstr "falsche magische Zahl für Krb5_tkt_authent-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:39 ++msgid "Bad magic number for krb5_creds structure" ++msgstr "falsche magische Zahl für Krb5_creds-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:40 ++msgid "Bad magic number for krb5_last_req_entry structure" ++msgstr "falsche magische Zahl für Krb5_last_req_entry-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:41 ++msgid "Bad magic number for krb5_pa_data structure" ++msgstr "falsche magische Zahl für Krb5_pa_data-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:42 ++msgid "Bad magic number for krb5_kdc_req structure" ++msgstr "falsche magische Zahl für Krb5_kdc_req-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:43 ++msgid "Bad magic number for krb5_enc_kdc_rep_part structure" ++msgstr "falsche magische Zahl für Krb5_enc_kdc_rep_part-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:44 ++msgid "Bad magic number for krb5_kdc_rep structure" ++msgstr "falsche magische Zahl für Krb5_kdc_rep-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:45 ++msgid "Bad magic number for krb5_error structure" ++msgstr "falsche magische Zahl für Krb5_error-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:46 ++msgid "Bad magic number for krb5_ap_req structure" ++msgstr "falsche magische Zahl für Krb5_ap_req-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:47 ++msgid "Bad magic number for krb5_ap_rep structure" ++msgstr "falsche magische Zahl für Krb5_ap_rep-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:48 ++msgid "Bad magic number for krb5_ap_rep_enc_part structure" ++msgstr "falsche magische Zahl für Krb5_ap_rep_enc_part-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:49 ++msgid "Bad magic number for krb5_response structure" ++msgstr "falsche magische Zahl für Krb5_response-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:50 ++msgid "Bad magic number for krb5_safe structure" ++msgstr "falsche magische Zahl für Krb5_safe-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:51 ++msgid "Bad magic number for krb5_priv structure" ++msgstr "falsche magische Zahl für Krb5_priv-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:52 ++msgid "Bad magic number for krb5_priv_enc_part structure" ++msgstr "falsche magische Zahl für Krb5_priv_enc_part-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:53 ++msgid "Bad magic number for krb5_cred structure" ++msgstr "falsche magische Zahl für Krb5_cred-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:54 ++msgid "Bad magic number for krb5_cred_info structure" ++msgstr "falsche magische Zahl für Krb5_cred_info-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:55 ++msgid "Bad magic number for krb5_cred_enc_part structure" ++msgstr "falsche magische Zahl für Krb5_cred_enc_part-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:56 ++msgid "Bad magic number for krb5_pwd_data structure" ++msgstr "falsche magische Zahl für Krb5_pwd_data-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:57 ++msgid "Bad magic number for krb5_address structure" ++msgstr "falsche magische Zahl für Krb5_address-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:58 ++msgid "Bad magic number for krb5_keytab_entry structure" ++msgstr "falsche magische Zahl für Krb5_keytab_entry-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:59 ++msgid "Bad magic number for krb5_context structure" ++msgstr "falsche magische Zahl für Krb5_context-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:60 ++msgid "Bad magic number for krb5_os_context structure" ++msgstr "falsche magische Zahl für Krb5_os_context-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:61 ++msgid "Bad magic number for krb5_alt_method structure" ++msgstr "falsche magische Zahl für Krb5_alt_method-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:62 ++msgid "Bad magic number for krb5_etype_info_entry structure" ++msgstr "falsche magische Zahl für Krb5_etype_info_entry-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:63 ++msgid "Bad magic number for krb5_db_context structure" ++msgstr "falsche magische Zahl für Krb5_db_context-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:64 ++msgid "Bad magic number for krb5_auth_context structure" ++msgstr "falsche magische Zahl für Krb5_auth_context-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:65 ++msgid "Bad magic number for krb5_keytab structure" ++msgstr "falsche magische Zahl für Krb5_keytab-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:66 ++msgid "Bad magic number for krb5_rcache structure" ++msgstr "falsche magische Zahl für Krb5_rcache-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:67 ++msgid "Bad magic number for krb5_ccache structure" ++msgstr "falsche magische Zahl für Krb5_ccache-Struktur" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:68 ++msgid "Bad magic number for krb5_preauth_ops" ++msgstr "falsche magische Zahl für Krb5_preauth_ops" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:69 ++msgid "Bad magic number for krb5_sam_challenge" ++msgstr "falsche magische Zahl für Krb5_sam_challenge" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:70 ++msgid "Bad magic number for krb5_sam_challenge_2" ++msgstr "falsche magische Zahl für Krb5_sam_challenge_2" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:71 ++msgid "Bad magic number for krb5_sam_key" ++msgstr "falsche magische Zahl für Krb5_sam_key" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:72 ++#: ../lib/krb5/error_tables/kv5m_err.c:73 ++msgid "Bad magic number for krb5_enc_sam_response_enc" ++msgstr "falsche magische Zahl für Krb5_enc_sam_response_enc" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:74 ++msgid "Bad magic number for krb5_sam_response" ++msgstr "falsche magische Zahl für Krb5_sam_response" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:75 ++msgid "Bad magic number for krb5_sam_response 2" ++msgstr "falsche magische Zahl für Krb5_sam_response 2" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:76 ++msgid "Bad magic number for krb5_predicted_sam_response" ++msgstr "falsche magische Zahl für Krb5_predicted_sam_response" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:77 ++msgid "Bad magic number for passwd_phrase_element" ++msgstr "falsche magische Zahl für Passwd_phrase_element" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:78 ++msgid "Bad magic number for GSSAPI OID" ++msgstr "falsche magische Zahl für GSSAPI OID" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:79 ++msgid "Bad magic number for GSSAPI QUEUE" ++msgstr "falsche magische Zahl für GSSAPI QUEUE" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:80 ++msgid "Bad magic number for fast armored request" ++msgstr "falsche magische Zahl für per FAST geschützte Anfrage" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:81 ++msgid "Bad magic number for FAST request" ++msgstr "falsche magische Zahl für FAST-Anfrage" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:82 ++msgid "Bad magic number for FAST response" ++msgstr "falsche magische Zahl für FAST-Antwort" ++ ++#: ../lib/krb5/error_tables/kv5m_err.c:83 ++msgid "Bad magic number for krb5_authdata_context" ++msgstr "falsche magische Zahl für Krb5_authdata_context" ++ ++#: ../lib/krb5/error_tables/krb524_err.c:23 ++msgid "Cannot convert V5 keyblock" ++msgstr "V5-Schlüsselblock kann nicht umgewandelt werden" ++ ++#: ../lib/krb5/error_tables/krb524_err.c:24 ++msgid "Cannot convert V5 address information" ++msgstr "V5-Adressinformationen können nicht umgewandelt werden" ++ ++#: ../lib/krb5/error_tables/krb524_err.c:25 ++msgid "Cannot convert V5 principal" ++msgstr "V5-Principal kann nicht umgewandelt werden" ++ ++#: ../lib/krb5/error_tables/krb524_err.c:26 ++msgid "V5 realm name longer than V4 maximum" ++msgstr "V5-Realm-Name ist länger als die V4-Maximallänge" ++ ++#: ../lib/krb5/error_tables/krb524_err.c:27 ++msgid "Kerberos V4 error" ++msgstr "Kerberos-V4-Fehler" ++ ++#: ../lib/krb5/error_tables/krb524_err.c:28 ++msgid "Encoding too large" ++msgstr "Kodierung zu lang" ++ ++#: ../lib/krb5/error_tables/krb524_err.c:29 ++msgid "Decoding out of data" ++msgstr "Dekodieren außerhalb der Daten" ++ ++#: ../lib/krb5/error_tables/krb524_err.c:30 ++msgid "Service not responding" ++msgstr "Dienst antwortet nicht" ++ ++#: ../lib/krb5/error_tables/krb524_err.c:31 ++msgid "Kerberos version 4 support is disabled" ++msgstr "Kerberos 4 Unterstützung ist deaktiviert" ++ ++#~ msgid "while creating server %s principal name" ++#~ msgstr "beim Erstellen des Principal-Namens für Server %s" ++ ++# KDC = Key Distribution Center ++#~ msgid "while getting credentials from kdc" ++#~ msgstr "beim Holen der Anmeldedaten vom KDC" ++ ++# FIXME s/Retrieving/retrieving/ ++#~ msgid "while Retrieving credentials" ++#~ msgstr "beim Abfragen der Anmeldedaten" ++ ++#~ msgid "while copying principal" ++#~ msgstr "beim Kopieren des Principals" ++ ++#~ msgid "%s does not have correct permissions for %s\n" ++#~ msgstr "%s hat nicht die erforderlichen Zugriffsrechte für %s\n" ++ ++#~ msgid "no salt\n" ++#~ msgstr "kein Salt\n" ++ ++#~ msgid "%s: Couldn't grab lock\n" ++#~ msgstr "%s: Es konnte keine Sperre erlangt werden.\n" ++ ++#~ msgid "%s: Loads disallowed when iprop is enabled and a ulog is present\n" ++#~ msgstr "" ++#~ "%s: Wenn Iprop aktiviert und Ulog vorhanden ist, ist Laden nicht " ++#~ "möglich.\n" ++ ++#~ msgid "trying to lock database" ++#~ msgstr "es wird versucht, die Datenbank zu sperren" ++ ++#~ msgid "GSS-API error %s: %s\n" ++#~ msgstr "GSS-API-Fehler %s: %s\n" ++ ++#~ msgid "Couldn't create KRB5 Name NameType OID\n" ++#~ msgstr "KRB5 Name NameType OID konnte nicht erstellt werden.\n" ++ ++#~ msgid "%s: %s while initializing, aborting" ++#~ msgstr "%s: %s beim Initialisieren, wird abgebrochen" ++ ++#~ msgid "" ++#~ "%s: Missing required configuration values (%lx) while initializing, " ++#~ "aborting" ++#~ msgstr "" ++#~ "%s: Beim Initialisieren fehlen die erforderlichen Konfigurationswerte " ++#~ "(%lx), wird abgebrochen" ++ ++#~ msgid "" ++#~ "%s: Missing required configuration values (%lx) while initializing, " ++#~ "aborting\n" ++#~ msgstr "" ++#~ "%s: Beim Initialisieren fehlen die erforderlichen Konfigurationswerte " ++#~ "(%lx), wird abgebrochen\n" ++ ++#~ msgid "%s: could not initialize loop, aborting" ++#~ msgstr "%s: Schleife konnte nicht initialisiert werden, wird abgebrochen" ++ ++#~ msgid "%s: could not initialize loop, aborting\n" ++#~ msgstr "%s: Schleife konnte nicht initialisiert werden, wird abgebrochen\n" ++ ++#~ msgid "%s: %s while initializing signal handlers, aborting" ++#~ msgstr "" ++#~ "%s: %s beim Initialisieren des Signalbehandlungsprogramms, wird " ++#~ "abgebrochen" ++ ++#~ msgid "%s: %s while initializing signal handlers, aborting\n" ++#~ msgstr "" ++#~ "%s: %s beim Initialisieren des Signalbehandlungsprogramms, wird " ++#~ "abgebrochen\n" ++ ++#~ msgid "%s: %s while initializing network, aborting" ++#~ msgstr "%s: %s beim Initialisieren des Netzwerks, wird abgebrochen" ++ ++#~ msgid "%s: %s while initializing network, aborting\n" ++#~ msgstr "%s: %s beim Initialisieren des Netzwerks, wird abgebrochen\n" ++ ++#~ msgid "Cannot build GSS-API authentication names, failing." ++#~ msgstr "" ++#~ "GSS-API-Authentifizierungsnamen können nicht gebildet werden, " ++#~ "fehlgeschlagen" ++ ++#~ msgid "Can't set kdb keytab's internal context." ++#~ msgstr "" ++#~ "Der interne Kontext von KDBs Schlüsseltabelle kann nicht gesetzt werden." ++ ++#~ msgid "Can't register kdb keytab." ++#~ msgstr "Die KDB-Schlüsseltabelle kann nicht registriert werden." ++ ++#~ msgid "Can't register acceptor keytab." ++#~ msgstr "Die Empfängerschlüsseltabelle kann nicht registriert werden." ++ ++#~ msgid "" ++#~ "Cannot set GSS-API authentication names (keytab not present?), failing." ++#~ msgstr "" ++#~ "GSS-API-Authentifizierungsnamen können nicht gesetzt werden " ++#~ "(Schlüsseltabelle nicht vorhanden?), fehlgeschlagen" ++ ++#~ msgid "Cannot initialize acl file: %s" ++#~ msgstr "ACL-Datei kann nicht initialisiert werden: %s" ++ ++#~ msgid "%s: Cannot initialize acl file: %s\n" ++#~ msgstr "%s: ACL-Datei kann nicht initialisiert werden: %s\n" ++ ++#~ msgid "Cannot detach from tty: %s" ++#~ msgstr "kann nicht vom Terminal gelöst werden: %s" ++ ++#~ msgid "Cannot create PID file %s: %s" ++#~ msgstr "PID-Datei %s kann nicht erstellt werden: %s" ++ ++#~ msgid "%s: %s while mapping update log (`%s.ulog')\n" ++#~ msgstr "%s: %s beim Abbilden des Aktualisierungsprotokolls (»%s.ulog«)\n" ++ ++#~ msgid "%s while mapping update log (`%s.ulog')" ++#~ msgstr "%s beim Abbilden des Aktualisierungsprotokolls (»%s.ulog«)" ++ ++#~ msgid "%s: Cannot create IProp RPC service (PROG=%d, VERS=%d)\n" ++#~ msgstr "" ++#~ "%s: IProp-RPC-Dienst kann nicht erstellt werden (PROG=%d, VERS=%d)\n" ++ ++#~ msgid "Cannot create IProp RPC service (PROG=%d, VERS=%d), failing." ++#~ msgstr "" ++#~ "IProp-RPC-Dienst kann nicht erstellt werden (PROG=%d, VERS=%d), " ++#~ "fehlgeschlagen" ++ ++#~ msgid "%s while getting IProp svc name, failing" ++#~ msgstr "%s beim Holen des IProp-Dienstnamens, fehlgeschlagen" ++ ++#~ msgid "%s: %s while getting IProp svc name, failing\n" ++#~ msgstr "%s: %s beim Holen des IProp-Dienstnamens, fehlgeschlagen\n" ++ ++#~ msgid "Unable to set RPCSEC_GSS service name (`%s'), failing." ++#~ msgstr "" ++#~ "der RPCSEC_GSS-Dienstname (»%s«) kann nicht gesetzt werden, fehlgeschlagen" ++ ++#~ msgid "%s: Unable to set RPCSEC_GSS service name (`%s'), failing.\n" ++#~ msgstr "" ++#~ "%s: der RPCSEC_GSS-Dienstname (»%s«) kann nicht gesetzt werden, " ++#~ "fehlgeschlagen\n" ++ ++#~ msgid "GSS-API authentication error %.*s: recursive failure!" ++#~ msgstr "GSS-API-Authentifizierungsfehler %.*s: rekursiver Fehlschlag!" ++ ++#~ msgid "skipping unrecognized local address family %d" ++#~ msgstr "nicht erkannte lokale Adressfamilie %d wird übersprungen" ++ ++#~ msgid "got routing msg type %d(%s) v%d" ++#~ msgstr "Routing-Meldungstyp %d(%s) v%d erhalten" ++ ++#~ msgid "Could not create temp stash file: %s" ++#~ msgstr "Temporäre Ablagedatei konnte nicht erstellt werden: %s" ++ ++#~ msgid "ulog_sync_header: could not sync to disk" ++#~ msgstr "ulog_sync_header: kann nicht auf Platte sychronisiert werden" ++ ++#~ msgid "%s: attempt to convert non-extended krb5_get_init_creds_opt" ++#~ msgstr "" ++#~ "%s: Es wird versucht, nicht erweiterte »krb5_get_init_creds_opt« " ++#~ "umzuwandeln" ++ ++#~ msgid "krb5_sname_to_principal, while adding entries to the database" ++#~ msgstr "" ++#~ "»krb5_sname_to_principal« beim Hinzufügen von Einträgen zur Datenbank" ++ ++#~ msgid "krb5_copy_principal, while adding entries to the database" ++#~ msgstr "»krb5_copy_principal« beim Hinzufügen von Einträgen zur Datenbank" ++ ++#~ msgid "" ++#~ "Unable to check if SASL EXTERNAL mechanism is supported by LDAP server. " ++#~ "Proceeding anyway ..." ++#~ msgstr "" ++#~ "Es konnte nicht geprüft werden, ob der Mechanismus SASL EXTERNAL vom LDAP-" ++#~ "Server unterstützt wird. Es wird trotzdem fortgesetzt …" ++ ++#~ msgid "" ++#~ "SASL EXTERNAL mechanism not supported by LDAP server. Can't perform " ++#~ "certificate-based bind." ++#~ msgstr "" ++#~ "Der Mechanismus SASL EXTERNAL wird nicht vom LDAP-Server unterstützt. Es " ++#~ "kann keine zertifikatbasierte Verbindung hergestellt werden." ++ ++#~ msgid "Error reading 'ldap_servers' attribute" ++#~ msgstr "Fehler beim Lesen des Attributs »ldap_servers«" ++ ++#~ msgid "Stash file entry corrupt" ++#~ msgstr "Eintrag in der Ablagedatei beschädigt" ++ ++#~ msgid "while setting server principal realm" ++#~ msgstr "beim Setzen des Server-Principal-Realms" ++ ++#~ msgid "while getting initial ticket\n" ++#~ msgstr "beim Holen eines Anfangs-Tickets\n" ++ ++#~ msgid "while destroying ticket cache" ++#~ msgstr "beim Zerstören des Ticket-Zwischenspeichers" ++ ++#~ msgid "while closing default ccache" ++#~ msgstr "beim Schließen des Standard-Ccaches" diff --git a/SOURCES/Add-KDC-policy-pluggable-interface.patch b/SOURCES/Add-KDC-policy-pluggable-interface.patch new file mode 100644 index 0000000..58f6db8 --- /dev/null +++ b/SOURCES/Add-KDC-policy-pluggable-interface.patch @@ -0,0 +1,994 @@ +From 7ed63b6bdeff7b94775432415682051eca479071 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Tue, 27 Jun 2017 17:15:39 -0400 +Subject: [PATCH] Add KDC policy pluggable interface + +Add the header include/krb5/kdcpolicy_plugin.h, defining a pluggable +interface for modules to deny AS and TGS requests and set maximum +ticket lifetimes. This interface replaces the policy.c stub functions. + +Add check_kdcpolicy_as() and check_kdcpolicy_tgs() as entry functions. +Call them after auth indicators and ticket lifetimes have been +determined. + +Add a test module and a test script with basic kdcpolicy tests. Add +plugin interface documentation in doc/plugindev/policy.rst. + +Also authored by Matt Rogers . + +ticket: 8606 (new) +(cherry picked from commit d0969f6a8170344031ef58fd2a161190f1edfb96) +[rharwood@redhat.com: mention but do not use kadm_auth] +--- + doc/plugindev/index.rst | 1 + + doc/plugindev/kdcpolicy.rst | 24 ++ + src/Makefile.in | 1 + + src/configure.in | 1 + + src/include/Makefile.in | 1 + + src/include/k5-int.h | 4 +- + src/include/k5-trace.h | 5 + + src/include/krb5/kdcpolicy_plugin.h | 128 +++++++++ + src/kdc/do_as_req.c | 7 + + src/kdc/do_tgs_req.c | 6 + + src/kdc/kdc_util.c | 7 - + src/kdc/kdc_util.h | 11 - + src/kdc/main.c | 8 + + src/kdc/policy.c | 267 +++++++++++++++--- + src/kdc/policy.h | 19 +- + src/kdc/tgs_policy.c | 6 - + src/lib/krb5/krb/plugin.c | 4 +- + src/plugins/kdcpolicy/test/Makefile.in | 20 ++ + src/plugins/kdcpolicy/test/deps | 0 + src/plugins/kdcpolicy/test/main.c | 111 ++++++++ + .../kdcpolicy/test/policy_test.exports | 1 + + src/tests/Makefile.in | 1 + + src/tests/t_kdcpolicy.py | 57 ++++ + 23 files changed, 616 insertions(+), 74 deletions(-) + create mode 100644 doc/plugindev/kdcpolicy.rst + create mode 100644 src/include/krb5/kdcpolicy_plugin.h + create mode 100644 src/plugins/kdcpolicy/test/Makefile.in + create mode 100644 src/plugins/kdcpolicy/test/deps + create mode 100644 src/plugins/kdcpolicy/test/main.c + create mode 100644 src/plugins/kdcpolicy/test/policy_test.exports + create mode 100644 src/tests/t_kdcpolicy.py + +diff --git a/doc/plugindev/index.rst b/doc/plugindev/index.rst +index 67dbc2790..0a012b82b 100644 +--- a/doc/plugindev/index.rst ++++ b/doc/plugindev/index.rst +@@ -32,5 +32,6 @@ Contents + gssapi.rst + internal.rst + certauth.rst ++ kdcpolicy.rst + + .. TODO: GSSAPI mechanism plugins +diff --git a/doc/plugindev/kdcpolicy.rst b/doc/plugindev/kdcpolicy.rst +new file mode 100644 +index 000000000..74f21f08f +--- /dev/null ++++ b/doc/plugindev/kdcpolicy.rst +@@ -0,0 +1,24 @@ ++.. _kdcpolicy_plugin: ++ ++KDC policy interface (kdcpolicy) ++================================ ++ ++The kdcpolicy interface was first introduced in release 1.16. It ++allows modules to veto otherwise valid AS and TGS requests or restrict ++the lifetime and renew time of the resulting ticket. For a detailed ++description of the kdcpolicy interface, see the header file ++````. ++ ++The optional **check_as** and **check_tgs** functions allow the module ++to perform access control. Additionally, a module can create and ++destroy module data with the **init** and **fini** methods. Module ++data objects last for the lifetime of the KDC process, and are ++provided to all other methods. The data has the type ++krb5_kdcpolicy_moddata, which should be cast to the appropriate ++internal type. ++ ++kdcpolicy modules can optionally inspect principal entries. To do ++this, the module must also include ```` to gain access to the ++principal entry structure definition. As the KDB interface is ++explicitly not as stable as other public interfaces, modules which do ++this may not retain compatibility across releases. +diff --git a/src/Makefile.in b/src/Makefile.in +index ad8565056..e47bddcb1 100644 +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -21,6 +21,7 @@ SUBDIRS=util include lib \ + plugins/kdb/db2 \ + @ldap_plugin_dir@ \ + plugins/kdb/test \ ++ plugins/kdcpolicy/test \ + plugins/preauth/otp \ + plugins/preauth/pkinit \ + plugins/preauth/test \ +diff --git a/src/configure.in b/src/configure.in +index 4ae2c07d5..ee1983043 100644 +--- a/src/configure.in ++++ b/src/configure.in +@@ -1470,6 +1470,7 @@ dnl ccapi ccapi/lib ccapi/lib/unix ccapi/server ccapi/server/unix ccapi/test + plugins/kdb/db2/libdb2/recno + plugins/kdb/db2/libdb2/test + plugins/kdb/test ++ plugins/kdcpolicy/test + plugins/preauth/otp + plugins/preauth/test + plugins/authdata/greet_client +diff --git a/src/include/Makefile.in b/src/include/Makefile.in +index 0239338a1..6a3fa8242 100644 +--- a/src/include/Makefile.in ++++ b/src/include/Makefile.in +@@ -144,6 +144,7 @@ install-headers-unix install: krb5/krb5.h profile.h + $(INSTALL_DATA) $(srcdir)/krb5/ccselect_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)ccselect_plugin.h + $(INSTALL_DATA) $(srcdir)/krb5/clpreauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)clpreauth_plugin.h + $(INSTALL_DATA) $(srcdir)/krb5/hostrealm_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)hostrealm_plugin.h ++ $(INSTALL_DATA) $(srcdir)/krb5/kdcpolicy_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)kdcpolicy_plugin.h + $(INSTALL_DATA) $(srcdir)/krb5/kdcpreauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)kdcpreauth_plugin.h + $(INSTALL_DATA) $(srcdir)/krb5/localauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)localauth_plugin.h + $(INSTALL_DATA) $(srcdir)/krb5/locate_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)locate_plugin.h +diff --git a/src/include/k5-int.h b/src/include/k5-int.h +index ed9c7bf75..39ffb9568 100644 +--- a/src/include/k5-int.h ++++ b/src/include/k5-int.h +@@ -1157,7 +1157,9 @@ struct plugin_interface { + #define PLUGIN_INTERFACE_TLS 8 + #define PLUGIN_INTERFACE_KDCAUTHDATA 9 + #define PLUGIN_INTERFACE_CERTAUTH 10 +-#define PLUGIN_NUM_INTERFACES 11 ++#define PLUGIN_INTERFACE_KADM5_AUTH 11 ++#define PLUGIN_INTERFACE_KDCPOLICY 12 ++#define PLUGIN_NUM_INTERFACES 13 + + /* Retrieve the plugin module of type interface_id and name modname, + * storing the result into module. */ +diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h +index c75e264e0..2885408a2 100644 +--- a/src/include/k5-trace.h ++++ b/src/include/k5-trace.h +@@ -454,4 +454,9 @@ void krb5int_trace(krb5_context context, const char *fmt, ...); + #define TRACE_GET_CRED_VIA_TKT_EXT_RETURN(c, ret) \ + TRACE(c, "Got cred; {kerr}", ret) + ++#define TRACE_KDCPOLICY_VTINIT_FAIL(c, ret) \ ++ TRACE(c, "KDC policy module failed to init vtable: {kerr}", ret) ++#define TRACE_KDCPOLICY_INIT_SKIP(c, name) \ ++ TRACE(c, "kadm5_auth module {str} declined to initialize", name) ++ + #endif /* K5_TRACE_H */ +diff --git a/src/include/krb5/kdcpolicy_plugin.h b/src/include/krb5/kdcpolicy_plugin.h +new file mode 100644 +index 000000000..c7592c5db +--- /dev/null ++++ b/src/include/krb5/kdcpolicy_plugin.h +@@ -0,0 +1,128 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* include/krb5/kdcpolicy_plugin.h - KDC policy plugin interface */ ++/* ++ * Copyright (C) 2017 by Red Hat, Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* ++ * Declarations for kdcpolicy plugin module implementors. ++ * ++ * The kdcpolicy pluggable interface currently has only one supported major ++ * version, which is 1. Major version 1 has a current minor version number of ++ * 1. ++ * ++ * kdcpolicy plugin modules should define a function named ++ * kdcpolicy__initvt, matching the signature: ++ * ++ * krb5_error_code ++ * kdcpolicy_modname_initvt(krb5_context context, int maj_ver, int min_ver, ++ * krb5_plugin_vtable vtable); ++ * ++ * The initvt function should: ++ * ++ * - Check that the supplied maj_ver number is supported by the module, or ++ * return KRB5_PLUGIN_VER_NOTSUPP if it is not. ++ * ++ * - Cast the vtable pointer as appropriate for maj_ver: ++ * maj_ver == 1: Cast to krb5_kdcpolicy_vtable ++ * ++ * - Initialize the methods of the vtable, stopping as appropriate for the ++ * supplied min_ver. Optional methods may be left uninitialized. ++ * ++ * Memory for the vtable is allocated by the caller, not by the module. ++ */ ++ ++#ifndef KRB5_POLICY_PLUGIN_H ++#define KRB5_POLICY_PLUGIN_H ++ ++#include ++ ++/* Abstract module datatype. */ ++typedef struct krb5_kdcpolicy_moddata_st *krb5_kdcpolicy_moddata; ++ ++/* A module can optionally include kdb.h to inspect principal entries when ++ * authorizing requests. */ ++struct _krb5_db_entry_new; ++ ++/* ++ * Optional: Initialize module data. Return 0 on success, ++ * KRB5_PLUGIN_NO_HANDLE if the module is inoperable (due to configuration, for ++ * example), and any other error code to abort KDC startup. Optionally set ++ * *data_out to a module data object to be passed to future calls. ++ */ ++typedef krb5_error_code ++(*krb5_kdcpolicy_init_fn)(krb5_context context, ++ krb5_kdcpolicy_moddata *data_out); ++ ++/* Optional: Clean up module data. */ ++typedef krb5_error_code ++(*krb5_kdcpolicy_fini_fn)(krb5_context context, ++ krb5_kdcpolicy_moddata moddata); ++ ++/* ++ * Optional: return an error code and set status to an appropriate string ++ * literal to deny an AS request; otherwise return 0. lifetime_out, if set, ++ * restricts the ticket lifetime. renew_lifetime_out, if set, restricts the ++ * ticket renewable lifetime. ++ */ ++typedef krb5_error_code ++(*krb5_kdcpolicy_check_as_fn)(krb5_context context, ++ krb5_kdcpolicy_moddata moddata, ++ const krb5_kdc_req *request, ++ const struct _krb5_db_entry_new *client, ++ const struct _krb5_db_entry_new *server, ++ const char *const *auth_indicators, ++ const char **status, krb5_deltat *lifetime_out, ++ krb5_deltat *renew_lifetime_out); ++ ++/* ++ * Optional: return an error code and set status to an appropriate string ++ * literal to deny a TGS request; otherwise return 0. lifetime_out, if set, ++ * restricts the ticket lifetime. renew_lifetime_out, if set, restricts the ++ * ticket renewable lifetime. ++ */ ++typedef krb5_error_code ++(*krb5_kdcpolicy_check_tgs_fn)(krb5_context context, ++ krb5_kdcpolicy_moddata moddata, ++ const krb5_kdc_req *request, ++ const struct _krb5_db_entry_new *server, ++ const krb5_ticket *ticket, ++ const char *const *auth_indicators, ++ const char **status, krb5_deltat *lifetime_out, ++ krb5_deltat *renew_lifetime_out); ++ ++typedef struct krb5_kdcpolicy_vtable_st { ++ const char *name; ++ krb5_kdcpolicy_init_fn init; ++ krb5_kdcpolicy_fini_fn fini; ++ krb5_kdcpolicy_check_as_fn check_as; ++ krb5_kdcpolicy_check_tgs_fn check_tgs; ++} *krb5_kdcpolicy_vtable; ++ ++#endif /* KRB5_POLICY_PLUGIN_H */ +diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c +index 59a39cd30..241b05b40 100644 +--- a/src/kdc/do_as_req.c ++++ b/src/kdc/do_as_req.c +@@ -207,6 +207,13 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode) + + state->ticket_reply.enc_part2 = &state->enc_tkt_reply; + ++ errcode = check_kdcpolicy_as(kdc_context, state->request, state->client, ++ state->server, state->auth_indicators, ++ state->kdc_time, &state->enc_tkt_reply.times, ++ &state->status); ++ if (errcode) ++ goto egress; ++ + /* + * Find the server key + */ +diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c +index aacd2f20d..4c722a4a3 100644 +--- a/src/kdc/do_tgs_req.c ++++ b/src/kdc/do_tgs_req.c +@@ -518,6 +518,12 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt, + kdc_get_ticket_renewtime(kdc_active_realm, request, header_enc_tkt, client, + server, &enc_tkt_reply); + ++ errcode = check_kdcpolicy_tgs(kdc_context, request, server, header_ticket, ++ auth_indicators, kdc_time, ++ &enc_tkt_reply.times, &status); ++ if (errcode) ++ goto cleanup; ++ + /* + * Set authtime to be the same as header or evidence ticket's + */ +diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c +index 778a629e5..8cbdf2c5b 100644 +--- a/src/kdc/kdc_util.c ++++ b/src/kdc/kdc_util.c +@@ -642,7 +642,6 @@ validate_as_request(kdc_realm_t *kdc_active_realm, + krb5_db_entry server, krb5_timestamp kdc_time, + const char **status, krb5_pa_data ***e_data) + { +- int errcode; + krb5_error_code ret; + + /* +@@ -750,12 +749,6 @@ validate_as_request(kdc_realm_t *kdc_active_realm, + if (ret && ret != KRB5_PLUGIN_OP_NOTSUPP) + return errcode_to_protocol(ret); + +- /* Check against local policy. */ +- errcode = against_local_policy_as(request, client, server, +- kdc_time, status, e_data); +- if (errcode) +- return errcode; +- + return 0; + } + +diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h +index 672f94380..dcedfd538 100644 +--- a/src/kdc/kdc_util.h ++++ b/src/kdc/kdc_util.h +@@ -166,17 +166,6 @@ kdc_err(krb5_context call_context, errcode_t code, const char *fmt, ...) + #endif + ; + +-/* policy.c */ +-int +-against_local_policy_as (krb5_kdc_req *, krb5_db_entry, +- krb5_db_entry, krb5_timestamp, +- const char **, krb5_pa_data ***); +- +-int +-against_local_policy_tgs (krb5_kdc_req *, krb5_db_entry, +- krb5_ticket *, const char **, +- krb5_pa_data ***); +- + /* kdc_preauth.c */ + krb5_boolean + enctype_requires_etype_info_2(krb5_enctype enctype); +diff --git a/src/kdc/main.c b/src/kdc/main.c +index a4dffb29a..ccac3a759 100644 +--- a/src/kdc/main.c ++++ b/src/kdc/main.c +@@ -31,6 +31,7 @@ + #include "kdc_util.h" + #include "kdc_audit.h" + #include "extern.h" ++#include "policy.h" + #include "kdc5_err.h" + #include "kdb_kt.h" + #include "net-server.h" +@@ -986,6 +987,12 @@ int main(int argc, char **argv) + + load_preauth_plugins(&shandle, kcontext, ctx); + load_authdata_plugins(kcontext); ++ retval = load_kdcpolicy_plugins(kcontext); ++ if (retval) { ++ kdc_err(kcontext, retval, _("while loading KDC policy plugin")); ++ finish_realms(); ++ return 1; ++ } + + retval = setup_sam(); + if (retval) { +@@ -1068,6 +1075,7 @@ int main(int argc, char **argv) + krb5_klog_syslog(LOG_INFO, _("shutting down")); + unload_preauth_plugins(kcontext); + unload_authdata_plugins(kcontext); ++ unload_kdcpolicy_plugins(kcontext); + unload_audit_modules(kcontext); + krb5_klog_close(kcontext); + finish_realms(); +diff --git a/src/kdc/policy.c b/src/kdc/policy.c +index 6cba4303f..e49644e06 100644 +--- a/src/kdc/policy.c ++++ b/src/kdc/policy.c +@@ -1,67 +1,246 @@ + /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ + /* kdc/policy.c - Policy decision routines for KDC */ + /* +- * Copyright 1990 by the Massachusetts Institute of Technology. ++ * Copyright (C) 2017 by Red Hat, Inc. ++ * All rights reserved. + * +- * Export of this software from the United States of America may +- * require a specific license from the United States Government. +- * It is the responsibility of any person or organization contemplating +- * export to obtain such a license before exporting. ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: + * +- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +- * distribute this software and its documentation for any purpose and +- * without fee is hereby granted, provided that the above copyright +- * notice appear in all copies and that both that copyright notice and +- * this permission notice appear in supporting documentation, and that +- * the name of M.I.T. not be used in advertising or publicity pertaining +- * to distribution of the software without specific, written prior +- * permission. Furthermore if you modify this software you must label +- * your software as modified software and not distribute it in such a +- * fashion that it might be confused with the original M.I.T. software. +- * M.I.T. makes no representations about the suitability of +- * this software for any purpose. It is provided "as is" without express +- * or implied warranty. ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + #include "k5-int.h" + #include "kdc_util.h" + #include "extern.h" ++#include "policy.h" ++#include "adm_proto.h" ++#include ++#include + +-int +-against_local_policy_as(register krb5_kdc_req *request, krb5_db_entry client, +- krb5_db_entry server, krb5_timestamp kdc_time, +- const char **status, krb5_pa_data ***e_data) ++typedef struct kdcpolicy_handle_st { ++ struct krb5_kdcpolicy_vtable_st vt; ++ krb5_kdcpolicy_moddata moddata; ++} *kdcpolicy_handle; ++ ++static kdcpolicy_handle *handles; ++ ++static void ++free_indicators(char **ais) + { +-#if 0 +- /* An AS request must include the addresses field */ +- if (request->addresses == 0) { +- *status = "NO ADDRESS"; +- return KRB5KDC_ERR_POLICY; +- } +-#endif ++ size_t i; + +- return 0; /* not against policy */ ++ if (ais == NULL) ++ return; ++ for (i = 0; ais[i] != NULL; i++) ++ free(ais[i]); ++ free(ais); ++} ++ ++/* Convert inds to a null-terminated list of C strings. */ ++static krb5_error_code ++authind_strings(krb5_data *const *inds, char ***strs_out) ++{ ++ krb5_error_code ret; ++ char **list = NULL; ++ size_t i, count; ++ ++ *strs_out = NULL; ++ ++ for (count = 0; inds != NULL && inds[count] != NULL; count++); ++ list = k5calloc(count + 1, sizeof(*list), &ret); ++ if (list == NULL) ++ goto error; ++ ++ for (i = 0; i < count; i++) { ++ list[i] = k5memdup0(inds[i]->data, inds[i]->length, &ret); ++ if (list[i] == NULL) ++ goto error; ++ } ++ ++ *strs_out = list; ++ return 0; ++ ++error: ++ free_indicators(list); ++ return ret; ++} ++ ++/* Constrain times->endtime to life and times->renew_till to rlife, relative to ++ * now. */ ++static void ++update_ticket_times(krb5_ticket_times *times, krb5_timestamp now, ++ krb5_deltat life, krb5_deltat rlife) ++{ ++ if (life) ++ times->endtime = ts_min(ts_incr(now, life), times->endtime); ++ if (rlife) ++ times->renew_till = ts_min(ts_incr(now, rlife), times->renew_till); ++} ++ ++/* Check an AS request against kdcpolicy modules, updating times with any ++ * module endtime constraints. Set an appropriate status string on error. */ ++krb5_error_code ++check_kdcpolicy_as(krb5_context context, const krb5_kdc_req *request, ++ const krb5_db_entry *client, const krb5_db_entry *server, ++ krb5_data *const *auth_indicators, krb5_timestamp kdc_time, ++ krb5_ticket_times *times, const char **status) ++{ ++ krb5_deltat life, rlife; ++ krb5_error_code ret; ++ kdcpolicy_handle *hp, h; ++ char **ais = NULL; ++ ++ *status = NULL; ++ ++ ret = authind_strings(auth_indicators, &ais); ++ if (ret) ++ goto done; ++ ++ for (hp = handles; *hp != NULL; hp++) { ++ h = *hp; ++ if (h->vt.check_as == NULL) ++ continue; ++ ++ ret = h->vt.check_as(context, h->moddata, request, client, server, ++ (const char **)ais, status, &life, &rlife); ++ if (ret) ++ goto done; ++ ++ update_ticket_times(times, kdc_time, life, rlife); ++ } ++ ++done: ++ free_indicators(ais); ++ return ret; + } + + /* +- * This is where local policy restrictions for the TGS should placed. ++ * Check the TGS request against the local TGS policy. Accepts an ++ * authentication indicator for the module policy decisions. Returns 0 and a ++ * NULL status string on success. + */ + krb5_error_code +-against_local_policy_tgs(register krb5_kdc_req *request, krb5_db_entry server, +- krb5_ticket *ticket, const char **status, +- krb5_pa_data ***e_data) ++check_kdcpolicy_tgs(krb5_context context, const krb5_kdc_req *request, ++ const krb5_db_entry *server, const krb5_ticket *ticket, ++ krb5_data *const *auth_indicators, krb5_timestamp kdc_time, ++ krb5_ticket_times *times, const char **status) + { +-#if 0 +- /* +- * For example, if your site wants to disallow ticket forwarding, +- * you might do something like this: +- */ ++ krb5_deltat life, rlife; ++ krb5_error_code ret; ++ kdcpolicy_handle *hp, h; ++ char **ais = NULL; + +- if (isflagset(request->kdc_options, KDC_OPT_FORWARDED)) { +- *status = "FORWARD POLICY"; +- return KRB5KDC_ERR_POLICY; ++ *status = NULL; ++ ++ ret = authind_strings(auth_indicators, &ais); ++ if (ret) ++ goto done; ++ ++ for (hp = handles; *hp != NULL; hp++) { ++ h = *hp; ++ if (h->vt.check_tgs == NULL) ++ continue; ++ ++ ret = h->vt.check_tgs(context, h->moddata, request, server, ticket, ++ (const char **)ais, status, &life, &rlife); ++ if (ret) ++ goto done; ++ ++ update_ticket_times(times, kdc_time, life, rlife); + } +-#endif + +- return 0; /* not against policy */ ++done: ++ free_indicators(ais); ++ return ret; ++} ++ ++void ++unload_kdcpolicy_plugins(krb5_context context) ++{ ++ kdcpolicy_handle *hp, h; ++ ++ for (hp = handles; *hp != NULL; hp++) { ++ h = *hp; ++ if (h->vt.fini != NULL) ++ h->vt.fini(context, h->moddata); ++ free(h); ++ } ++ free(handles); ++ handles = NULL; ++} ++ ++krb5_error_code ++load_kdcpolicy_plugins(krb5_context context) ++{ ++ krb5_error_code ret; ++ krb5_plugin_initvt_fn *modules = NULL, *mod; ++ kdcpolicy_handle h; ++ size_t count; ++ ++ ret = k5_plugin_load_all(context, PLUGIN_INTERFACE_KDCPOLICY, &modules); ++ if (ret) ++ goto cleanup; ++ ++ for (count = 0; modules[count] != NULL; count++); ++ handles = k5calloc(count + 1, sizeof(*handles), &ret); ++ if (handles == NULL) ++ goto cleanup; ++ ++ count = 0; ++ for (mod = modules; *mod != NULL; mod++) { ++ h = k5calloc(1, sizeof(*h), &ret); ++ if (h == NULL) ++ goto cleanup; ++ ++ ret = (*mod)(context, 1, 1, (krb5_plugin_vtable)&h->vt); ++ if (ret) { /* Version mismatch. */ ++ TRACE_KDCPOLICY_VTINIT_FAIL(context, ret); ++ free(h); ++ continue; ++ } ++ if (h->vt.init != NULL) { ++ ret = h->vt.init(context, &h->moddata); ++ if (ret == KRB5_PLUGIN_NO_HANDLE) { ++ TRACE_KADM5_AUTH_INIT_SKIP(context, h->vt.name); ++ free(h); ++ continue; ++ } ++ if (ret) { ++ kdc_err(context, ret, _("while loading policy module %s"), ++ h->vt.name); ++ free(h); ++ goto cleanup; ++ } ++ } ++ handles[count++] = h; ++ } ++ ++ ret = 0; ++ ++cleanup: ++ if (ret) ++ unload_kdcpolicy_plugins(context); ++ k5_plugin_free_modules(context, modules); ++ return ret; + } +diff --git a/src/kdc/policy.h b/src/kdc/policy.h +index 6b000dc90..2a57b0a01 100644 +--- a/src/kdc/policy.h ++++ b/src/kdc/policy.h +@@ -26,11 +26,22 @@ + #ifndef __KRB5_KDC_POLICY__ + #define __KRB5_KDC_POLICY__ + +-extern int against_postdate_policy (krb5_timestamp); ++krb5_error_code ++load_kdcpolicy_plugins(krb5_context context); + +-extern int against_flag_policy_as (const krb5_kdc_req *); ++void ++unload_kdcpolicy_plugins(krb5_context context); + +-extern int against_flag_policy_tgs (const krb5_kdc_req *, +- const krb5_ticket *); ++krb5_error_code ++check_kdcpolicy_as(krb5_context context, const krb5_kdc_req *request, ++ const krb5_db_entry *client, const krb5_db_entry *server, ++ krb5_data *const *auth_indicators, krb5_timestamp kdc_time, ++ krb5_ticket_times *times, const char **status); ++ ++krb5_error_code ++check_kdcpolicy_tgs(krb5_context context, const krb5_kdc_req *request, ++ const krb5_db_entry *server, const krb5_ticket *ticket, ++ krb5_data *const *auth_indicators, krb5_timestamp kdc_time, ++ krb5_ticket_times *times, const char **status); + + #endif /* __KRB5_KDC_POLICY__ */ +diff --git a/src/kdc/tgs_policy.c b/src/kdc/tgs_policy.c +index d0f25d1b7..33cfbcd81 100644 +--- a/src/kdc/tgs_policy.c ++++ b/src/kdc/tgs_policy.c +@@ -375,11 +375,5 @@ validate_tgs_request(kdc_realm_t *kdc_active_realm, + if (ret && ret != KRB5_PLUGIN_OP_NOTSUPP) + return errcode_to_protocol(ret); + +- /* Check local policy. */ +- errcode = against_local_policy_tgs(request, server, ticket, +- status, e_data); +- if (errcode) +- return errcode; +- + return 0; + } +diff --git a/src/lib/krb5/krb/plugin.c b/src/lib/krb5/krb/plugin.c +index 17dd6bd30..31aaf661d 100644 +--- a/src/lib/krb5/krb/plugin.c ++++ b/src/lib/krb5/krb/plugin.c +@@ -58,7 +58,9 @@ const char *interface_names[] = { + "audit", + "tls", + "kdcauthdata", +- "certauth" ++ "certauth", ++ "kadm5_auth", ++ "kdcpolicy", + }; + + /* Return the context's interface structure for id, or NULL if invalid. */ +diff --git a/src/plugins/kdcpolicy/test/Makefile.in b/src/plugins/kdcpolicy/test/Makefile.in +new file mode 100644 +index 000000000..b81f1a7ce +--- /dev/null ++++ b/src/plugins/kdcpolicy/test/Makefile.in +@@ -0,0 +1,20 @@ ++mydir=plugins$(S)policy$(S)test ++BUILDTOP=$(REL)..$(S)..$(S).. ++ ++LIBBASE=policy_test ++LIBMAJOR=0 ++LIBMINOR=0 ++RELDIR=../plugins/kdcpolicy/test ++SHLIB_EXPDEPS=$(KRB5_BASE_DEPLIBS) ++SHLIB_EXPLIBS=$(KRB5_BASE_LIBS) ++ ++STLIBOBJS=main.o ++ ++SRCS=$(srcdir)/main.c ++ ++all-unix: all-libs ++install-unix: ++clean-unix:: clean-libs clean-libobjs ++ ++@libnover_frag@ ++@libobj_frag@ +diff --git a/src/plugins/kdcpolicy/test/deps b/src/plugins/kdcpolicy/test/deps +new file mode 100644 +index 000000000..e69de29bb +diff --git a/src/plugins/kdcpolicy/test/main.c b/src/plugins/kdcpolicy/test/main.c +new file mode 100644 +index 000000000..eb8fde053 +--- /dev/null ++++ b/src/plugins/kdcpolicy/test/main.c +@@ -0,0 +1,111 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* include/krb5/kdcpolicy_plugin.h - KDC policy plugin interface */ ++/* ++ * Copyright (C) 2017 by Red Hat, Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "k5-int.h" ++#include "kdb.h" ++#include ++ ++static krb5_error_code ++output_from_indicator(const char *const *auth_indicators, ++ krb5_deltat *lifetime_out, ++ krb5_deltat *renew_lifetime_out, ++ const char **status) ++{ ++ if (auth_indicators[0] == NULL) { ++ *status = NULL; ++ return 0; ++ } ++ ++ if (strcmp(auth_indicators[0], "ONE_HOUR") == 0) { ++ *lifetime_out = 3600; ++ *renew_lifetime_out = *lifetime_out * 2; ++ return 0; ++ } else if (strcmp(auth_indicators[0], "SEVEN_HOURS") == 0) { ++ *lifetime_out = 7 * 3600; ++ *renew_lifetime_out = *lifetime_out * 2; ++ return 0; ++ } ++ ++ *status = "LOCAL_POLICY"; ++ return KRB5KDC_ERR_POLICY; ++} ++ ++static krb5_error_code ++test_check_as(krb5_context context, krb5_kdcpolicy_moddata moddata, ++ const krb5_kdc_req *request, const krb5_db_entry *client, ++ const krb5_db_entry *server, const char *const *auth_indicators, ++ const char **status, krb5_deltat *lifetime_out, ++ krb5_deltat *renew_lifetime_out) ++{ ++ if (request->client != NULL && request->client->length >= 1 && ++ data_eq_string(request->client->data[0], "fail")) { ++ *status = "LOCAL_POLICY"; ++ return KRB5KDC_ERR_POLICY; ++ } ++ return output_from_indicator(auth_indicators, lifetime_out, ++ renew_lifetime_out, status); ++} ++ ++static krb5_error_code ++test_check_tgs(krb5_context context, krb5_kdcpolicy_moddata moddata, ++ const krb5_kdc_req *request, const krb5_db_entry *server, ++ const krb5_ticket *ticket, const char *const *auth_indicators, ++ const char **status, krb5_deltat *lifetime_out, ++ krb5_deltat *renew_lifetime_out) ++{ ++ if (request->server != NULL && request->server->length >= 1 && ++ data_eq_string(request->server->data[0], "fail")) { ++ *status = "LOCAL_POLICY"; ++ return KRB5KDC_ERR_POLICY; ++ } ++ return output_from_indicator(auth_indicators, lifetime_out, ++ renew_lifetime_out, status); ++} ++ ++krb5_error_code ++kdcpolicy_test_initvt(krb5_context context, int maj_ver, int min_ver, ++ krb5_plugin_vtable vtable); ++krb5_error_code ++kdcpolicy_test_initvt(krb5_context context, int maj_ver, int min_ver, ++ krb5_plugin_vtable vtable) ++{ ++ krb5_kdcpolicy_vtable vt; ++ ++ if (maj_ver != 1) ++ return KRB5_PLUGIN_VER_NOTSUPP; ++ ++ vt = (krb5_kdcpolicy_vtable)vtable; ++ vt->name = "test"; ++ vt->check_as = test_check_as; ++ vt->check_tgs = test_check_tgs; ++ return 0; ++} +diff --git a/src/plugins/kdcpolicy/test/policy_test.exports b/src/plugins/kdcpolicy/test/policy_test.exports +new file mode 100644 +index 000000000..9682ec74f +--- /dev/null ++++ b/src/plugins/kdcpolicy/test/policy_test.exports +@@ -0,0 +1 @@ ++kdcpolicy_test_initvt +diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in +index 2b3112537..a2093108b 100644 +--- a/src/tests/Makefile.in ++++ b/src/tests/Makefile.in +@@ -169,6 +169,7 @@ check-pytests: localauth plugorder rdreq responder s2p s4u2proxy unlockiter + $(RUNPYTEST) $(srcdir)/t_tabdump.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_certauth.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_y2038.py $(PYTESTFLAGS) ++ $(RUNPYTEST) $(srcdir)/t_kdcpolicy.py $(PYTESTFLAGS) + + clean: + $(RM) adata etinfo forward gcred hist hooks hrealm icred kdbtest +diff --git a/src/tests/t_kdcpolicy.py b/src/tests/t_kdcpolicy.py +new file mode 100644 +index 000000000..6a745b959 +--- /dev/null ++++ b/src/tests/t_kdcpolicy.py +@@ -0,0 +1,57 @@ ++#!/usr/bin/python ++from k5test import * ++from datetime import datetime ++import re ++ ++testpreauth = os.path.join(buildtop, 'plugins', 'preauth', 'test', 'test.so') ++testpolicy = os.path.join(buildtop, 'plugins', 'kdcpolicy', 'test', ++ 'policy_test.so') ++krb5_conf = {'plugins': {'kdcpreauth': {'module': 'test:' + testpreauth}, ++ 'clpreauth': {'module': 'test:' + testpreauth}, ++ 'kdcpolicy': {'module': 'test:' + testpolicy}}} ++kdc_conf = {'realms': {'$realm': {'default_principal_flags': '+preauth', ++ 'max_renewable_life': '1d'}}} ++realm = K5Realm(krb5_conf=krb5_conf, kdc_conf=kdc_conf) ++ ++realm.run([kadminl, 'addprinc', '-pw', password('fail'), 'fail']) ++ ++def verify_time(out, target_time): ++ times = re.findall(r'\d\d/\d\d/\d\d \d\d:\d\d:\d\d', out) ++ times = [datetime.strptime(t, '%m/%d/%y %H:%M:%S') for t in times] ++ while len(times) > 0: ++ starttime = times.pop(0) ++ endtime = times.pop(0) ++ renewtime = times.pop(0) ++ ++ if str(endtime - starttime) != target_time: ++ fail('unexpected lifetime value') ++ if str(renewtime - endtime) != target_time: ++ fail('unexpected renewable value') ++ ++rflags = ['-r', '1d', '-l', '12h'] ++ ++# Test AS+TGS success path. ++realm.kinit(realm.user_princ, password('user'), ++ rflags + ['-X', 'indicators=SEVEN_HOURS']) ++realm.run([kvno, realm.host_princ]) ++realm.run(['./adata', realm.host_princ], expected_msg='+97: [SEVEN_HOURS]') ++out = realm.run([klist, realm.ccache, '-e']) ++verify_time(out, '7:00:00') ++ ++# Test AS+TGS success path with different values. ++realm.kinit(realm.user_princ, password('user'), ++ rflags + ['-X', 'indicators=ONE_HOUR']) ++realm.run([kvno, realm.host_princ]) ++realm.run(['./adata', realm.host_princ], expected_msg='+97: [ONE_HOUR]') ++out = realm.run([klist, realm.ccache, '-e']) ++verify_time(out, '1:00:00') ++ ++# Test TGS failure path (using previous creds). ++realm.run([kvno, 'fail@%s' % realm.realm], expected_code=1, ++ expected_msg='KDC policy rejects request') ++ ++# Test AS failure path. ++realm.kinit('fail@%s' % realm.realm, password('fail'), ++ expected_code=1, expected_msg='KDC policy rejects request') ++ ++success('kdcpolicy tests') diff --git a/SOURCES/Add-PKINIT-UPN-tests-to-t_pkinit.py.patch b/SOURCES/Add-PKINIT-UPN-tests-to-t_pkinit.py.patch new file mode 100644 index 0000000..74af7bd --- /dev/null +++ b/SOURCES/Add-PKINIT-UPN-tests-to-t_pkinit.py.patch @@ -0,0 +1,101 @@ +From aaa3ceb3c9fa8ff206edcd6d66659c5e69e4811d Mon Sep 17 00:00:00 2001 +From: Matt Rogers +Date: Fri, 9 Dec 2016 11:43:27 -0500 +Subject: [PATCH] Add PKINIT UPN tests to t_pkinit.py + +[ghudson@mit.edu: simplify and explain tests; add test for +id-pkinit-san match against canonicalized client principal] + +ticket: 8528 +(cherry picked from commit d520fd3f032121b61b22681838af96ee505fe44d) +--- + src/tests/t_pkinit.py | 57 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 57 insertions(+) + +diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py +index 526473b42..ac4d326b6 100755 +--- a/src/tests/t_pkinit.py ++++ b/src/tests/t_pkinit.py +@@ -23,6 +23,9 @@ privkey_pem = os.path.join(certs, 'privkey.pem') + privkey_enc_pem = os.path.join(certs, 'privkey-enc.pem') + user_p12 = os.path.join(certs, 'user.p12') + user_enc_p12 = os.path.join(certs, 'user-enc.p12') ++user_upn_p12 = os.path.join(certs, 'user-upn.p12') ++user_upn2_p12 = os.path.join(certs, 'user-upn2.p12') ++user_upn3_p12 = os.path.join(certs, 'user-upn3.p12') + path = os.path.join(os.getcwd(), 'testdir', 'tmp-pkinit-certs') + path_enc = os.path.join(os.getcwd(), 'testdir', 'tmp-pkinit-certs-enc') + +@@ -36,6 +39,20 @@ pkinit_kdc_conf = {'realms': {'$realm': { + restrictive_kdc_conf = {'realms': {'$realm': { + 'restrict_anonymous_to_tgt': 'true' }}} + ++testprincs = {'krbtgt/KRBTEST.COM': {'keys': 'aes128-cts'}, ++ 'user': {'keys': 'aes128-cts', 'flags': '+preauth'}, ++ 'user2': {'keys': 'aes128-cts', 'flags': '+preauth'}} ++alias_kdc_conf = {'realms': {'$realm': { ++ 'default_principal_flags': '+preauth', ++ 'pkinit_eku_checking': 'none', ++ 'pkinit_allow_upn': 'true', ++ 'pkinit_identity': 'FILE:%s,%s' % (kdc_pem, privkey_pem), ++ 'database_module': 'test'}}, ++ 'dbmodules': {'test': { ++ 'db_library': 'test', ++ 'alias': {'user@krbtest.com': 'user'}, ++ 'princs': testprincs}}} ++ + file_identity = 'FILE:%s,%s' % (user_pem, privkey_pem) + file_enc_identity = 'FILE:%s,%s' % (user_pem, privkey_enc_pem) + dir_identity = 'DIR:%s' % path +@@ -45,11 +62,51 @@ dir_file_identity = 'FILE:%s,%s' % (os.path.join(path, 'user.crt'), + dir_file_enc_identity = 'FILE:%s,%s' % (os.path.join(path_enc, 'user.crt'), + os.path.join(path_enc, 'user.key')) + p12_identity = 'PKCS12:%s' % user_p12 ++p12_upn_identity = 'PKCS12:%s' % user_upn_p12 ++p12_upn2_identity = 'PKCS12:%s' % user_upn2_p12 ++p12_upn3_identity = 'PKCS12:%s' % user_upn3_p12 + p12_enc_identity = 'PKCS12:%s' % user_enc_p12 + p11_identity = 'PKCS11:soft-pkcs11.so' + p11_token_identity = ('PKCS11:module_name=soft-pkcs11.so:' + 'slotid=1:token=SoftToken (token)') + ++# Start a realm with the test kdb module for the following UPN SAN tests. ++realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=alias_kdc_conf, ++ create_kdb=False) ++realm.start_kdc() ++ ++# Compatibility check: cert contains UPN "user", which matches the ++# request principal user@KRBTEST.COM if parsed as a normal principal. ++realm.kinit(realm.user_princ, ++ flags=['-X', 'X509_user_identity=%s' % p12_upn2_identity]) ++ ++# Compatibility check: cert contains UPN "user@KRBTEST.COM", which matches ++# the request principal user@KRBTEST.COM if parsed as a normal principal. ++realm.kinit(realm.user_princ, ++ flags=['-X', 'X509_user_identity=%s' % p12_upn3_identity]) ++ ++# Cert contains UPN "user@krbtest.com" which is aliased to the request ++# principal. ++realm.kinit(realm.user_princ, ++ flags=['-X', 'X509_user_identity=%s' % p12_upn_identity]) ++ ++# Test an id-pkinit-san match to a post-canonical principal. ++realm.kinit('user@krbtest.com', ++ flags=['-E', '-X', 'X509_user_identity=%s' % p12_identity]) ++ ++# Test a UPN match to a post-canonical principal. (This only works ++# for the cert with the UPN containing just "user", as we don't allow ++# UPN reparsing when comparing to the canonicalized client principal.) ++realm.kinit('user@krbtest.com', ++ flags=['-E', '-X', 'X509_user_identity=%s' % p12_upn2_identity]) ++ ++# Test a mismatch. ++out = realm.run([kinit, '-X', 'X509_user_identity=%s' % p12_upn2_identity, ++ 'user2'], expected_code=1) ++if 'kinit: Client name mismatch while getting initial credentials' not in out: ++ fail('Wrong error for UPN SAN mismatch') ++realm.stop() ++ + realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=pkinit_kdc_conf, + get_creds=False) + diff --git a/SOURCES/Add-PKINIT-test-case-for-generic-client-cert.patch b/SOURCES/Add-PKINIT-test-case-for-generic-client-cert.patch new file mode 100644 index 0000000..7b6928e --- /dev/null +++ b/SOURCES/Add-PKINIT-test-case-for-generic-client-cert.patch @@ -0,0 +1,50 @@ +From 5d072bc7e890e18903a18d22ecda7662db1d603e Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Fri, 25 Aug 2017 12:39:14 -0400 +Subject: [PATCH] Add PKINIT test case for generic client cert + +In t_pkinit.py, add a test case where a client cert with no extensions +is authorized via subject and issuer using a pkinit_cert_match string +attribute. + +ticket: 8562 +(cherry picked from commit 8c5d50888aab554239fd51306e79c5213833c898) +--- + src/tests/t_pkinit.py | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py +index 5a0624de7..22ab81743 100755 +--- a/src/tests/t_pkinit.py ++++ b/src/tests/t_pkinit.py +@@ -26,6 +26,7 @@ user_enc_p12 = os.path.join(certs, 'user-enc.p12') + user_upn_p12 = os.path.join(certs, 'user-upn.p12') + user_upn2_p12 = os.path.join(certs, 'user-upn2.p12') + user_upn3_p12 = os.path.join(certs, 'user-upn3.p12') ++generic_p12 = os.path.join(certs, 'generic.p12') + path = os.path.join(os.getcwd(), 'testdir', 'tmp-pkinit-certs') + path_enc = os.path.join(os.getcwd(), 'testdir', 'tmp-pkinit-certs-enc') + +@@ -65,6 +66,7 @@ p12_identity = 'PKCS12:%s' % user_p12 + p12_upn_identity = 'PKCS12:%s' % user_upn_p12 + p12_upn2_identity = 'PKCS12:%s' % user_upn2_p12 + p12_upn3_identity = 'PKCS12:%s' % user_upn3_p12 ++p12_generic_identity = 'PKCS12:%s' % generic_p12 + p12_enc_identity = 'PKCS12:%s' % user_enc_p12 + p11_identity = 'PKCS11:soft-pkcs11.so' + p11_token_identity = ('PKCS11:module_name=soft-pkcs11.so:' +@@ -342,6 +344,14 @@ realm.kinit(realm.user_princ, + flags=['-X', 'X509_user_identity=%s' % p12_identity], + expected_code=1, expected_msg=msg) + ++# Authorize a client cert with no PKINIT extensions using subject and ++# issuer. (Relies on EKU checking being turned off.) ++rule = '&&CN=user$O=MIT,' ++realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) ++realm.kinit(realm.user_princ, ++ flags=['-X', 'X509_user_identity=%s' % p12_generic_identity]) ++realm.klist(realm.user_princ) ++ + if not have_soft_pkcs11: + skip_rest('PKINIT PKCS11 tests', 'soft-pkcs11.so not found') + diff --git a/SOURCES/Add-a-hash-table-implementation-to-libkrb5support.patch b/SOURCES/Add-a-hash-table-implementation-to-libkrb5support.patch new file mode 100644 index 0000000..9e188fd --- /dev/null +++ b/SOURCES/Add-a-hash-table-implementation-to-libkrb5support.patch @@ -0,0 +1,657 @@ +From 4250a33a40c14325fb6076cded8e88b5a717ed13 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Sat, 4 Aug 2018 20:11:09 -0400 +Subject: [PATCH] Add a hash table implementation to libkrb5support + +(cherry picked from commit 09e814fe47f5ceeb35bee15ced6e346db8a5e81d) +[rharwood@redhat.com: gitignore, no utf16] +--- + src/include/k5-hashtab.h | 79 ++++++ + src/util/support/Makefile.in | 15 +- + src/util/support/deps | 11 + + src/util/support/hashtab.c | 243 ++++++++++++++++++ + src/util/support/libkrb5support-fixed.exports | 5 + + src/util/support/t_hashtab.c | 176 +++++++++++++ + 6 files changed, 526 insertions(+), 3 deletions(-) + create mode 100644 src/include/k5-hashtab.h + create mode 100644 src/util/support/hashtab.c + create mode 100644 src/util/support/t_hashtab.c + +diff --git a/src/include/k5-hashtab.h b/src/include/k5-hashtab.h +new file mode 100644 +index 000000000..dc0ef3613 +--- /dev/null ++++ b/src/include/k5-hashtab.h +@@ -0,0 +1,79 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* include/k5-hash.h - hash table interface definitions */ ++/* ++ * Copyright (C) 2018 by the Massachusetts Institute of Technology. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* ++ * This file contains declarations for a simple hash table using siphash. Some ++ * limitations which might need to be addressed in the future: ++ * ++ * - The table does not manage caller memory. This limitation could be ++ * addressed by adding an optional free callback to k5_hashtab_create(), to ++ * be called by k5_hashtab_free() and k5_hashtab_remove(). ++ * ++ * - There is no way to iterate over a hash table. ++ * ++ * - k5_hashtab_add() does not check for duplicate entries. ++ */ ++ ++#ifndef K5_HASH_H ++#define K5_HASH_H ++ ++#define K5_HASH_SEED_LEN 16 ++ ++struct k5_hashtab; ++ ++/* ++ * Create a new hash table in *ht_out. seed must point to random bytes if keys ++ * might be under the control of an attacker; otherwise it may be NULL. ++ * initial_buckets controls the initial allocation of hash buckets; pass zero ++ * to use a default value. The number of hash buckets will be doubled as the ++ * number of entries increases. Return 0 on success, ENOMEM on failure. ++ */ ++int k5_hashtab_create(const uint8_t seed[K5_HASH_SEED_LEN], ++ size_t initial_buckets, struct k5_hashtab **ht_out); ++ ++/* Release the memory used by a hash table. Keys and values are the caller's ++ * responsibility. */ ++void k5_hashtab_free(struct k5_hashtab *ht); ++ ++/* Add an entry to a hash table. key and val must remain valid until the entry ++ * is removed or the hash table is freed. The caller must avoid duplicates. */ ++int k5_hashtab_add(struct k5_hashtab *ht, const void *key, size_t klen, ++ void *val); ++ ++/* Remove an entry from a hash table by key. Does not free key or the ++ * associated value. Return 1 if the key was found and removed, 0 if not. */ ++int k5_hashtab_remove(struct k5_hashtab *ht, const void *key, size_t klen); ++ ++/* Retrieve a value from a hash table by key. */ ++void *k5_hashtab_get(struct k5_hashtab *ht, const void *key, size_t klen); ++ ++#endif /* K5_HASH_H */ +diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in +index b3576f0b7..12797068f 100644 +--- a/src/util/support/Makefile.in ++++ b/src/util/support/Makefile.in +@@ -83,6 +83,7 @@ STLIBOBJS= \ + base64.o \ + json.o \ + hex.o \ ++ hashtab.o \ + bcmp.o \ + strerror_r.o \ + dir_filenames.o \ +@@ -110,6 +111,7 @@ LIBOBJS= \ + $(OUTPRE)base64.$(OBJEXT) \ + $(OUTPRE)json.$(OBJEXT) \ + $(OUTPRE)hex.$(OBJEXT) \ ++ $(OUTPRE)hashtab.$(OBJEXT) \ + $(OUTPRE)bcmp.$(OBJEXT) \ + $(OUTPRE)strerror_r.$(OBJEXT) \ + $(OUTPRE)dir_filenames.$(OBJEXT) \ +@@ -142,11 +144,13 @@ SRCS=\ + $(srcdir)/t_path.c \ + $(srcdir)/t_json.c \ + $(srcdir)/t_hex.c \ ++ $(srcdir)/t_hashtab.c \ + $(srcdir)/zap.c \ + $(srcdir)/path.c \ + $(srcdir)/base64.c \ + $(srcdir)/json.c \ + $(srcdir)/hex.c \ ++ $(srcdir)/hashtab.c \ + $(srcdir)/bcmp.c \ + $(srcdir)/strerror_r.c \ + $(srcdir)/dir_filenames.c \ +@@ -225,13 +229,17 @@ t_json: $(T_JSON_OBJS) + t_hex: t_hex.o hex.o + $(CC_LINK) -o $@ t_hex.o hex.o + ++t_hashtab: t_hashtab.o ++ $(CC_LINK) -o $@ t_hashtab.o ++ + t_unal: t_unal.o + $(CC_LINK) -o t_unal t_unal.o + + t_utf8: t_utf8.o utf8.o + $(CC_LINK) -o t_utf8 t_utf8.o utf8.o + +-TEST_PROGS= t_k5buf t_path t_path_win t_base64 t_json t_hex t_unal t_utf8 ++TEST_PROGS= t_k5buf t_path t_path_win t_base64 t_json t_hex t_hashtab t_unal \ ++ t_utf8 + + check-unix: $(TEST_PROGS) + ./t_k5buf +@@ -240,14 +248,15 @@ check-unix: $(TEST_PROGS) + ./t_base64 + ./t_json + ./t_hex ++ ./t_hashtab + ./t_unal + ./t_utf8 + + clean: + $(RM) t_k5buf.o t_k5buf t_unal.o t_unal path_win.o path_win + $(RM) t_path_win.o t_path_win t_path.o t_path t_base64.o t_base64 +- $(RM) t_json.o t_json t_hex.o t_hex libkrb5support.exports +- $(RM) t_utf8.o t_utf8 ++ $(RM) t_json.o t_json t_hex.o t_hex t_hashtab.o t_hashtab ++ $(RM) t_utf8.o t_utf8 libkrb5support.exports + + @lib_frag@ + @libobj_frag@ +diff --git a/src/util/support/deps b/src/util/support/deps +index 551843357..d43baea13 100644 +--- a/src/util/support/deps ++++ b/src/util/support/deps +@@ -65,6 +65,10 @@ t_json.so t_json.po $(OUTPRE)t_json.$(OBJEXT): $(top_srcdir)/include/k5-json.h \ + t_hex.so t_hex.po $(OUTPRE)t_hex.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(top_srcdir)/include/k5-hex.h $(top_srcdir)/include/k5-platform.h \ + $(top_srcdir)/include/k5-thread.h t_hex.c ++t_hashtab.so t_hashtab.po $(OUTPRE)t_hashtab.$(OBJEXT): \ ++ $(BUILDTOP)/include/autoconf.h $(top_srcdir)/include/k5-hashtab.h \ ++ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-queue.h \ ++ $(top_srcdir)/include/k5-thread.h hashtab.c t_hashtab.c + zap.so zap.po $(OUTPRE)zap.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ + zap.c +@@ -81,12 +85,19 @@ json.so json.po $(OUTPRE)json.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + hex.so hex.po $(OUTPRE)hex.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(top_srcdir)/include/k5-hex.h $(top_srcdir)/include/k5-platform.h \ + $(top_srcdir)/include/k5-thread.h hex.c ++hashtab.so hashtab.po $(OUTPRE)hashtab.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ ++ $(top_srcdir)/include/k5-hashtab.h $(top_srcdir)/include/k5-platform.h \ ++ $(top_srcdir)/include/k5-queue.h $(top_srcdir)/include/k5-thread.h \ ++ hashtab.c + bcmp.so bcmp.po $(OUTPRE)bcmp.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ + bcmp.c + strerror_r.so strerror_r.po $(OUTPRE)strerror_r.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(top_srcdir)/include/k5-platform.h \ + $(top_srcdir)/include/k5-thread.h strerror_r.c ++dir_filenames.so dir_filenames.po $(OUTPRE)dir_filenames.$(OBJEXT): \ ++ $(BUILDTOP)/include/autoconf.h $(top_srcdir)/include/k5-platform.h \ ++ $(top_srcdir)/include/k5-thread.h dir_filenames.c + t_utf8.so t_utf8.po $(OUTPRE)t_utf8.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ + $(top_srcdir)/include/k5-utf8.h t_utf8.c +diff --git a/src/util/support/hashtab.c b/src/util/support/hashtab.c +new file mode 100644 +index 000000000..e04e491b2 +--- /dev/null ++++ b/src/util/support/hashtab.c +@@ -0,0 +1,243 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* util/support/hash.c - hash table implementation */ ++/* ++ * Copyright (C) 2018 by the Massachusetts Institute of Technology. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "k5-platform.h" ++#include "k5-hashtab.h" ++#include "k5-queue.h" ++ ++struct entry { ++ const void *key; ++ size_t klen; ++ void *val; ++ K5_SLIST_ENTRY(entry) next; ++}; ++ ++struct k5_hashtab { ++ uint64_t k0; ++ uint64_t k1; ++ size_t nbuckets; ++ size_t nentries; ++ K5_SLIST_HEAD(bucket_list, entry) *buckets; ++}; ++ ++/* Return x rotated to the left by r bits. */ ++static inline uint64_t ++rotl64(uint64_t x, int r) ++{ ++ return (x << r) | (x >> (64 - r)); ++} ++ ++static inline void ++sipround(uint64_t *v0, uint64_t *v1, uint64_t *v2, uint64_t *v3) ++{ ++ *v0 += *v1; ++ *v2 += *v3; ++ *v1 = rotl64(*v1, 13) ^ *v0; ++ *v3 = rotl64(*v3, 16) ^ *v2; ++ *v0 = rotl64(*v0, 32); ++ *v2 += *v1; ++ *v0 += *v3; ++ *v1 = rotl64(*v1, 17) ^ *v2; ++ *v3 = rotl64(*v3, 21) ^ *v0; ++ *v2 = rotl64(*v2, 32); ++} ++ ++/* SipHash-2-4 from https://131002.net/siphash/siphash.pdf (Jean-Philippe ++ * Aumasson and Daniel J. Bernstein) */ ++static uint64_t ++siphash24(const uint8_t *data, size_t len, uint64_t k0, uint64_t k1) ++{ ++ uint64_t v0 = k0 ^ 0x736F6D6570736575; ++ uint64_t v1 = k1 ^ 0x646F72616E646F6D; ++ uint64_t v2 = k0 ^ 0x6C7967656E657261; ++ uint64_t v3 = k1 ^ 0x7465646279746573; ++ uint64_t mi; ++ const uint8_t *p, *end = data + (len - len % 8); ++ uint8_t last[8] = { 0 }; ++ ++ /* Process each full 8-byte chunk of data. */ ++ for (p = data; p < end; p += 8) { ++ mi = load_64_le(p); ++ v3 ^= mi; ++ sipround(&v0, &v1, &v2, &v3); ++ sipround(&v0, &v1, &v2, &v3); ++ v0 ^= mi; ++ } ++ ++ /* Process the last 0-7 bytes followed by the length mod 256. */ ++ memcpy(last, end, len % 8); ++ last[7] = len & 0xFF; ++ mi = load_64_le(last); ++ v3 ^= mi; ++ sipround(&v0, &v1, &v2, &v3); ++ sipround(&v0, &v1, &v2, &v3); ++ v0 ^= mi; ++ ++ /* Finalize. */ ++ v2 ^= 0xFF; ++ sipround(&v0, &v1, &v2, &v3); ++ sipround(&v0, &v1, &v2, &v3); ++ sipround(&v0, &v1, &v2, &v3); ++ sipround(&v0, &v1, &v2, &v3); ++ return v0 ^ v1 ^ v2 ^ v3; ++} ++ ++int ++k5_hashtab_create(const uint8_t seed[K5_HASH_SEED_LEN], size_t initial_buckets, ++ struct k5_hashtab **ht_out) ++{ ++ struct k5_hashtab *ht; ++ ++ *ht_out = NULL; ++ ++ ht = malloc(sizeof(*ht)); ++ if (ht == NULL) ++ return ENOMEM; ++ ++ if (seed != NULL) { ++ ht->k0 = load_64_le(seed); ++ ht->k1 = load_64_le(seed + 8); ++ } else { ++ ht->k0 = ht->k1 = 0; ++ } ++ ht->nbuckets = (initial_buckets > 0) ? initial_buckets : 64; ++ ht->nentries = 0; ++ ht->buckets = calloc(ht->nbuckets, sizeof(*ht->buckets)); ++ if (ht->buckets == NULL) { ++ free(ht); ++ return ENOMEM; ++ } ++ ++ *ht_out = ht; ++ return 0; ++} ++ ++void ++k5_hashtab_free(struct k5_hashtab *ht) ++{ ++ size_t i; ++ struct entry *ent; ++ ++ for (i = 0; i < ht->nbuckets; i++) { ++ while (!K5_SLIST_EMPTY(&ht->buckets[i])) { ++ ent = K5_SLIST_FIRST(&ht->buckets[i]); ++ K5_SLIST_REMOVE_HEAD(&ht->buckets[i], next); ++ free(ent); ++ } ++ } ++ free(ht->buckets); ++ free(ht); ++} ++ ++static int ++resize_table(struct k5_hashtab *ht) ++{ ++ size_t i, j, newsize = ht->nbuckets * 2; ++ struct bucket_list *newbuckets; ++ struct entry *ent; ++ ++ newbuckets = calloc(newsize, sizeof(*newbuckets)); ++ if (newbuckets == NULL) ++ return ENOMEM; ++ ++ /* Rehash all the entries into the new buckets. */ ++ for (i = 0; i < ht->nbuckets; i++) { ++ while (!K5_SLIST_EMPTY(&ht->buckets[i])) { ++ ent = K5_SLIST_FIRST(&ht->buckets[i]); ++ j = siphash24(ent->key, ent->klen, ht->k0, ht->k1) % newsize; ++ K5_SLIST_REMOVE_HEAD(&ht->buckets[i], next); ++ K5_SLIST_INSERT_HEAD(&newbuckets[j], ent, next); ++ } ++ } ++ ++ free(ht->buckets); ++ ht->buckets = newbuckets; ++ ht->nbuckets = newsize; ++ return 0; ++} ++ ++int ++k5_hashtab_add(struct k5_hashtab *ht, const void *key, size_t klen, void *val) ++{ ++ size_t i; ++ struct entry *ent; ++ ++ if (ht->nentries == ht->nbuckets) { ++ if (resize_table(ht) != 0) ++ return ENOMEM; ++ } ++ ++ ent = malloc(sizeof(*ent)); ++ if (ent == NULL) ++ return ENOMEM; ++ ent->key = key; ++ ent->klen = klen; ++ ent->val = val; ++ ++ i = siphash24(key, klen, ht->k0, ht->k1) % ht->nbuckets; ++ K5_SLIST_INSERT_HEAD(&ht->buckets[i], ent, next); ++ ++ ht->nentries++; ++ return 0; ++} ++ ++int ++k5_hashtab_remove(struct k5_hashtab *ht, const void *key, size_t klen) ++{ ++ size_t i; ++ struct entry *ent; ++ ++ i = siphash24(key, klen, ht->k0, ht->k1) % ht->nbuckets; ++ K5_SLIST_FOREACH(ent, &ht->buckets[i], next) { ++ if (ent->klen == klen && memcmp(ent->key, key, klen) == 0) { ++ K5_SLIST_REMOVE(&ht->buckets[i], ent, entry, next); ++ free(ent); ++ ht->nentries--; ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++void * ++k5_hashtab_get(struct k5_hashtab *ht, const void *key, size_t klen) ++{ ++ size_t i; ++ struct entry *ent; ++ ++ i = siphash24(key, klen, ht->k0, ht->k1) % ht->nbuckets; ++ K5_SLIST_FOREACH(ent, &ht->buckets[i], next) { ++ if (ent->klen == klen && memcmp(ent->key, key, klen) == 0) ++ return ent->val; ++ } ++ return NULL; ++} +diff --git a/src/util/support/libkrb5support-fixed.exports b/src/util/support/libkrb5support-fixed.exports +index 6193d7331..c63c5fbc3 100644 +--- a/src/util/support/libkrb5support-fixed.exports ++++ b/src/util/support/libkrb5support-fixed.exports +@@ -16,6 +16,11 @@ k5_get_error + k5_free_error + k5_clear_error + k5_set_error_info_callout_fn ++k5_hashtab_add ++k5_hashtab_create ++k5_hashtab_free ++k5_hashtab_get ++k5_hashtab_remove + k5_hex_decode + k5_hex_encode + k5_json_array_add +diff --git a/src/util/support/t_hashtab.c b/src/util/support/t_hashtab.c +new file mode 100644 +index 000000000..f51abc4f1 +--- /dev/null ++++ b/src/util/support/t_hashtab.c +@@ -0,0 +1,176 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* util/support/t_hash.c - tests for hash table code */ ++/* ++ * Copyright (C) 2018 by the Massachusetts Institute of Technology. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* hash.c has no linker dependencies, so we can simply include its source code ++ * to test its static functions and look inside its structures. */ ++#include "hashtab.c" ++ ++/* These match the sip64 test vectors in the reference C implementation of ++ * siphash at https://github.com/veorq/SipHash */ ++const uint64_t vectors[64] = { ++ 0x726FDB47DD0E0E31, ++ 0x74F839C593DC67FD, ++ 0x0D6C8009D9A94F5A, ++ 0x85676696D7FB7E2D, ++ 0xCF2794E0277187B7, ++ 0x18765564CD99A68D, ++ 0xCBC9466E58FEE3CE, ++ 0xAB0200F58B01D137, ++ 0x93F5F5799A932462, ++ 0x9E0082DF0BA9E4B0, ++ 0x7A5DBBC594DDB9F3, ++ 0xF4B32F46226BADA7, ++ 0x751E8FBC860EE5FB, ++ 0x14EA5627C0843D90, ++ 0xF723CA908E7AF2EE, ++ 0xA129CA6149BE45E5, ++ 0x3F2ACC7F57C29BDB, ++ 0x699AE9F52CBE4794, ++ 0x4BC1B3F0968DD39C, ++ 0xBB6DC91DA77961BD, ++ 0xBED65CF21AA2EE98, ++ 0xD0F2CBB02E3B67C7, ++ 0x93536795E3A33E88, ++ 0xA80C038CCD5CCEC8, ++ 0xB8AD50C6F649AF94, ++ 0xBCE192DE8A85B8EA, ++ 0x17D835B85BBB15F3, ++ 0x2F2E6163076BCFAD, ++ 0xDE4DAAACA71DC9A5, ++ 0xA6A2506687956571, ++ 0xAD87A3535C49EF28, ++ 0x32D892FAD841C342, ++ 0x7127512F72F27CCE, ++ 0xA7F32346F95978E3, ++ 0x12E0B01ABB051238, ++ 0x15E034D40FA197AE, ++ 0x314DFFBE0815A3B4, ++ 0x027990F029623981, ++ 0xCADCD4E59EF40C4D, ++ 0x9ABFD8766A33735C, ++ 0x0E3EA96B5304A7D0, ++ 0xAD0C42D6FC585992, ++ 0x187306C89BC215A9, ++ 0xD4A60ABCF3792B95, ++ 0xF935451DE4F21DF2, ++ 0xA9538F0419755787, ++ 0xDB9ACDDFF56CA510, ++ 0xD06C98CD5C0975EB, ++ 0xE612A3CB9ECBA951, ++ 0xC766E62CFCADAF96, ++ 0xEE64435A9752FE72, ++ 0xA192D576B245165A, ++ 0x0A8787BF8ECB74B2, ++ 0x81B3E73D20B49B6F, ++ 0x7FA8220BA3B2ECEA, ++ 0x245731C13CA42499, ++ 0xB78DBFAF3A8D83BD, ++ 0xEA1AD565322A1A0B, ++ 0x60E61C23A3795013, ++ 0x6606D7E446282B93, ++ 0x6CA4ECB15C5F91E1, ++ 0x9F626DA15C9625F3, ++ 0xE51B38608EF25F57, ++ 0x958A324CEB064572 ++}; ++ ++static void ++test_siphash() ++{ ++ uint8_t seq[64]; ++ uint64_t k0, k1, hval; ++ size_t i; ++ ++ for (i = 0; i < sizeof(seq); i++) ++ seq[i] = i; ++ k0 = load_64_le(seq); ++ k1 = load_64_le(seq + 8); ++ ++ for (i = 0; i < sizeof(seq); i++) { ++ hval = siphash24(seq, i, k0, k1); ++ assert(hval == vectors[i]); ++ } ++} ++ ++static void ++test_hashtab() ++{ ++ int st; ++ struct k5_hashtab *ht; ++ size_t i; ++ char zeros[100] = { 0 }; ++ ++ st = k5_hashtab_create(NULL, 4, &ht); ++ assert(st == 0 && ht != NULL && ht->nentries == 0); ++ ++ st = k5_hashtab_add(ht, "abc", 3, &st); ++ assert(st == 0 && ht->nentries == 1); ++ assert(k5_hashtab_get(ht, "abc", 3) == &st); ++ assert(k5_hashtab_get(ht, "bcde", 4) == NULL); ++ ++ st = k5_hashtab_add(ht, "bcde", 4, &ht); ++ assert(st == 0 && ht->nentries == 2); ++ assert(k5_hashtab_get(ht, "abc", 3) == &st); ++ assert(k5_hashtab_get(ht, "bcde", 4) == &ht); ++ ++ k5_hashtab_remove(ht, "abc", 3); ++ assert(ht->nentries == 1); ++ assert(k5_hashtab_get(ht, "abc", 3) == NULL); ++ assert(k5_hashtab_get(ht, "bcde", 4) == &ht); ++ ++ k5_hashtab_remove(ht, "bcde", 4); ++ assert(ht->nentries == 0); ++ assert(k5_hashtab_get(ht, "abc", 3) == NULL); ++ assert(k5_hashtab_get(ht, "bcde", 4) == NULL); ++ ++ for (i = 0; i < sizeof(zeros); i++) { ++ st = k5_hashtab_add(ht, zeros, i, zeros + i); ++ assert(st == 0 && ht->nentries == i + 1 && ht->nbuckets >= i + 1); ++ } ++ for (i = 0; i < sizeof(zeros); i++) { ++ assert(k5_hashtab_get(ht, zeros, i) == zeros + i); ++ k5_hashtab_remove(ht, zeros, i); ++ assert(ht->nentries == sizeof(zeros) - i - 1); ++ if (i > 0) ++ assert(k5_hashtab_get(ht, zeros, i - 1) == NULL); ++ } ++ ++ k5_hashtab_free(ht); ++} ++ ++int ++main() ++{ ++ test_siphash(); ++ test_hashtab(); ++ return 0; ++} diff --git a/SOURCES/Add-certauth-pluggable-interface.patch b/SOURCES/Add-certauth-pluggable-interface.patch new file mode 100644 index 0000000..a6f2525 --- /dev/null +++ b/SOURCES/Add-certauth-pluggable-interface.patch @@ -0,0 +1,1146 @@ +From 5a0b9b43a070c273ae4ee39ee460fa759ff9d934 Mon Sep 17 00:00:00 2001 +From: Matt Rogers +Date: Tue, 28 Feb 2017 15:55:24 -0500 +Subject: [PATCH] Add certauth pluggable interface + +Add the header include/krb5/certauth_plugin.h, defining a pluggable +interface to control authorization of PKINIT client certificates. + +Add the "pkinit_san" and "pkinit_eku" builtin certauth modules and +related PKINIT crypto X.509 helper functions. Add authorize_cert() as +the entry function for certauth plugin module checks called in +pkinit_server_verify_padata(). Modify kdcpreauth_moddata to hold the +list of certauth module handles, and load the modules when the PKINIT +kdcpreauth server plugin is initialized. Change +crypto_retrieve_X509_sans() to return ENOENT when no SAN is found. + +Add test modules in plugins/certauth/test. Create t_certauth.py with +basic certauth tests. Add plugin interface documentation in +doc/plugindev/certauth.rst and doc/admin/krb5_conf.rst. + +[ghudson@mit.edu: simplified code, edited docs] + +ticket: 8561 (new) +(cherry picked from commit b619ce84470519bea65470be3263cd85fba94f57) +--- + doc/admin/conf_files/krb5_conf.rst | 21 ++ + doc/plugindev/certauth.rst | 27 ++ + doc/plugindev/index.rst | 1 + + src/Makefile.in | 1 + + src/configure.in | 1 + + src/include/Makefile.in | 1 + + src/include/k5-int.h | 3 +- + src/include/krb5/certauth_plugin.h | 103 ++++++ + src/lib/krb5/krb/plugin.c | 3 +- + src/plugins/certauth/test/Makefile.in | 20 ++ + .../certauth/test/certauth_test.exports | 2 + + src/plugins/certauth/test/deps | 14 + + src/plugins/certauth/test/main.c | 209 +++++++++++ + src/plugins/preauth/pkinit/pkinit_crypto.h | 4 + + .../preauth/pkinit/pkinit_crypto_openssl.c | 30 ++ + src/plugins/preauth/pkinit/pkinit_srv.c | 335 +++++++++++++++--- + src/plugins/preauth/pkinit/pkinit_trace.h | 5 + + src/tests/Makefile.in | 1 + + src/tests/t_certauth.py | 47 +++ + 19 files changed, 786 insertions(+), 42 deletions(-) + create mode 100644 doc/plugindev/certauth.rst + create mode 100644 src/include/krb5/certauth_plugin.h + create mode 100644 src/plugins/certauth/test/Makefile.in + create mode 100644 src/plugins/certauth/test/certauth_test.exports + create mode 100644 src/plugins/certauth/test/deps + create mode 100644 src/plugins/certauth/test/main.c + create mode 100644 src/tests/t_certauth.py + +diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst +index 653aad613..c0e4349c0 100644 +--- a/doc/admin/conf_files/krb5_conf.rst ++++ b/doc/admin/conf_files/krb5_conf.rst +@@ -858,6 +858,27 @@ built-in modules exist for this interface: + This module authorizes a principal to a local account if the + principal name maps to the local account name. + ++.. _certauth: ++ ++certauth interface ++################## ++ ++The certauth section (introduced in release 1.16) controls modules for ++the certificate authorization interface, which determines whether a ++certificate is allowed to preauthenticate a user via PKINIT. The ++following built-in modules exist for this interface: ++ ++**pkinit_san** ++ This module authorizes the certificate if it contains a PKINIT ++ Subject Alternative Name for the requested client principal, or a ++ Microsoft UPN SAN matching the principal if **pkinit_allow_upn** ++ is set to true for the realm. ++ ++**pkinit_eku** ++ This module rejects the certificate if it does not contain an ++ Extended Key Usage attribute consistent with the ++ **pkinit_eku_checking** value for the realm. ++ + + PKINIT options + -------------- +diff --git a/doc/plugindev/certauth.rst b/doc/plugindev/certauth.rst +new file mode 100644 +index 000000000..8a7f7c5eb +--- /dev/null ++++ b/doc/plugindev/certauth.rst +@@ -0,0 +1,27 @@ ++.. _certauth_plugin: ++ ++PKINIT certificate authorization interface (certauth) ++===================================================== ++ ++The certauth interface was first introduced in release 1.16. It ++allows customization of the X.509 certificate attribute requirements ++placed on certificates used by PKINIT enabled clients. For a detailed ++description of the certauth interface, see the header file ++```` ++ ++A certauth module implements the **authorize** method to determine ++whether a client's certificate is authorized to authenticate a client ++principal. **authorize** receives the DER-encoded certificate, the ++requested client principal, and a pointer to the client's ++krb5_db_entry (for modules that link against libkdb5). It returns the ++authorization status and optionally outputs a list of authentication ++indicator strings to be added to the ticket. A module must use its ++own internal or library-provided ASN.1 certificate decoder. ++ ++A module can optionally create and destroy module data with the ++**init** and **fini** methods. Module data objects last for the ++lifetime of the KDC process. ++ ++If a module allocates and returns a list of authentication indicators ++from **authorize**, it must also implement the **free_ind** method ++to free the list. +diff --git a/doc/plugindev/index.rst b/doc/plugindev/index.rst +index 3fb921778..67dbc2790 100644 +--- a/doc/plugindev/index.rst ++++ b/doc/plugindev/index.rst +@@ -31,5 +31,6 @@ Contents + profile.rst + gssapi.rst + internal.rst ++ certauth.rst + + .. TODO: GSSAPI mechanism plugins +diff --git a/src/Makefile.in b/src/Makefile.in +index 2ebf2fb4d..b0249778c 100644 +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -17,6 +17,7 @@ SUBDIRS=util include lib \ + plugins/pwqual/test \ + plugins/authdata/greet_server \ + plugins/authdata/greet_client \ ++ plugins/certauth/test \ + plugins/kdb/db2 \ + @ldap_plugin_dir@ \ + plugins/kdb/test \ +diff --git a/src/configure.in b/src/configure.in +index acf3a458b..24f653f0d 100644 +--- a/src/configure.in ++++ b/src/configure.in +@@ -1451,6 +1451,7 @@ dnl ccapi ccapi/lib ccapi/lib/unix ccapi/server ccapi/server/unix ccapi/test + + kdc slave config-files build-tools man doc include + ++ plugins/certauth/test + plugins/hostrealm/test + plugins/localauth/test + plugins/kadm5_hook/test +diff --git a/src/include/Makefile.in b/src/include/Makefile.in +index f5b921833..0239338a1 100644 +--- a/src/include/Makefile.in ++++ b/src/include/Makefile.in +@@ -140,6 +140,7 @@ install-headers-unix install: krb5/krb5.h profile.h + $(INSTALL_DATA) $(srcdir)/krb5.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5.h + $(INSTALL_DATA) $(srcdir)/kdb.h $(DESTDIR)$(KRB5_INCDIR)$(S)kdb.h + $(INSTALL_DATA) krb5/krb5.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)krb5.h ++ $(INSTALL_DATA) $(srcdir)/krb5/certauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)certauth_plugin.h + $(INSTALL_DATA) $(srcdir)/krb5/ccselect_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)ccselect_plugin.h + $(INSTALL_DATA) $(srcdir)/krb5/clpreauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)clpreauth_plugin.h + $(INSTALL_DATA) $(srcdir)/krb5/hostrealm_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)hostrealm_plugin.h +diff --git a/src/include/k5-int.h b/src/include/k5-int.h +index 173cb0264..cea644d0a 100644 +--- a/src/include/k5-int.h ++++ b/src/include/k5-int.h +@@ -1156,7 +1156,8 @@ struct plugin_interface { + #define PLUGIN_INTERFACE_AUDIT 7 + #define PLUGIN_INTERFACE_TLS 8 + #define PLUGIN_INTERFACE_KDCAUTHDATA 9 +-#define PLUGIN_NUM_INTERFACES 10 ++#define PLUGIN_INTERFACE_CERTAUTH 10 ++#define PLUGIN_NUM_INTERFACES 11 + + /* Retrieve the plugin module of type interface_id and name modname, + * storing the result into module. */ +diff --git a/src/include/krb5/certauth_plugin.h b/src/include/krb5/certauth_plugin.h +new file mode 100644 +index 000000000..f22fc1e84 +--- /dev/null ++++ b/src/include/krb5/certauth_plugin.h +@@ -0,0 +1,103 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* include/krb5/certauth_plugin.h - certauth plugin header. */ ++/* ++ * Copyright (C) 2017 by Red Hat, Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* ++ * Certificate authorization plugin interface. The PKINIT server module uses ++ * this interface to check client certificate attributes after the certificate ++ * signature has been verified. ++ */ ++#ifndef KRB5_CERTAUTH_PLUGIN_H ++#define KRB5_CERTAUTH_PLUGIN_H ++ ++#include ++#include ++ ++/* Abstract module data type. */ ++typedef struct krb5_certauth_moddata_st *krb5_certauth_moddata; ++ ++typedef struct _krb5_db_entry_new krb5_db_entry; ++ ++/* ++ * Optional: Initialize module data. ++ */ ++typedef krb5_error_code ++(*krb5_certauth_init_fn)(krb5_context context, ++ krb5_certauth_moddata *moddata_out); ++ ++/* ++ * Optional: Clean up the module data. ++ */ ++typedef void ++(*krb5_certauth_fini_fn)(krb5_context context, krb5_certauth_moddata moddata); ++ ++/* ++ * Mandatory: ++ * Return 0 if the DER-encoded cert is authorized for PKINIT authentication by ++ * princ; otherwise return one of the following error codes: ++ * - KRB5KDC_ERR_CLIENT_NAME_MISMATCH - incorrect SAN value ++ * - KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE - incorrect EKU ++ * - KRB5KDC_ERR_CERTIFICATE_MISMATCH - other extension error ++ * - KRB5_PLUGIN_NO_HANDLE - the module has no opinion about cert ++ * ++ * - opts is used by built-in modules to receive internal data, and must be ++ * ignored by other modules. ++ * - db_entry receives the client principal database entry, and can be ignored ++ * by modules that do not link with libkdb5. ++ * - *authinds_out optionally returns a null-terminated list of authentication ++ * indicator strings upon KRB5_PLUGIN_NO_HANDLE or accepted authorization. ++ */ ++typedef krb5_error_code ++(*krb5_certauth_authorize_fn)(krb5_context context, ++ krb5_certauth_moddata moddata, ++ const uint8_t *cert, size_t cert_len, ++ krb5_const_principal princ, const void *opts, ++ const krb5_db_entry *db_entry, ++ char ***authinds_out); ++ ++/* ++ * Free indicators allocated by a module. Mandatory if authorize returns ++ * authentication indicators. ++ */ ++typedef void ++(*krb5_certauth_free_indicator_fn)(krb5_context context, ++ krb5_certauth_moddata moddata, ++ char **authinds); ++ ++typedef struct krb5_certauth_vtable_st { ++ char *name; ++ krb5_certauth_init_fn init; ++ krb5_certauth_fini_fn fini; ++ krb5_certauth_authorize_fn authorize; ++ krb5_certauth_free_indicator_fn free_ind; ++} *krb5_certauth_vtable; ++ ++#endif /* KRB5_CERTAUTH_PLUGIN_H */ +diff --git a/src/lib/krb5/krb/plugin.c b/src/lib/krb5/krb/plugin.c +index 7d64b7c7e..17dd6bd30 100644 +--- a/src/lib/krb5/krb/plugin.c ++++ b/src/lib/krb5/krb/plugin.c +@@ -57,7 +57,8 @@ const char *interface_names[] = { + "hostrealm", + "audit", + "tls", +- "kdcauthdata" ++ "kdcauthdata", ++ "certauth" + }; + + /* Return the context's interface structure for id, or NULL if invalid. */ +diff --git a/src/plugins/certauth/test/Makefile.in b/src/plugins/certauth/test/Makefile.in +new file mode 100644 +index 000000000..d3524084c +--- /dev/null ++++ b/src/plugins/certauth/test/Makefile.in +@@ -0,0 +1,20 @@ ++mydir=plugins$(S)certauth$(S)test ++BUILDTOP=$(REL)..$(S)..$(S).. ++ ++LIBBASE=certauth_test ++LIBMAJOR=0 ++LIBMINOR=0 ++RELDIR=../plugins/certauth/test ++SHLIB_EXPDEPS=$(KRB5_BASE_DEPLIBS) ++SHLIB_EXPLIBS=$(KRB5_BASE_LIBS) ++ ++STLIBOBJS=main.o ++ ++SRCS=$(srcdir)/main.c ++ ++all-unix: all-libs ++install-unix: ++clean-unix:: clean-libs clean-libobjs ++ ++@libnover_frag@ ++@libobj_frag@ +diff --git a/src/plugins/certauth/test/certauth_test.exports b/src/plugins/certauth/test/certauth_test.exports +new file mode 100644 +index 000000000..1c8cd24e2 +--- /dev/null ++++ b/src/plugins/certauth/test/certauth_test.exports +@@ -0,0 +1,2 @@ ++certauth_test1_initvt ++certauth_test2_initvt +diff --git a/src/plugins/certauth/test/deps b/src/plugins/certauth/test/deps +new file mode 100644 +index 000000000..2974b3b57 +--- /dev/null ++++ b/src/plugins/certauth/test/deps +@@ -0,0 +1,14 @@ ++# ++# Generated makefile dependencies follow. ++# ++main.so main.po $(OUTPRE)main.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ ++ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ ++ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ ++ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ ++ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ ++ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ ++ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ ++ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ ++ $(top_srcdir)/include/krb5/certauth_plugin.h $(top_srcdir)/include/krb5/plugin.h \ ++ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ ++ main.c +diff --git a/src/plugins/certauth/test/main.c b/src/plugins/certauth/test/main.c +new file mode 100644 +index 000000000..7ef7377fb +--- /dev/null ++++ b/src/plugins/certauth/test/main.c +@@ -0,0 +1,209 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* plugins/certauth/main.c - certauth plugin test modules. */ ++/* ++ * Copyright (C) 2017 by Red Hat, Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include "krb5/certauth_plugin.h" ++ ++struct krb5_certauth_moddata_st { ++ int initialized; ++}; ++ ++/* Test module 1 returns OK with an indicator. */ ++static krb5_error_code ++test1_authorize(krb5_context context, krb5_certauth_moddata moddata, ++ const uint8_t *cert, size_t cert_len, ++ krb5_const_principal princ, const void *opts, ++ const krb5_db_entry *db_entry, char ***authinds_out) ++{ ++ char **ais = NULL; ++ ++ ais = calloc(2, sizeof(*ais)); ++ assert(ais != NULL); ++ ais[0] = strdup("test1"); ++ assert(ais[0] != NULL); ++ *authinds_out = ais; ++ return KRB5_PLUGIN_NO_HANDLE; ++} ++ ++static void ++test_free_ind(krb5_context context, krb5_certauth_moddata moddata, ++ char **authinds) ++{ ++ size_t i; ++ ++ if (authinds == NULL) ++ return; ++ for (i = 0; authinds[i] != NULL; i++) ++ free(authinds[i]); ++ free(authinds); ++} ++ ++/* A basic moddata test. */ ++static krb5_error_code ++test2_init(krb5_context context, krb5_certauth_moddata *moddata_out) ++{ ++ krb5_certauth_moddata mod; ++ ++ mod = calloc(1, sizeof(*mod)); ++ assert(mod != NULL); ++ mod->initialized = 1; ++ *moddata_out = mod; ++ return 0; ++} ++ ++static void ++test2_fini(krb5_context context, krb5_certauth_moddata moddata) ++{ ++ free(moddata); ++} ++ ++/* Return true if cert appears to contain the CN name, based on a search of the ++ * DER encoding. */ ++static krb5_boolean ++has_cn(krb5_context context, const uint8_t *cert, size_t cert_len, ++ const char *name) ++{ ++ krb5_boolean match = FALSE; ++ uint8_t name_len, cntag[5] = "\x06\x03\x55\x04\x03"; ++ const uint8_t *c; ++ struct k5buf buf; ++ size_t c_left; ++ ++ /* Construct a DER search string of the CN AttributeType encoding followed ++ * by a UTF8String encoding containing name as the AttributeValue. */ ++ k5_buf_init_dynamic(&buf); ++ k5_buf_add_len(&buf, cntag, sizeof(cntag)); ++ k5_buf_add(&buf, "\x0C"); ++ assert(strlen(name) < 128); ++ name_len = strlen(name); ++ k5_buf_add_len(&buf, &name_len, 1); ++ k5_buf_add_len(&buf, name, name_len); ++ assert(k5_buf_status(&buf) == 0); ++ ++ /* Check for the CN needle in the certificate haystack. */ ++ c_left = cert_len; ++ c = memchr(cert, *cntag, c_left); ++ while (c != NULL) { ++ c_left = cert_len - (c - cert); ++ if (buf.len > c_left) ++ break; ++ if (memcmp(c, buf.data, buf.len) == 0) { ++ match = TRUE; ++ break; ++ } ++ assert(c_left >= 1); ++ c = memchr(c + 1, *cntag, c_left - 1); ++ } ++ ++ k5_buf_free(&buf); ++ return match; ++} ++ ++/* ++ * Test module 2 returns OK if princ matches the CN part of the subject name, ++ * and returns indicators of the module name and princ. ++ */ ++static krb5_error_code ++test2_authorize(krb5_context context, krb5_certauth_moddata moddata, ++ const uint8_t *cert, size_t cert_len, ++ krb5_const_principal princ, const void *opts, ++ const krb5_db_entry *db_entry, char ***authinds_out) ++{ ++ krb5_error_code ret; ++ char *name = NULL, **ais = NULL; ++ ++ *authinds_out = NULL; ++ ++ assert(moddata != NULL && moddata->initialized); ++ ++ ret = krb5_unparse_name_flags(context, princ, ++ KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name); ++ if (ret) ++ goto cleanup; ++ ++ if (!has_cn(context, cert, cert_len, name)) { ++ ret = KRB5KDC_ERR_CERTIFICATE_MISMATCH; ++ goto cleanup; ++ } ++ ++ /* Create an indicator list with the module name and CN. */ ++ ais = calloc(3, sizeof(*ais)); ++ assert(ais != NULL); ++ ais[0] = strdup("test2"); ++ ais[1] = strdup(name); ++ assert(ais[0] != NULL && ais[1] != NULL); ++ *authinds_out = ais; ++ ++ ais = NULL; ++ ++cleanup: ++ krb5_free_unparsed_name(context, name); ++ return ret; ++} ++ ++krb5_error_code ++certauth_test1_initvt(krb5_context context, int maj_ver, int min_ver, ++ krb5_plugin_vtable vtable); ++krb5_error_code ++certauth_test1_initvt(krb5_context context, int maj_ver, int min_ver, ++ krb5_plugin_vtable vtable) ++{ ++ krb5_certauth_vtable vt; ++ ++ if (maj_ver != 1) ++ return KRB5_PLUGIN_VER_NOTSUPP; ++ vt = (krb5_certauth_vtable)vtable; ++ vt->name = "test1"; ++ vt->authorize = test1_authorize; ++ vt->free_ind = test_free_ind; ++ return 0; ++} ++ ++krb5_error_code ++certauth_test2_initvt(krb5_context context, int maj_ver, int min_ver, ++ krb5_plugin_vtable vtable); ++krb5_error_code ++certauth_test2_initvt(krb5_context context, int maj_ver, int min_ver, ++ krb5_plugin_vtable vtable) ++{ ++ krb5_certauth_vtable vt; ++ ++ if (maj_ver != 1) ++ return KRB5_PLUGIN_VER_NOTSUPP; ++ vt = (krb5_certauth_vtable)vtable; ++ vt->name = "test2"; ++ vt->authorize = test2_authorize; ++ vt->init = test2_init; ++ vt->fini = test2_fini; ++ vt->free_ind = test_free_ind; ++ return 0; ++} +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h +index b483affed..49b96b8ee 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto.h ++++ b/src/plugins/preauth/pkinit/pkinit_crypto.h +@@ -664,4 +664,8 @@ extern const size_t krb5_pkinit_sha512_oid_len; + */ + extern krb5_data const * const supported_kdf_alg_ids[]; + ++krb5_error_code ++crypto_encode_der_cert(krb5_context context, pkinit_req_crypto_context reqctx, ++ uint8_t **der_out, size_t *der_len); ++ + #endif /* _PKINIT_CRYPTO_H */ +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index 8def8c542..a5b010b26 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -2137,6 +2137,7 @@ crypto_retrieve_X509_sans(krb5_context context, + + if (!(ext = X509_get_ext(cert, l)) || !(ialt = X509V3_EXT_d2i(ext))) { + pkiDebug("%s: found no subject alt name extensions\n", __FUNCTION__); ++ retval = ENOENT; + goto cleanup; + } + num_sans = sk_GENERAL_NAME_num(ialt); +@@ -6176,3 +6177,32 @@ crypto_get_deferred_ids(krb5_context context, + ret = (const pkinit_deferred_id *)deferred; + return ret; + } ++ ++/* Return the received certificate as DER-encoded data. */ ++krb5_error_code ++crypto_encode_der_cert(krb5_context context, pkinit_req_crypto_context reqctx, ++ uint8_t **der_out, size_t *der_len) ++{ ++ int len; ++ unsigned char *der, *p; ++ ++ *der_out = NULL; ++ *der_len = 0; ++ ++ if (reqctx->received_cert == NULL) ++ return EINVAL; ++ p = NULL; ++ len = i2d_X509(reqctx->received_cert, NULL); ++ if (len <= 0) ++ return EINVAL; ++ p = der = malloc(len); ++ if (p == NULL) ++ return ENOMEM; ++ if (i2d_X509(reqctx->received_cert, &p) <= 0) { ++ free(p); ++ return EINVAL; ++ } ++ *der_out = der; ++ *der_len = len; ++ return 0; ++} +diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c +index b5638a367..731d14eb8 100644 +--- a/src/plugins/preauth/pkinit/pkinit_srv.c ++++ b/src/plugins/preauth/pkinit/pkinit_srv.c +@@ -31,6 +31,25 @@ + + #include + #include "pkinit.h" ++#include "krb5/certauth_plugin.h" ++ ++/* Aliases used by the built-in certauth modules */ ++struct certauth_req_opts { ++ krb5_kdcpreauth_callbacks cb; ++ krb5_kdcpreauth_rock rock; ++ pkinit_kdc_context plgctx; ++ pkinit_kdc_req_context reqctx; ++}; ++ ++typedef struct certauth_module_handle_st { ++ struct krb5_certauth_vtable_st vt; ++ krb5_certauth_moddata moddata; ++} *certauth_handle; ++ ++struct krb5_kdcpreauth_moddata_st { ++ pkinit_kdc_context *realm_contexts; ++ certauth_handle *certauth_modules; ++}; + + static krb5_error_code + pkinit_init_kdc_req_context(krb5_context, pkinit_kdc_req_context *blob); +@@ -51,6 +70,34 @@ pkinit_find_realm_context(krb5_context context, + krb5_kdcpreauth_moddata moddata, + krb5_principal princ); + ++static void ++free_realm_contexts(krb5_context context, pkinit_kdc_context *realm_contexts) ++{ ++ int i; ++ ++ if (realm_contexts == NULL) ++ return; ++ for (i = 0; realm_contexts[i] != NULL; i++) ++ pkinit_server_plugin_fini_realm(context, realm_contexts[i]); ++ pkiDebug("%s: freeing context at %p\n", __FUNCTION__, realm_contexts); ++ free(realm_contexts); ++} ++ ++static void ++free_certauth_handles(krb5_context context, certauth_handle *list) ++{ ++ int i; ++ ++ if (list == NULL) ++ return; ++ for (i = 0; list[i] != NULL; i++) { ++ if (list[i]->vt.fini != NULL) ++ list[i]->vt.fini(context, list[i]->moddata); ++ free(list[i]); ++ } ++ free(list); ++} ++ + static krb5_error_code + pkinit_create_edata(krb5_context context, + pkinit_plg_crypto_context plg_cryptoctx, +@@ -123,7 +170,7 @@ verify_client_san(krb5_context context, + pkinit_kdc_req_context reqctx, + krb5_kdcpreauth_callbacks cb, + krb5_kdcpreauth_rock rock, +- krb5_principal client, ++ krb5_const_principal client, + int *valid_san) + { + krb5_error_code retval; +@@ -134,12 +181,15 @@ verify_client_san(krb5_context context, + char *client_string = NULL, *san_string; + #endif + ++ *valid_san = 0; + retval = crypto_retrieve_cert_sans(context, plgctx->cryptoctx, + reqctx->cryptoctx, plgctx->idctx, + &princs, + plgctx->opts->allow_upn ? &upns : NULL, + NULL); +- if (retval) { ++ if (retval == ENOENT) { ++ goto out; ++ } else if (retval) { + pkiDebug("%s: error from retrieve_certificate_sans()\n", __FUNCTION__); + retval = KRB5KDC_ERR_CLIENT_NAME_MISMATCH; + goto out; +@@ -273,6 +323,73 @@ out: + return retval; + } + ++ ++/* Run the received, verified certificate through certauth modules, to verify ++ * that it is authorized to authenticate as client. */ ++static krb5_error_code ++authorize_cert(krb5_context context, certauth_handle *certauth_modules, ++ pkinit_kdc_context plgctx, pkinit_kdc_req_context reqctx, ++ krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, ++ krb5_principal client) ++{ ++ krb5_error_code ret; ++ certauth_handle h; ++ struct certauth_req_opts opts; ++ krb5_boolean accepted = FALSE; ++ uint8_t *cert; ++ size_t i, cert_len; ++ void *db_ent = NULL; ++ char **ais = NULL, **ai = NULL; ++ ++ /* Re-encode the received certificate into DER, which is extra work, but ++ * avoids creating an X.509 library dependency in the interface. */ ++ ret = crypto_encode_der_cert(context, reqctx->cryptoctx, &cert, &cert_len); ++ if (ret) ++ goto cleanup; ++ ++ /* Set options for the builtin module. */ ++ opts.plgctx = plgctx; ++ opts.reqctx = reqctx; ++ opts.cb = cb; ++ opts.rock = rock; ++ ++ db_ent = cb->client_entry(context, rock); ++ ++ /* ++ * Check the certificate against each certauth module. For the certificate ++ * to be authorized at least one module must return 0, and no module can an ++ * error code other than KRB5_PLUGIN_NO_HANDLE (pass). Add indicators from ++ * modules that return 0 or pass. ++ */ ++ ret = KRB5_PLUGIN_NO_HANDLE; ++ for (i = 0; certauth_modules != NULL && certauth_modules[i] != NULL; i++) { ++ h = certauth_modules[i]; ++ ret = h->vt.authorize(context, h->moddata, cert, cert_len, client, ++ &opts, db_ent, &ais); ++ if (ret == 0) ++ accepted = TRUE; ++ else if (ret != KRB5_PLUGIN_NO_HANDLE) ++ goto cleanup; ++ ++ if (ais != NULL) { ++ /* Assert authentication indicators from the module. */ ++ for (ai = ais; *ai != NULL; ai++) { ++ ret = cb->add_auth_indicator(context, rock, *ai); ++ if (ret) ++ goto cleanup; ++ } ++ h->vt.free_ind(context, h->moddata, ais); ++ ais = NULL; ++ } ++ } ++ ++ ret = accepted ? 0 : KRB5KDC_ERR_CLIENT_NAME_MISMATCH; ++ ++cleanup: ++ free(cert); ++ return ret; ++} ++ + static void + pkinit_server_verify_padata(krb5_context context, + krb5_data *req_pkt, +@@ -295,7 +412,6 @@ pkinit_server_verify_padata(krb5_context context, + pkinit_kdc_req_context reqctx = NULL; + krb5_checksum cksum = {0, 0, 0, NULL}; + krb5_data *der_req = NULL; +- int valid_eku = 0, valid_san = 0; + krb5_data k5data; + int is_signed = 1; + krb5_pa_data **e_data = NULL; +@@ -388,27 +504,11 @@ pkinit_server_verify_padata(krb5_context context, + goto cleanup; + } + if (is_signed) { +- +- retval = verify_client_san(context, plgctx, reqctx, cb, rock, +- request->client, &valid_san); +- if (retval) +- goto cleanup; +- if (!valid_san) { +- pkiDebug("%s: did not find an acceptable SAN in user " +- "certificate\n", __FUNCTION__); +- retval = KRB5KDC_ERR_CLIENT_NAME_MISMATCH; +- goto cleanup; +- } +- retval = verify_client_eku(context, plgctx, reqctx, &valid_eku); ++ retval = authorize_cert(context, moddata->certauth_modules, plgctx, ++ reqctx, cb, rock, request->client); + if (retval) + goto cleanup; + +- if (!valid_eku) { +- pkiDebug("%s: did not find an acceptable EKU in user " +- "certificate\n", __FUNCTION__); +- retval = KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE; +- goto cleanup; +- } + } else { /* !is_signed */ + if (!krb5_principal_compare(context, request->client, + krb5_anonymous_principal())) { +@@ -1245,11 +1345,15 @@ pkinit_find_realm_context(krb5_context context, + krb5_principal princ) + { + int i; +- pkinit_kdc_context *realm_contexts = (pkinit_kdc_context *)moddata; ++ pkinit_kdc_context *realm_contexts; + + if (moddata == NULL) + return NULL; + ++ realm_contexts = moddata->realm_contexts; ++ if (realm_contexts == NULL) ++ return NULL; ++ + for (i = 0; realm_contexts[i] != NULL; i++) { + pkinit_kdc_context p = realm_contexts[i]; + +@@ -1331,6 +1435,155 @@ errout: + return retval; + } + ++static krb5_error_code ++pkinit_san_authorize(krb5_context context, krb5_certauth_moddata moddata, ++ const uint8_t *cert, size_t cert_len, ++ krb5_const_principal princ, const void *opts, ++ const krb5_db_entry *db_entry, char ***authinds_out) ++{ ++ krb5_error_code ret; ++ int valid_san; ++ const struct certauth_req_opts *req_opts = opts; ++ ++ *authinds_out = NULL; ++ ++ ret = verify_client_san(context, req_opts->plgctx, req_opts->reqctx, ++ req_opts->cb, req_opts->rock, princ, &valid_san); ++ if (ret == ENOENT) ++ return KRB5_PLUGIN_NO_HANDLE; ++ else if (ret) ++ return ret; ++ ++ if (!valid_san) { ++ pkiDebug("%s: did not find an acceptable SAN in user certificate\n", ++ __FUNCTION__); ++ return KRB5KDC_ERR_CLIENT_NAME_MISMATCH; ++ } ++ ++ return 0; ++} ++ ++static krb5_error_code ++pkinit_eku_authorize(krb5_context context, krb5_certauth_moddata moddata, ++ const uint8_t *cert, size_t cert_len, ++ krb5_const_principal princ, const void *opts, ++ const krb5_db_entry *db_entry, char ***authinds_out) ++{ ++ krb5_error_code ret; ++ int valid_eku; ++ const struct certauth_req_opts *req_opts = opts; ++ ++ *authinds_out = NULL; ++ ++ /* Verify the client EKU. */ ++ ret = verify_client_eku(context, req_opts->plgctx, req_opts->reqctx, ++ &valid_eku); ++ if (ret) ++ return ret; ++ ++ if (!valid_eku) { ++ pkiDebug("%s: did not find an acceptable EKU in user certificate\n", ++ __FUNCTION__); ++ return KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE; ++ } ++ ++ return 0; ++} ++ ++static krb5_error_code ++certauth_pkinit_san_initvt(krb5_context context, int maj_ver, int min_ver, ++ krb5_plugin_vtable vtable) ++{ ++ krb5_certauth_vtable vt; ++ ++ if (maj_ver != 1) ++ return KRB5_PLUGIN_VER_NOTSUPP; ++ vt = (krb5_certauth_vtable)vtable; ++ vt->name = "pkinit_san"; ++ vt->authorize = pkinit_san_authorize; ++ return 0; ++} ++ ++static krb5_error_code ++certauth_pkinit_eku_initvt(krb5_context context, int maj_ver, int min_ver, ++ krb5_plugin_vtable vtable) ++{ ++ krb5_certauth_vtable vt; ++ ++ if (maj_ver != 1) ++ return KRB5_PLUGIN_VER_NOTSUPP; ++ vt = (krb5_certauth_vtable)vtable; ++ vt->name = "pkinit_eku"; ++ vt->authorize = pkinit_eku_authorize; ++ return 0; ++} ++ ++static krb5_error_code ++load_certauth_plugins(krb5_context context, certauth_handle **handle_out) ++{ ++ krb5_error_code ret; ++ krb5_plugin_initvt_fn *modules = NULL, *mod; ++ certauth_handle *list = NULL, h; ++ size_t count; ++ ++ /* Register the builtin modules. */ ++ ret = k5_plugin_register(context, PLUGIN_INTERFACE_CERTAUTH, ++ "pkinit_san", certauth_pkinit_san_initvt); ++ if (ret) ++ goto cleanup; ++ ++ ret = k5_plugin_register(context, PLUGIN_INTERFACE_CERTAUTH, ++ "pkinit_eku", certauth_pkinit_eku_initvt); ++ if (ret) ++ goto cleanup; ++ ++ ret = k5_plugin_load_all(context, PLUGIN_INTERFACE_CERTAUTH, &modules); ++ if (ret) ++ goto cleanup; ++ ++ /* Allocate handle list. */ ++ for (count = 0; modules[count]; count++); ++ list = k5calloc(count + 1, sizeof(*list), &ret); ++ if (list == NULL) ++ goto cleanup; ++ ++ /* Initialize each module, ignoring ones that fail. */ ++ count = 0; ++ for (mod = modules; *mod != NULL; mod++) { ++ h = k5calloc(1, sizeof(*h), &ret); ++ if (h == NULL) ++ goto cleanup; ++ ++ ret = (*mod)(context, 1, 1, (krb5_plugin_vtable)&h->vt); ++ if (ret) { ++ TRACE_CERTAUTH_VTINIT_FAIL(context, ret); ++ free(h); ++ continue; ++ } ++ h->moddata = NULL; ++ if (h->vt.init != NULL) { ++ ret = h->vt.init(context, &h->moddata); ++ if (ret) { ++ TRACE_CERTAUTH_INIT_FAIL(context, h->vt.name, ret); ++ free(h); ++ continue; ++ } ++ } ++ list[count++] = h; ++ list[count] = NULL; ++ } ++ list[count] = NULL; ++ ++ ret = 0; ++ *handle_out = list; ++ list = NULL; ++ ++cleanup: ++ k5_plugin_free_modules(context, modules); ++ free_certauth_handles(context, list); ++ return ret; ++} ++ + static int + pkinit_server_plugin_init(krb5_context context, + krb5_kdcpreauth_moddata *moddata_out, +@@ -1338,6 +1591,8 @@ pkinit_server_plugin_init(krb5_context context, + { + krb5_error_code retval = ENOMEM; + pkinit_kdc_context plgctx, *realm_contexts = NULL; ++ certauth_handle *certauth_modules = NULL; ++ krb5_kdcpreauth_moddata moddata; + size_t i, j; + size_t numrealms; + +@@ -1368,16 +1623,22 @@ pkinit_server_plugin_init(krb5_context context, + goto errout; + } + +- *moddata_out = (krb5_kdcpreauth_moddata)realm_contexts; +- retval = 0; +- pkiDebug("%s: returning context at %p\n", __FUNCTION__, realm_contexts); ++ retval = load_certauth_plugins(context, &certauth_modules); ++ if (retval) ++ goto errout; ++ ++ moddata = k5calloc(1, sizeof(*moddata), &retval); ++ if (moddata == NULL) ++ goto errout; ++ moddata->realm_contexts = realm_contexts; ++ moddata->certauth_modules = certauth_modules; ++ *moddata_out = moddata; ++ pkiDebug("%s: returning context at %p\n", __FUNCTION__, moddata); ++ return 0; + + errout: +- if (retval) { +- pkinit_server_plugin_fini(context, +- (krb5_kdcpreauth_moddata)realm_contexts); +- } +- ++ free_realm_contexts(context, realm_contexts); ++ free_certauth_handles(context, certauth_modules); + return retval; + } + +@@ -1405,17 +1666,11 @@ static void + pkinit_server_plugin_fini(krb5_context context, + krb5_kdcpreauth_moddata moddata) + { +- pkinit_kdc_context *realm_contexts = (pkinit_kdc_context *)moddata; +- int i; +- +- if (realm_contexts == NULL) ++ if (moddata == NULL) + return; +- +- for (i = 0; realm_contexts[i] != NULL; i++) { +- pkinit_server_plugin_fini_realm(context, realm_contexts[i]); +- } +- pkiDebug("%s: freeing context at %p\n", __FUNCTION__, realm_contexts); +- free(realm_contexts); ++ free_realm_contexts(context, moddata->realm_contexts); ++ free_certauth_handles(context, moddata->certauth_modules); ++ free(moddata); + } + + static krb5_error_code +diff --git a/src/plugins/preauth/pkinit/pkinit_trace.h b/src/plugins/preauth/pkinit/pkinit_trace.h +index b3f5cbb20..458d0961e 100644 +--- a/src/plugins/preauth/pkinit/pkinit_trace.h ++++ b/src/plugins/preauth/pkinit/pkinit_trace.h +@@ -91,4 +91,9 @@ + #define TRACE_PKINIT_OPENSSL_ERROR(c, msg) \ + TRACE(c, "PKINIT OpenSSL error: {str}", msg) + ++#define TRACE_CERTAUTH_VTINIT_FAIL(c, ret) \ ++ TRACE(c, "certauth module failed to init vtable: {kerr}", ret) ++#define TRACE_CERTAUTH_INIT_FAIL(c, name, ret) \ ++ TRACE(c, "certauth module {str} failed to init: {kerr}", name, ret) ++ + #endif /* PKINIT_TRACE_H */ +diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in +index b55469146..0e93d6b59 100644 +--- a/src/tests/Makefile.in ++++ b/src/tests/Makefile.in +@@ -167,6 +167,7 @@ check-pytests: localauth plugorder rdreq responder s2p s4u2proxy unlockiter + $(RUNPYTEST) $(srcdir)/t_preauth.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_princflags.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_tabdump.py $(PYTESTFLAGS) ++ $(RUNPYTEST) $(srcdir)/t_certauth.py $(PYTESTFLAGS) + + clean: + $(RM) adata etinfo forward gcred hist hooks hrealm icred kdbtest +diff --git a/src/tests/t_certauth.py b/src/tests/t_certauth.py +new file mode 100644 +index 000000000..e64a57b0d +--- /dev/null ++++ b/src/tests/t_certauth.py +@@ -0,0 +1,47 @@ ++#!/usr/bin/python ++from k5test import * ++ ++# Skip this test if pkinit wasn't built. ++if not os.path.exists(os.path.join(plugins, 'preauth', 'pkinit.so')): ++ skip_rest('certauth tests', 'PKINIT module not built') ++ ++certs = os.path.join(srctop, 'tests', 'dejagnu', 'pkinit-certs') ++ca_pem = os.path.join(certs, 'ca.pem') ++kdc_pem = os.path.join(certs, 'kdc.pem') ++privkey_pem = os.path.join(certs, 'privkey.pem') ++user_pem = os.path.join(certs, 'user.pem') ++ ++modpath = os.path.join(buildtop, 'plugins', 'certauth', 'test', ++ 'certauth_test.so') ++pkinit_krb5_conf = {'realms': {'$realm': { ++ 'pkinit_anchors': 'FILE:%s' % ca_pem}}, ++ 'plugins': {'certauth': {'module': ['test1:' + modpath, ++ 'test2:' + modpath], ++ 'enable_only': ['test1', 'test2']}}} ++pkinit_kdc_conf = {'realms': {'$realm': { ++ 'default_principal_flags': '+preauth', ++ 'pkinit_eku_checking': 'none', ++ 'pkinit_identity': 'FILE:%s,%s' % (kdc_pem, privkey_pem), ++ 'pkinit_indicator': ['indpkinit1', 'indpkinit2']}}} ++ ++file_identity = 'FILE:%s,%s' % (user_pem, privkey_pem) ++ ++realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=pkinit_kdc_conf, ++ get_creds=False) ++ ++# Let the test module match user to CN=user, with indicators. ++realm.kinit(realm.user_princ, ++ flags=['-X', 'X509_user_identity=%s' % file_identity]) ++realm.klist(realm.user_princ) ++realm.run([kvno, realm.host_princ]) ++realm.run(['./adata', realm.host_princ], ++ expected_msg='+97: [test1, test2, user, indpkinit1, indpkinit2]') ++ ++# Let the test module mismatch with user2 to CN=user. ++realm.addprinc("user2@KRBTEST.COM") ++out = realm.kinit("user2@KRBTEST.COM", ++ flags=['-X', 'X509_user_identity=%s' % file_identity], ++ expected_code=1, ++ expected_msg='kinit: Certificate mismatch') ++ ++success("certauth tests") diff --git a/SOURCES/Add-k5_dir_filenames-to-libkrb5support.patch b/SOURCES/Add-k5_dir_filenames-to-libkrb5support.patch new file mode 100644 index 0000000..a6c9a83 --- /dev/null +++ b/SOURCES/Add-k5_dir_filenames-to-libkrb5support.patch @@ -0,0 +1,224 @@ +From a3f548a88d0bbf16ccc60843fb72e02e32a765f3 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Tue, 5 Jun 2018 14:01:05 -0400 +Subject: [PATCH] Add k5_dir_filenames() to libkrb5support + +Add a support function to get a list of filenames from a directory in +sorted order. + +(cherry picked from commit 27534121eb39089ff4335d8b465027e9ba783682) +(cherry picked from commit 9010a0dbf59771cb0a9c1e6fd5a18a92a1200ca7) +[rharwood@redhat.com: exports file context doesn't match] +--- + src/include/k5-platform.h | 7 + + src/util/support/Makefile.in | 3 + + src/util/support/dir_filenames.c | 135 ++++++++++++++++++ + src/util/support/libkrb5support-fixed.exports | 2 + + 4 files changed, 147 insertions(+) + create mode 100644 src/util/support/dir_filenames.c + +diff --git a/src/include/k5-platform.h b/src/include/k5-platform.h +index 994f46323..5a58ccba2 100644 +--- a/src/include/k5-platform.h ++++ b/src/include/k5-platform.h +@@ -44,6 +44,8 @@ + * + constant time memory comparison + * + path manipulation + * + _, N_, dgettext, bindtextdomain (for localization) ++ * + getopt_long ++ * + fetching filenames from a directory + */ + + #ifndef K5_PLATFORM_H +@@ -1099,4 +1101,9 @@ extern int k5_getopt_long(int nargc, char **nargv, char *options, + #define getopt_long k5_getopt_long + #endif /* HAVE_GETOPT_LONG */ + ++/* Set *fnames_out to a null-terminated list of filenames within dirname, ++ * sorted according to strcmp(). Return 0 on success, or ENOENT/ENOMEM. */ ++int k5_dir_filenames(const char *dirname, char ***fnames_out); ++void k5_free_filenames(char **fnames); ++ + #endif /* K5_PLATFORM_H */ +diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in +index 17bcd2a67..9326742d7 100644 +--- a/src/util/support/Makefile.in ++++ b/src/util/support/Makefile.in +@@ -84,6 +84,7 @@ STLIBOBJS= \ + json.o \ + bcmp.o \ + strerror_r.o \ ++ dir_filenames.o \ + $(GETTIMEOFDAY_ST_OBJ) \ + $(IPC_ST_OBJ) \ + $(STRLCPY_ST_OBJ) \ +@@ -109,6 +110,7 @@ LIBOBJS= \ + $(OUTPRE)json.$(OBJEXT) \ + $(OUTPRE)bcmp.$(OBJEXT) \ + $(OUTPRE)strerror_r.$(OBJEXT) \ ++ $(OUTPRE)dir_filenames.$(OBJEXT) \ + $(GETTIMEOFDAY_OBJ) \ + $(IPC_OBJ) \ + $(STRLCPY_OBJ) \ +@@ -143,6 +145,7 @@ SRCS=\ + $(srcdir)/json.c \ + $(srcdir)/bcmp.c \ + $(srcdir)/strerror_r.c \ ++ $(srcdir)/dir_filenames.c \ + $(srcdir)/t_utf8.c \ + $(srcdir)/getopt.c \ + $(srcdir)/getopt_long.c +diff --git a/src/util/support/dir_filenames.c b/src/util/support/dir_filenames.c +new file mode 100644 +index 000000000..9312b0238 +--- /dev/null ++++ b/src/util/support/dir_filenames.c +@@ -0,0 +1,135 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* util/support/dir_filenames.c - fetch filenames in a directory */ ++/* ++ * Copyright (C) 2018 by the Massachusetts Institute of Technology. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "k5-platform.h" ++ ++void ++k5_free_filenames(char **fnames) ++{ ++ char **fn; ++ ++ for (fn = fnames; fn != NULL && *fn != NULL; fn++) ++ free(*fn); ++ free(fnames); ++} ++ ++/* Resize the filename list and add a name. */ ++static int ++add_filename(char ***fnames, int *n_fnames, const char *name) ++{ ++ char **newlist; ++ ++ newlist = realloc(*fnames, (*n_fnames + 2) * sizeof(*newlist)); ++ if (newlist == NULL) ++ return ENOMEM; ++ *fnames = newlist; ++ newlist[*n_fnames] = strdup(name); ++ if (newlist[*n_fnames] == NULL) ++ return ENOMEM; ++ (*n_fnames)++; ++ newlist[*n_fnames] = NULL; ++ return 0; ++} ++ ++static int ++compare_with_strcmp(const void *a, const void *b) ++{ ++ return strcmp(*(char **)a, *(char **)b); ++} ++ ++#ifdef _WIN32 ++ ++int ++k5_dir_filenames(const char *dirname, char ***fnames_out) ++{ ++ char *wildcard; ++ WIN32_FIND_DATA ffd; ++ HANDLE handle; ++ char **fnames = NULL; ++ int n_fnames = 0; ++ ++ *fnames_out = NULL; ++ ++ if (asprintf(&wildcard, "%s\\*", dirname) < 0) ++ return ENOMEM; ++ handle = FindFirstFile(wildcard, &ffd); ++ free(wildcard); ++ if (handle == INVALID_HANDLE_VALUE) ++ return ENOENT; ++ ++ do { ++ if (add_filename(&fnames, &n_fnames, &ffd.cFileName) != 0) { ++ k5_free_filenames(fnames); ++ FindClose(handle); ++ return ENOMEM; ++ } ++ } while (FindNextFile(handle, &ffd) != 0); ++ ++ FindClose(handle); ++ qsort(fnames, n_fnames, sizeof(*fnames), compare_with_strcmp); ++ *fnames_out = fnames; ++ return 0; ++} ++ ++#else /* _WIN32 */ ++ ++#include ++ ++int ++k5_dir_filenames(const char *dirname, char ***fnames_out) ++{ ++ DIR *dir; ++ struct dirent *ent; ++ char **fnames = NULL; ++ int n_fnames = 0; ++ ++ *fnames_out = NULL; ++ ++ dir = opendir(dirname); ++ if (dir == NULL) ++ return ENOENT; ++ ++ while ((ent = readdir(dir)) != NULL) { ++ if (add_filename(&fnames, &n_fnames, ent->d_name) != 0) { ++ k5_free_filenames(fnames); ++ closedir(dir); ++ return ENOMEM; ++ } ++ } ++ ++ closedir(dir); ++ qsort(fnames, n_fnames, sizeof(*fnames), compare_with_strcmp); ++ *fnames_out = fnames; ++ return 0; ++} ++ ++#endif /* not _WIN32 */ +diff --git a/src/util/support/libkrb5support-fixed.exports b/src/util/support/libkrb5support-fixed.exports +index d5d4177b7..2cdcddfe0 100644 +--- a/src/util/support/libkrb5support-fixed.exports ++++ b/src/util/support/libkrb5support-fixed.exports +@@ -52,6 +52,8 @@ k5_path_isabs + k5_path_join + k5_path_split + k5_strerror_r ++k5_dir_filenames ++k5_free_filenames + krb5int_key_register + krb5int_key_delete + krb5int_getspecific diff --git a/SOURCES/Add-k5test-expected_msg-expected_trace.patch b/SOURCES/Add-k5test-expected_msg-expected_trace.patch new file mode 100644 index 0000000..0ac868b --- /dev/null +++ b/SOURCES/Add-k5test-expected_msg-expected_trace.patch @@ -0,0 +1,96 @@ +From 6ad27ff3bde8911a6f873269a61924937d45cd8c Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Tue, 17 Jan 2017 11:24:41 -0500 +Subject: [PATCH] Add k5test expected_msg, expected_trace + +In k5test.py, add the optional keyword argument "expected_msg" to +methods that run commands, to make it easier to look for substrings in +the command output. Add the optional keyword "expected_trace" to run +the command with KRB5_TRACE enabled and look for an ordered series of +substrings in the trace output. + +(cherry picked from commit 8bb5fce69a4aa6c3082fa7def66a93974e10e17a) +[rharwood@redhat.com: back out .gitignore] +--- + src/config/post.in | 2 +- + src/util/k5test.py | 37 ++++++++++++++++++++++++++++++++++--- + 2 files changed, 35 insertions(+), 4 deletions(-) + +diff --git a/src/config/post.in b/src/config/post.in +index 77a9bffdf..aecac9d3b 100644 +--- a/src/config/post.in ++++ b/src/config/post.in +@@ -156,7 +156,7 @@ clean: clean-$(WHAT) + + clean-unix:: + $(RM) $(OBJS) $(DEPTARGETS_CLEAN) $(EXTRA_FILES) +- $(RM) et-[ch]-*.et et-[ch]-*.[ch] testlog ++ $(RM) et-[ch]-*.et et-[ch]-*.[ch] testlog testtrace + -$(RM) -r testdir + + clean-windows:: +diff --git a/src/util/k5test.py b/src/util/k5test.py +index c3d026377..4d30baf40 100644 +--- a/src/util/k5test.py ++++ b/src/util/k5test.py +@@ -223,8 +223,11 @@ Scripts may use the following realm methods and attributes: + command-line debugging options. Fail if the command does not return + 0. Log the command output appropriately, and return it as a single + multi-line string. Keyword arguments can contain input='string' to +- send an input string to the command, and expected_code=N to expect a +- return code other than 0. ++ send an input string to the command, expected_code=N to expect a ++ return code other than 0, expected_msg=MSG to expect a substring in ++ the command output, and expected_trace=('a', 'b', ...) to expect an ++ ordered series of line substrings in the command's KRB5_TRACE ++ output. + + * realm.kprop_port(): Returns a port number based on realm.portbase + intended for use by kprop and kpropd. +@@ -647,10 +650,31 @@ def _stop_or_shell(stop, shell, env, ind): + subprocess.call(os.getenv('SHELL'), env=env) + + +-def _run_cmd(args, env, input=None, expected_code=0): ++# Read tracefile and look for the expected strings in successive lines. ++def _check_trace(tracefile, expected): ++ output('*** Trace output for previous command:\n') ++ i = 0 ++ with open(tracefile, 'r') as f: ++ for line in f: ++ output(line) ++ if i < len(expected) and expected[i] in line: ++ i += 1 ++ if i < len(expected): ++ fail('Expected string not found in trace output: ' + expected[i]) ++ ++ ++def _run_cmd(args, env, input=None, expected_code=0, expected_msg=None, ++ expected_trace=None): + global null_input, _cmd_index, _last_cmd, _last_cmd_output, _debug + global _stop_before, _stop_after, _shell_before, _shell_after + ++ if expected_trace is not None: ++ tracefile = 'testtrace' ++ if os.path.exists(tracefile): ++ os.remove(tracefile) ++ env = env.copy() ++ env['KRB5_TRACE'] = tracefile ++ + if (_match_cmdnum(_debug, _cmd_index)): + return _debug_cmd(args, env, input) + +@@ -679,6 +703,13 @@ def _run_cmd(args, env, input=None, expected_code=0): + # Check the return code and return the output. + if code != expected_code: + fail('%s failed with code %d.' % (args[0], code)) ++ ++ if expected_msg is not None and expected_msg not in outdata: ++ fail('Expected string not found in command output: ' + expected_msg) ++ ++ if expected_trace is not None: ++ _check_trace(tracefile, expected_trace) ++ + return outdata + + diff --git a/SOURCES/Add-libkrb5support-hex-functions-and-tests.patch b/SOURCES/Add-libkrb5support-hex-functions-and-tests.patch new file mode 100644 index 0000000..0ab3952 --- /dev/null +++ b/SOURCES/Add-libkrb5support-hex-functions-and-tests.patch @@ -0,0 +1,480 @@ +From 795c3972220e97bf7bb6557a424c9d246132ac84 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Mon, 19 Feb 2018 00:51:44 -0500 +Subject: [PATCH] Add libkrb5support hex functions and tests + +(cherry picked from commit 720dea558da0062d3cea4385327161e62cf09a5e) +[rharwood@redhat.com: gitignore, backport around no utf16] +--- + src/include/k5-hex.h | 53 ++++++ + src/util/support/Makefile.in | 13 +- + src/util/support/deps | 6 + + src/util/support/hex.c | 116 ++++++++++++ + src/util/support/libkrb5support-fixed.exports | 2 + + src/util/support/t_hex.c | 169 ++++++++++++++++++ + 6 files changed, 357 insertions(+), 2 deletions(-) + create mode 100644 src/include/k5-hex.h + create mode 100644 src/util/support/hex.c + create mode 100644 src/util/support/t_hex.c + +diff --git a/src/include/k5-hex.h b/src/include/k5-hex.h +new file mode 100644 +index 000000000..75bd2cb19 +--- /dev/null ++++ b/src/include/k5-hex.h +@@ -0,0 +1,53 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* include/k5-hex.h - libkrb5support hex encoding/decoding declarations */ ++/* ++ * Copyright (C) 2018 by the Massachusetts Institute of Technology. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#ifndef K5_HEX_H ++#define K5_HEX_H ++ ++#include "k5-platform.h" ++ ++/* ++ * Encode len bytes in hex, placing the result in allocated storage in ++ * *hex_out. Use uppercase hex digits if uppercase is non-zero. Return 0 on ++ * success, ENOMEM on error. ++ */ ++int k5_hex_encode(const void *bytes, size_t len, int uppercase, ++ char **hex_out); ++ ++/* ++ * Decode hex bytes, placing the result in allocated storage in *bytes_out and ++ * *len_out. Null-terminate the result (primarily for decoding passwords in ++ * libkdb_ldap). Return 0 on success, ENOMEM or EINVAL on error. ++ */ ++int k5_hex_decode(const char *hex, uint8_t **bytes_out, size_t *len_out); ++ ++#endif /* K5_HEX_H */ +diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in +index 9326742d7..b3576f0b7 100644 +--- a/src/util/support/Makefile.in ++++ b/src/util/support/Makefile.in +@@ -82,6 +82,7 @@ STLIBOBJS= \ + path.o \ + base64.o \ + json.o \ ++ hex.o \ + bcmp.o \ + strerror_r.o \ + dir_filenames.o \ +@@ -108,6 +109,7 @@ LIBOBJS= \ + $(OUTPRE)path.$(OBJEXT) \ + $(OUTPRE)base64.$(OBJEXT) \ + $(OUTPRE)json.$(OBJEXT) \ ++ $(OUTPRE)hex.$(OBJEXT) \ + $(OUTPRE)bcmp.$(OBJEXT) \ + $(OUTPRE)strerror_r.$(OBJEXT) \ + $(OUTPRE)dir_filenames.$(OBJEXT) \ +@@ -139,10 +141,12 @@ SRCS=\ + $(srcdir)/t_unal.c \ + $(srcdir)/t_path.c \ + $(srcdir)/t_json.c \ ++ $(srcdir)/t_hex.c \ + $(srcdir)/zap.c \ + $(srcdir)/path.c \ + $(srcdir)/base64.c \ + $(srcdir)/json.c \ ++ $(srcdir)/hex.c \ + $(srcdir)/bcmp.c \ + $(srcdir)/strerror_r.c \ + $(srcdir)/dir_filenames.c \ +@@ -218,13 +222,16 @@ T_JSON_OBJS= t_json.o json.o base64.o k5buf.o $(PRINTF_ST_OBJ) + t_json: $(T_JSON_OBJS) + $(CC_LINK) -o $@ $(T_JSON_OBJS) + ++t_hex: t_hex.o hex.o ++ $(CC_LINK) -o $@ t_hex.o hex.o ++ + t_unal: t_unal.o + $(CC_LINK) -o t_unal t_unal.o + + t_utf8: t_utf8.o utf8.o + $(CC_LINK) -o t_utf8 t_utf8.o utf8.o + +-TEST_PROGS= t_k5buf t_path t_path_win t_base64 t_json t_unal t_utf8 ++TEST_PROGS= t_k5buf t_path t_path_win t_base64 t_json t_hex t_unal t_utf8 + + check-unix: $(TEST_PROGS) + ./t_k5buf +@@ -232,13 +239,15 @@ check-unix: $(TEST_PROGS) + ./t_path_win + ./t_base64 + ./t_json ++ ./t_hex + ./t_unal + ./t_utf8 + + clean: + $(RM) t_k5buf.o t_k5buf t_unal.o t_unal path_win.o path_win + $(RM) t_path_win.o t_path_win t_path.o t_path t_base64.o t_base64 +- $(RM) t_json.o t_json libkrb5support.exports t_utf8.o t_utf8 ++ $(RM) t_json.o t_json t_hex.o t_hex libkrb5support.exports ++ $(RM) t_utf8.o t_utf8 + + @lib_frag@ + @libobj_frag@ +diff --git a/src/util/support/deps b/src/util/support/deps +index 4dff014f4..551843357 100644 +--- a/src/util/support/deps ++++ b/src/util/support/deps +@@ -62,6 +62,9 @@ t_path.so t_path.po $(OUTPRE)t_path.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + t_path.c + t_json.so t_json.po $(OUTPRE)t_json.$(OBJEXT): $(top_srcdir)/include/k5-json.h \ + t_json.c ++t_hex.so t_hex.po $(OUTPRE)t_hex.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ ++ $(top_srcdir)/include/k5-hex.h $(top_srcdir)/include/k5-platform.h \ ++ $(top_srcdir)/include/k5-thread.h t_hex.c + zap.so zap.po $(OUTPRE)zap.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ + zap.c +@@ -75,6 +78,9 @@ json.so json.po $(OUTPRE)json.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(top_srcdir)/include/k5-base64.h $(top_srcdir)/include/k5-buf.h \ + $(top_srcdir)/include/k5-json.h $(top_srcdir)/include/k5-platform.h \ + $(top_srcdir)/include/k5-thread.h json.c ++hex.so hex.po $(OUTPRE)hex.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ ++ $(top_srcdir)/include/k5-hex.h $(top_srcdir)/include/k5-platform.h \ ++ $(top_srcdir)/include/k5-thread.h hex.c + bcmp.so bcmp.po $(OUTPRE)bcmp.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ + bcmp.c +diff --git a/src/util/support/hex.c b/src/util/support/hex.c +new file mode 100644 +index 000000000..4407ff9ff +--- /dev/null ++++ b/src/util/support/hex.c +@@ -0,0 +1,116 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* util/support/hex.c - hex encoding/decoding implementation */ ++/* ++ * Copyright (C) 2018 by the Massachusetts Institute of Technology. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include ++ ++static inline char ++hex_digit(uint8_t bval, int uppercase) ++{ ++ assert(bval >= 0 && bval <= 0xF); ++ if (bval < 10) ++ return '0' + bval; ++ else if (uppercase) ++ return 'A' + (bval - 10); ++ else ++ return 'a' + (bval - 10); ++} ++ ++int ++k5_hex_encode(const void *bytes, size_t len, int uppercase, char **hex_out) ++{ ++ size_t i; ++ const uint8_t *p = bytes; ++ char *hex; ++ ++ *hex_out = NULL; ++ ++ hex = malloc(len * 2 + 1); ++ if (hex == NULL) ++ return ENOMEM; ++ ++ for (i = 0; i < len; i++) { ++ hex[i * 2] = hex_digit(p[i] >> 4, uppercase); ++ hex[i * 2 + 1] = hex_digit(p[i] & 0xF, uppercase); ++ } ++ hex[len * 2] = '\0'; ++ ++ *hex_out = hex; ++ return 0; ++} ++ ++/* Decode a hex digit. Return 0-15 on success, -1 on invalid input. */ ++static inline int ++decode_hexchar(unsigned char c) ++{ ++ if (isdigit(c)) ++ return c - '0'; ++ if (c >= 'A' && c <= 'F') ++ return c - 'A' + 10; ++ if (c >= 'a' && c <= 'f') ++ return c - 'a' + 10; ++ return -1; ++} ++ ++int ++k5_hex_decode(const char *hex, uint8_t **bytes_out, size_t *len_out) ++{ ++ size_t hexlen, i; ++ int h1, h2; ++ uint8_t *bytes; ++ ++ *bytes_out = NULL; ++ *len_out = 0; ++ ++ hexlen = strlen(hex); ++ if (hexlen % 2 != 0) ++ return EINVAL; ++ bytes = malloc(hexlen / 2 + 1); ++ if (bytes == NULL) ++ return ENOMEM; ++ ++ for (i = 0; i < hexlen / 2; i++) { ++ h1 = decode_hexchar(hex[i * 2]); ++ h2 = decode_hexchar(hex[i * 2 + 1]); ++ if (h1 == -1 || h2 == -1) { ++ free(bytes); ++ return EINVAL; ++ } ++ bytes[i] = h1 * 16 + h2; ++ } ++ bytes[i] = 0; ++ ++ *bytes_out = bytes; ++ *len_out = hexlen / 2; ++ return 0; ++} +diff --git a/src/util/support/libkrb5support-fixed.exports b/src/util/support/libkrb5support-fixed.exports +index 2cdcddfe0..6193d7331 100644 +--- a/src/util/support/libkrb5support-fixed.exports ++++ b/src/util/support/libkrb5support-fixed.exports +@@ -16,6 +16,8 @@ k5_get_error + k5_free_error + k5_clear_error + k5_set_error_info_callout_fn ++k5_hex_decode ++k5_hex_encode + k5_json_array_add + k5_json_array_create + k5_json_array_fmt +diff --git a/src/util/support/t_hex.c b/src/util/support/t_hex.c +new file mode 100644 +index 000000000..a586a1bc8 +--- /dev/null ++++ b/src/util/support/t_hex.c +@@ -0,0 +1,169 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* util/support/t_hex.c - Test hex encoding and decoding */ ++/* ++ * Copyright (C) 2018 by the Massachusetts Institute of Technology. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++ ++struct { ++ const char *hex; ++ const char *binary; ++ size_t binary_len; ++ int uppercase; ++} tests[] = { ++ /* Invalid hex strings */ ++ { "1" }, ++ { "123" }, ++ { "0/" }, ++ { "/0" }, ++ { "0:" }, ++ { ":0" }, ++ { "0@" }, ++ { "@0" }, ++ { "0G" }, ++ { "G0" }, ++ { "0`" }, ++ { "`0" }, ++ { "0g" }, ++ { "g0" }, ++ { " 00 " }, ++ { "0\x01" }, ++ ++ { "", "", 0 }, ++ { "00", "\x00", 1 }, ++ { "01", "\x01", 1 }, ++ { "10", "\x10", 1 }, ++ { "01ff", "\x01\xFF", 2 }, ++ { "A0B0C0", "\xA0\xB0\xC0", 3, 1 }, ++ { "1a2b3c4d5e6f", "\x1A\x2B\x3C\x4D\x5E\x6F", 6 }, ++ { "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", ++ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" ++ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 32 }, ++ ++ /* All byte values, lowercase */ ++ { "0001020304050607", "\x00\x01\x02\x03\x04\x05\x06\x07", 8 }, ++ { "08090a0b0c0d0e0f", "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 8 }, ++ { "1011121314151617", "\x10\x11\x12\x13\x14\x15\x16\x17", 8 }, ++ { "18191a1b1c1d1e1f", "\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 8 }, ++ { "2021222324252627", "\x20\x21\x22\x23\x24\x25\x26\x27", 8 }, ++ { "28292a2b2c2d2e2f", "\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F", 8 }, ++ { "3031323334353637", "\x30\x31\x32\x33\x34\x35\x36\x37", 8 }, ++ { "38393a3b3c3d3e3f", "\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F", 8 }, ++ { "4041424344454647", "\x40\x41\x42\x43\x44\x45\x46\x47", 8 }, ++ { "48494a4b4c4d4e4f", "\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F", 8 }, ++ { "5051525354555657", "\x50\x51\x52\x53\x54\x55\x56\x57", 8 }, ++ { "58595a5b5c5d5e5f", "\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F", 8 }, ++ { "6061626364656667", "\x60\x61\x62\x63\x64\x65\x66\x67", 8 }, ++ { "68696a6b6c6d6e6f", "\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F", 8 }, ++ { "7071727374757677", "\x70\x71\x72\x73\x74\x75\x76\x77", 8 }, ++ { "78797a7b7c7d7e7f", "\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F", 8 }, ++ { "8081828384858687", "\x80\x81\x82\x83\x84\x85\x86\x87", 8 }, ++ { "88898a8b8c8d8e8f", "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F", 8 }, ++ { "9091929394959697", "\x90\x91\x92\x93\x94\x95\x96\x97", 8 }, ++ { "98999a9b9c9d9e9f", "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F", 8 }, ++ { "a0a1a2a3a4a5a6a7", "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7", 8 }, ++ { "a8a9aaabacadaeaf", "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF", 8 }, ++ { "b0b1b2b3b4b5b6b7", "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7", 8 }, ++ { "b8b9babbbcbdbebf", "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF", 8 }, ++ { "c0c1c2c3c4c5c6c7", "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7", 8 }, ++ { "c8c9cacbcccdcecf", "\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 8 }, ++ { "d0d1d2d3d4d5d6d7", "\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7", 8 }, ++ { "d8d9dadbdcdddedf", "\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF", 8 }, ++ { "e0e1e2e3e4e5e6e7", "\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7", 8 }, ++ { "e8e9eaebecedeeef", "\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF", 8 }, ++ { "f0f1f2f3f4f5f6f7", "\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7", 8 }, ++ { "f8f9fafbfcfdfeff", "\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF", 8 }, ++ ++ /* All byte values, uppercase */ ++ { "0001020304050607", "\x00\x01\x02\x03\x04\x05\x06\x07", 8, 1 }, ++ { "08090A0B0C0D0E0F", "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 8, 1 }, ++ { "1011121314151617", "\x10\x11\x12\x13\x14\x15\x16\x17", 8, 1 }, ++ { "18191A1B1C1D1E1F", "\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 8, 1 }, ++ { "2021222324252627", "\x20\x21\x22\x23\x24\x25\x26\x27", 8, 1 }, ++ { "28292A2B2C2D2E2F", "\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F", 8, 1 }, ++ { "3031323334353637", "\x30\x31\x32\x33\x34\x35\x36\x37", 8, 1 }, ++ { "38393A3B3C3D3E3F", "\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F", 8, 1 }, ++ { "4041424344454647", "\x40\x41\x42\x43\x44\x45\x46\x47", 8, 1 }, ++ { "48494A4B4C4D4E4F", "\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F", 8, 1 }, ++ { "5051525354555657", "\x50\x51\x52\x53\x54\x55\x56\x57", 8, 1 }, ++ { "58595A5B5C5D5E5F", "\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F", 8, 1 }, ++ { "6061626364656667", "\x60\x61\x62\x63\x64\x65\x66\x67", 8, 1 }, ++ { "68696A6B6C6D6E6F", "\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F", 8, 1 }, ++ { "7071727374757677", "\x70\x71\x72\x73\x74\x75\x76\x77", 8, 1 }, ++ { "78797A7B7C7D7E7F", "\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F", 8, 1 }, ++ { "8081828384858687", "\x80\x81\x82\x83\x84\x85\x86\x87", 8, 1 }, ++ { "88898A8B8C8D8E8F", "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F", 8, 1 }, ++ { "9091929394959697", "\x90\x91\x92\x93\x94\x95\x96\x97", 8, 1 }, ++ { "98999A9B9C9D9E9F", "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F", 8, 1 }, ++ { "A0A1A2A3A4A5A6A7", "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7", 8, 1 }, ++ { "A8A9AAABACADAEAF", "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF", 8, 1 }, ++ { "B0B1B2B3B4B5B6B7", "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7", 8, 1 }, ++ { "B8B9BABBBCBDBEBF", "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF", 8, 1 }, ++ { "C0C1C2C3C4C5C6C7", "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7", 8, 1 }, ++ { "C8C9CACBCCCDCECF", "\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 8, 1 }, ++ { "D0D1D2D3D4D5D6D7", "\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7", 8, 1 }, ++ { "D8D9DADBDCDDDEDF", "\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF", 8, 1 }, ++ { "E0E1E2E3E4E5E6E7", "\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7", 8, 1 }, ++ { "E8E9EAEBECEDEEEF", "\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF", 8, 1 }, ++ { "F0F1F2F3F4F5F6F7", "\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7", 8, 1 }, ++ { "F8F9FAFBFCFDFEFF", "\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF", 8, 1 }, ++}; ++ ++int main() ++{ ++ size_t i; ++ char *hex; ++ int ret; ++ uint8_t *bytes; ++ size_t len; ++ ++ for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) { ++ if (tests[i].binary == NULL) { ++ ret = k5_hex_decode(tests[i].hex, &bytes, &len); ++ assert(ret == EINVAL && bytes == NULL && len == 0); ++ continue; ++ } ++ ++ ret = k5_hex_decode(tests[i].hex, &bytes, &len); ++ assert(ret == 0); ++ assert(len == tests[i].binary_len); ++ assert(memcmp(bytes, tests[i].binary, len) == 0); ++ assert(bytes[len] == 0); ++ free(bytes); ++ ++ ret = k5_hex_encode((uint8_t *)tests[i].binary, tests[i].binary_len, ++ tests[i].uppercase, &hex); ++ assert(ret == 0); ++ assert(strcmp(tests[i].hex, hex) == 0); ++ free(hex); ++ } ++ return 0; ++} diff --git a/SOURCES/Add-support-to-query-the-SSF-of-a-GSS-context.patch b/SOURCES/Add-support-to-query-the-SSF-of-a-GSS-context.patch new file mode 100644 index 0000000..28d8a50 --- /dev/null +++ b/SOURCES/Add-support-to-query-the-SSF-of-a-GSS-context.patch @@ -0,0 +1,419 @@ +From 0bcadcebe22566a3bebd95974603b6b6593a4119 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Thu, 30 Mar 2017 11:27:09 -0400 +Subject: [PATCH] Add support to query the SSF of a GSS context + +Cyrus SASL provides a Security Strength Factor number to assess the +relative "strength" of the negotiated mechanism, and applications +sometimes make access control decisions based on it. + +Add a call that allows us to query the mechanism that established the +GSS security context to ask what is the current SSF, based on the +enctype of the session key. + +ticket: 8569 (new) +(cherry picked from commit 7feb7da54c0321b5a3eeb6c3797846a3cf7eda28) +[rharwood@redhat.com: stub out GSS_KRB5_GET_CRED_IMPERSONATOR] +--- + src/include/k5-int.h | 1 + + src/lib/crypto/krb/crypto_int.h | 1 + + src/lib/crypto/krb/enctype_util.c | 16 ++++++++++++ + src/lib/crypto/krb/etypes.c | 33 ++++++++++++++----------- + src/lib/crypto/libk5crypto.exports | 1 + + src/lib/gssapi/generic/gssapi_ext.h | 11 +++++++++ + src/lib/gssapi/generic/gssapi_generic.c | 9 +++++++ + src/lib/gssapi/krb5/gssapiP_krb5.h | 6 +++++ + src/lib/gssapi/krb5/gssapi_krb5.c | 4 +++ + src/lib/gssapi/krb5/inq_context.c | 27 ++++++++++++++++++++ + src/lib/gssapi/libgssapi_krb5.exports | 1 + + src/lib/gssapi32.def | 3 +++ + src/lib/krb5_32.def | 3 +++ + src/tests/gssapi/t_enctypes.c | 14 +++++++++++ + 14 files changed, 115 insertions(+), 15 deletions(-) + +diff --git a/src/include/k5-int.h b/src/include/k5-int.h +index cea644d0a..06ca2b66d 100644 +--- a/src/include/k5-int.h ++++ b/src/include/k5-int.h +@@ -2114,6 +2114,7 @@ krb5_get_tgs_ktypes(krb5_context, krb5_const_principal, krb5_enctype **); + krb5_boolean krb5_is_permitted_enctype(krb5_context, krb5_enctype); + + krb5_boolean KRB5_CALLCONV krb5int_c_weak_enctype(krb5_enctype); ++krb5_error_code k5_enctype_to_ssf(krb5_enctype enctype, unsigned int *ssf_out); + + krb5_error_code krb5_kdc_rep_decrypt_proc(krb5_context, const krb5_keyblock *, + krb5_const_pointer, krb5_kdc_rep *); +diff --git a/src/lib/crypto/krb/crypto_int.h b/src/lib/crypto/krb/crypto_int.h +index d75b49c69..e5099291e 100644 +--- a/src/lib/crypto/krb/crypto_int.h ++++ b/src/lib/crypto/krb/crypto_int.h +@@ -111,6 +111,7 @@ struct krb5_keytypes { + prf_func prf; + krb5_cksumtype required_ctype; + krb5_flags flags; ++ unsigned int ssf; + }; + + #define ETYPE_WEAK 1 +diff --git a/src/lib/crypto/krb/enctype_util.c b/src/lib/crypto/krb/enctype_util.c +index 0ed74bd6e..b1b40e7ec 100644 +--- a/src/lib/crypto/krb/enctype_util.c ++++ b/src/lib/crypto/krb/enctype_util.c +@@ -131,3 +131,19 @@ krb5_enctype_to_name(krb5_enctype enctype, krb5_boolean shortest, + return ENOMEM; + return 0; + } ++ ++/* The security of a mechanism cannot be summarized with a simple integer ++ * value, but we provide a per-enctype value for Cyrus SASL's SSF. */ ++krb5_error_code ++k5_enctype_to_ssf(krb5_enctype enctype, unsigned int *ssf_out) ++{ ++ const struct krb5_keytypes *ktp; ++ ++ *ssf_out = 0; ++ ++ ktp = find_enctype(enctype); ++ if (ktp == NULL) ++ return EINVAL; ++ *ssf_out = ktp->ssf; ++ return 0; ++} +diff --git a/src/lib/crypto/krb/etypes.c b/src/lib/crypto/krb/etypes.c +index 0e5e977d4..53d4a5c79 100644 +--- a/src/lib/crypto/krb/etypes.c ++++ b/src/lib/crypto/krb/etypes.c +@@ -42,7 +42,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_des_string_to_key, k5_rand2key_des, + krb5int_des_prf, + CKSUMTYPE_RSA_MD5_DES, +- ETYPE_WEAK }, ++ ETYPE_WEAK, 56 }, + { ENCTYPE_DES_CBC_MD4, + "des-cbc-md4", { 0 }, "DES cbc mode with RSA-MD4", + &krb5int_enc_des, &krb5int_hash_md4, +@@ -51,7 +51,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_des_string_to_key, k5_rand2key_des, + krb5int_des_prf, + CKSUMTYPE_RSA_MD4_DES, +- ETYPE_WEAK }, ++ ETYPE_WEAK, 56 }, + { ENCTYPE_DES_CBC_MD5, + "des-cbc-md5", { "des" }, "DES cbc mode with RSA-MD5", + &krb5int_enc_des, &krb5int_hash_md5, +@@ -60,7 +60,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_des_string_to_key, k5_rand2key_des, + krb5int_des_prf, + CKSUMTYPE_RSA_MD5_DES, +- ETYPE_WEAK }, ++ ETYPE_WEAK, 56 }, + { ENCTYPE_DES_CBC_RAW, + "des-cbc-raw", { 0 }, "DES cbc mode raw", + &krb5int_enc_des, NULL, +@@ -69,7 +69,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_des_string_to_key, k5_rand2key_des, + krb5int_des_prf, + 0, +- ETYPE_WEAK }, ++ ETYPE_WEAK, 56 }, + { ENCTYPE_DES3_CBC_RAW, + "des3-cbc-raw", { 0 }, "Triple DES cbc mode raw", + &krb5int_enc_des3, NULL, +@@ -78,7 +78,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_dk_string_to_key, k5_rand2key_des3, + NULL, /*PRF*/ + 0, +- ETYPE_WEAK }, ++ ETYPE_WEAK, 112 }, + + { ENCTYPE_DES3_CBC_SHA1, + "des3-cbc-sha1", { "des3-hmac-sha1", "des3-cbc-sha1-kd" }, +@@ -89,7 +89,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_dk_string_to_key, k5_rand2key_des3, + krb5int_dk_prf, + CKSUMTYPE_HMAC_SHA1_DES3, +- 0 /*flags*/ }, ++ 0 /*flags*/, 112 }, + + { ENCTYPE_DES_HMAC_SHA1, + "des-hmac-sha1", { 0 }, "DES with HMAC/sha1", +@@ -99,7 +99,10 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_dk_string_to_key, k5_rand2key_des, + NULL, /*PRF*/ + 0, +- ETYPE_WEAK }, ++ ETYPE_WEAK, 56 }, ++ ++ /* rc4-hmac uses a 128-bit key, but due to weaknesses in the RC4 cipher, we ++ * consider its strength degraded and assign it an SSF value of 64. */ + { ENCTYPE_ARCFOUR_HMAC, + "arcfour-hmac", { "rc4-hmac", "arcfour-hmac-md5" }, + "ArcFour with HMAC/md5", +@@ -110,7 +113,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_arcfour_decrypt, krb5int_arcfour_string_to_key, + k5_rand2key_direct, krb5int_arcfour_prf, + CKSUMTYPE_HMAC_MD5_ARCFOUR, +- 0 /*flags*/ }, ++ 0 /*flags*/, 64 }, + { ENCTYPE_ARCFOUR_HMAC_EXP, + "arcfour-hmac-exp", { "rc4-hmac-exp", "arcfour-hmac-md5-exp" }, + "Exportable ArcFour with HMAC/md5", +@@ -121,7 +124,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_arcfour_decrypt, krb5int_arcfour_string_to_key, + k5_rand2key_direct, krb5int_arcfour_prf, + CKSUMTYPE_HMAC_MD5_ARCFOUR, +- ETYPE_WEAK ++ ETYPE_WEAK, 40 + }, + + { ENCTYPE_AES128_CTS_HMAC_SHA1_96, +@@ -133,7 +136,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_aes_string_to_key, k5_rand2key_direct, + krb5int_dk_prf, + CKSUMTYPE_HMAC_SHA1_96_AES128, +- 0 /*flags*/ }, ++ 0 /*flags*/, 128 }, + { ENCTYPE_AES256_CTS_HMAC_SHA1_96, + "aes256-cts-hmac-sha1-96", { "aes256-cts", "aes256-sha1" }, + "AES-256 CTS mode with 96-bit SHA-1 HMAC", +@@ -143,7 +146,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_aes_string_to_key, k5_rand2key_direct, + krb5int_dk_prf, + CKSUMTYPE_HMAC_SHA1_96_AES256, +- 0 /*flags*/ }, ++ 0 /*flags*/, 256 }, + + { ENCTYPE_CAMELLIA128_CTS_CMAC, + "camellia128-cts-cmac", { "camellia128-cts" }, +@@ -155,7 +158,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_camellia_string_to_key, k5_rand2key_direct, + krb5int_dk_cmac_prf, + CKSUMTYPE_CMAC_CAMELLIA128, +- 0 /*flags*/ }, ++ 0 /*flags*/, 128 }, + { ENCTYPE_CAMELLIA256_CTS_CMAC, + "camellia256-cts-cmac", { "camellia256-cts" }, + "Camellia-256 CTS mode with CMAC", +@@ -166,7 +169,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_camellia_string_to_key, k5_rand2key_direct, + krb5int_dk_cmac_prf, + CKSUMTYPE_CMAC_CAMELLIA256, +- 0 /*flags */ }, ++ 0 /*flags */, 256 }, + + { ENCTYPE_AES128_CTS_HMAC_SHA256_128, + "aes128-cts-hmac-sha256-128", { "aes128-sha2" }, +@@ -177,7 +180,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_aes2_string_to_key, k5_rand2key_direct, + krb5int_aes2_prf, + CKSUMTYPE_HMAC_SHA256_128_AES128, +- 0 /*flags*/ }, ++ 0 /*flags*/, 128 }, + { ENCTYPE_AES256_CTS_HMAC_SHA384_192, + "aes256-cts-hmac-sha384-192", { "aes256-sha2" }, + "AES-256 CTS mode with 192-bit SHA-384 HMAC", +@@ -187,7 +190,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_aes2_string_to_key, k5_rand2key_direct, + krb5int_aes2_prf, + CKSUMTYPE_HMAC_SHA384_192_AES256, +- 0 /*flags*/ }, ++ 0 /*flags*/, 256 }, + }; + + const int krb5int_enctypes_length = +diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports +index 447e45644..82eb5f30c 100644 +--- a/src/lib/crypto/libk5crypto.exports ++++ b/src/lib/crypto/libk5crypto.exports +@@ -108,3 +108,4 @@ krb5int_nfold + k5_allow_weak_pbkdf2iter + krb5_c_prfplus + krb5_c_derive_prfplus ++k5_enctype_to_ssf +diff --git a/src/lib/gssapi/generic/gssapi_ext.h b/src/lib/gssapi/generic/gssapi_ext.h +index 9ad44216d..9d3a7e736 100644 +--- a/src/lib/gssapi/generic/gssapi_ext.h ++++ b/src/lib/gssapi/generic/gssapi_ext.h +@@ -575,4 +575,15 @@ gss_import_cred( + } + #endif + ++/* ++ * When used with gss_inquire_sec_context_by_oid(), return a buffer set with ++ * the first member containing an unsigned 32-bit integer in network byte ++ * order. This is the Security Strength Factor (SSF) associated with the ++ * secure channel established by the security context. NOTE: This value is ++ * made available solely as an indication for use by APIs like Cyrus SASL that ++ * classify the strength of a secure channel via this number. The strength of ++ * a channel cannot necessarily be represented by a simple number. ++ */ ++GSS_DLLIMP extern gss_OID GSS_C_SEC_CONTEXT_SASL_SSF; ++ + #endif /* GSSAPI_EXT_H_ */ +diff --git a/src/lib/gssapi/generic/gssapi_generic.c b/src/lib/gssapi/generic/gssapi_generic.c +index 5496aa335..fa144c2bf 100644 +--- a/src/lib/gssapi/generic/gssapi_generic.c ++++ b/src/lib/gssapi/generic/gssapi_generic.c +@@ -157,6 +157,13 @@ static const gss_OID_desc const_oids[] = { + {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x19"}, + {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x1a"}, + {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x1b"}, ++ ++ /* ++ * GSS_SEC_CONTEXT_SASL_SSF_OID 1.2.840.113554.1.2.2.5.15 ++ * iso(1) member-body(2) United States(840) mit(113554) ++ * infosys(1) gssapi(2) krb5(2) krb5-gssapi-ext(5) sasl-ssf(15) ++ */ ++ {11, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0f"}, + }; + + /* Here are the constants which point to the static structure above. +@@ -218,6 +225,8 @@ GSS_DLLIMP gss_const_OID GSS_C_MA_PFS = oids+33; + GSS_DLLIMP gss_const_OID GSS_C_MA_COMPRESS = oids+34; + GSS_DLLIMP gss_const_OID GSS_C_MA_CTX_TRANS = oids+35; + ++GSS_DLLIMP gss_OID GSS_C_SEC_CONTEXT_SASL_SSF = oids+36; ++ + static gss_OID_set_desc gss_ma_known_attrs_desc = { 27, oids+9 }; + gss_OID_set gss_ma_known_attrs = &gss_ma_known_attrs_desc; + +diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h +index d7bdef7e2..ef030707e 100644 +--- a/src/lib/gssapi/krb5/gssapiP_krb5.h ++++ b/src/lib/gssapi/krb5/gssapiP_krb5.h +@@ -1144,6 +1144,12 @@ gss_krb5int_extract_authtime_from_sec_context(OM_uint32 *, + const gss_OID, + gss_buffer_set_t *); + ++#define GET_SEC_CONTEXT_SASL_SSF_OID_LENGTH 11 ++#define GET_SEC_CONTEXT_SASL_SSF_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0f" ++OM_uint32 ++gss_krb5int_sec_context_sasl_ssf(OM_uint32 *, const gss_ctx_id_t, ++ const gss_OID, gss_buffer_set_t *); ++ + #define GSS_KRB5_IMPORT_CRED_OID_LENGTH 11 + #define GSS_KRB5_IMPORT_CRED_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0d" + +diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c +index 99092ccab..de4131980 100644 +--- a/src/lib/gssapi/krb5/gssapi_krb5.c ++++ b/src/lib/gssapi/krb5/gssapi_krb5.c +@@ -352,6 +352,10 @@ static struct { + { + {GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID_LENGTH, GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID}, + gss_krb5int_extract_authtime_from_sec_context ++ }, ++ { ++ {GET_SEC_CONTEXT_SASL_SSF_OID_LENGTH, GET_SEC_CONTEXT_SASL_SSF_OID}, ++ gss_krb5int_sec_context_sasl_ssf + } + }; + +diff --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c +index 9024b3c7e..d2e466e60 100644 +--- a/src/lib/gssapi/krb5/inq_context.c ++++ b/src/lib/gssapi/krb5/inq_context.c +@@ -310,3 +310,30 @@ gss_krb5int_extract_authtime_from_sec_context(OM_uint32 *minor_status, + + return generic_gss_add_buffer_set_member(minor_status, &rep, data_set); + } ++ ++OM_uint32 ++gss_krb5int_sec_context_sasl_ssf(OM_uint32 *minor_status, ++ const gss_ctx_id_t context_handle, ++ const gss_OID desired_object, ++ gss_buffer_set_t *data_set) ++{ ++ krb5_gss_ctx_id_rec *ctx; ++ krb5_key key; ++ krb5_error_code code; ++ gss_buffer_desc ssfbuf; ++ unsigned int ssf; ++ uint8_t buf[4]; ++ ++ ctx = (krb5_gss_ctx_id_rec *)context_handle; ++ key = ctx->have_acceptor_subkey ? ctx->acceptor_subkey : ctx->subkey; ++ ++ code = k5_enctype_to_ssf(key->keyblock.enctype, &ssf); ++ if (code) ++ return GSS_S_FAILURE; ++ ++ store_32_be(ssf, buf); ++ ssfbuf.value = buf; ++ ssfbuf.length = sizeof(buf); ++ ++ return generic_gss_add_buffer_set_member(minor_status, &ssfbuf, data_set); ++} +diff --git a/src/lib/gssapi/libgssapi_krb5.exports b/src/lib/gssapi/libgssapi_krb5.exports +index 9facb3f42..936540e41 100644 +--- a/src/lib/gssapi/libgssapi_krb5.exports ++++ b/src/lib/gssapi/libgssapi_krb5.exports +@@ -37,6 +37,7 @@ GSS_C_MA_CBINDINGS + GSS_C_MA_PFS + GSS_C_MA_COMPRESS + GSS_C_MA_CTX_TRANS ++GSS_C_SEC_CONTEXT_SASL_SSF + gss_accept_sec_context + gss_acquire_cred + gss_acquire_cred_with_password +diff --git a/src/lib/gssapi32.def b/src/lib/gssapi32.def +index 362b9bce8..dff057754 100644 +--- a/src/lib/gssapi32.def ++++ b/src/lib/gssapi32.def +@@ -182,3 +182,6 @@ EXPORTS + gss_verify_mic_iov @146 + ; Added in 1.14 + GSS_KRB5_CRED_NO_CI_FLAGS_X @147 DATA ++; Added in 1.16 ++; GSS_KRB5_GET_CRED_IMPERSONATOR @148 DATA ++ GSS_C_SEC_CONTEXT_SASL_SSF @149 DATA +diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def +index e5b560dfc..f7b428e16 100644 +--- a/src/lib/krb5_32.def ++++ b/src/lib/krb5_32.def +@@ -470,3 +470,6 @@ EXPORTS + krb5_get_init_creds_opt_set_pac_request @435 + krb5int_trace @436 ; PRIVATE GSSAPI + krb5_expand_hostname @437 ++ ++; new in 1.16 ++ k5_enctype_to_ssf @438 ; PRIVATE GSSAPI +diff --git a/src/tests/gssapi/t_enctypes.c b/src/tests/gssapi/t_enctypes.c +index a2ad18f47..3fd31e2f8 100644 +--- a/src/tests/gssapi/t_enctypes.c ++++ b/src/tests/gssapi/t_enctypes.c +@@ -32,6 +32,7 @@ + + #include "k5-int.h" + #include "common.h" ++#include "gssapi_ext.h" + + /* + * This test program establishes contexts with the krb5 mech, the default +@@ -86,6 +87,9 @@ main(int argc, char *argv[]) + gss_krb5_lucid_context_v1_t *ilucid, *alucid; + gss_krb5_rfc1964_keydata_t *i1964, *a1964; + gss_krb5_cfx_keydata_t *icfx, *acfx; ++ gss_buffer_set_t bufset = GSS_C_NO_BUFFER_SET; ++ gss_OID ssf_oid = GSS_C_SEC_CONTEXT_SASL_SSF; ++ unsigned int ssf; + size_t count; + void *lptr; + int c; +@@ -139,6 +143,16 @@ main(int argc, char *argv[]) + establish_contexts(&mech_krb5, icred, acred, tname, flags, &ictx, &actx, + NULL, NULL, NULL); + ++ /* Query the SSF value and range-check the result. */ ++ major = gss_inquire_sec_context_by_oid(&minor, ictx, ssf_oid, &bufset); ++ check_gsserr("gss_inquire_sec_context_by_oid(ssf)", major, minor); ++ if (bufset->elements[0].length != 4) ++ errout("SSF buffer has unexpected length"); ++ ssf = load_32_be(bufset->elements[0].value); ++ if (ssf < 56 || ssf > 256) ++ errout("SSF value not within acceptable range (56-256)"); ++ (void)gss_release_buffer_set(&minor, &bufset); ++ + /* Export to lucid contexts. */ + major = gss_krb5_export_lucid_sec_context(&minor, &ictx, 1, &lptr); + check_gsserr("gss_export_lucid_sec_context(initiator)", major, minor); diff --git a/SOURCES/Add-test-case-for-PKINIT-DH-renegotiation.patch b/SOURCES/Add-test-case-for-PKINIT-DH-renegotiation.patch new file mode 100644 index 0000000..51d5ee1 --- /dev/null +++ b/SOURCES/Add-test-case-for-PKINIT-DH-renegotiation.patch @@ -0,0 +1,45 @@ +From d65bcba04f0051ac3ad74be7415da85b1c80a0ad Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Wed, 11 Jan 2017 10:49:30 -0500 +Subject: [PATCH] Add test case for PKINIT DH renegotiation + +In t_pkinit.py, add a PKINIT test case where the KDC sends +KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED and the client retries with the +KDC's TD_DH_PARAMETERS value, using the clpreauth tryagain method. +Use the trace log to verify that the renegotiation actually takes +place. + +(cherry picked from commit 7ad7eb7fd591e6c789ea24b94eccbf74ee4d79f8) +--- + src/tests/t_pkinit.py | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py +index ac4d326b6..183977750 100755 +--- a/src/tests/t_pkinit.py ++++ b/src/tests/t_pkinit.py +@@ -174,6 +174,24 @@ realm.kinit(realm.user_princ, + '-X', 'flag_RSA_PROTOCOL=yes']) + realm.klist(realm.user_princ) + ++# Test a DH parameter renegotiation by temporarily setting a 4096-bit ++# minimum on the KDC. ++tracefile = os.path.join(realm.testdir, 'trace') ++minbits_kdc_conf = {'realms': {'$realm': {'pkinit_dh_min_bits': '4096'}}} ++minbits_env = realm.special_env('restrict', True, kdc_conf=minbits_kdc_conf) ++realm.stop_kdc() ++realm.start_kdc(env=minbits_env) ++realm.run(['env', 'KRB5_TRACE=' + tracefile, kinit, '-X', ++ 'X509_user_identity=' + file_identity, realm.user_princ]) ++with open(tracefile, 'r') as f: ++ trace = f.read() ++if ('Key parameters not accepted' not in trace or ++ 'Preauth tryagain input types' not in trace or ++ 'trying again with KDC-provided parameters' not in trace): ++ fail('DH renegotiation steps not found in kinit trace log') ++realm.stop_kdc() ++realm.start_kdc() ++ + # Run the basic test - PKINIT with FILE: identity, with a password on the key, + # supplied by the prompter. + # Expect failure if the responder does nothing, and we have no prompter. diff --git a/SOURCES/Add-test-cases-for-preauth-fallback-behavior.patch b/SOURCES/Add-test-cases-for-preauth-fallback-behavior.patch new file mode 100644 index 0000000..8002723 --- /dev/null +++ b/SOURCES/Add-test-cases-for-preauth-fallback-behavior.patch @@ -0,0 +1,826 @@ +From e1448b09ac4e94ff8e66a7cf0315841c38c48c37 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Fri, 20 Jan 2017 12:44:12 -0500 +Subject: [PATCH] Add test cases for preauth fallback behavior + +Add options to icred for performing optimistic preauth and setting +preauth options, and for choosing between the normal and stepwise +interfaces. Add options to the test preauth module to allow induced +failures at several points in processing, factoring out some padata +manipulation functions into a new file to avoid repeating too much +code. Add test cases to t_preauth.py using the new facilities to +exercise and verify several preauth fallback scenarios. Amend the +tryagain test case in t_pkinit.py to look for more trace log messages. + +ticket: 8537 +(cherry picked from commit 748beda1e36d76bed8b06b272ecb72988eede94b) +[rharwood@redhat.com: more expected_trace] +--- + src/plugins/preauth/test/Makefile.in | 4 +- + src/plugins/preauth/test/cltest.c | 86 ++++++++++----- + src/plugins/preauth/test/common.c | 61 +++++++++++ + src/plugins/preauth/test/common.h | 41 +++++++ + src/plugins/preauth/test/deps | 14 ++- + src/plugins/preauth/test/kdctest.c | 96 ++++++++++------ + src/tests/icred.c | 69 +++++++++--- + src/tests/t_general.py | 1 + + src/tests/t_pkinit.py | 12 +- + src/tests/t_preauth.py | 158 ++++++++++++++++++++++++++- + 10 files changed, 452 insertions(+), 90 deletions(-) + create mode 100644 src/plugins/preauth/test/common.c + create mode 100644 src/plugins/preauth/test/common.h + +diff --git a/src/plugins/preauth/test/Makefile.in b/src/plugins/preauth/test/Makefile.in +index ac3cb8155..77321b60f 100644 +--- a/src/plugins/preauth/test/Makefile.in ++++ b/src/plugins/preauth/test/Makefile.in +@@ -9,9 +9,9 @@ RELDIR=../plugins/preauth/test + SHLIB_EXPDEPS=$(KRB5_BASE_DEPLIBS) + SHLIB_EXPLIBS=$(KRB5_BASE_LIBS) + +-STLIBOBJS=cltest.o kdctest.o ++STLIBOBJS=cltest.o kdctest.o common.o + +-SRCS= $(srcdir)/cltest.c $(srcdir)/kdctest.c ++SRCS= $(srcdir)/cltest.c $(srcdir)/kdctest.c $(srcdir)/common.c + + all-unix: all-liblinks + install-unix: install-libs +diff --git a/src/plugins/preauth/test/cltest.c b/src/plugins/preauth/test/cltest.c +index 4c31e1c0f..f5f7c5aba 100644 +--- a/src/plugins/preauth/test/cltest.c ++++ b/src/plugins/preauth/test/cltest.c +@@ -1,7 +1,7 @@ + /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ + /* plugins/preauth/test/cltest.c - Test clpreauth module */ + /* +- * Copyright (C) 2015 by the Massachusetts Institute of Technology. ++ * Copyright (C) 2015, 2017 by the Massachusetts Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without +@@ -32,7 +32,7 @@ + + /* + * This module is used to test preauth interface features. At this time, the +- * clpreauth module does two things: ++ * clpreauth module does the following: + * + * - It decrypts a message from the initial KDC pa-data using the reply key and + * prints it to stdout. (The unencrypted message "no key" can also be +@@ -45,17 +45,27 @@ + * it to the server, instructing the kdcpreauth module to assert one or more + * space-separated authentication indicators. (This string is sent on both + * round trips if a second round trip is requested.) ++ * ++ * - If a KDC_ERR_ENCTYPE_NOSUPP error with e-data is received, it prints the ++ * accompanying error padata and sends a follow-up request containing ++ * "tryagain". ++ * ++ * - If the "fail_optimistic", "fail_2rt", or "fail_tryagain" gic options are ++ * set, it fails with a recognizable error string at the requested point in ++ * processing. + */ + + #include "k5-int.h" + #include +- +-#define TEST_PA_TYPE -123 ++#include "common.h" + + static krb5_preauthtype pa_types[] = { TEST_PA_TYPE, 0 }; + + struct client_state { + char *indicators; ++ krb5_boolean fail_optimistic; ++ krb5_boolean fail_2rt; ++ krb5_boolean fail_tryagain; + }; + + struct client_request_state { +@@ -70,6 +80,7 @@ test_init(krb5_context context, krb5_clpreauth_moddata *moddata_out) + st = malloc(sizeof(*st)); + assert(st != NULL); + st->indicators = NULL; ++ st->fail_optimistic = st->fail_2rt = st->fail_tryagain = FALSE; + *moddata_out = (krb5_clpreauth_moddata)st; + return 0; + } +@@ -114,7 +125,6 @@ test_process(krb5_context context, krb5_clpreauth_moddata moddata, + struct client_state *st = (struct client_state *)moddata; + struct client_request_state *reqst = (struct client_request_state *)modreq; + krb5_error_code ret; +- krb5_pa_data **list, *pa; + krb5_keyblock *k; + krb5_enc_data enc; + krb5_data plain; +@@ -123,20 +133,18 @@ test_process(krb5_context context, krb5_clpreauth_moddata moddata, + if (pa_data->length == 0) { + /* This is an optimistic preauth test. Send a recognizable padata + * value so the KDC knows not to expect a cookie. */ +- list = k5calloc(2, sizeof(*list), &ret); +- assert(!ret); +- pa = k5alloc(sizeof(*pa), &ret); +- assert(!ret); +- pa->pa_type = TEST_PA_TYPE; +- pa->contents = (uint8_t *)strdup("optimistic"); +- assert(pa->contents != NULL); +- pa->length = 10; +- list[0] = pa; +- list[1] = NULL; +- *out_pa_data = list; ++ if (st->fail_optimistic) { ++ k5_setmsg(context, KRB5_PREAUTH_FAILED, "induced optimistic fail"); ++ return KRB5_PREAUTH_FAILED; ++ } ++ *out_pa_data = make_pa_list("optimistic", 10); + return 0; + } else if (reqst->second_round_trip) { + printf("2rt: %.*s\n", pa_data->length, pa_data->contents); ++ if (st->fail_2rt) { ++ k5_setmsg(context, KRB5_PREAUTH_FAILED, "induced 2rt fail"); ++ return KRB5_PREAUTH_FAILED; ++ } + } else if (pa_data->length == 6 && + memcmp(pa_data->contents, "no key", 6) == 0) { + printf("no key\n"); +@@ -157,17 +165,34 @@ test_process(krb5_context context, krb5_clpreauth_moddata moddata, + reqst->second_round_trip = TRUE; + + indstr = (st->indicators != NULL) ? st->indicators : ""; +- list = k5calloc(2, sizeof(*list), &ret); +- assert(!ret); +- pa = k5alloc(sizeof(*pa), &ret); +- assert(!ret); +- pa->pa_type = TEST_PA_TYPE; +- pa->contents = (uint8_t *)strdup(indstr); +- assert(pa->contents != NULL); +- pa->length = strlen(indstr); +- list[0] = pa; +- list[1] = NULL; +- *out_pa_data = list; ++ *out_pa_data = make_pa_list(indstr, strlen(indstr)); ++ return 0; ++} ++ ++static krb5_error_code ++test_tryagain(krb5_context context, krb5_clpreauth_moddata moddata, ++ krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt, ++ krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock, ++ krb5_kdc_req *request, krb5_data *enc_req, krb5_data *enc_prev, ++ krb5_preauthtype pa_type, krb5_error *error, ++ krb5_pa_data **padata, krb5_prompter_fct prompter, ++ void *prompter_data, krb5_pa_data ***padata_out) ++{ ++ struct client_state *st = (struct client_state *)moddata; ++ int i; ++ ++ *padata_out = NULL; ++ if (st->fail_tryagain) { ++ k5_setmsg(context, KRB5_PREAUTH_FAILED, "induced tryagain fail"); ++ return KRB5_PREAUTH_FAILED; ++ } ++ if (error->error != KDC_ERR_ENCTYPE_NOSUPP) ++ return KRB5_PREAUTH_FAILED; ++ for (i = 0; padata[i] != NULL; i++) { ++ if (padata[i]->pa_type == TEST_PA_TYPE) ++ printf("tryagain: %.*s\n", padata[i]->length, padata[i]->contents); ++ } ++ *padata_out = make_pa_list("tryagain", 8); + return 0; + } + +@@ -181,6 +206,12 @@ test_gic_opt(krb5_context kcontext, krb5_clpreauth_moddata moddata, + free(st->indicators); + st->indicators = strdup(value); + assert(st->indicators != NULL); ++ } else if (strcmp(attr, "fail_optimistic") == 0) { ++ st->fail_optimistic = TRUE; ++ } else if (strcmp(attr, "fail_2rt") == 0) { ++ st->fail_2rt = TRUE; ++ } else if (strcmp(attr, "fail_tryagain") == 0) { ++ st->fail_tryagain = TRUE; + } + return 0; + } +@@ -205,6 +236,7 @@ clpreauth_test_initvt(krb5_context context, int maj_ver, + vt->request_init = test_request_init; + vt->request_fini = test_request_fini; + vt->process = test_process; ++ vt->tryagain = test_tryagain; + vt->gic_opts = test_gic_opt; + return 0; + } +diff --git a/src/plugins/preauth/test/common.c b/src/plugins/preauth/test/common.c +new file mode 100644 +index 000000000..4d1f49dfa +--- /dev/null ++++ b/src/plugins/preauth/test/common.c +@@ -0,0 +1,61 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* plugins/preauth/test/common.c - common functions for test preauth module */ ++/* ++ * Copyright (C) 2017 by the Massachusetts Institute of Technology. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "k5-int.h" ++#include "common.h" ++ ++krb5_pa_data * ++make_pa(const char *contents, size_t len) ++{ ++ krb5_error_code ret; ++ krb5_pa_data *pa; ++ ++ pa = calloc(1, sizeof(*pa)); ++ assert(pa != NULL); ++ pa->pa_type = TEST_PA_TYPE; ++ pa->contents = k5memdup(contents, len, &ret); ++ assert(!ret); ++ pa->length = len; ++ return pa; ++} ++ ++/* Make a one-element padata list of type TEST_PA_TYPE. */ ++krb5_pa_data ** ++make_pa_list(const char *contents, size_t len) ++{ ++ krb5_pa_data **list; ++ ++ list = calloc(2, sizeof(*list)); ++ assert(list != NULL); ++ list[0] = make_pa(contents, len); ++ return list; ++} +diff --git a/src/plugins/preauth/test/common.h b/src/plugins/preauth/test/common.h +new file mode 100644 +index 000000000..b748e0874 +--- /dev/null ++++ b/src/plugins/preauth/test/common.h +@@ -0,0 +1,41 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* plugins/preauth/test/common.h - Declarations for test preauth module */ ++/* ++ * Copyright (C) 2017 by the Massachusetts Institute of Technology. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#ifndef COMMON_H ++#define COMMON_H ++ ++#define TEST_PA_TYPE -123 ++ ++krb5_pa_data *make_pa(const char *contents, size_t len); ++krb5_pa_data **make_pa_list(const char *contents, size_t len); ++ ++#endif /* COMMON_H */ +diff --git a/src/plugins/preauth/test/deps b/src/plugins/preauth/test/deps +index b48f00032..b1429e9e1 100644 +--- a/src/plugins/preauth/test/deps ++++ b/src/plugins/preauth/test/deps +@@ -11,7 +11,7 @@ cltest.so cltest.po $(OUTPRE)cltest.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ + $(top_srcdir)/include/krb5/clpreauth_plugin.h $(top_srcdir)/include/krb5/plugin.h \ + $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ +- cltest.c ++ cltest.c common.h + kdctest.so kdctest.po $(OUTPRE)kdctest.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ +@@ -22,4 +22,14 @@ kdctest.so kdctest.po $(OUTPRE)kdctest.$(OBJEXT): $(BUILDTOP)/include/autoconf.h + $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ + $(top_srcdir)/include/krb5/kdcpreauth_plugin.h $(top_srcdir)/include/krb5/plugin.h \ + $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ +- kdctest.c ++ common.h kdctest.c ++common.so common.po $(OUTPRE)common.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ ++ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ ++ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ ++ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ ++ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ ++ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ ++ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ ++ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ ++ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ ++ $(top_srcdir)/include/socket-utils.h common.c common.h +diff --git a/src/plugins/preauth/test/kdctest.c b/src/plugins/preauth/test/kdctest.c +index 026dc680d..66b77969a 100644 +--- a/src/plugins/preauth/test/kdctest.c ++++ b/src/plugins/preauth/test/kdctest.c +@@ -1,7 +1,7 @@ + /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ + /* plugins/preauth/test/kdctest.c - Test kdcpreauth module */ + /* +- * Copyright (C) 2015 by the Massachusetts Institute of Technology. ++ * Copyright (C) 2015, 2017 by the Massachusetts Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without +@@ -40,10 +40,20 @@ + * key; the encrypted message "no attr" is sent if there is no string + * attribute.) It also sets a cookie containing "method-data". + * +- * - It retrieves the "2rt" attribute from the client principal. If set, the +- * verify method sends the client a KDC_ERR_MORE_PREAUTH_DATA_REQUIRED error +- * with the contents of the 2rt attribute as pa-data, and sets a cookie +- * containing "more". ++ * - If the "err" attribute is set on the client principal, the verify method ++ * returns an KDC_ERR_ETYPE_NOSUPP error on the first try, with the contents ++ * of the err attribute as pa-data. If the client tries again with the ++ * padata value "tryagain", the verify method preuthenticates successfully ++ * with no additional processing. ++ * ++ * - If the "failopt" attribute is set on the client principal, the verify ++ * method returns KDC_ERR_PREAUTH_FAILED on optimistic preauth attempts. ++ * ++ * - If the "2rt" attribute is set on client principal, the verify method sends ++ * the client a KDC_ERR_MORE_PREAUTH_DATA_REQUIRED error with the contents of ++ * the 2rt attribute as pa-data, and sets a cookie containing "more". If the ++ * "fail2rt" attribute is set on the client principal, the client's second ++ * try results in a KDC_ERR_PREAUTH_FAILED error. + * + * - It receives a space-separated list from the clpreauth module and asserts + * each string as an authentication indicator. It always succeeds in +@@ -52,6 +62,7 @@ + + #include "k5-int.h" + #include ++#include "common.h" + + #define TEST_PA_TYPE -123 + +@@ -73,11 +84,6 @@ test_edata(krb5_context context, krb5_kdc_req *req, + + ret = cb->get_string(context, rock, "teststring", &attr); + assert(!ret); +- pa = k5alloc(sizeof(*pa), &ret); +- assert(!ret); +- if (pa == NULL) +- abort(); +- pa->pa_type = TEST_PA_TYPE; + if (k != NULL) { + d = string2data((attr != NULL) ? attr : "no attr"); + ret = krb5_c_encrypt_length(context, k->enctype, d.length, &enclen); +@@ -86,12 +92,10 @@ test_edata(krb5_context context, krb5_kdc_req *req, + assert(!ret); + ret = krb5_c_encrypt(context, k, 1024, NULL, &d, &enc); + assert(!ret); +- pa->contents = (uint8_t *)enc.ciphertext.data; +- pa->length = enc.ciphertext.length; ++ pa = make_pa(enc.ciphertext.data, enc.ciphertext.length); ++ free(enc.ciphertext.data); + } else { +- pa->contents = (uint8_t *)strdup("no key"); +- assert(pa->contents != NULL); +- pa->length = 6; ++ pa = make_pa("no key", 6); + } + + /* Exercise setting a cookie information from the edata method. */ +@@ -111,12 +115,19 @@ test_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request, + krb5_kdcpreauth_verify_respond_fn respond, void *arg) + { + krb5_error_code ret; +- krb5_boolean second_round_trip = FALSE; +- krb5_pa_data **list; ++ krb5_boolean second_round_trip = FALSE, optimistic = FALSE; ++ krb5_pa_data **list = NULL; + krb5_data cookie_data, d; +- char *str, *ind, *attr, *toksave = NULL; ++ char *str, *ind, *toksave = NULL; ++ char *attr_err, *attr_2rt, *attr_fail2rt, *attr_failopt; + +- ret = cb->get_string(context, rock, "2rt", &attr); ++ ret = cb->get_string(context, rock, "err", &attr_err); ++ assert(!ret); ++ ret = cb->get_string(context, rock, "2rt", &attr_2rt); ++ assert(!ret); ++ ret = cb->get_string(context, rock, "fail2rt", &attr_fail2rt); ++ assert(!ret); ++ ret = cb->get_string(context, rock, "failopt", &attr_failopt); + assert(!ret); + + /* Check the incoming cookie value. */ +@@ -124,13 +135,36 @@ test_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request, + /* Make sure we are seeing optimistic preauth and not a lost cookie. */ + d = make_data(data->contents, data->length); + assert(data_eq_string(d, "optimistic")); ++ optimistic = TRUE; + } else if (data_eq_string(cookie_data, "more")) { + second_round_trip = TRUE; + } else { +- assert(data_eq_string(cookie_data, "method-data")); ++ assert(data_eq_string(cookie_data, "method-data") || ++ data_eq_string(cookie_data, "err")); + } + +- if (attr == NULL || second_round_trip) { ++ if (attr_err != NULL) { ++ d = make_data(data->contents, data->length); ++ if (data_eq_string(d, "tryagain")) { ++ /* Authenticate successfully. */ ++ enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH; ++ } else { ++ d = string2data("err"); ++ ret = cb->set_cookie(context, rock, TEST_PA_TYPE, &d); ++ assert(!ret); ++ ret = KRB5KDC_ERR_ETYPE_NOSUPP; ++ list = make_pa_list(attr_err, strlen(attr_err)); ++ } ++ } else if (attr_2rt != NULL && !second_round_trip) { ++ d = string2data("more"); ++ ret = cb->set_cookie(context, rock, TEST_PA_TYPE, &d); ++ assert(!ret); ++ ret = KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED; ++ list = make_pa_list(attr_2rt, strlen(attr_2rt)); ++ } else if ((attr_fail2rt != NULL && second_round_trip) || ++ (attr_failopt != NULL && optimistic)) { ++ ret = KRB5KDC_ERR_PREAUTH_FAILED; ++ } else { + /* Parse and assert the indicators. */ + str = k5memdup0(data->contents, data->length, &ret); + if (ret) +@@ -142,21 +176,13 @@ test_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request, + } + free(str); + enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH; +- cb->free_string(context, rock, attr); +- (*respond)(arg, 0, NULL, NULL, NULL); +- } else { +- d = string2data("more"); +- ret = cb->set_cookie(context, rock, TEST_PA_TYPE, &d); +- list = k5calloc(2, sizeof(*list), &ret); +- assert(!ret); +- list[0] = k5alloc(sizeof(*list[0]), &ret); +- assert(!ret); +- list[0]->pa_type = TEST_PA_TYPE; +- list[0]->contents = (uint8_t *)attr; +- list[0]->length = strlen(attr); +- (*respond)(arg, KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, NULL, list, +- NULL); + } ++ ++ cb->free_string(context, rock, attr_err); ++ cb->free_string(context, rock, attr_2rt); ++ cb->free_string(context, rock, attr_fail2rt); ++ cb->free_string(context, rock, attr_failopt); ++ (*respond)(arg, ret, NULL, list, NULL); + } + + static krb5_error_code +diff --git a/src/tests/icred.c b/src/tests/icred.c +index 071f91c80..55f929cd7 100644 +--- a/src/tests/icred.c ++++ b/src/tests/icred.c +@@ -35,8 +35,8 @@ + * it is very simplistic, but it can be extended as needed. + */ + ++#include "k5-platform.h" + #include +-#include + + static krb5_context ctx; + +@@ -59,29 +59,64 @@ main(int argc, char **argv) + const char *princstr, *password; + krb5_principal client; + krb5_init_creds_context icc; ++ krb5_get_init_creds_opt *opt; + krb5_creds creds; +- +- if (argc != 3) { +- fprintf(stderr, "Usage: icred princname password\n"); +- exit(1); +- } +- princstr = argv[1]; +- password = argv[2]; ++ krb5_boolean stepwise = FALSE; ++ krb5_preauthtype ptypes[64]; ++ int c, nptypes = 0; ++ char *val; + + check(krb5_init_context(&ctx)); ++ check(krb5_get_init_creds_opt_alloc(ctx, &opt)); ++ ++ while ((c = getopt(argc, argv, "so:X:")) != -1) { ++ switch (c) { ++ case 's': ++ stepwise = TRUE; ++ break; ++ case 'o': ++ assert(nptypes < 64); ++ ptypes[nptypes++] = atoi(optarg); ++ break; ++ case 'X': ++ val = strchr(optarg, '='); ++ if (val != NULL) ++ *val++ = '\0'; ++ else ++ val = "yes"; ++ check(krb5_get_init_creds_opt_set_pa(ctx, opt, optarg, val)); ++ break; ++ default: ++ abort(); ++ } ++ } ++ ++ argc -= optind; ++ argv += optind; ++ if (argc != 2) ++ abort(); ++ princstr = argv[0]; ++ password = argv[1]; ++ + check(krb5_parse_name(ctx, princstr, &client)); + +- /* Try once with the traditional interface. */ +- check(krb5_get_init_creds_password(ctx, &creds, client, password, NULL, +- NULL, 0, NULL, NULL)); +- krb5_free_cred_contents(ctx, &creds); ++ if (nptypes > 0) ++ krb5_get_init_creds_opt_set_preauth_list(opt, ptypes, nptypes); + +- /* Try again with the step interface. */ +- check(krb5_init_creds_init(ctx, client, NULL, NULL, 0, NULL, &icc)); +- check(krb5_init_creds_set_password(ctx, icc, password)); +- check(krb5_init_creds_get(ctx, icc)); +- krb5_init_creds_free(ctx, icc); ++ if (stepwise) { ++ /* Use the stepwise interface. */ ++ check(krb5_init_creds_init(ctx, client, NULL, NULL, 0, NULL, &icc)); ++ check(krb5_init_creds_set_password(ctx, icc, password)); ++ check(krb5_init_creds_get(ctx, icc)); ++ krb5_init_creds_free(ctx, icc); ++ } else { ++ /* Use the traditional one-shot interface. */ ++ check(krb5_get_init_creds_password(ctx, &creds, client, password, NULL, ++ NULL, 0, NULL, opt)); ++ krb5_free_cred_contents(ctx, &creds); ++ } + ++ krb5_get_init_creds_opt_free(ctx, opt); + krb5_free_principal(ctx, client); + krb5_free_context(ctx); + return 0; +diff --git a/src/tests/t_general.py b/src/tests/t_general.py +index 6d523fe45..b16cffa37 100755 +--- a/src/tests/t_general.py ++++ b/src/tests/t_general.py +@@ -30,6 +30,7 @@ conf={'plugins': {'pwqual': {'disable': 'empty'}}} + realm = K5Realm(create_user=False, create_host=False, krb5_conf=conf) + realm.run([kadminl, 'addprinc', '-pw', '', 'user']) + realm.run(['./icred', 'user', '']) ++realm.run(['./icred', '-s', 'user', '']) + realm.stop() + + realm = K5Realm(create_host=False) +diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py +index 38424932b..c25475096 100755 +--- a/src/tests/t_pkinit.py ++++ b/src/tests/t_pkinit.py +@@ -176,14 +176,20 @@ realm.klist(realm.user_princ) + + # Test a DH parameter renegotiation by temporarily setting a 4096-bit + # minimum on the KDC. (Preauth type 16 is PKINIT PA_PK_AS_REQ; +-# 133 is FAST PA-FX-COOKIE.) ++# 109 is PKINIT TD_DH_PARAMETERS; 133 is FAST PA-FX-COOKIE.) + minbits_kdc_conf = {'realms': {'$realm': {'pkinit_dh_min_bits': '4096'}}} + minbits_env = realm.special_env('restrict', True, kdc_conf=minbits_kdc_conf) + realm.stop_kdc() + realm.start_kdc(env=minbits_env) +-expected_trace = ('Key parameters not accepted', +- 'Preauth tryagain input types', ++expected_trace = ('Sending unauthenticated request', ++ '/Additional pre-authentication required', ++ 'Preauthenticating using KDC method data', ++ 'Preauth module pkinit (16) (real) returned: 0/Success', ++ 'Produced preauth for next request: 133, 16', ++ '/Key parameters not accepted', ++ 'Preauth tryagain input types (16): 109, 133', + 'trying again with KDC-provided parameters', ++ 'Preauth module pkinit (16) tryagain returned: 0/Success', + 'Followup preauth for next request: 16, 133') + realm.kinit(realm.user_princ, + flags=['-X', 'X509_user_identity=%s' % file_identity], +diff --git a/src/tests/t_preauth.py b/src/tests/t_preauth.py +index 9b6da5a96..7d4d299dc 100644 +--- a/src/tests/t_preauth.py ++++ b/src/tests/t_preauth.py +@@ -18,11 +18,161 @@ out = realm.run([kinit, 'nokeyuser'], input=password('user')+'\n', + if 'no key' not in out: + fail('Expected "no key" message not in kinit output') + +-# Exercise KDC_ERR_MORE_PREAUTH_DATA_REQUIRED and secure cookies. ++# Preauth type -123 is the test preauth module type; 133 is FAST ++# PA-FX-COOKIE; 2 is encrypted timestamp. ++ ++# Test normal preauth flow. ++expected_trace = ('Sending unauthenticated request', ++ '/Additional pre-authentication required', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: 133, -123', ++ 'Decrypted AS reply') ++realm.run(['./icred', realm.user_princ, password('user')], ++ expected_msg='testval', expected_trace=expected_trace) ++ ++# Test successful optimistic preauth. ++expected_trace = ('Attempting optimistic preauth', ++ 'Processing preauth types: -123', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: -123', ++ 'Decrypted AS reply') ++realm.run(['./icred', '-o', '-123', realm.user_princ, password('user')], ++ expected_trace=expected_trace) ++ ++# Test optimistic preauth failing on client, followed by successful ++# preauth using the same module. ++expected_trace = ('Attempting optimistic preauth', ++ 'Processing preauth types: -123', ++ '/induced optimistic fail', ++ 'Sending unauthenticated request', ++ '/Additional pre-authentication required', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: 133, -123', ++ 'Decrypted AS reply') ++realm.run(['./icred', '-o', '-123', '-X', 'fail_optimistic', realm.user_princ, ++ password('user')], expected_msg='testval', ++ expected_trace=expected_trace) ++ ++# Test optimistic preauth failing on KDC, followed by successful preauth ++# using the same module. ++realm.run([kadminl, 'setstr', realm.user_princ, 'failopt', 'yes']) ++expected_trace = ('Attempting optimistic preauth', ++ 'Processing preauth types: -123', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: -123', ++ '/Preauthentication failed', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: 133, -123', ++ 'Decrypted AS reply') ++realm.run(['./icred', '-o', '-123', realm.user_princ, password('user')], ++ expected_msg='testval', expected_trace=expected_trace) ++realm.run([kadminl, 'delstr', realm.user_princ, 'failopt']) ++ ++# Test KDC_ERR_MORE_PREAUTH_DATA_REQUIRED and secure cookies. + realm.run([kadminl, 'setstr', realm.user_princ, '2rt', 'secondtrip']) +-out = realm.run([kinit, realm.user_princ], input=password('user')+'\n') +-if '2rt: secondtrip' not in out: +- fail('multi round-trip cookie test') ++expected_trace = ('Sending unauthenticated request', ++ '/Additional pre-authentication required', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: 133, -123', ++ '/More preauthentication data is required', ++ 'Continuing preauth mech -123', ++ 'Processing preauth types: -123, 133', ++ 'Produced preauth for next request: 133, -123', ++ 'Decrypted AS reply') ++realm.run(['./icred', realm.user_princ, password('user')], ++ expected_msg='2rt: secondtrip', expected_trace=expected_trace) ++ ++# Test client-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, ++# falling back to encrypted timestamp. ++expected_trace = ('Sending unauthenticated request', ++ '/Additional pre-authentication required', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: 133, -123', ++ '/More preauthentication data is required', ++ 'Continuing preauth mech -123', ++ 'Processing preauth types: -123, 133', ++ '/induced 2rt fail', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Encrypted timestamp (for ', ++ 'module encrypted_timestamp (2) (real) returned: 0/Success', ++ 'Produced preauth for next request: 133, 2', ++ 'Decrypted AS reply') ++realm.run(['./icred', '-X', 'fail_2rt', realm.user_princ, password('user')], ++ expected_msg='2rt: secondtrip', expected_trace=expected_trace) ++ ++# Test KDC-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, ++# falling back to encrypted timestamp. ++realm.run([kadminl, 'setstr', realm.user_princ, 'fail2rt', 'yes']) ++expected_trace = ('Sending unauthenticated request', ++ '/Additional pre-authentication required', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: 133, -123', ++ '/More preauthentication data is required', ++ 'Continuing preauth mech -123', ++ 'Processing preauth types: -123, 133', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: 133, -123', ++ '/Preauthentication failed', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Encrypted timestamp (for ', ++ 'module encrypted_timestamp (2) (real) returned: 0/Success', ++ 'Produced preauth for next request: 133, 2', ++ 'Decrypted AS reply') ++realm.run(['./icred', realm.user_princ, password('user')], ++ expected_msg='2rt: secondtrip', expected_trace=expected_trace) ++realm.run([kadminl, 'delstr', realm.user_princ, 'fail2rt']) ++ ++# Test tryagain flow by inducing a KDC_ERR_ENCTYPE_NOSUPP error on the KDC. ++realm.run([kadminl, 'setstr', realm.user_princ, 'err', 'testagain']) ++expected_trace = ('Sending unauthenticated request', ++ '/Additional pre-authentication required', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: 133, -123', ++ '/KDC has no support for encryption type', ++ 'Recovering from KDC error 14 using preauth mech -123', ++ 'Preauth tryagain input types (-123): -123, 133', ++ 'Preauth module test (-123) tryagain returned: 0/Success', ++ 'Followup preauth for next request: -123, 133', ++ 'Decrypted AS reply') ++realm.run(['./icred', realm.user_princ, password('user')], ++ expected_msg='tryagain: testagain', expected_trace=expected_trace) ++ ++# Test a client-side tryagain failure, falling back to encrypted ++# timestamp. ++expected_trace = ('Sending unauthenticated request', ++ '/Additional pre-authentication required', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: 133, -123', ++ '/KDC has no support for encryption type', ++ 'Recovering from KDC error 14 using preauth mech -123', ++ 'Preauth tryagain input types (-123): -123, 133', ++ '/induced tryagain fail', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Encrypted timestamp (for ', ++ 'module encrypted_timestamp (2) (real) returned: 0/Success', ++ 'Produced preauth for next request: 133, 2', ++ 'Decrypted AS reply') ++realm.run(['./icred', '-X', 'fail_tryagain', realm.user_princ, ++ password('user')], expected_trace=expected_trace) + + # Test that multiple stepwise initial creds operations can be + # performed with the same krb5_context, with proper tracking of diff --git a/SOURCES/Add-test-cert-generation-to-make-certs.sh.patch b/SOURCES/Add-test-cert-generation-to-make-certs.sh.patch new file mode 100644 index 0000000..c44a755 --- /dev/null +++ b/SOURCES/Add-test-cert-generation-to-make-certs.sh.patch @@ -0,0 +1,90 @@ +From c1bda7ba15f8dcf04b6ca24d9f1c7bcf842e4feb Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Tue, 5 Sep 2017 15:54:31 -0400 +Subject: [PATCH] Add test cert generation to make-certs.sh + +Based on commit 5a1d0388ba2e4ec510ed715ce5fbc7f748941425 but missing +everything but the make-certs change since infrastructure cannot patch +binaries. Plan to run make-certs during build, but this will only +work with openssl < 1.1. +--- + src/tests/dejagnu/pkinit-certs/make-certs.sh | 53 +++++++++++++++++++- + 1 file changed, 52 insertions(+), 1 deletion(-) + +diff --git a/src/tests/dejagnu/pkinit-certs/make-certs.sh b/src/tests/dejagnu/pkinit-certs/make-certs.sh +index b82ef6f83..0f07709b0 100755 +--- a/src/tests/dejagnu/pkinit-certs/make-certs.sh ++++ b/src/tests/dejagnu/pkinit-certs/make-certs.sh +@@ -4,7 +4,9 @@ NAMETYPE=1 + KEYSIZE=2048 + DAYS=4000 + REALM=KRBTEST.COM ++LOWREALM=krbtest.com + KRB5_PRINCIPAL_SAN=1.3.6.1.5.2.2 ++KRB5_UPN_SAN=1.3.6.1.4.1.311.20.2.3 + PKINIT_KDC_EKU=1.3.6.1.5.2.3.5 + PKINIT_CLIENT_EKU=1.3.6.1.5.2.3.4 + TLS_SERVER_EKU=1.3.6.1.5.5.7.3.1 +@@ -85,6 +87,30 @@ keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement + basicConstraints = critical,CA:FALSE + subjectAltName = otherName:$KRB5_PRINCIPAL_SAN;SEQUENCE:krb5princ_client + extendedKeyUsage = $CLIENT_EKU_LIST ++ ++[exts_upn_client] ++subjectKeyIdentifier = hash ++authorityKeyIdentifier = keyid:always,issuer:always ++keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement ++basicConstraints = critical,CA:FALSE ++subjectAltName = otherName:$KRB5_UPN_SAN;UTF8:user@$LOWREALM ++extendedKeyUsage = $CLIENT_EKU_LIST ++ ++[exts_upn2_client] ++subjectKeyIdentifier = hash ++authorityKeyIdentifier = keyid:always,issuer:always ++keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement ++basicConstraints = critical,CA:FALSE ++subjectAltName = otherName:$KRB5_UPN_SAN;UTF8:user ++extendedKeyUsage = $CLIENT_EKU_LIST ++ ++[exts_upn3_client] ++subjectKeyIdentifier = hash ++authorityKeyIdentifier = keyid:always,issuer:always ++keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement ++basicConstraints = critical,CA:FALSE ++subjectAltName = otherName:$KRB5_UPN_SAN;UTF8:user@$REALM ++extendedKeyUsage = $CLIENT_EKU_LIST + EOF + + # Generate a private key. +@@ -113,5 +139,30 @@ openssl pkcs12 -export -in user.pem -inkey privkey.pem -out user.p12 \ + openssl pkcs12 -export -in user.pem -inkey privkey.pem -out user-enc.p12 \ + -passout pass:encrypted + ++# Generate a client certificate and PKCS#12 bundles with a UPN SAN. ++SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \ ++ -key privkey.pem -out user-upn.csr ++SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn_client \ ++ -set_serial 4 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ ++ -out user-upn.pem -in user-upn.csr ++openssl pkcs12 -export -in user-upn.pem -inkey privkey.pem -out user-upn.p12 \ ++ -passout pass: ++ ++SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \ ++ -key privkey.pem -out user-upn2.csr ++SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn2_client \ ++ -set_serial 5 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ ++ -out user-upn2.pem -in user-upn2.csr ++openssl pkcs12 -export -in user-upn2.pem -inkey privkey.pem \ ++ -out user-upn2.p12 -passout pass: ++ ++SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \ ++ -key privkey.pem -out user-upn3.csr ++SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn3_client \ ++ -set_serial 6 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ ++ -out user-upn3.pem -in user-upn3.csr ++openssl pkcs12 -export -in user-upn3.pem -inkey privkey.pem \ ++ -out user-upn3.p12 -passout pass: ++ + # Clean up. +-rm -f openssl.cnf kdc.csr user.csr ++rm -f openssl.cnf kdc.csr user.csr user-upn.csr user-upn2.csr user-upn3.csr diff --git a/SOURCES/Add-test-cert-with-no-extensions.patch b/SOURCES/Add-test-cert-with-no-extensions.patch new file mode 100644 index 0000000..5c5e361 --- /dev/null +++ b/SOURCES/Add-test-cert-with-no-extensions.patch @@ -0,0 +1,34 @@ +From 728d567d1c7445e89edad046d8aac5344143d51d Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Thu, 5 Oct 2017 12:54:13 -0400 +Subject: [PATCH] Add test cert with no extensions + +Add commands to make-certs.sh to generate a test client certificate +with no certificate extensions. Re-run make-certs.sh. + +ticket: 8562 +(cherry-picked from commit 0d23835660ab131d244d395e4568969b5c0dc678) +[rharwood@redhat.com: only backport the make-certs.sh changes] +--- + src/tests/dejagnu/pkinit-certs/make-certs.sh | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/tests/dejagnu/pkinit-certs/make-certs.sh b/src/tests/dejagnu/pkinit-certs/make-certs.sh +index 0d8c2019a..23426af8a 100755 +--- a/src/tests/dejagnu/pkinit-certs/make-certs.sh ++++ b/src/tests/dejagnu/pkinit-certs/make-certs.sh +@@ -163,5 +163,14 @@ SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn3_client \ + openssl pkcs12 -export -in user-upn3.pem -inkey privkey.pem \ + -out user-upn3.p12 -passout pass: + ++# Generate a client certificate and PKCS#12 bundle with no PKINIT extensions. ++SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \ ++ -key privkey.pem -out generic.csr ++SUBJECT=user openssl x509 -set_serial 7 -days $DAYS -req -CA ca.pem \ ++ -CAkey privkey.pem -out generic.pem -in generic.csr ++openssl pkcs12 -export -in generic.pem -inkey privkey.pem -out generic.p12 \ ++ -passout pass: ++ + # Clean up. + rm -f openssl.cnf kdc.csr user.csr user-upn.csr user-upn2.csr user-upn3.csr ++rm -f generic.csr diff --git a/SOURCES/Add-tests-for-per-request-preauth-data-scoping.patch b/SOURCES/Add-tests-for-per-request-preauth-data-scoping.patch new file mode 100644 index 0000000..dc9ca95 --- /dev/null +++ b/SOURCES/Add-tests-for-per-request-preauth-data-scoping.patch @@ -0,0 +1,228 @@ +From 2d8f53212aec704a60e0a96327d8cfd999306ceb Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Wed, 4 Jan 2017 18:31:15 -0500 +Subject: [PATCH] Add tests for per-request preauth data scoping + +Add a test harness which interleaves calls for multiple initial creds +contexts using the same library context. Add a test case to +t_preauth.py using the new harness and the test preauth module to +verify that modreq pointers are correctly tracked. + +ticket: 7877 +(cherry picked from commit c0b25fe282355d4f329418956b9c6295780af633) +[rharwood@redhat.com: drop .gitignore] +--- + src/tests/Makefile.in | 23 +++++--- + src/tests/icinterleave.c | 124 +++++++++++++++++++++++++++++++++++++++ + src/tests/t_preauth.py | 13 ++++ + 3 files changed, 151 insertions(+), 9 deletions(-) + create mode 100644 src/tests/icinterleave.c + +diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in +index a2093108b..bd1b21346 100644 +--- a/src/tests/Makefile.in ++++ b/src/tests/Makefile.in +@@ -6,12 +6,12 @@ SUBDIRS = resolve asn.1 create hammer verify gssapi dejagnu shlib \ + RUN_DB_TEST = $(RUN_SETUP) KRB5_KDC_PROFILE=kdc.conf KRB5_CONFIG=krb5.conf \ + LC_ALL=C $(VALGRIND) + +-OBJS= adata.o etinfo.o forward.o gcred.o hist.o hooks.o hrealm.o icred.o \ +- kdbtest.o localauth.o plugorder.o rdreq.o responder.o s2p.o \ +- s4u2proxy.o unlockiter.o ++OBJS= adata.o etinfo.o forward.o gcred.o hist.o hooks.o hrealm.o \ ++ icinterleave.o icred.o kdbtest.o localauth.o plugorder.o rdreq.o \ ++ responder.o s2p.o s4u2proxy.o unlockiter.o + EXTRADEPSRCS= adata.c etinfo.c forward.c gcred.c hist.c hooks.c hrealm.c \ +- icred.c kdbtest.c localauth.c plugorder.c rdreq.o responder.c s2p.c \ +- s4u2proxy.c unlockiter.c ++ icinterleave.c icred.c kdbtest.c localauth.c plugorder.c rdreq.o \ ++ responder.c s2p.c s4u2proxy.c unlockiter.c + + TEST_DB = ./testdb + TEST_REALM = FOO.TEST.REALM +@@ -44,6 +44,9 @@ hooks: hooks.o $(KRB5_BASE_DEPLIBS) + hrealm: hrealm.o $(KRB5_BASE_DEPLIBS) + $(CC_LINK) -o $@ hrealm.o $(KRB5_BASE_LIBS) + ++icinterleave: icinterleave.o $(KRB5_BASE_DEPLIBS) ++ $(CC_LINK) -o $@ icinterleave.o $(KRB5_BASE_LIBS) ++ + icred: icred.o $(KRB5_BASE_DEPLIBS) + $(CC_LINK) -o $@ icred.o $(KRB5_BASE_LIBS) + +@@ -115,8 +118,9 @@ kdb_check: kdc.conf krb5.conf + $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) destroy -f + $(RM) $(TEST_DB)* stash_file + +-check-pytests: adata etinfo forward gcred hist hooks hrealm icred kdbtest +-check-pytests: localauth plugorder rdreq responder s2p s4u2proxy unlockiter ++check-pytests: adata etinfo forward gcred hist hooks hrealm icinterleave icred ++check-pytests: kdbtest localauth plugorder rdreq responder s2p s4u2proxy ++check-pytests: unlockiter + $(RUNPYTEST) $(srcdir)/t_general.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_hooks.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_dump.py $(PYTESTFLAGS) +@@ -172,8 +176,9 @@ check-pytests: localauth plugorder rdreq responder s2p s4u2proxy unlockiter + $(RUNPYTEST) $(srcdir)/t_kdcpolicy.py $(PYTESTFLAGS) + + clean: +- $(RM) adata etinfo forward gcred hist hooks hrealm icred kdbtest +- $(RM) localauth plugorder rdreq responder s2p s4u2proxy unlockiter ++ $(RM) adata etinfo forward gcred hist hooks hrealm icinterleave icred ++ $(RM) kdbtest localauth plugorder rdreq responder s2p s4u2proxy ++ $(RM) unlockiter + $(RM) krb5.conf kdc.conf + $(RM) -rf kdc_realm/sandbox ldap + $(RM) au.log +diff --git a/src/tests/icinterleave.c b/src/tests/icinterleave.c +new file mode 100644 +index 000000000..d76ecf361 +--- /dev/null ++++ b/src/tests/icinterleave.c +@@ -0,0 +1,124 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* tests/icinterleave.c - interleaved init_creds_step test harness */ ++/* ++ * Copyright (C) 2017 by the Massachusetts Institute of Technology. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* ++ * This test harness performs multiple initial creds operations using ++ * krb5_init_creds_step(), interleaving the operations to test the scoping of ++ * the preauth state. All principals must have the same password (or not ++ * require a password). ++ */ ++ ++#include "k5-int.h" ++ ++static krb5_context ctx; ++ ++static void ++check(krb5_error_code code) ++{ ++ const char *errmsg; ++ ++ if (code) { ++ errmsg = krb5_get_error_message(ctx, code); ++ fprintf(stderr, "%s\n", errmsg); ++ krb5_free_error_message(ctx, errmsg); ++ exit(1); ++ } ++} ++ ++int ++main(int argc, char **argv) ++{ ++ const char *password; ++ char **princstrs; ++ krb5_principal client; ++ krb5_init_creds_context *iccs; ++ krb5_data req, *reps, realm; ++ krb5_boolean any_left; ++ int i, nclients, master; ++ unsigned int flags; ++ ++ if (argc < 3) { ++ fprintf(stderr, "Usage: icinterleave password princ1 princ2 ...\n"); ++ exit(1); ++ } ++ password = argv[1]; ++ princstrs = argv + 2; ++ nclients = argc - 2; ++ ++ check(krb5_init_context(&ctx)); ++ ++ /* Create an initial creds context for each client principal. */ ++ iccs = calloc(nclients, sizeof(*iccs)); ++ assert(iccs != NULL); ++ for (i = 0; i < nclients; i++) { ++ check(krb5_parse_name(ctx, princstrs[i], &client)); ++ check(krb5_init_creds_init(ctx, client, NULL, NULL, 0, NULL, ++ &iccs[i])); ++ check(krb5_init_creds_set_password(ctx, iccs[i], password)); ++ krb5_free_principal(ctx, client); ++ } ++ ++ reps = calloc(nclients, sizeof(*reps)); ++ assert(reps != NULL); ++ ++ any_left = TRUE; ++ while (any_left) { ++ any_left = FALSE; ++ for (i = 0; i < nclients; i++) { ++ if (iccs[i] == NULL) ++ continue; ++ any_left = TRUE; ++ ++ printf("step %d\n", i + 1); ++ ++ req = empty_data(); ++ realm = empty_data(); ++ check(krb5_init_creds_step(ctx, iccs[i], &reps[i], &req, &realm, ++ &flags)); ++ if (!(flags & KRB5_INIT_CREDS_STEP_FLAG_CONTINUE)) { ++ printf("finish %d\n", i + 1); ++ krb5_init_creds_free(ctx, iccs[i]); ++ iccs[i] = NULL; ++ continue; ++ } ++ ++ master = 0; ++ krb5_free_data_contents(ctx, &reps[i]); ++ check(krb5_sendto_kdc(ctx, &req, &realm, &reps[i], &master, 0)); ++ krb5_free_data_contents(ctx, &req); ++ krb5_free_data_contents(ctx, &realm); ++ } ++ } ++ ++ krb5_free_context(ctx); ++ return 0; ++} +diff --git a/src/tests/t_preauth.py b/src/tests/t_preauth.py +index 0ef8bbca4..9b6da5a96 100644 +--- a/src/tests/t_preauth.py ++++ b/src/tests/t_preauth.py +@@ -24,4 +24,17 @@ out = realm.run([kinit, realm.user_princ], input=password('user')+'\n') + if '2rt: secondtrip' not in out: + fail('multi round-trip cookie test') + ++# Test that multiple stepwise initial creds operations can be ++# performed with the same krb5_context, with proper tracking of ++# clpreauth module request handles. ++realm.run([kadminl, 'addprinc', '-pw', 'pw', 'u1']) ++realm.run([kadminl, 'addprinc', '+requires_preauth', '-pw', 'pw', 'u2']) ++realm.run([kadminl, 'addprinc', '+requires_preauth', '-pw', 'pw', 'u3']) ++realm.run([kadminl, 'setstr', 'u2', '2rt', 'extra']) ++out = realm.run(['./icinterleave', 'pw', 'u1', 'u2', 'u3']) ++if out != ('step 1\nstep 2\nstep 3\nstep 1\nfinish 1\nstep 2\nno attr\n' ++ 'step 3\nno attr\nstep 2\n2rt: extra\nstep 3\nfinish 3\nstep 2\n' ++ 'finish 2\n'): ++ fail('unexpected output from icinterleave') ++ + success('Pre-authentication framework tests') diff --git a/SOURCES/Add-the-certauth-dbmatch-module.patch b/SOURCES/Add-the-certauth-dbmatch-module.patch new file mode 100644 index 0000000..e14b029 --- /dev/null +++ b/SOURCES/Add-the-certauth-dbmatch-module.patch @@ -0,0 +1,316 @@ +From fab1e4f8553dcf8a573c41bb8ea93912a622aae0 Mon Sep 17 00:00:00 2001 +From: Matt Rogers +Date: Wed, 15 Mar 2017 19:57:15 -0400 +Subject: [PATCH] Add the certauth dbmatch module + +Add and enable the "dbmatch" builtin module. Add the +pkinit_client_cert_match() and crypto_req_cert_matching_data() helper +functions. Add dbmatch tests to t_pkinit.py. Add documentation to +krb5_conf.rst, pkinit.rst, and kadmin_local.rst. + +[ghudson@mit.edu: simplified code, edited docs] + +ticket: 8562 (new) +(cherry picked from commit 89634ca049e698d7dd2554f5c49bfc499be96188) +--- + doc/admin/admin_commands/kadmin_local.rst | 7 +++ + doc/admin/conf_files/krb5_conf.rst | 5 ++ + doc/admin/pkinit.rst | 20 +++++++ + src/plugins/preauth/pkinit/pkinit.h | 7 +++ + src/plugins/preauth/pkinit/pkinit_crypto.h | 6 ++ + .../preauth/pkinit/pkinit_crypto_openssl.c | 18 ++++++ + src/plugins/preauth/pkinit/pkinit_matching.c | 37 +++++++++++++ + src/plugins/preauth/pkinit/pkinit_srv.c | 55 +++++++++++++++++++ + src/tests/t_pkinit.py | 37 +++++++++++++ + 9 files changed, 192 insertions(+) + +diff --git a/doc/admin/admin_commands/kadmin_local.rst b/doc/admin/admin_commands/kadmin_local.rst +index 0e955faf2..cefe6054b 100644 +--- a/doc/admin/admin_commands/kadmin_local.rst ++++ b/doc/admin/admin_commands/kadmin_local.rst +@@ -661,6 +661,13 @@ KDC: + *principal*. The *value* is a JSON string representing an array + of objects, each having optional ``type`` and ``username`` fields. + ++**pkinit_cert_match** ++ Specifies a matching expression that defines the certificate ++ attributes required for the client certificate used by the ++ principal during PKINIT authentication. The matching expression ++ is in the same format as those used by the **pkinit_cert_match** ++ option in :ref:`krb5.conf(5)`. (New in release 1.16.) ++ + This command requires the **modify** privilege. + + Alias: **setstr** +diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst +index cc996f11a..d428124c9 100644 +--- a/doc/admin/conf_files/krb5_conf.rst ++++ b/doc/admin/conf_files/krb5_conf.rst +@@ -883,6 +883,11 @@ following built-in modules exist for this interface: + Extended Key Usage attribute consistent with the + **pkinit_eku_checking** value for the realm. + ++**dbmatch** ++ This module authorizes or rejects the certificate according to ++ whether it matches the **pkinit_cert_match** string attribute on ++ the client principal, if that attribute is present. ++ + + PKINIT options + -------------- +diff --git a/doc/admin/pkinit.rst b/doc/admin/pkinit.rst +index 460d75d1e..c601c5c9e 100644 +--- a/doc/admin/pkinit.rst ++++ b/doc/admin/pkinit.rst +@@ -223,6 +223,26 @@ time as follows:: + + kadmin -q 'add_principal +requires_preauth -nokey YOUR_PRINCNAME' + ++By default, the KDC requires PKINIT client certificates to have the ++standard Extended Key Usage and Subject Alternative Name attributes ++for PKINIT. Starting in release 1.16, it is possible to authorize ++client certificates based on the subject or other criteria instead of ++the standard PKINIT Subject Alternative Name, by setting the ++**pkinit_cert_match** string attribute on each client principal entry. ++For example:: ++ ++ kadmin set_string user@REALM pkinit_cert_match "CN=user@REALM$" ++ ++The **pkinit_cert_match** string attribute follows the syntax used by ++the :ref:`krb5.conf(5)` **pkinit_cert_match** relation. To allow the ++use of non-PKINIT client certificates, it will also be necessary to ++disable key usage checking using the **pkinit_eku_checking** relation; ++for example:: ++ ++ [kdcdefaults] ++ pkinit_eku_checking = none ++ ++ + + Configuring the clients + ----------------------- +diff --git a/src/plugins/preauth/pkinit/pkinit.h b/src/plugins/preauth/pkinit/pkinit.h +index a49f3078e..430b3f334 100644 +--- a/src/plugins/preauth/pkinit/pkinit.h ++++ b/src/plugins/preauth/pkinit/pkinit.h +@@ -292,6 +292,13 @@ krb5_error_code pkinit_cert_matching + pkinit_identity_crypto_context id_cryptoctx, + krb5_principal princ); + ++krb5_error_code pkinit_client_cert_match ++ (krb5_context context, ++ pkinit_plg_crypto_context plgctx, ++ pkinit_req_crypto_context reqctx, ++ const char *match_rule, ++ krb5_boolean *matched); ++ + /* + * Client's list of identities for which it needs PINs or passwords + */ +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h +index b6e4e0ac3..149923b1d 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto.h ++++ b/src/plugins/preauth/pkinit/pkinit_crypto.h +@@ -637,4 +637,10 @@ krb5_error_code + crypto_encode_der_cert(krb5_context context, pkinit_req_crypto_context reqctx, + uint8_t **der_out, size_t *der_len); + ++krb5_error_code ++crypto_req_cert_matching_data(krb5_context context, ++ pkinit_plg_crypto_context plgctx, ++ pkinit_req_crypto_context reqctx, ++ pkinit_cert_matching_data **md_out); ++ + #endif /* _PKINIT_CRYPTO_H */ +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index 3949eb9c2..534161b19 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -6099,3 +6099,21 @@ crypto_encode_der_cert(krb5_context context, pkinit_req_crypto_context reqctx, + *der_len = len; + return 0; + } ++ ++/* ++ * Get the certificate matching data from the request certificate. ++ */ ++krb5_error_code ++crypto_req_cert_matching_data(krb5_context context, ++ pkinit_plg_crypto_context plgctx, ++ pkinit_req_crypto_context reqctx, ++ pkinit_cert_matching_data **md_out) ++{ ++ *md_out = NULL; ++ ++ if (reqctx == NULL || reqctx->received_cert == NULL) ++ return ENOENT; ++ ++ return get_matching_data(context, plgctx, reqctx, reqctx->received_cert, ++ md_out); ++} +diff --git a/src/plugins/preauth/pkinit/pkinit_matching.c b/src/plugins/preauth/pkinit/pkinit_matching.c +index d929fb3c0..c2a4c084d 100644 +--- a/src/plugins/preauth/pkinit/pkinit_matching.c ++++ b/src/plugins/preauth/pkinit/pkinit_matching.c +@@ -724,3 +724,40 @@ cleanup: + crypto_cert_free_matching_data_list(context, matchdata); + return retval; + } ++ ++krb5_error_code ++pkinit_client_cert_match(krb5_context context, ++ pkinit_plg_crypto_context plgctx, ++ pkinit_req_crypto_context reqctx, ++ const char *match_rule, ++ krb5_boolean *matched) ++{ ++ krb5_error_code ret; ++ pkinit_cert_matching_data *md = NULL; ++ rule_component *rc = NULL; ++ int comp_match = 0; ++ rule_set *rs = NULL; ++ ++ *matched = FALSE; ++ ret = parse_rule_set(context, match_rule, &rs); ++ if (ret) ++ goto cleanup; ++ ++ ret = crypto_req_cert_matching_data(context, plgctx, reqctx, &md); ++ if (ret) ++ goto cleanup; ++ ++ for (rc = rs->crs; rc != NULL; rc = rc->next) { ++ comp_match = component_match(context, rc, md); ++ if ((comp_match && rs->relation == relation_or) || ++ (!comp_match && rs->relation == relation_and)) { ++ break; ++ } ++ } ++ *matched = comp_match; ++ ++cleanup: ++ free_rule_set(context, rs); ++ crypto_cert_free_matching_data(context, md); ++ return ret; ++} +diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c +index 42ad45fe4..7d86e597e 100644 +--- a/src/plugins/preauth/pkinit/pkinit_srv.c ++++ b/src/plugins/preauth/pkinit/pkinit_srv.c +@@ -1537,6 +1537,56 @@ certauth_pkinit_eku_initvt(krb5_context context, int maj_ver, int min_ver, + return 0; + } + ++/* ++ * Do certificate auth based on a match expression in the pkinit_cert_match ++ * attribute string. An expression should be in the same form as those used ++ * for the pkinit_cert_match configuration option. ++ */ ++static krb5_error_code ++dbmatch_authorize(krb5_context context, krb5_certauth_moddata moddata, ++ const uint8_t *cert, size_t cert_len, ++ krb5_const_principal princ, const void *opts, ++ const krb5_db_entry *db_entry, char ***authinds_out) ++{ ++ krb5_error_code ret; ++ const struct certauth_req_opts *req_opts = opts; ++ char *pattern; ++ krb5_boolean matched; ++ ++ *authinds_out = NULL; ++ ++ /* Fetch the matching pattern. Pass if it isn't specified. */ ++ ret = req_opts->cb->get_string(context, req_opts->rock, ++ "pkinit_cert_match", &pattern); ++ if (ret) ++ return ret; ++ if (pattern == NULL) ++ return KRB5_PLUGIN_NO_HANDLE; ++ ++ /* Check the certificate against the match expression. */ ++ ret = pkinit_client_cert_match(context, req_opts->plgctx->cryptoctx, ++ req_opts->reqctx->cryptoctx, pattern, ++ &matched); ++ req_opts->cb->free_string(context, req_opts->rock, pattern); ++ if (ret) ++ return ret; ++ return matched ? 0 : KRB5KDC_ERR_CERTIFICATE_MISMATCH; ++} ++ ++static krb5_error_code ++certauth_dbmatch_initvt(krb5_context context, int maj_ver, int min_ver, ++ krb5_plugin_vtable vtable) ++{ ++ krb5_certauth_vtable vt; ++ ++ if (maj_ver != 1) ++ return KRB5_PLUGIN_VER_NOTSUPP; ++ vt = (krb5_certauth_vtable)vtable; ++ vt->name = "dbmatch"; ++ vt->authorize = dbmatch_authorize; ++ return 0; ++} ++ + static krb5_error_code + load_certauth_plugins(krb5_context context, certauth_handle **handle_out) + { +@@ -1556,6 +1606,11 @@ load_certauth_plugins(krb5_context context, certauth_handle **handle_out) + if (ret) + goto cleanup; + ++ ret = k5_plugin_register(context, PLUGIN_INTERFACE_CERTAUTH, "dbmatch", ++ certauth_dbmatch_initvt); ++ if (ret) ++ goto cleanup; ++ + ret = k5_plugin_load_all(context, PLUGIN_INTERFACE_CERTAUTH, &modules); + if (ret) + goto cleanup; +diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py +index 64ff2393a..5a0624de7 100755 +--- a/src/tests/t_pkinit.py ++++ b/src/tests/t_pkinit.py +@@ -305,6 +305,43 @@ realm.run(['./responder', '-X', 'X509_user_identity=%s' % p12_enc_identity, + realm.klist(realm.user_princ) + realm.run([kvno, realm.host_princ]) + ++# Match a single rule. ++rule = '^user@KRBTEST.COM$' ++realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) ++realm.kinit(realm.user_princ, ++ flags=['-X', 'X509_user_identity=%s' % p12_identity]) ++realm.klist(realm.user_princ) ++ ++# Match a combined rule (default prefix is &&). ++rule = 'CN=user$digitalSignature,keyEncipherment' ++realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) ++realm.kinit(realm.user_princ, ++ flags=['-X', 'X509_user_identity=%s' % p12_identity]) ++realm.klist(realm.user_princ) ++ ++# Fail an && rule. ++rule = '&&O=OTHER.COM^user@KRBTEST.COM$' ++realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) ++msg = 'kinit: Certificate mismatch while getting initial credentials' ++realm.kinit(realm.user_princ, ++ flags=['-X', 'X509_user_identity=%s' % p12_identity], ++ expected_code=1, expected_msg=msg) ++ ++# Pass an || rule. ++rule = '||O=KRBTEST.COM^otheruser@KRBTEST.COM$' ++realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) ++realm.kinit(realm.user_princ, ++ flags=['-X', 'X509_user_identity=%s' % p12_identity]) ++realm.klist(realm.user_princ) ++ ++# Fail an || rule. ++rule = '||O=OTHER.COM^otheruser@KRBTEST.COM$' ++realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) ++msg = 'kinit: Certificate mismatch while getting initial credentials' ++realm.kinit(realm.user_princ, ++ flags=['-X', 'X509_user_identity=%s' % p12_identity], ++ expected_code=1, expected_msg=msg) ++ + if not have_soft_pkcs11: + skip_rest('PKINIT PKCS11 tests', 'soft-pkcs11.so not found') + diff --git a/SOURCES/Add-the-client_name-kdcpreauth-callback.patch b/SOURCES/Add-the-client_name-kdcpreauth-callback.patch new file mode 100644 index 0000000..d9f3412 --- /dev/null +++ b/SOURCES/Add-the-client_name-kdcpreauth-callback.patch @@ -0,0 +1,58 @@ +From 810e831592eeed8422197d9c8de237552645412f Mon Sep 17 00:00:00 2001 +From: Matt Rogers +Date: Tue, 4 Apr 2017 16:54:56 -0400 +Subject: [PATCH] Add the client_name() kdcpreauth callback + +Add a kdcpreauth callback to returns the canonicalized client principal. + +ticket: 8570 (new) +(cherry picked from commit a84f39ec30f3deeda7836da6e8b3d8dcf7a045b1) +--- + src/include/krb5/kdcpreauth_plugin.h | 6 ++++++ + src/kdc/kdc_preauth.c | 9 ++++++++- + 2 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/src/include/krb5/kdcpreauth_plugin.h b/src/include/krb5/kdcpreauth_plugin.h +index 92aa5a5a5..fa4436b83 100644 +--- a/src/include/krb5/kdcpreauth_plugin.h ++++ b/src/include/krb5/kdcpreauth_plugin.h +@@ -232,6 +232,12 @@ typedef struct krb5_kdcpreauth_callbacks_st { + krb5_kdcpreauth_rock rock, + krb5_principal princ); + ++ /* ++ * Get an alias to the client DB entry principal (possibly canonicalized). ++ */ ++ krb5_principal (*client_name)(krb5_context context, ++ krb5_kdcpreauth_rock rock); ++ + /* End of version 4 kdcpreauth callbacks. */ + + } *krb5_kdcpreauth_callbacks; +diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c +index 0ce79c667..81d0b8cff 100644 +--- a/src/kdc/kdc_preauth.c ++++ b/src/kdc/kdc_preauth.c +@@ -591,6 +591,12 @@ match_client(krb5_context context, krb5_kdcpreauth_rock rock, + return match; + } + ++static krb5_principal ++client_name(krb5_context context, krb5_kdcpreauth_rock rock) ++{ ++ return rock->client->princ; ++} ++ + static struct krb5_kdcpreauth_callbacks_st callbacks = { + 4, + max_time_skew, +@@ -607,7 +613,8 @@ static struct krb5_kdcpreauth_callbacks_st callbacks = { + add_auth_indicator, + get_cookie, + set_cookie, +- match_client ++ match_client, ++ client_name + }; + + static krb5_error_code diff --git a/SOURCES/Add-timestamp-helper-functions.patch b/SOURCES/Add-timestamp-helper-functions.patch new file mode 100644 index 0000000..6cf4fa8 --- /dev/null +++ b/SOURCES/Add-timestamp-helper-functions.patch @@ -0,0 +1,80 @@ +From 7beabe5cf16644dd0857a5e65fc43470e8b5d852 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Sat, 22 Apr 2017 09:49:12 -0400 +Subject: [PATCH] Add timestamp helper functions + +Add k5-int.h helper functions to manipulate krb5_timestamp values, +avoiding undefined behavior and treating negative timestamp values as +times between 2038 and 2106. Add a doxygen comment for krb5_timestamp +indicating how third-party code should use it safely. + +ticket: 8352 +(cherry picked from commit 58e9155060cd93b1a7557e37fbc9b077b76465c2) +--- + src/include/k5-int.h | 31 +++++++++++++++++++++++++++++++ + src/include/krb5/krb5.hin | 9 +++++++++ + 2 files changed, 40 insertions(+) + +diff --git a/src/include/k5-int.h b/src/include/k5-int.h +index 06ca2b66d..82ee20760 100644 +--- a/src/include/k5-int.h ++++ b/src/include/k5-int.h +@@ -2353,6 +2353,37 @@ k5memdup0(const void *in, size_t len, krb5_error_code *code) + return ptr; + } + ++/* Convert a krb5_timestamp to a time_t value, treating the negative range of ++ * krb5_timestamp as times between 2038 and 2106 (if time_t is 64-bit). */ ++static inline time_t ++ts2tt(krb5_timestamp timestamp) ++{ ++ return (time_t)(uint32_t)timestamp; ++} ++ ++/* Return the delta between two timestamps (a - b) as a signed 32-bit value, ++ * without relying on undefined behavior. */ ++static inline krb5_deltat ++ts_delta(krb5_timestamp a, krb5_timestamp b) ++{ ++ return (krb5_deltat)((uint32_t)a - (uint32_t)b); ++} ++ ++/* Increment a timestamp by a signed 32-bit interval, without relying on ++ * undefined behavior. */ ++static inline krb5_timestamp ++ts_incr(krb5_timestamp ts, krb5_deltat delta) ++{ ++ return (krb5_timestamp)((uint32_t)ts + (uint32_t)delta); ++} ++ ++/* Return true if a comes after b. */ ++static inline krb5_boolean ++ts_after(krb5_timestamp a, krb5_timestamp b) ++{ ++ return (uint32_t)a > (uint32_t)b; ++} ++ + krb5_error_code KRB5_CALLCONV + krb5_get_credentials_for_user(krb5_context context, krb5_flags options, + krb5_ccache ccache, +diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin +index cf60d6c41..53ad85384 100644 +--- a/src/include/krb5/krb5.hin ++++ b/src/include/krb5/krb5.hin +@@ -187,7 +187,16 @@ typedef krb5_int32 krb5_cryptotype; + + typedef krb5_int32 krb5_preauthtype; /* This may change, later on */ + typedef krb5_int32 krb5_flags; ++ ++/** ++ * Represents a timestamp in seconds since the POSIX epoch. This legacy type ++ * is used frequently in the ABI, but cannot represent timestamps after 2038 as ++ * a positive number. Code which uses this type should cast values of it to ++ * uint32_t so that negative values are treated as timestamps between 2038 and ++ * 2106 on platforms with 64-bit time_t. ++ */ + typedef krb5_int32 krb5_timestamp; ++ + typedef krb5_int32 krb5_deltat; + + /** diff --git a/SOURCES/Add-timestamp-tests.patch b/SOURCES/Add-timestamp-tests.patch new file mode 100644 index 0000000..704fed1 --- /dev/null +++ b/SOURCES/Add-timestamp-tests.patch @@ -0,0 +1,599 @@ +From 88c93d33d66abe9811e478fd678ff2e5f38a29aa Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Sat, 29 Apr 2017 17:30:36 -0400 +Subject: [PATCH] Add timestamp tests + +Add a test program for krb5int_validate_times() covering cases before +and across the y2038 boundary. Add a GSSAPI test program to exercise +lifetime queries, and tests using it in t_gssapi.py for ticket end +times after y2038. Add a new test script t_y2038.py which only runs +on platforms with 64-bit time_t to exercise end-user operations across +and after y2038. Add an LDAP test case to test storage of post-y2038 +timestamps. + +ticket: 8352 +(cherry picked from commit 8ca62e54e89e2fbd6a089e8ab20b4e374a486003) +[rharwood@redhat.com: prune gitignore] +--- + src/Makefile.in | 1 + + src/config/pre.in | 2 + + src/configure.in | 3 + + src/lib/krb5/krb/Makefile.in | 14 +++- + src/lib/krb5/krb/t_valid_times.c | 109 ++++++++++++++++++++++++ + src/tests/Makefile.in | 1 + + src/tests/gssapi/Makefile.in | 27 +++--- + src/tests/gssapi/t_gssapi.py | 32 +++++++ + src/tests/gssapi/t_lifetime.c | 140 +++++++++++++++++++++++++++++++ + src/tests/t_kdb.py | 7 ++ + src/tests/t_y2038.py | 75 +++++++++++++++++ + 11 files changed, 395 insertions(+), 16 deletions(-) + create mode 100644 src/lib/krb5/krb/t_valid_times.c + create mode 100644 src/tests/gssapi/t_lifetime.c + create mode 100644 src/tests/t_y2038.py + +diff --git a/src/Makefile.in b/src/Makefile.in +index b0249778c..ad8565056 100644 +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -521,6 +521,7 @@ pyrunenv.vals: Makefile + done > $@ + echo "tls_impl = '$(TLS_IMPL)'" >> $@ + echo "have_sasl = '$(HAVE_SASL)'" >> $@ ++ echo "sizeof_time_t = $(SIZEOF_TIME_T)" >> $@ + + runenv.py: pyrunenv.vals + echo 'env = {}' > $@ +diff --git a/src/config/pre.in b/src/config/pre.in +index d961b5621..f23c07d9d 100644 +--- a/src/config/pre.in ++++ b/src/config/pre.in +@@ -452,6 +452,8 @@ HAVE_SASL = @HAVE_SASL@ + # Whether we have libresolv 1.1.5 for URI discovery tests + HAVE_RESOLV_WRAPPER = @HAVE_RESOLV_WRAPPER@ + ++SIZEOF_TIME_T = @SIZEOF_TIME_T@ ++ + # error table rules + # + ### /* these are invoked as $(...) foo.et, which works, but could be better */ +diff --git a/src/configure.in b/src/configure.in +index 24f653f0d..4ae2c07d5 100644 +--- a/src/configure.in ++++ b/src/configure.in +@@ -744,6 +744,9 @@ fi + + AC_HEADER_TIME + AC_CHECK_TYPE(time_t, long) ++AC_CHECK_SIZEOF(time_t) ++SIZEOF_TIME_T=$ac_cv_sizeof_time_t ++AC_SUBST(SIZEOF_TIME_T) + + # Determine where to put the replay cache. + +diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in +index 0fe02a95d..55f82b147 100644 +--- a/src/lib/krb5/krb/Makefile.in ++++ b/src/lib/krb5/krb/Makefile.in +@@ -364,6 +364,7 @@ SRCS= $(srcdir)/addr_comp.c \ + $(srcdir)/t_in_ccache.c \ + $(srcdir)/t_response_items.c \ + $(srcdir)/t_sname_match.c \ ++ $(srcdir)/t_valid_times.c \ + $(srcdir)/t_vfy_increds.c + + # Someday, when we have a "maintainer mode", do this right: +@@ -457,9 +458,12 @@ t_response_items: t_response_items.o response_items.o $(KRB5_BASE_DEPLIBS) + t_sname_match: t_sname_match.o sname_match.o $(KRB5_BASE_DEPLIBS) + $(CC_LINK) -o $@ t_sname_match.o sname_match.o $(KRB5_BASE_LIBS) + ++t_valid_times: t_valid_times.o valid_times.o $(KRB5_BASE_DEPLIBS) ++ $(CC_LINK) -o $@ t_valid_times.o valid_times.o $(KRB5_BASE_LIBS) ++ + TEST_PROGS= t_walk_rtree t_kerb t_ser t_deltat t_expand t_authdata t_pac \ +- t_in_ccache t_cc_config t_copy_context \ +- t_princ t_etypes t_vfy_increds t_response_items t_sname_match ++ t_in_ccache t_cc_config t_copy_context t_princ t_etypes t_vfy_increds \ ++ t_response_items t_sname_match t_valid_times + + check-unix: $(TEST_PROGS) + $(RUN_TEST_LOCAL_CONF) ./t_kerb \ +@@ -496,6 +500,7 @@ check-unix: $(TEST_PROGS) + $(RUN_TEST) ./t_response_items + $(RUN_TEST) ./t_copy_context + $(RUN_TEST) ./t_sname_match ++ $(RUN_TEST) ./t_valid_times + + check-pytests: t_expire_warn t_vfy_increds + $(RUNPYTEST) $(srcdir)/t_expire_warn.py $(PYTESTFLAGS) +@@ -522,8 +527,9 @@ clean: + $(OUTPRE)t_ad_fx_armor$(EXEEXT) $(OUTPRE)t_ad_fx_armor.$(OBJEXT) \ + $(OUTPRE)t_vfy_increds$(EXEEXT) $(OUTPRE)t_vfy_increds.$(OBJEXT) \ + $(OUTPRE)t_response_items$(EXEEXT) \ +- $(OUTPRE)t_response_items.$(OBJEXT) $(OUTPRE)t_sname_match$(EXEEXT) \ +- $(OUTPRE)t_sname_match.$(OBJEXT) \ ++ $(OUTPRE)t_response_items.$(OBJEXT) \ ++ $(OUTPRE)t_sname_match$(EXEEXT) $(OUTPRE)t_sname_match.$(OBJEXT) \ ++ $(OUTPRE)t_valid_times$(EXEEXT) $(OUTPRE)t_valid_times.$(OBJECT) \ + $(OUTPRE)t_parse_host_string$(EXEEXT) \ + $(OUTPRE)t_parse_host_string.$(OBJEXT) + +diff --git a/src/lib/krb5/krb/t_valid_times.c b/src/lib/krb5/krb/t_valid_times.c +new file mode 100644 +index 000000000..1b469ffc2 +--- /dev/null ++++ b/src/lib/krb5/krb/t_valid_times.c +@@ -0,0 +1,109 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* lib/krb5/krb/t_valid_times.c - test program for krb5int_validate_times() */ ++/* ++ * Copyright (C) 2017 by the Massachusetts Institute of Technology. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "k5-int.h" ++#include "int-proto.h" ++ ++#define BOUNDARY (uint32_t)INT32_MIN ++ ++int ++main() ++{ ++ krb5_error_code ret; ++ krb5_context context; ++ krb5_ticket_times times = { 0, 0, 0, 0 }; ++ ++ ret = krb5_init_context(&context); ++ assert(!ret); ++ ++ /* Current time is within authtime and end time. */ ++ ret = krb5_set_debugging_time(context, 1000, 0); ++ times.authtime = 500; ++ times.endtime = 1500; ++ ret = krb5int_validate_times(context, ×); ++ assert(!ret); ++ ++ /* Current time is before starttime, but within clock skew. */ ++ times.starttime = 1100; ++ ret = krb5int_validate_times(context, ×); ++ assert(!ret); ++ ++ /* Current time is before starttime by more than clock skew. */ ++ times.starttime = 1400; ++ ret = krb5int_validate_times(context, ×); ++ assert(ret == KRB5KRB_AP_ERR_TKT_NYV); ++ ++ /* Current time is after end time, but within clock skew. */ ++ times.starttime = 500; ++ times.endtime = 800; ++ ret = krb5int_validate_times(context, ×); ++ assert(!ret); ++ ++ /* Current time is after end time by more than clock skew. */ ++ times.endtime = 600; ++ ret = krb5int_validate_times(context, ×); ++ assert(ret == KRB5KRB_AP_ERR_TKT_EXPIRED); ++ ++ /* Current time is within starttime and endtime; current time and ++ * endtime are across y2038 boundary. */ ++ ret = krb5_set_debugging_time(context, BOUNDARY - 100, 0); ++ assert(!ret); ++ times.starttime = BOUNDARY - 200; ++ times.endtime = BOUNDARY + 500; ++ ret = krb5int_validate_times(context, ×); ++ assert(!ret); ++ ++ /* Current time is before starttime, but by less than clock skew. */ ++ times.starttime = BOUNDARY + 100; ++ ret = krb5int_validate_times(context, ×); ++ assert(!ret); ++ ++ /* Current time is before starttime by more than clock skew. */ ++ times.starttime = BOUNDARY + 250; ++ ret = krb5int_validate_times(context, ×); ++ assert(ret == KRB5KRB_AP_ERR_TKT_NYV); ++ ++ /* Current time is after endtime, but by less than clock skew. */ ++ ret = krb5_set_debugging_time(context, BOUNDARY + 100, 0); ++ assert(!ret); ++ times.starttime = BOUNDARY - 1000; ++ times.endtime = BOUNDARY - 100; ++ ret = krb5int_validate_times(context, ×); ++ assert(!ret); ++ ++ /* Current time is after endtime by more than clock skew. */ ++ times.endtime = BOUNDARY - 300; ++ ret = krb5int_validate_times(context, ×); ++ assert(ret == KRB5KRB_AP_ERR_TKT_EXPIRED); ++ ++ return 0; ++} +diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in +index 0e93d6b59..2b3112537 100644 +--- a/src/tests/Makefile.in ++++ b/src/tests/Makefile.in +@@ -168,6 +168,7 @@ check-pytests: localauth plugorder rdreq responder s2p s4u2proxy unlockiter + $(RUNPYTEST) $(srcdir)/t_princflags.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_tabdump.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_certauth.py $(PYTESTFLAGS) ++ $(RUNPYTEST) $(srcdir)/t_y2038.py $(PYTESTFLAGS) + + clean: + $(RM) adata etinfo forward gcred hist hooks hrealm icred kdbtest +diff --git a/src/tests/gssapi/Makefile.in b/src/tests/gssapi/Makefile.in +index 6c1464297..604f926de 100644 +--- a/src/tests/gssapi/Makefile.in ++++ b/src/tests/gssapi/Makefile.in +@@ -15,15 +15,16 @@ SRCS= $(srcdir)/ccinit.c $(srcdir)/ccrefresh.c $(srcdir)/common.c \ + $(srcdir)/t_gssexts.c $(srcdir)/t_imp_cred.c $(srcdir)/t_imp_name.c \ + $(srcdir)/t_invalid.c $(srcdir)/t_inq_cred.c $(srcdir)/t_inq_ctx.c \ + $(srcdir)/t_inq_mechs_name.c $(srcdir)/t_iov.c \ +- $(srcdir)/t_namingexts.c $(srcdir)/t_oid.c $(srcdir)/t_pcontok.c \ +- $(srcdir)/t_prf.c $(srcdir)/t_s4u.c $(srcdir)/t_s4u2proxy_krb5.c \ +- $(srcdir)/t_saslname.c $(srcdir)/t_spnego.c $(srcdir)/t_srcattrs.c ++ $(srcdir)/t_lifetime.c $(srcdir)/t_namingexts.c $(srcdir)/t_oid.c \ ++ $(srcdir)/t_pcontok.c $(srcdir)/t_prf.c $(srcdir)/t_s4u.c \ ++ $(srcdir)/t_s4u2proxy_krb5.c $(srcdir)/t_saslname.c \ ++ $(srcdir)/t_spnego.c $(srcdir)/t_srcattrs.c + + OBJS= ccinit.o ccrefresh.o common.o t_accname.o t_ccselect.o t_ciflags.o \ + t_credstore.o t_enctypes.o t_err.o t_export_cred.o t_export_name.o \ + t_gssexts.o t_imp_cred.o t_imp_name.o t_invalid.o t_inq_cred.o \ +- t_inq_ctx.o t_inq_mechs_name.o t_iov.o t_namingexts.o t_oid.o \ +- t_pcontok.o t_prf.o t_s4u.o t_s4u2proxy_krb5.o t_saslname.o \ ++ t_inq_ctx.o t_inq_mechs_name.o t_iov.o t_lifetime.o t_namingexts.o \ ++ t_oid.o t_pcontok.o t_prf.o t_s4u.o t_s4u2proxy_krb5.o t_saslname.o \ + t_spnego.o t_srcattrs.o + + COMMON_DEPS= common.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS) +@@ -31,9 +32,9 @@ COMMON_LIBS= common.o $(GSS_LIBS) $(KRB5_BASE_LIBS) + + all: ccinit ccrefresh t_accname t_ccselect t_ciflags t_credstore t_enctypes \ + t_err t_export_cred t_export_name t_gssexts t_imp_cred t_imp_name \ +- t_invalid t_inq_cred t_inq_ctx t_inq_mechs_name t_iov t_namingexts \ +- t_oid t_pcontok t_prf t_s4u t_s4u2proxy_krb5 t_saslname t_spnego \ +- t_srcattrs ++ t_invalid t_inq_cred t_inq_ctx t_inq_mechs_name t_iov t_lifetime \ ++ t_namingexts t_oid t_pcontok t_prf t_s4u t_s4u2proxy_krb5 t_saslname \ ++ t_spnego t_srcattrs + + check-unix: t_oid + $(RUN_TEST) ./t_invalid +@@ -42,8 +43,8 @@ check-unix: t_oid + + check-pytests: ccinit ccrefresh t_accname t_ccselect t_ciflags t_credstore \ + t_enctypes t_err t_export_cred t_export_name t_imp_cred t_inq_cred \ +- t_inq_ctx t_inq_mechs_name t_iov t_pcontok t_s4u t_s4u2proxy_krb5 \ +- t_spnego t_srcattrs ++ t_inq_ctx t_inq_mechs_name t_iov t_lifetime t_pcontok t_s4u \ ++ t_s4u2proxy_krb5 t_spnego t_srcattrs + $(RUNPYTEST) $(srcdir)/t_gssapi.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_ccselect.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_client_keytab.py $(PYTESTFLAGS) +@@ -88,6 +89,8 @@ t_inq_mechs_name: t_inq_mechs_name.o $(COMMON_DEPS) + $(CC_LINK) -o $@ t_inq_mechs_name.o $(COMMON_LIBS) + t_iov: t_iov.o $(COMMON_DEPS) + $(CC_LINK) -o $@ t_iov.o $(COMMON_LIBS) ++t_lifetime: t_lifetime.o $(COMMON_DEPS) ++ $(CC_LINK) -o $@ t_lifetime.o $(COMMON_LIBS) + t_namingexts: t_namingexts.o $(COMMON_DEPS) + $(CC_LINK) -o $@ t_namingexts.o $(COMMON_LIBS) + t_pcontok: t_pcontok.o $(COMMON_DEPS) +@@ -111,5 +114,5 @@ clean: + $(RM) ccinit ccrefresh t_accname t_ccselect t_ciflags t_credstore + $(RM) t_enctypes t_err t_export_cred t_export_name t_gssexts t_imp_cred + $(RM) t_imp_name t_invalid t_inq_cred t_inq_ctx t_inq_mechs_name t_iov +- $(RM) t_namingexts t_oid t_pcontok t_prf t_s4u t_s4u2proxy_krb5 +- $(RM) t_saslname t_spnego t_srcattrs ++ $(RM) t_lifetime t_namingexts t_oid t_pcontok t_prf t_s4u ++ $(RM) t_s4u2proxy_krb5 t_saslname t_spnego t_srcattrs +diff --git a/src/tests/gssapi/t_gssapi.py b/src/tests/gssapi/t_gssapi.py +index e23c936d7..fa214242f 100755 +--- a/src/tests/gssapi/t_gssapi.py ++++ b/src/tests/gssapi/t_gssapi.py +@@ -220,4 +220,36 @@ realm.run(['./t_ciflags', 'p:' + realm.host_princ]) + # contexts. + realm.run(['./t_inq_ctx', 'user', password('user'), 'p:%s' % realm.host_princ]) + ++# Test lifetime results, using a realm with a large maximum lifetime ++# so that we can test ticket end dates after y2038. There are no ++# time_t conversions involved, so we can run these tests on platforms ++# with 32-bit time_t. ++realm.stop() ++conf = {'realms': {'$realm': {'max_life': '9000d'}}} ++realm = K5Realm(kdc_conf=conf, get_creds=False) ++ ++# Check a lifetime string result against an expected number value (or None). ++# Allow some variance due to time elapsed during the tests. ++def check_lifetime(msg, val, expected): ++ if expected is None and val != 'indefinite': ++ fail('%s: expected indefinite, got %s' % (msg, val)) ++ if expected is not None and val == 'indefinite': ++ fail('%s: expected %d, got indefinite' % (msg, expected)) ++ if expected is not None and abs(int(val) - expected) > 100: ++ fail('%s: expected %d, got %s' % (msg, expected, val)) ++ ++realm.kinit(realm.user_princ, password('user'), flags=['-l', '8500d']) ++out = realm.run(['./t_lifetime', 'p:' + realm.host_princ, str(8000 * 86400)]) ++ln = out.split('\n') ++check_lifetime('icred gss_acquire_cred', ln[0], 8500 * 86400) ++check_lifetime('icred gss_inquire_cred', ln[1], 8500 * 86400) ++check_lifetime('acred gss_acquire_cred', ln[2], None) ++check_lifetime('acred gss_inquire_cred', ln[3], None) ++check_lifetime('ictx gss_init_sec_context', ln[4], 8000 * 86400) ++check_lifetime('ictx gss_inquire_context', ln[5], 8000 * 86400) ++check_lifetime('ictx gss_context_time', ln[6], 8000 * 86400) ++check_lifetime('actx gss_accept_sec_context', ln[7], 8000 * 86400 + 300) ++check_lifetime('actx gss_inquire_context', ln[8], 8000 * 86400 + 300) ++check_lifetime('actx gss_context_time', ln[9], 8000 * 86400 + 300) ++ + success('GSSAPI tests') +diff --git a/src/tests/gssapi/t_lifetime.c b/src/tests/gssapi/t_lifetime.c +new file mode 100644 +index 000000000..8dcf18621 +--- /dev/null ++++ b/src/tests/gssapi/t_lifetime.c +@@ -0,0 +1,140 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* tests/gssapi/t_lifetime.c - display cred and context lifetimes */ ++/* ++ * Copyright (C) 2017 by the Massachusetts Institute of Technology. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include ++#include "common.h" ++ ++/* ++ * Using the default credential, exercise the GSS functions which accept or ++ * produce lifetimes. Display the following results, one per line, as ASCII ++ * integers or the string "indefinite": ++ * ++ * initiator cred lifetime according to gss_acquire_cred() ++ * initiator cred lifetime according to gss_inquire_cred() ++ * acceptor cred lifetime according to gss_acquire_cred() ++ * acceptor cred lifetime according to gss_inquire_cred() ++ * initiator context lifetime according to gss_init_sec_context() ++ * initiator context lifetime according to gss_inquire_context() ++ * initiator context lifetime according to gss_context_time() ++ * acceptor context lifetime according to gss_init_sec_context() ++ * acceptor context lifetime according to gss_inquire_context() ++ * acceptor context lifetime according to gss_context_time() ++ */ ++ ++static void ++display_time(OM_uint32 tval) ++{ ++ if (tval == GSS_C_INDEFINITE) ++ puts("indefinite"); ++ else ++ printf("%u\n", (unsigned int)tval); ++} ++ ++int ++main(int argc, char *argv[]) ++{ ++ OM_uint32 minor, major; ++ gss_cred_id_t icred, acred; ++ gss_name_t tname; ++ gss_ctx_id_t ictx = GSS_C_NO_CONTEXT, actx = GSS_C_NO_CONTEXT; ++ gss_buffer_desc itok = GSS_C_EMPTY_BUFFER, atok = GSS_C_EMPTY_BUFFER; ++ OM_uint32 time_req = GSS_C_INDEFINITE, time_rec; ++ ++ if (argc < 2 || argc > 3) { ++ fprintf(stderr, "Usage: %s targetname [time_req]\n", argv[0]); ++ return 1; ++ } ++ tname = import_name(argv[1]); ++ if (argc >= 3) ++ time_req = atoll(argv[2]); ++ ++ /* Get initiator cred and display its lifetime according to ++ * gss_acquire_cred and gss_inquire_cred. */ ++ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, time_req, &mechset_krb5, ++ GSS_C_INITIATE, &icred, NULL, &time_rec); ++ check_gsserr("gss_acquire_cred(initiate)", major, minor); ++ display_time(time_rec); ++ major = gss_inquire_cred(&minor, icred, NULL, &time_rec, NULL, NULL); ++ check_gsserr("gss_inquire_cred(initiate)", major, minor); ++ display_time(time_rec); ++ ++ /* Get acceptor cred and display its lifetime according to gss_acquire_cred ++ * and gss_inquire_cred. */ ++ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, time_req, &mechset_krb5, ++ GSS_C_ACCEPT, &acred, NULL, &time_rec); ++ check_gsserr("gss_acquire_cred(accept)", major, minor); ++ display_time(time_rec); ++ major = gss_inquire_cred(&minor, acred, NULL, &time_rec, NULL, NULL); ++ check_gsserr("gss_inquire_cred(accept)", major, minor); ++ display_time(time_rec); ++ ++ /* Make an initiator context and display its lifetime according to ++ * gss_init_sec_context, gss_inquire_context, and gss_context_time. */ ++ major = gss_init_sec_context(&minor, icred, &ictx, tname, &mech_krb5, 0, ++ time_req, GSS_C_NO_CHANNEL_BINDINGS, &atok, ++ NULL, &itok, NULL, &time_rec); ++ check_gsserr("gss_init_sec_context", major, minor); ++ assert(major == GSS_S_COMPLETE); ++ display_time(time_rec); ++ major = gss_inquire_context(&minor, ictx, NULL, NULL, &time_rec, NULL, ++ NULL, NULL, NULL); ++ check_gsserr("gss_inquire_context(initiate)", major, minor); ++ display_time(time_rec); ++ major = gss_context_time(&minor, ictx, &time_rec); ++ check_gsserr("gss_context_time(initiate)", major, minor); ++ display_time(time_rec); ++ ++ major = gss_accept_sec_context(&minor, &actx, acred, &itok, ++ GSS_C_NO_CHANNEL_BINDINGS, NULL, ++ NULL, &atok, NULL, &time_rec, NULL); ++ check_gsserr("gss_accept_sec_context", major, minor); ++ assert(major == GSS_S_COMPLETE); ++ display_time(time_rec); ++ major = gss_inquire_context(&minor, actx, NULL, NULL, &time_rec, NULL, ++ NULL, NULL, NULL); ++ check_gsserr("gss_inquire_context(accept)", major, minor); ++ display_time(time_rec); ++ major = gss_context_time(&minor, actx, &time_rec); ++ check_gsserr("gss_context_time(accept)", major, minor); ++ display_time(time_rec); ++ ++ (void)gss_release_buffer(&minor, &itok); ++ (void)gss_release_buffer(&minor, &atok); ++ (void)gss_release_name(&minor, &tname); ++ (void)gss_release_cred(&minor, &icred); ++ (void)gss_release_cred(&minor, &acred); ++ (void)gss_delete_sec_context(&minor, &ictx, NULL); ++ (void)gss_delete_sec_context(&minor, &actx, NULL); ++ return 0; ++} +diff --git a/src/tests/t_kdb.py b/src/tests/t_kdb.py +index 185225afa..c0eeb0118 100755 +--- a/src/tests/t_kdb.py ++++ b/src/tests/t_kdb.py +@@ -446,6 +446,13 @@ realm.run([kadminl, 'addprinc', '-policy', 'keepoldpasspol', '-pw', 'aaaa', + for p in ('bbbb', 'cccc', 'aaaa'): + realm.run([kadminl, 'cpw', '-keepold', '-pw', p, 'keepoldpassprinc']) + ++if runenv.sizeof_time_t <= 4: ++ skipped('y2038 LDAP test', 'platform has 32-bit time_t') ++else: ++ # Test storage of timestamps after y2038. ++ realm.run([kadminl, 'modprinc', '-pwexpire', '2040-02-03', 'user']) ++ realm.run([kadminl, 'getprinc', 'user'], expected_msg=' 2040\n') ++ + realm.stop() + + # Briefly test dump and load. +diff --git a/src/tests/t_y2038.py b/src/tests/t_y2038.py +new file mode 100644 +index 000000000..02e946df4 +--- /dev/null ++++ b/src/tests/t_y2038.py +@@ -0,0 +1,75 @@ ++#!/usr/bin/python ++from k5test import * ++ ++# These tests will become much less important after the y2038 boundary ++# has elapsed, and may start exhibiting problems around the year 2075. ++ ++if runenv.sizeof_time_t <= 4: ++ skip_rest('y2038 timestamp tests', 'platform has 32-bit time_t') ++ ++# Start a KDC running roughly 21 years in the future, after the y2038 ++# boundary. Set long maximum lifetimes for later tests. ++conf = {'realms': {'$realm': {'max_life': '9000d', ++ 'max_renewable_life': '9000d'}}} ++realm = K5Realm(start_kdc=False, kdc_conf=conf) ++realm.start_kdc(['-T', '662256000']) ++ ++# kinit without preauth should succeed with clock skew correction, but ++# will result in an expired ticket, because we sent an absolute end ++# time and didn't get a chance to correct it.. ++realm.kinit(realm.user_princ, password('user')) ++realm.run([kvno, realm.host_princ], expected_code=1, ++ expected_msg='Ticket expired') ++ ++# kinit with preauth should succeed and result in a valid ticket, as ++# we get a chance to correct the end time based on the KDC time. Try ++# with encrypted timestamp and encrypted challenge. ++realm.run([kadminl, 'modprinc', '+requires_preauth', 'user']) ++realm.kinit(realm.user_princ, password('user')) ++realm.run([kvno, realm.host_princ]) ++realm.kinit(realm.user_princ, password('user'), flags=['-T', realm.ccache]) ++realm.run([kvno, realm.host_princ]) ++ ++# Test that expiration warning works after y2038, by setting a ++# password expiration time ten minutes after the KDC time. ++realm.run([kadminl, 'modprinc', '-pwexpire', '662256600 seconds', 'user']) ++out = realm.kinit(realm.user_princ, password('user')) ++if 'will expire in less than one hour' not in out: ++ fail('password expiration message') ++year = int(out.split()[-1]) ++if year < 2038 or year > 9999: ++ fail('password expiration year') ++ ++realm.stop_kdc() ++realm.start_kdc() ++realm.start_kadmind() ++realm.prep_kadmin() ++ ++# Test getdate parsing of absolute timestamps after 2038 and ++# marshalling over the kadmin protocol. The local time zone will ++# affect the display time by a little bit, so just look for the year. ++realm.run_kadmin(['modprinc', '-pwexpire', '2040-02-03', realm.host_princ]) ++realm.run_kadmin(['getprinc', realm.host_princ], expected_msg=' 2040\n') ++ ++# Get a ticket whose lifetime crosses the y2038 boundary and ++# range-check the expiration year as reported by klist. ++realm.kinit(realm.user_princ, password('user'), ++ flags=['-l', '8000d', '-r', '8500d']) ++realm.run([kvno, realm.host_princ]) ++out = realm.run([klist]) ++if int(out.split('\n')[4].split()[2].split('/')[2]) < 39: ++ fail('unexpected tgt expiration year') ++if int(out.split('\n')[5].split()[2].split('/')[2]) < 40: ++ fail('unexpected tgt rtill year') ++if int(out.split('\n')[6].split()[2].split('/')[2]) < 39: ++ fail('unexpected service ticket expiration year') ++if int(out.split('\n')[7].split()[2].split('/')[2]) < 40: ++ fail('unexpected service ticket rtill year') ++realm.kinit(realm.user_princ, None, ['-R']) ++out = realm.run([klist]) ++if int(out.split('\n')[4].split()[2].split('/')[2]) < 39: ++ fail('unexpected renewed tgt expiration year') ++if int(out.split('\n')[5].split()[2].split('/')[2]) < 40: ++ fail('unexpected renewed tgt rtill year') ++ ++success('y2038 tests') diff --git a/SOURCES/Add-vector-support-to-k5_sha256.patch b/SOURCES/Add-vector-support-to-k5_sha256.patch new file mode 100644 index 0000000..63438d3 --- /dev/null +++ b/SOURCES/Add-vector-support-to-k5_sha256.patch @@ -0,0 +1,106 @@ +From d8620f016248a9ee1fbb93aa773eb3952b99fd3d Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Sat, 3 Feb 2018 20:53:42 -0500 +Subject: [PATCH] Add vector support to k5_sha256() + +Add a length argument so that multiple krb5_data values can be passed +to k5_sha256(), for efficient computation of SHA-256 hashes over +concatenations of data values. + +(cherry picked from commit 4f3373e8c55b3e9bdfb5b065e07214c5816c85fa) +--- + src/include/k5-int.h | 4 ++-- + src/lib/crypto/builtin/sha2/sha256.c | 6 ++++-- + src/lib/crypto/crypto_tests/t_sha2.c | 2 +- + src/lib/crypto/openssl/sha256.c | 6 ++++-- + src/lib/krb5/rcache/rc_conv.c | 2 +- + 5 files changed, 12 insertions(+), 8 deletions(-) + +diff --git a/src/include/k5-int.h b/src/include/k5-int.h +index 10b034037..7c549bce2 100644 +--- a/src/include/k5-int.h ++++ b/src/include/k5-int.h +@@ -634,9 +634,9 @@ krb5int_arcfour_gsscrypt(const krb5_keyblock *keyblock, krb5_keyusage usage, + + #define K5_SHA256_HASHLEN (256 / 8) + +-/* Write the SHA-256 hash of in to out. */ ++/* Write the SHA-256 hash of in (containing n elements) to out. */ + krb5_error_code +-k5_sha256(const krb5_data *in, uint8_t out[K5_SHA256_HASHLEN]); ++k5_sha256(const krb5_data *in, size_t n, uint8_t out[K5_SHA256_HASHLEN]); + + /* + * Attempt to zero memory in a way that compilers won't optimize out. +diff --git a/src/lib/crypto/builtin/sha2/sha256.c b/src/lib/crypto/builtin/sha2/sha256.c +index e34bed575..4b5fe10a3 100644 +--- a/src/lib/crypto/builtin/sha2/sha256.c ++++ b/src/lib/crypto/builtin/sha2/sha256.c +@@ -257,12 +257,14 @@ k5_sha256_final(void *res, SHA256_CTX *m) + } + + krb5_error_code +-k5_sha256(const krb5_data *in, uint8_t out[K5_SHA256_HASHLEN]) ++k5_sha256(const krb5_data *in, size_t n, uint8_t out[K5_SHA256_HASHLEN]) + { + SHA256_CTX ctx; ++ size_t i; + + k5_sha256_init(&ctx); +- k5_sha256_update(&ctx, in->data, in->length); ++ for (i = 0; i < n; i++) ++ k5_sha256_update(&ctx, in[i].data, in[i].length); + k5_sha256_final(out, &ctx); + return 0; + } +diff --git a/src/lib/crypto/crypto_tests/t_sha2.c b/src/lib/crypto/crypto_tests/t_sha2.c +index 12f32869b..e6fa58498 100644 +--- a/src/lib/crypto/crypto_tests/t_sha2.c ++++ b/src/lib/crypto/crypto_tests/t_sha2.c +@@ -125,7 +125,7 @@ hash_test(const struct krb5_hash_provider *hash, struct test *tests) + + if (hash == &krb5int_hash_sha256) { + /* Try again using k5_sha256(). */ +- if (k5_sha256(&iov.data, (uint8_t *)hval.data) != 0) ++ if (k5_sha256(&iov.data, 1, (uint8_t *)hval.data) != 0) + abort(); + if (memcmp(hval.data, t->hash, hval.length) != 0) + abort(); +diff --git a/src/lib/crypto/openssl/sha256.c b/src/lib/crypto/openssl/sha256.c +index fa095d472..0edd8b7ba 100644 +--- a/src/lib/crypto/openssl/sha256.c ++++ b/src/lib/crypto/openssl/sha256.c +@@ -34,16 +34,18 @@ + #include + + krb5_error_code +-k5_sha256(const krb5_data *in, uint8_t out[K5_SHA256_HASHLEN]) ++k5_sha256(const krb5_data *in, size_t n, uint8_t out[K5_SHA256_HASHLEN]) + { + EVP_MD_CTX *ctx; ++ size_t i; + int ok; + + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) + return ENOMEM; + ok = EVP_DigestInit_ex(ctx, EVP_sha256(), NULL); +- ok = ok && EVP_DigestUpdate(ctx, in->data, in->length); ++ for (i = 0; i < n; i++) ++ ok = ok && EVP_DigestUpdate(ctx, in[i].data, in[i].length); + ok = ok && EVP_DigestFinal_ex(ctx, out, NULL); + EVP_MD_CTX_free(ctx); + return ok ? 0 : ENOMEM; +diff --git a/src/lib/krb5/rcache/rc_conv.c b/src/lib/krb5/rcache/rc_conv.c +index 0e021f5d8..f2fe528ac 100644 +--- a/src/lib/krb5/rcache/rc_conv.c ++++ b/src/lib/krb5/rcache/rc_conv.c +@@ -58,7 +58,7 @@ krb5_rc_hash_message(krb5_context context, const krb5_data *message, + *out = NULL; + + /* Calculate the binary checksum. */ +- retval = k5_sha256(message, cksum); ++ retval = k5_sha256(message, 1, cksum); + if (retval) + return retval; + diff --git a/SOURCES/Add-y2038-documentation.patch b/SOURCES/Add-y2038-documentation.patch new file mode 100644 index 0000000..a7fcce8 --- /dev/null +++ b/SOURCES/Add-y2038-documentation.patch @@ -0,0 +1,59 @@ +From 087bd1bdff17025af6e5189898209035ec8d75da Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Thu, 4 May 2017 17:03:35 -0400 +Subject: [PATCH] Add y2038 documentation + +ticket: 8352 +(cherry picked from commit 85d64c43dbf7a7faa56a1999494cdfa49e8bd2c9) +--- + doc/appdev/index.rst | 1 + + doc/appdev/y2038.rst | 28 ++++++++++++++++++++++++++++ + 2 files changed, 29 insertions(+) + create mode 100644 doc/appdev/y2038.rst + +diff --git a/doc/appdev/index.rst b/doc/appdev/index.rst +index 3d62045ca..961bb1e9e 100644 +--- a/doc/appdev/index.rst ++++ b/doc/appdev/index.rst +@@ -5,6 +5,7 @@ For application developers + :maxdepth: 1 + + gssapi.rst ++ y2038.rst + h5l_mit_apidiff.rst + init_creds.rst + princ_handle.rst +diff --git a/doc/appdev/y2038.rst b/doc/appdev/y2038.rst +new file mode 100644 +index 000000000..bc4122dad +--- /dev/null ++++ b/doc/appdev/y2038.rst +@@ -0,0 +1,28 @@ ++Year 2038 considerations for uses of krb5_timestamp ++=================================================== ++ ++POSIX time values, which measure the number of seconds since January 1 ++1970, will exceed the maximum value representable in a signed 32-bit ++integer in January 2038. This documentation describes considerations ++for consumers of the MIT krb5 libraries. ++ ++Applications or libraries which use libkrb5 and consume the timestamps ++included in credentials or other structures make use of the ++:c:type:`krb5_timestamp` type. For historical reasons, krb5_timestamp ++is a signed 32-bit integer, even on platforms where a larger type is ++natively used to represent time values. To behave properly for time ++values after January 2038, calling code should cast krb5_timestamp ++values to uint32_t, and then to time_t:: ++ ++ (time_t)(uint32_t)timestamp ++ ++Used in this way, krb5_timestamp values can represent time values up ++until February 2106, provided that the platform uses a 64-bit or ++larger time_t type. This usage will also remain safe if a later ++version of MIT krb5 changes krb5_timestamp to an unsigned 32-bit ++integer. ++ ++The GSSAPI only uses representations of time intervals, not absolute ++times. Callers of the GSSAPI should require no changes to behave ++correctly after January 2038, provided that they use MIT krb5 release ++1.16 or later. diff --git a/SOURCES/Address-some-optimized-out-memset-calls.patch b/SOURCES/Address-some-optimized-out-memset-calls.patch new file mode 100644 index 0000000..2c5ddd6 --- /dev/null +++ b/SOURCES/Address-some-optimized-out-memset-calls.patch @@ -0,0 +1,96 @@ +From 05dc6552ea0e8f0002d21ca36d7ff47d4c088bd7 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Sun, 30 Dec 2018 16:40:28 -0500 +Subject: [PATCH] Address some optimized-out memset() calls + +Ilja Van Sprundel reported a list of memset() calls which gcc +optimizes out. In krb_auth_su.c, use zap() to clear the password, and +remove two memset() calls when there is no password to clear. In +iakerb.c, remove an unnecessary memset() before setting the only two +fields of the IAKERB header structure. In svr_principal.c, use +krb5_free_key_keyblock_contents() instead of hand-freeing key data. +In asn1_k_encode.c, remove an unnecessary memset() of the kdc_req_hack +shell before returning. + +(cherry picked from commit 1057b0befec1f1c0e9d4da5521a58496e2dc0997) +(cherry picked from commit 1dfff7202448a950c9133cdfe43d650092d930fd) +(cherry picked from commit 54348bbfaec50bb72d1625c015f8e5c4cfa59e0d) +--- + src/clients/ksu/krb_auth_su.c | 4 +--- + src/lib/gssapi/krb5/iakerb.c | 1 - + src/lib/kadm5/srv/svr_principal.c | 10 ++-------- + src/lib/krb5/asn.1/asn1_k_encode.c | 1 - + 4 files changed, 3 insertions(+), 13 deletions(-) + +diff --git a/src/clients/ksu/krb_auth_su.c b/src/clients/ksu/krb_auth_su.c +index 7af48195c..e39685fff 100644 +--- a/src/clients/ksu/krb_auth_su.c ++++ b/src/clients/ksu/krb_auth_su.c +@@ -183,21 +183,19 @@ krb5_boolean ksu_get_tgt_via_passwd(context, client, options, zero_password, + if (code ) { + com_err(prog_name, code, _("while reading password for '%s'\n"), + client_name); +- memset(password, 0, sizeof(password)); + return (FALSE); + } + + if ( pwsize == 0) { + fprintf(stderr, _("No password given\n")); + *zero_password = TRUE; +- memset(password, 0, sizeof(password)); + return (FALSE); + } + + code = krb5_get_init_creds_password(context, &creds, client, password, + krb5_prompter_posix, NULL, 0, NULL, + options); +- memset(password, 0, sizeof(password)); ++ zap(password, sizeof(password)); + + + if (code) { +diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c +index bb1072fe4..47c161ec9 100644 +--- a/src/lib/gssapi/krb5/iakerb.c ++++ b/src/lib/gssapi/krb5/iakerb.c +@@ -262,7 +262,6 @@ iakerb_make_token(iakerb_ctx_id_t ctx, + /* + * Assemble the IAKERB-HEADER from the realm and cookie + */ +- memset(&iah, 0, sizeof(iah)); + iah.target_realm = *realm; + iah.cookie = cookie; + +diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c +index 64a4a2e97..73733d371 100644 +--- a/src/lib/kadm5/srv/svr_principal.c ++++ b/src/lib/kadm5/srv/svr_principal.c +@@ -2141,14 +2141,8 @@ static int decrypt_key_data(krb5_context context, + ret = krb5_dbe_decrypt_key_data(context, NULL, &key_data[i], &keys[i], + NULL); + if (ret) { +- for (; i >= 0; i--) { +- if (keys[i].contents) { +- memset (keys[i].contents, 0, keys[i].length); +- free( keys[i].contents ); +- } +- } +- +- memset(keys, 0, n_key_data*sizeof(krb5_keyblock)); ++ for (; i >= 0; i--) ++ krb5_free_keyblock_contents(context, &keys[i]); + free(keys); + return ret; + } +diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c +index 889460989..c4f9aacdf 100644 +--- a/src/lib/krb5/asn.1/asn1_k_encode.c ++++ b/src/lib/krb5/asn.1/asn1_k_encode.c +@@ -532,7 +532,6 @@ decode_kdc_req_body(const taginfo *t, const unsigned char *asn1, size_t len, + if (ret) { + free_kdc_req_body(b); + free(h.server_realm.data); +- memset(&h, 0, sizeof(h)); + return ret; + } + b->server->realm = h.server_realm; diff --git a/SOURCES/Adjust-processing-of-pa_type-ccache-config.patch b/SOURCES/Adjust-processing-of-pa_type-ccache-config.patch new file mode 100644 index 0000000..4b787e1 --- /dev/null +++ b/SOURCES/Adjust-processing-of-pa_type-ccache-config.patch @@ -0,0 +1,121 @@ +From bfeb18163ba1364d37c9179bcf5e9c042c268a8b Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Fri, 13 Jan 2017 10:14:36 -0500 +Subject: [PATCH] Adjust processing of pa_type ccache config + +Read the allowed preauth type from the input ccache in +restart_init_creds_loop(); there is no need to reread it each time we +produce a request. Move read_allowed_preauth_type() earlier in the +file to allow it to be called from restart_init_creds_loop() without a +prototype. + +Clear the selected preauth type in restart_init_creds_loop(), not in +init_creds_step_request(). We want to make sure that it doesn't +survive a restart due to a realm referral or expiry, but we don't want +to forget about it when retrying after an error. + +(cherry picked from commit 468c6eb7bb860f7ec0381086a22859f822b41c43) +--- + src/lib/krb5/krb/get_in_tkt.c | 61 ++++++++++++++++++----------------- + 1 file changed, 31 insertions(+), 30 deletions(-) + +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index 52e07bb67..da12204ac 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -791,6 +791,31 @@ set_request_times(krb5_context context, krb5_init_creds_context ctx) + return 0; + } + ++static void ++read_allowed_preauth_type(krb5_context context, krb5_init_creds_context ctx) ++{ ++ krb5_error_code ret; ++ krb5_data config; ++ char *tmp, *p; ++ krb5_ccache in_ccache = k5_gic_opt_get_in_ccache(ctx->opt); ++ ++ ctx->allowed_preauth_type = KRB5_PADATA_NONE; ++ if (in_ccache == NULL) ++ return; ++ memset(&config, 0, sizeof(config)); ++ if (krb5_cc_get_config(context, in_ccache, ctx->request->server, ++ KRB5_CC_CONF_PA_TYPE, &config) != 0) ++ return; ++ tmp = k5memdup0(config.data, config.length, &ret); ++ krb5_free_data_contents(context, &config); ++ if (tmp == NULL) ++ return; ++ ctx->allowed_preauth_type = strtol(tmp, &p, 10); ++ if (p == NULL || *p != '\0') ++ ctx->allowed_preauth_type = KRB5_PADATA_NONE; ++ free(tmp); ++} ++ + /** + * Throw away any pre-authentication realm state and begin with a + * unauthenticated or optimistically authenticated request. If fast_upgrade is +@@ -807,6 +832,7 @@ restart_init_creds_loop(krb5_context context, krb5_init_creds_context ctx, + krb5_free_error(context, ctx->err_reply); + ctx->preauth_to_use = ctx->err_padata = NULL; + ctx->err_reply = NULL; ++ ctx->selected_preauth_type = KRB5_PADATA_NONE; + + krb5int_fast_free_state(context, ctx->fast_state); + ctx->fast_state = NULL; +@@ -849,6 +875,11 @@ restart_init_creds_loop(krb5_context context, krb5_init_creds_context ctx, + &ctx->outer_request_body); + if (code != 0) + goto cleanup; ++ ++ /* Read the allowed preauth type for this server principal from the input ++ * ccache, if the application supplied one. */ ++ read_allowed_preauth_type(context, ctx); ++ + cleanup: + return code; + } +@@ -1154,31 +1185,6 @@ init_creds_validate_reply(krb5_context context, + return 0; + } + +-static void +-read_allowed_preauth_type(krb5_context context, krb5_init_creds_context ctx) +-{ +- krb5_error_code ret; +- krb5_data config; +- char *tmp, *p; +- krb5_ccache in_ccache = k5_gic_opt_get_in_ccache(ctx->opt); +- +- ctx->allowed_preauth_type = KRB5_PADATA_NONE; +- if (in_ccache == NULL) +- return; +- memset(&config, 0, sizeof(config)); +- if (krb5_cc_get_config(context, in_ccache, ctx->request->server, +- KRB5_CC_CONF_PA_TYPE, &config) != 0) +- return; +- tmp = k5memdup0(config.data, config.length, &ret); +- krb5_free_data_contents(context, &config); +- if (tmp == NULL) +- return; +- ctx->allowed_preauth_type = strtol(tmp, &p, 10); +- if (p == NULL || *p != '\0') +- ctx->allowed_preauth_type = KRB5_PADATA_NONE; +- free(tmp); +-} +- + static krb5_error_code + save_selected_preauth_type(krb5_context context, krb5_ccache ccache, + krb5_init_creds_context ctx) +@@ -1317,11 +1323,6 @@ init_creds_step_request(krb5_context context, + if (code) + goto cleanup; + +- /* Read the allowed patype for this server principal from the in_ccache, +- * if the application supplied one. */ +- read_allowed_preauth_type(context, ctx); +- ctx->selected_preauth_type = KRB5_PADATA_NONE; +- + /* + * Read cached preauth configuration data for this server principal from + * the in_ccache, if the application supplied one, and delete any that was diff --git a/SOURCES/Allow-clock-skew-in-krb5-gss_context_time.patch b/SOURCES/Allow-clock-skew-in-krb5-gss_context_time.patch new file mode 100644 index 0000000..d9e5c5f --- /dev/null +++ b/SOURCES/Allow-clock-skew-in-krb5-gss_context_time.patch @@ -0,0 +1,36 @@ +From 527fafc0e0abf90c1bb3d66c31ea92a96e095f08 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Sat, 22 Apr 2017 16:51:23 -0400 +Subject: [PATCH] Allow clock skew in krb5 gss_context_time() + +Commit b496ce4095133536e0ace36b74130e4b9ecb5e11 (ticket #8268) adds +the clock skew to krb5 acceptor context lifetimes for +gss_accept_sec_context() and gss_inquire_context(), but not for +gss_context_time(). Add the clock skew in gss_context_time() as well. + +ticket: 8581 (new) +target_version: 1.14-next +target_version: 1.15-next +tags: pullup + +(cherry picked from commit b0a072e6431261734e7350996a363801f180e8ea) +--- + src/lib/gssapi/krb5/context_time.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/lib/gssapi/krb5/context_time.c b/src/lib/gssapi/krb5/context_time.c +index a18cfb05b..450593288 100644 +--- a/src/lib/gssapi/krb5/context_time.c ++++ b/src/lib/gssapi/krb5/context_time.c +@@ -51,7 +51,10 @@ krb5_gss_context_time(minor_status, context_handle, time_rec) + return(GSS_S_FAILURE); + } + +- if ((lifetime = ctx->krb_times.endtime - now) <= 0) { ++ lifetime = ctx->krb_times.endtime - now; ++ if (!ctx->initiate) ++ lifetime += ctx->k5_context->clockskew; ++ if (lifetime <= 0) { + *time_rec = 0; + *minor_status = 0; + return(GSS_S_CONTEXT_EXPIRED); diff --git a/SOURCES/Bring-back-general-kerberos-man-page.patch b/SOURCES/Bring-back-general-kerberos-man-page.patch new file mode 100644 index 0000000..dcfe5e9 --- /dev/null +++ b/SOURCES/Bring-back-general-kerberos-man-page.patch @@ -0,0 +1,468 @@ +From df8c8cc7cd18fa94c920c4763545b6fd93a21fcd Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Tue, 9 Oct 2018 17:05:10 -0400 +Subject: [PATCH] Bring back general kerberos man page + +Restore the content of kerberos(1) as it stood in +0f81e372a2830c9170f6e08dfa956841d0ebdfb1. Convert to ReST to match +the other man pages, and install it as the more appropriate +kerberos(7). + +Build kerberos(7) and check it in to avoid breaking the build. + +ticket: 8755 (new) +tags: pullup +target_version: 1.16-next + +(cherry picked from commit c38197ee9808503f86ccffd4a2bd94389e17df0b) +--- + doc/conf.py | 1 + + doc/user/user_config/index.rst | 1 + + doc/user/user_config/kerberos.rst | 148 ++++++++++++++++++++++++ + src/Makefile.in | 4 +- + src/config/pre.in | 2 + + src/man/Makefile.in | 14 ++- + src/man/kerberos.man | 180 ++++++++++++++++++++++++++++++ + 7 files changed, 345 insertions(+), 5 deletions(-) + create mode 100644 doc/user/user_config/kerberos.rst + create mode 100644 src/man/kerberos.man + +diff --git a/doc/conf.py b/doc/conf.py +index 3ee2df630..68dad781f 100644 +--- a/doc/conf.py ++++ b/doc/conf.py +@@ -292,6 +292,7 @@ man_pages = [ + ('user/user_commands/krb5-config', 'krb5-config', u'tool for linking against MIT Kerberos libraries', [u'MIT'], 1), + ('user/user_config/k5login', 'k5login', u'Kerberos V5 acl file for host access', [u'MIT'], 5), + ('user/user_config/k5identity', 'k5identity', u'Kerberos V5 client principal selection rules', [u'MIT'], 5), ++ ('user/user_config/kerberos', 'kerberos', u'Overview of using Kerberos', [u'MIT'], 7), + ('admin/admin_commands/krb5kdc', 'krb5kdc', u'Kerberos V5 KDC', [u'MIT'], 8), + ('admin/admin_commands/kadmin_local', 'kadmin', u'Kerberos V5 database administration program', [u'MIT'], 1), + ('admin/admin_commands/kprop', 'kprop', u'propagate a Kerberos V5 principal database to a slave server', [u'MIT'], 8), +diff --git a/doc/user/user_config/index.rst b/doc/user/user_config/index.rst +index 6b3d4393b..ad0dc1a72 100644 +--- a/doc/user/user_config/index.rst ++++ b/doc/user/user_config/index.rst +@@ -8,5 +8,6 @@ been disabled by your host's configuration): + .. toctree:: + :maxdepth: 1 + ++ kerberos.rst + k5login.rst + k5identity.rst +diff --git a/doc/user/user_config/kerberos.rst b/doc/user/user_config/kerberos.rst +new file mode 100644 +index 000000000..6c4453b3b +--- /dev/null ++++ b/doc/user/user_config/kerberos.rst +@@ -0,0 +1,148 @@ ++.. _kerberos(7): ++ ++kerberos ++======== ++ ++DESCRIPTION ++----------- ++ ++The Kerberos system authenticates individual users in a network ++environment. After authenticating yourself to Kerberos, you can use ++Kerberos-enabled programs without having to present passwords. ++ ++If you enter your username and :ref:`kinit(1)` responds with this ++message: ++ ++kinit(v5): Client not found in Kerberos database while getting initial ++credentials ++ ++you haven't been registered as a Kerberos user. See your system ++administrator. ++ ++A Kerberos name usually contains three parts. The first is the ++**primary**, which is usually a user's or service's name. The second ++is the **instance**, which in the case of a user is usually null. ++Some users may have privileged instances, however, such as ``root`` or ++``admin``. In the case of a service, the instance is the fully ++qualified name of the machine on which it runs; i.e. there can be an ++rlogin service running on the machine ABC, which is different from the ++rlogin service running on the machine XYZ. The third part of a ++Kerberos name is the **realm**. The realm corresponds to the Kerberos ++service providing authentication for the principal. ++ ++When writing a Kerberos name, the principal name is separated from the ++instance (if not null) by a slash, and the realm (if not the local ++realm) follows, preceded by an "@" sign. The following are examples ++of valid Kerberos names:: ++ ++ david ++ jennifer/admin ++ joeuser@BLEEP.COM ++ cbrown/root@FUBAR.ORG ++ ++When you authenticate yourself with Kerberos you get an initial ++Kerberos **ticket**. (A Kerberos ticket is an encrypted protocol ++message that provides authentication.) Kerberos uses this ticket for ++network utilities such as rlogin and rcp. The ticket transactions are ++done transparently, so you don't have to worry about their management. ++ ++Note, however, that tickets expire. Privileged tickets, such as those ++with the instance ``root``, expire in a few minutes, while tickets ++that carry more ordinary privileges may be good for several hours or a ++day, depending on the installation's policy. If your login session ++extends beyond the time limit, you will have to re-authenticate ++yourself to Kerberos to get new tickets. Use the :ref:`kinit(1)` ++command to re-authenticate yourself. ++ ++If you use the kinit command to get your tickets, make sure you use ++the kdestroy command to destroy your tickets before you end your login ++session. You should put the kdestroy command in your ``.logout`` file ++so that your tickets will be destroyed automatically when you logout. ++For more information about the kinit and kdestroy commands, see the ++:ref:`kinit(1)` and :ref:`kdestroy(1)` manual pages. ++ ++Kerberos tickets can be forwarded. In order to forward tickets, you ++must request **forwardable** tickets when you kinit. Once you have ++forwardable tickets, most Kerberos programs have a command line option ++to forward them to the remote host. ++ ++ENVIRONMENT VARIABLES ++--------------------- ++ ++Several environment variables affect the operation of Kerberos-enabled ++programs. These inclide: ++ ++**KRB5CCNAME** ++ Specifies the location of the credential cache, in the form ++ *TYPE*:*residual*. If no *type* prefix is present, the **FILE** ++ type is assumed and *residual* is the pathname of the cache file. ++ A collection of multiple caches may be used by specifying the ++ **dir** type and the pathname of a private directory (which must ++ already exist). The default cache file is /tmp/krb5cc_*uid*, ++ where *uid* is the decimal user ID of the user. ++ ++**KRB5_KTNAME** ++ Specifies the location of the keytab file, in the form ++ *TYPE*:*residual*. If no *type* is present, the **FILE** type is ++ assumed and *residual* is the pathname of the keytab file. The ++ default keytab file is ``/etc/krb5.keytab``. ++ ++**KRB5_CONFIG** ++ Specifies the location of the Kerberos configuration file. The ++ default is ``/etc/krb5.conf``. ++ ++**KRB5_KDC_PROFILE** ++ Specifies the location of the KDC configuration file, which ++ contains additional configuration directives for the Key ++ Distribution Center daemon and associated programs. The default ++ is ``/usr/local/var/krb5kdc/kdc.conf``. ++ ++**KRB5RCACHETYPE** ++ Specifies the default type of replay cache to use for servers. ++ Valid types include **dfl** for the normal file type and **none** ++ for no replay cache. ++ ++**KRB5RCACHEDIR** ++ Specifies the default directory for replay caches used by servers. ++ The default is the value of the **TMPDIR** environment variable, ++ or ``/var/tmp`` if **TMPDIR** is not set. ++ ++**KRB5_TRACE** ++ Specifies a filename to write trace log output to. Trace logs can ++ help illuminate decisions made internally by the Kerberos ++ libraries. The default is not to write trace log output anywhere. ++ ++Most environment variables are disabled for certain programs, such as ++login system programs and setuid programs, which are designed to be ++secure when run within an untrusted process environment. ++ ++SEE ALSO ++-------- ++ ++:ref:`kdestroy(1)`, :ref:`kinit(1)`, :ref:`klist(1)`, ++:ref:`kswitch(1)`, :ref:`kpasswd(1)`, :ref:`ksu(1)`, ++:ref:`krb5.conf(5)`, :ref:`kdc.conf(5)`, :ref:`kadmin(1)`, ++:ref:`kadmind(8)`, :ref:`kdb5_util(8)`, :ref:`krb5kdc(8)` ++ ++BUGS ++---- ++ ++AUTHORS ++------- ++ ++| Steve Miller, MIT Project Athena/Digital Equipment Corporation ++| Clifford Neuman, MIT Project Athena ++| Greg Hudson, MIT Kerberos Consortium ++ ++HISTORY ++------- ++ ++The MIT Kerberos 5 implementation was developed at MIT, with ++contributions from many outside parties. It is currently maintained ++by the MIT Kerberos Consortium. ++ ++RESTRICTIONS ++------------ ++ ++Copyright 1985, 1986, 1989-1996, 2002, 2011 Masachusetts Institute of ++Technology +diff --git a/src/Makefile.in b/src/Makefile.in +index e47bddcb1..91032361f 100644 +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -60,9 +60,9 @@ world: + INSTALLMKDIRS = $(KRB5ROOT) $(KRB5MANROOT) $(KRB5OTHERMKDIRS) \ + $(ADMIN_BINDIR) $(SERVER_BINDIR) $(CLIENT_BINDIR) \ + $(ADMIN_MANDIR) $(SERVER_MANDIR) $(CLIENT_MANDIR) \ +- $(FILE_MANDIR) \ ++ $(FILE_MANDIR) $(OVERVIEW_MANDIR) \ + $(ADMIN_CATDIR) $(SERVER_CATDIR) $(CLIENT_CATDIR) \ +- $(FILE_CATDIR) \ ++ $(FILE_CATDIR) $(OVERVIEW_CATDIR) \ + $(KRB5_LIBDIR) $(KRB5_INCDIR) \ + $(KRB5_DB_MODULE_DIR) $(KRB5_PA_MODULE_DIR) \ + $(KRB5_AD_MODULE_DIR) \ +diff --git a/src/config/pre.in b/src/config/pre.in +index f23c07d9d..a851c56c7 100644 +--- a/src/config/pre.in ++++ b/src/config/pre.in +@@ -210,6 +210,8 @@ ADMIN_CATDIR = $(KRB5MANROOT)/cat8 + SERVER_CATDIR = $(KRB5MANROOT)/cat8 + CLIENT_CATDIR = $(KRB5MANROOT)/cat1 + FILE_CATDIR = $(KRB5MANROOT)/cat5 ++OVERVIEW_MANDIR = $(KRB5MANROOT)/man7 ++OVERVIEW_CATDIR = $(KRB5MANROOT)/cat7 + KRB5_LIBDIR = @libdir@ + KRB5_INCDIR = @includedir@ + MODULE_DIR = @libdir@/krb5/plugins +diff --git a/src/man/Makefile.in b/src/man/Makefile.in +index 4bc670bad..e3722b1cd 100644 +--- a/src/man/Makefile.in ++++ b/src/man/Makefile.in +@@ -15,7 +15,7 @@ MANSUBS=k5identity.sub k5login.sub k5srvutil.sub kadm5.acl.sub kadmin.sub \ + kadmind.sub kdb5_ldap_util.sub kdb5_util.sub kdc.conf.sub \ + kdestroy.sub kinit.sub klist.sub kpasswd.sub kprop.sub kpropd.sub \ + kproplog.sub krb5.conf.sub krb5-config.sub krb5kdc.sub ksu.sub \ +- kswitch.sub ktutil.sub kvno.sub sclient.sub sserver.sub ++ kswitch.sub ktutil.sub kvno.sub sclient.sub sserver.sub kerberos.sub + + docsrc=$(top_srcdir)/../doc + +@@ -56,9 +56,11 @@ all: $(MANSUBS) + clean: + rm -rf $(MANSUBS) rst_man + +-install: install-clientman install-fileman install-adminman install-serverman ++install: install-clientman install-fileman install-adminman \ ++ install-overviewman install-serverman + +-install-catman: install-clientcat install-filecat install-admincat install-servercat ++install-catman: install-clientcat install-filecat install-admincat \ ++ install-overviewcat install-servercat + + install-clientman: + $(INSTALL_DATA) k5srvutil.sub $(DESTDIR)$(CLIENT_MANDIR)/k5srvutil.1 +@@ -85,6 +87,9 @@ install-fileman: + $(INSTALL_DATA) kdc.conf.sub $(DESTDIR)$(FILE_MANDIR)/kdc.conf.5 + $(INSTALL_DATA) krb5.conf.sub $(DESTDIR)$(FILE_MANDIR)/krb5.conf.5 + ++install-overviewman: ++ $(INSTALL_DATA) kerberos.sub $(DESTDIR)$(OVERVIEW_MANDIR)/kerberos.7 ++ + install-adminman: + $(INSTALL_DATA) $(srcdir)/kadmin.local.8 \ + $(DESTDIR)$(ADMIN_MANDIR)/kadmin.local.8 +@@ -127,6 +132,9 @@ install-filecat: + $(GROFF_MAN) kdc.conf.sub > $(DESTDIR)$(FILE_CATDIR)/kdc.conf.5 + $(GROFF_MAN) krb5.conf.sub > $(DESTDIR)$(FILE_CATDIR)/krb5.conf.5 + ++install-overviewcat: ++ $(GROFF_MAN) kerberos.sub > $(DESTDIR)$(OVERVIEW_CATDIR)/kerberos.7 ++ + install-admincat: + ($(RM) $(DESTDIR)$(ADMIN_CATDIR)/kadmin.local.8; \ + $(LN_S) $(CLIENT_CATDIR)/kadmin.1 \ +diff --git a/src/man/kerberos.man b/src/man/kerberos.man +new file mode 100644 +index 000000000..7b2b5d932 +--- /dev/null ++++ b/src/man/kerberos.man +@@ -0,0 +1,180 @@ ++.\" Man page generated from reStructuredText. ++. ++.TH "KERBEROS" "7" " " "1.17" "MIT Kerberos" ++.SH NAME ++kerberos \- Overview of using Kerberos ++. ++.nr rst2man-indent-level 0 ++. ++.de1 rstReportMargin ++\\$1 \\n[an-margin] ++level \\n[rst2man-indent-level] ++level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] ++- ++\\n[rst2man-indent0] ++\\n[rst2man-indent1] ++\\n[rst2man-indent2] ++.. ++.de1 INDENT ++.\" .rstReportMargin pre: ++. RS \\$1 ++. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] ++. nr rst2man-indent-level +1 ++.\" .rstReportMargin post: ++.. ++.de UNINDENT ++. RE ++.\" indent \\n[an-margin] ++.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] ++.nr rst2man-indent-level -1 ++.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] ++.in \\n[rst2man-indent\\n[rst2man-indent-level]]u ++.. ++.SH DESCRIPTION ++.sp ++The Kerberos system authenticates individual users in a network ++environment. After authenticating yourself to Kerberos, you can use ++Kerberos\-enabled programs without having to present passwords. ++.sp ++If you enter your username and kinit(1) responds with this ++message: ++.sp ++kinit(v5): Client not found in Kerberos database while getting initial ++credentials ++.sp ++you haven\(aqt been registered as a Kerberos user. See your system ++administrator. ++.sp ++A Kerberos name usually contains three parts. The first is the ++\fBprimary\fP, which is usually a user\(aqs or service\(aqs name. The second ++is the \fBinstance\fP, which in the case of a user is usually null. ++Some users may have privileged instances, however, such as \fBroot\fP or ++\fBadmin\fP\&. In the case of a service, the instance is the fully ++qualified name of the machine on which it runs; i.e. there can be an ++rlogin service running on the machine ABC, which is different from the ++rlogin service running on the machine XYZ. The third part of a ++Kerberos name is the \fBrealm\fP\&. The realm corresponds to the Kerberos ++service providing authentication for the principal. ++.sp ++When writing a Kerberos name, the principal name is separated from the ++instance (if not null) by a slash, and the realm (if not the local ++realm) follows, preceded by an "@" sign. The following are examples ++of valid Kerberos names: ++.INDENT 0.0 ++.INDENT 3.5 ++.sp ++.nf ++.ft C ++david ++jennifer/admin ++joeuser@BLEEP.COM ++cbrown/root@FUBAR.ORG ++.ft P ++.fi ++.UNINDENT ++.UNINDENT ++.sp ++When you authenticate yourself with Kerberos you get an initial ++Kerberos \fBticket\fP\&. (A Kerberos ticket is an encrypted protocol ++message that provides authentication.) Kerberos uses this ticket for ++network utilities such as rlogin and rcp. The ticket transactions are ++done transparently, so you don\(aqt have to worry about their management. ++.sp ++Note, however, that tickets expire. Privileged tickets, such as those ++with the instance \fBroot\fP, expire in a few minutes, while tickets ++that carry more ordinary privileges may be good for several hours or a ++day, depending on the installation\(aqs policy. If your login session ++extends beyond the time limit, you will have to re\-authenticate ++yourself to Kerberos to get new tickets. Use the kinit(1) ++command to re\-authenticate yourself. ++.sp ++If you use the kinit command to get your tickets, make sure you use ++the kdestroy command to destroy your tickets before you end your login ++session. You should put the kdestroy command in your \fB\&.logout\fP file ++so that your tickets will be destroyed automatically when you logout. ++For more information about the kinit and kdestroy commands, see the ++kinit(1) and kdestroy(1) manual pages. ++.sp ++Kerberos tickets can be forwarded. In order to forward tickets, you ++must request \fBforwardable\fP tickets when you kinit. Once you have ++forwardable tickets, most Kerberos programs have a command line option ++to forward them to the remote host. ++.SH ENVIRONMENT VARIABLES ++.sp ++Several environment variables affect the operation of Kerberos\-enabled ++programs. These inclide: ++.INDENT 0.0 ++.TP ++\fBKRB5CCNAME\fP ++Specifies the location of the credential cache, in the form ++\fITYPE\fP:\fIresidual\fP\&. If no \fItype\fP prefix is present, the \fBFILE\fP ++type is assumed and \fIresidual\fP is the pathname of the cache file. ++A collection of multiple caches may be used by specifying the ++\fBdir\fP type and the pathname of a private directory (which must ++already exist). The default cache file is /tmp/krb5cc_*uid*, ++where \fIuid\fP is the decimal user ID of the user. ++.TP ++\fBKRB5_KTNAME\fP ++Specifies the location of the keytab file, in the form ++\fITYPE\fP:\fIresidual\fP\&. If no \fItype\fP is present, the \fBFILE\fP type is ++assumed and \fIresidual\fP is the pathname of the keytab file. The ++default keytab file is \fB/etc/krb5.keytab\fP\&. ++.TP ++\fBKRB5_CONFIG\fP ++Specifies the location of the Kerberos configuration file. The ++default is \fB/etc/krb5.conf\fP\&. ++.TP ++\fBKRB5_KDC_PROFILE\fP ++Specifies the location of the KDC configuration file, which ++contains additional configuration directives for the Key ++Distribution Center daemon and associated programs. The default ++is \fB/usr/local/var/krb5kdc/kdc.conf\fP\&. ++.TP ++\fBKRB5RCACHETYPE\fP ++Specifies the default type of replay cache to use for servers. ++Valid types include \fBdfl\fP for the normal file type and \fBnone\fP ++for no replay cache. ++.TP ++\fBKRB5RCACHEDIR\fP ++Specifies the default directory for replay caches used by servers. ++The default is the value of the \fBTMPDIR\fP environment variable, ++or \fB/var/tmp\fP if \fBTMPDIR\fP is not set. ++.TP ++\fBKRB5_TRACE\fP ++Specifies a filename to write trace log output to. Trace logs can ++help illuminate decisions made internally by the Kerberos ++libraries. The default is not to write trace log output anywhere. ++.UNINDENT ++.sp ++Most environment variables are disabled for certain programs, such as ++login system programs and setuid programs, which are designed to be ++secure when run within an untrusted process environment. ++.SH SEE ALSO ++.sp ++kdestroy(1), kinit(1), klist(1), ++kswitch(1), kpasswd(1), ksu(1), ++krb5.conf(5), kdc.conf(5), kadmin(1), ++kadmind(8), kdb5_util(8), krb5kdc(8) ++.SH BUGS ++.SH AUTHORS ++.nf ++Steve Miller, MIT Project Athena/Digital Equipment Corporation ++Clifford Neuman, MIT Project Athena ++Greg Hudson, MIT Kerberos Consortium ++.fi ++.sp ++.SH HISTORY ++.sp ++The MIT Kerberos 5 implementation was developed at MIT, with ++contributions from many outside parties. It is currently maintained ++by the MIT Kerberos Consortium. ++.SH RESTRICTIONS ++.sp ++Copyright 1985, 1986, 1989\-1996, 2002, 2011 Masachusetts Institute of ++Technology ++.SH AUTHOR ++MIT ++.SH COPYRIGHT ++1985-2018, MIT ++.\" Generated by docutils manpage writer. ++. diff --git a/SOURCES/Continue-after-KDC_ERR_PREAUTH_FAILED.patch b/SOURCES/Continue-after-KDC_ERR_PREAUTH_FAILED.patch new file mode 100644 index 0000000..7da3368 --- /dev/null +++ b/SOURCES/Continue-after-KDC_ERR_PREAUTH_FAILED.patch @@ -0,0 +1,100 @@ +From 75b375abcec69421c430a0241e5c72cafd96cb7f Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Mon, 16 Jan 2017 15:09:32 -0500 +Subject: [PATCH] Continue after KDC_ERR_PREAUTH_FAILED + +If the KDC sends KDC_ERR_PREAUTH_FAILED, try another mechanism, or +send an unauthenticated request if optimistic preauth failed. + +ticket: 8537 +(cherry picked from commit 52d2de31bc4728dbc2f59c6033dcdab86da919e9) +--- + src/lib/krb5/krb/get_in_tkt.c | 45 ++++++++++++++++++++++++++++------- + 1 file changed, 36 insertions(+), 9 deletions(-) + +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index 8d0f964f9..c7d7bfe74 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -1308,6 +1308,7 @@ init_creds_step_request(krb5_context context, + krb5_error_code code; + krb5_preauthtype pa_type; + struct errinfo save = EMPTY_ERRINFO; ++ uint32_t rcode = (ctx->err_reply == NULL) ? 0 : ctx->err_reply->error; + + if (ctx->loopcount >= MAX_IN_TKT_LOOPS) { + code = KRB5_GET_IN_TKT_LOOP; +@@ -1358,8 +1359,10 @@ init_creds_step_request(krb5_context context, + TRACE_INIT_CREDS_PREAUTH_MORE(context, ctx->selected_preauth_type); + code = k5_preauth(context, ctx, ctx->more_padata, TRUE, + &ctx->request->padata, &pa_type); +- } else if (ctx->err_reply != NULL && +- ctx->err_reply->error != KDC_ERR_PREAUTH_REQUIRED) { ++ } else if (rcode == KDC_ERR_PREAUTH_FAILED) { ++ /* Report the KDC-side failure code if we can't try another mech. */ ++ code = KRB5KDC_ERR_PREAUTH_FAILED; ++ } else if (rcode && rcode != KDC_ERR_PREAUTH_REQUIRED) { + /* Retrying after an error (possibly mechanism-specific), using error + * padata to figure out what to change. */ + TRACE_INIT_CREDS_PREAUTH_TRYAGAIN(context, ctx->err_reply->error, +@@ -1380,7 +1383,7 @@ init_creds_step_request(krb5_context context, + + if (ctx->request->padata == NULL && ctx->method_padata != NULL) { + /* Retrying after KDC_ERR_PREAUTH_REQUIRED, or trying again with a +- * different mechanism after a client-side failure. */ ++ * different mechanism after a failure. */ + TRACE_INIT_CREDS_PREAUTH(context); + code = k5_preauth(context, ctx, ctx->method_padata, TRUE, + &ctx->request->padata, &ctx->selected_preauth_type); +@@ -1480,6 +1483,18 @@ is_referral(krb5_context context, krb5_error *err, krb5_principal client) + return !krb5_realm_compare(context, err->client, client); + } + ++/* Transfer error padata to method data in ctx and sort it according to ++ * configuration. */ ++static krb5_error_code ++accept_method_data(krb5_context context, krb5_init_creds_context ctx) ++{ ++ krb5_free_pa_data(context, ctx->method_padata); ++ ctx->method_padata = ctx->err_padata; ++ ctx->err_padata = NULL; ++ return sort_krb5_padata_sequence(context, &ctx->request->client->realm, ++ ctx->method_padata); ++} ++ + static krb5_error_code + init_creds_step_reply(krb5_context context, + krb5_init_creds_context ctx, +@@ -1538,14 +1553,26 @@ init_creds_step_reply(krb5_context context, + ctx->restarted = FALSE; + code = restart_init_creds_loop(context, ctx, FALSE); + } else if (reply_code == KDC_ERR_PREAUTH_REQUIRED && retry) { +- krb5_free_pa_data(context, ctx->method_padata); +- ctx->method_padata = ctx->err_padata; +- ctx->err_padata = NULL; + note_req_timestamp(context, ctx, ctx->err_reply->stime, + ctx->err_reply->susec); +- code = sort_krb5_padata_sequence(context, +- &ctx->request->client->realm, +- ctx->method_padata); ++ code = accept_method_data(context, ctx); ++ } else if (reply_code == KDC_ERR_PREAUTH_FAILED && retry) { ++ note_req_timestamp(context, ctx, ctx->err_reply->stime, ++ ctx->err_reply->susec); ++ if (ctx->method_padata == NULL) { ++ /* Optimistic preauth failed on the KDC. Allow all mechanisms ++ * to be tried again using method data. */ ++ k5_reset_preauth_types_tried(ctx); ++ } else { ++ /* Don't try again with the mechanism that failed. */ ++ code = k5_preauth_note_failed(ctx, ctx->selected_preauth_type); ++ if (code) ++ goto cleanup; ++ } ++ ctx->selected_preauth_type = KRB5_PADATA_NONE; ++ /* Accept or update method data if the KDC sent it. */ ++ if (ctx->err_padata != NULL) ++ code = accept_method_data(context, ctx); + } else if (reply_code == KDC_ERR_MORE_PREAUTH_DATA_REQUIRED && retry) { + ctx->more_padata = ctx->err_padata; + ctx->err_padata = NULL; diff --git a/SOURCES/Continue-after-KRB5_CC_END-in-KCM-cache-iteration.patch b/SOURCES/Continue-after-KRB5_CC_END-in-KCM-cache-iteration.patch new file mode 100644 index 0000000..08ba8cc --- /dev/null +++ b/SOURCES/Continue-after-KRB5_CC_END-in-KCM-cache-iteration.patch @@ -0,0 +1,42 @@ +From c66f120e6eba811ba1417ce67b49a01958b1c9d1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= +Date: Wed, 28 Mar 2018 18:27:06 +0200 +Subject: [PATCH] Continue after KRB5_CC_END in KCM cache iteration + +The KCM server returns KRB5_CC_END in response to a GET_CACHE_BY_UUID +request to indicate that the specified ccache uuid no longer exists. +In krb5_ptcursor_next(), ignore this error and continue the iteration, +as the Heimdal KCM client code does. + +In addition to addressing the case where a third party deletes a cache +between the GET_CACHE_UUID_LIST request and when we reach that uuid in +the iteration, this change also fixes a bug in kdestroy -A where the +caller deletes the primary cache and we later request it by uuid when +iterating over the list. + +[ghudson@mit.edu: rewrote commit message; edited comment] + +(cherry picked from commit 49087f5e6309f298f8898c35af6f4ade418ced60) + +ticket: 8658 +version_fixed: 1.16.1 + +(cherry picked from commit 576d4294ea789c3d25c50a43fe9246cfe499585f) +--- + src/lib/krb5/ccache/cc_kcm.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c +index a889e67b4..a3afd7056 100644 +--- a/src/lib/krb5/ccache/cc_kcm.c ++++ b/src/lib/krb5/ccache/cc_kcm.c +@@ -966,6 +966,9 @@ kcm_ptcursor_next(krb5_context context, krb5_cc_ptcursor cursor, + kcmreq_init(&req, KCM_OP_GET_CACHE_BY_UUID, NULL); + k5_buf_add_len(&req.reqbuf, id, KCM_UUID_LEN); + ret = kcmio_call(context, data->io, &req); ++ /* Continue if the cache has been deleted. */ ++ if (ret == KRB5_CC_END) ++ continue; + if (ret) + goto cleanup; + ret = kcmreq_get_name(&req, &name); diff --git a/SOURCES/Continue-preauth-after-client-side-failures.patch b/SOURCES/Continue-preauth-after-client-side-failures.patch new file mode 100644 index 0000000..c03b071 --- /dev/null +++ b/SOURCES/Continue-preauth-after-client-side-failures.patch @@ -0,0 +1,109 @@ +From d45e1ea83a6ed9eef0e7e6bfe86c8d4995a7402d Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Sat, 14 Jan 2017 13:55:22 -0500 +Subject: [PATCH] Continue preauth after client-side failures + +If the module for the selected preauth mechanism fails when processing +a KDC_ERR_MORE_PREAUTH_DATA_REQUIRED error, or fails a tryagain +operation, try again with a different preauth mech using the cached +method data. + +If optimistic preauth fails on the client side, send an +unauthenticated request, allowing the mechanisms we tried +optimistically to be tried again. + +ticket: 8537 +(cherry picked from commit 644840a207917661a6ccf706e7830bec273e23b3) +--- + src/lib/krb5/krb/get_in_tkt.c | 49 +++++++++++++++++++++++------------ + 1 file changed, 32 insertions(+), 17 deletions(-) + +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index 8c7919e65..8d0f964f9 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -1307,6 +1307,7 @@ init_creds_step_request(krb5_context context, + { + krb5_error_code code; + krb5_preauthtype pa_type; ++ struct errinfo save = EMPTY_ERRINFO; + + if (ctx->loopcount >= MAX_IN_TKT_LOOPS) { + code = KRB5_GET_IN_TKT_LOOP; +@@ -1341,38 +1342,51 @@ init_creds_step_request(krb5_context context, + if (ctx->optimistic_padata != NULL) { + /* Our first attempt, using an optimistic padata list. */ + TRACE_INIT_CREDS_PREAUTH_OPTIMISTIC(context); +- code = k5_preauth(context, ctx, ctx->optimistic_padata, FALSE, ++ code = k5_preauth(context, ctx, ctx->optimistic_padata, TRUE, + &ctx->request->padata, &ctx->selected_preauth_type); + krb5_free_pa_data(context, ctx->optimistic_padata); + ctx->optimistic_padata = NULL; +- if (code != 0) +- goto cleanup; ++ if (code) { ++ /* Make an unauthenticated request, and possibly try again using ++ * the same mechanisms as we tried optimistically. */ ++ k5_reset_preauth_types_tried(ctx); ++ krb5_clear_error_message(context); ++ code = 0; ++ } + } if (ctx->more_padata != NULL) { + /* Continuing after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED. */ + TRACE_INIT_CREDS_PREAUTH_MORE(context, ctx->selected_preauth_type); + code = k5_preauth(context, ctx, ctx->more_padata, TRUE, + &ctx->request->padata, &pa_type); +- if (code != 0) +- goto cleanup; + } else if (ctx->err_reply != NULL && +- ctx->err_reply->error == KDC_ERR_PREAUTH_REQUIRED) { +- /* Continuing after KDC_ERR_PREAUTH_REQUIRED, using method data. */ +- TRACE_INIT_CREDS_PREAUTH(context); +- code = k5_preauth(context, ctx, ctx->method_padata, TRUE, +- &ctx->request->padata, &ctx->selected_preauth_type); +- if (code != 0) +- goto cleanup; +- } else if (ctx->err_reply != NULL) { +- /* Retry after an error other than PREAUTH_REQUIRED, using error padata +- * to figure out what to change. */ ++ ctx->err_reply->error != KDC_ERR_PREAUTH_REQUIRED) { ++ /* Retrying after an error (possibly mechanism-specific), using error ++ * padata to figure out what to change. */ + TRACE_INIT_CREDS_PREAUTH_TRYAGAIN(context, ctx->err_reply->error, + ctx->selected_preauth_type); + code = k5_preauth_tryagain(context, ctx, ctx->selected_preauth_type, + ctx->err_reply, ctx->err_padata, + &ctx->request->padata); +- if (code != 0) { +- /* couldn't come up with anything better */ ++ if (code) { ++ krb5_clear_error_message(context); + code = ctx->err_reply->error + ERROR_TABLE_BASE_krb5; ++ } ++ } ++ if (code) { ++ /* See if we can try a different preauth mech before giving up. */ ++ k5_save_ctx_error(context, code, &save); ++ ctx->selected_preauth_type = KRB5_PADATA_NONE; ++ } ++ ++ if (ctx->request->padata == NULL && ctx->method_padata != NULL) { ++ /* Retrying after KDC_ERR_PREAUTH_REQUIRED, or trying again with a ++ * different mechanism after a client-side failure. */ ++ TRACE_INIT_CREDS_PREAUTH(context); ++ code = k5_preauth(context, ctx, ctx->method_padata, TRUE, ++ &ctx->request->padata, &ctx->selected_preauth_type); ++ if (code) { ++ if (save.code != 0) ++ code = k5_restore_ctx_error(context, &save); + goto cleanup; + } + } +@@ -1413,6 +1427,7 @@ init_creds_step_request(krb5_context context, + cleanup: + krb5_free_pa_data(context, ctx->request->padata); + ctx->request->padata = NULL; ++ k5_clear_error(&save); + return code; + } + diff --git a/SOURCES/Convert-some-pkiDebug-messages-to-TRACE-macros.patch b/SOURCES/Convert-some-pkiDebug-messages-to-TRACE-macros.patch new file mode 100644 index 0000000..5d28f23 --- /dev/null +++ b/SOURCES/Convert-some-pkiDebug-messages-to-TRACE-macros.patch @@ -0,0 +1,423 @@ +From 7564be02d140b5caa225679c8f728ee49d9a9e0a Mon Sep 17 00:00:00 2001 +From: Matt Rogers +Date: Wed, 29 Mar 2017 10:35:13 -0400 +Subject: [PATCH] Convert some pkiDebug messages to TRACE macros + +ticket: 8568 (new) +(cherry picked from commit 9852862a83952a94300adfafa3e333f43396ec33) +(cherry picked from commit 686fa6476eb759532d566794fa8d430774d44cf7) +--- + .../preauth/pkinit/pkinit_crypto_openssl.c | 46 +++++-------- + src/plugins/preauth/pkinit/pkinit_identity.c | 3 - + src/plugins/preauth/pkinit/pkinit_matching.c | 1 + + src/plugins/preauth/pkinit/pkinit_srv.c | 24 +++---- + src/plugins/preauth/pkinit/pkinit_trace.h | 68 ++++++++++++++++++- + 5 files changed, 97 insertions(+), 45 deletions(-) + +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index a5b010b26..792a2f771 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -2320,7 +2320,6 @@ crypto_check_cert_eku(krb5_context context, + + X509_NAME_oneline(X509_get_subject_name(reqctx->received_cert), + buf, sizeof(buf)); +- pkiDebug("%s: looking for EKUs in cert = %s\n", __FUNCTION__, buf); + + if ((i = X509_get_ext_by_NID(reqctx->received_cert, + NID_ext_key_usage, -1)) >= 0) { +@@ -2354,7 +2353,6 @@ crypto_check_cert_eku(krb5_context context, + + if (found_eku) { + ASN1_BIT_STRING *usage = NULL; +- pkiDebug("%s: found acceptable EKU, checking for digitalSignature\n", __FUNCTION__); + + /* check that digitalSignature KeyUsage is present */ + X509_check_ca(reqctx->received_cert); +@@ -2363,12 +2361,10 @@ crypto_check_cert_eku(krb5_context context, + + if (!ku_reject(reqctx->received_cert, + X509v3_KU_DIGITAL_SIGNATURE)) { +- pkiDebug("%s: found digitalSignature KU\n", +- __FUNCTION__); ++ TRACE_PKINIT_EKU(context); + *valid_eku = 1; + } else +- pkiDebug("%s: didn't find digitalSignature KU\n", +- __FUNCTION__); ++ TRACE_PKINIT_EKU_NO_KU(context); + } + ASN1_BIT_STRING_free(usage); + } +@@ -4317,8 +4313,7 @@ pkinit_get_certs_pkcs12(krb5_context context, + + fp = fopen(idopts->cert_filename, "rb"); + if (fp == NULL) { +- pkiDebug("Failed to open PKCS12 file '%s', error %d\n", +- idopts->cert_filename, errno); ++ TRACE_PKINIT_PKCS_OPEN_FAIL(context, idopts->cert_filename, errno); + goto cleanup; + } + set_cloexec_file(fp); +@@ -4326,8 +4321,7 @@ pkinit_get_certs_pkcs12(krb5_context context, + p12 = d2i_PKCS12_fp(fp, NULL); + fclose(fp); + if (p12 == NULL) { +- pkiDebug("Failed to decode PKCS12 file '%s' contents\n", +- idopts->cert_filename); ++ TRACE_PKINIT_PKCS_DECODE_FAIL(context, idopts->cert_filename); + goto cleanup; + } + /* +@@ -4345,7 +4339,7 @@ pkinit_get_certs_pkcs12(krb5_context context, + char *p12name = reassemble_pkcs12_name(idopts->cert_filename); + const char *tmp; + +- pkiDebug("Initial PKCS12_parse with no password failed\n"); ++ TRACE_PKINIT_PKCS_PARSE_FAIL_FIRST(context); + + if (id_cryptoctx->defer_id_prompt) { + /* Supply the identity name to be passed to the responder. */ +@@ -4386,14 +4380,14 @@ pkinit_get_certs_pkcs12(krb5_context context, + NULL, NULL, 1, &kprompt); + k5int_set_prompt_types(context, 0); + if (r) { +- pkiDebug("Failed to prompt for PKCS12 password"); ++ TRACE_PKINIT_PKCS_PROMPT_FAIL(context); + goto cleanup; + } + } + + ret = PKCS12_parse(p12, rdat.data, &y, &x, NULL); + if (ret == 0) { +- pkiDebug("Second PKCS12_parse with password failed\n"); ++ TRACE_PKINIT_PKCS_PARSE_FAIL_SECOND(context); + goto cleanup; + } + } +@@ -4516,8 +4510,7 @@ pkinit_get_certs_fs(krb5_context context, + } + + if (idopts->key_filename == NULL) { +- pkiDebug("%s: failed to get user's private key location\n", +- __FUNCTION__); ++ TRACE_PKINIT_NO_PRIVKEY(context); + goto cleanup; + } + +@@ -4545,8 +4538,7 @@ pkinit_get_certs_dir(krb5_context context, + char *dirname, *suf; + + if (idopts->cert_filename == NULL) { +- pkiDebug("%s: failed to get user's certificate directory location\n", +- __FUNCTION__); ++ TRACE_PKINIT_NO_CERT(context); + return ENOENT; + } + +@@ -4590,8 +4582,7 @@ pkinit_get_certs_dir(krb5_context context, + retval = pkinit_load_fs_cert_and_key(context, id_cryptoctx, + certname, keyname, i); + if (retval == 0) { +- pkiDebug("%s: Successfully loaded cert (and key) for %s\n", +- __FUNCTION__, dentry->d_name); ++ TRACE_PKINIT_LOADED_CERT(context, dentry->d_name); + i++; + } + else +@@ -4599,8 +4590,7 @@ pkinit_get_certs_dir(krb5_context context, + } + + if (!id_cryptoctx->defer_id_prompt && i == 0) { +- pkiDebug("%s: No cert/key pairs found in directory '%s'\n", +- __FUNCTION__, idopts->cert_filename); ++ TRACE_PKINIT_NO_CERT_AND_KEY(context, idopts->cert_filename); + retval = ENOENT; + goto cleanup; + } +@@ -5370,9 +5360,7 @@ crypto_cert_select_default(krb5_context context, + goto errout; + } + if (cert_count != 1) { +- pkiDebug("%s: ERROR: There are %d certs to choose from, " +- "but there must be exactly one.\n", +- __FUNCTION__, cert_count); ++ TRACE_PKINIT_NO_DEFAULT_CERT(context, cert_count); + retval = EINVAL; + goto errout; + } +@@ -5520,7 +5508,7 @@ load_cas_and_crls(krb5_context context, + switch(catype) { + case CATYPE_ANCHORS: + if (sk_X509_num(ca_certs) == 0) { +- pkiDebug("no anchors in file, %s\n", filename); ++ TRACE_PKINIT_NO_CA_ANCHOR(context, filename); + if (id_cryptoctx->trustedCAs == NULL) + sk_X509_free(ca_certs); + } else { +@@ -5530,7 +5518,7 @@ load_cas_and_crls(krb5_context context, + break; + case CATYPE_INTERMEDIATES: + if (sk_X509_num(ca_certs) == 0) { +- pkiDebug("no intermediates in file, %s\n", filename); ++ TRACE_PKINIT_NO_CA_INTERMEDIATE(context, filename); + if (id_cryptoctx->intermediateCAs == NULL) + sk_X509_free(ca_certs); + } else { +@@ -5540,7 +5528,7 @@ load_cas_and_crls(krb5_context context, + break; + case CATYPE_CRLS: + if (sk_X509_CRL_num(ca_crls) == 0) { +- pkiDebug("no crls in file, %s\n", filename); ++ TRACE_PKINIT_NO_CRL(context, filename); + if (id_cryptoctx->revoked == NULL) + sk_X509_CRL_free(ca_crls); + } else { +@@ -5626,14 +5614,14 @@ crypto_load_cas_and_crls(krb5_context context, + int catype, + char *id) + { +- pkiDebug("%s: called with idtype %s and catype %s\n", +- __FUNCTION__, idtype2string(idtype), catype2string(catype)); + switch (idtype) { + case IDTYPE_FILE: ++ TRACE_PKINIT_LOAD_FROM_FILE(context); + return load_cas_and_crls(context, plg_cryptoctx, req_cryptoctx, + id_cryptoctx, catype, id); + break; + case IDTYPE_DIR: ++ TRACE_PKINIT_LOAD_FROM_DIR(context); + return load_cas_and_crls_dir(context, plg_cryptoctx, req_cryptoctx, + id_cryptoctx, catype, id); + break; +diff --git a/src/plugins/preauth/pkinit/pkinit_identity.c b/src/plugins/preauth/pkinit/pkinit_identity.c +index a897efa25..737552e85 100644 +--- a/src/plugins/preauth/pkinit/pkinit_identity.c ++++ b/src/plugins/preauth/pkinit/pkinit_identity.c +@@ -608,7 +608,6 @@ pkinit_identity_prompt(krb5_context context, + retval = pkinit_cert_matching(context, plg_cryptoctx, + req_cryptoctx, id_cryptoctx, princ); + if (retval) { +- pkiDebug("%s: No matching certificate found\n", __FUNCTION__); + crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx, + id_cryptoctx); + goto errout; +@@ -621,8 +620,6 @@ pkinit_identity_prompt(krb5_context context, + retval = crypto_cert_select_default(context, plg_cryptoctx, + req_cryptoctx, id_cryptoctx); + if (retval) { +- pkiDebug("%s: Failed while selecting default certificate\n", +- __FUNCTION__); + crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx, + id_cryptoctx); + goto errout; +diff --git a/src/plugins/preauth/pkinit/pkinit_matching.c b/src/plugins/preauth/pkinit/pkinit_matching.c +index a50c50c8d..cad4c2b9a 100644 +--- a/src/plugins/preauth/pkinit/pkinit_matching.c ++++ b/src/plugins/preauth/pkinit/pkinit_matching.c +@@ -812,6 +812,7 @@ pkinit_cert_matching(krb5_context context, + goto cleanup; + } + } else { ++ TRACE_PKINIT_NO_MATCHING_CERT(context); + retval = ENOENT; /* XXX */ + goto cleanup; + } +diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c +index 32ca122f2..9c6e96c9e 100644 +--- a/src/plugins/preauth/pkinit/pkinit_srv.c ++++ b/src/plugins/preauth/pkinit/pkinit_srv.c +@@ -188,6 +188,7 @@ verify_client_san(krb5_context context, + plgctx->opts->allow_upn ? &upns : NULL, + NULL); + if (retval == ENOENT) { ++ TRACE_PKINIT_SERVER_NO_SAN(context); + goto out; + } else if (retval) { + pkiDebug("%s: error from retrieve_certificate_sans()\n", __FUNCTION__); +@@ -224,7 +225,7 @@ verify_client_san(krb5_context context, + krb5_free_unparsed_name(context, san_string); + #endif + if (cb->match_client(context, rock, princs[i])) { +- pkiDebug("%s: pkinit san match found\n", __FUNCTION__); ++ TRACE_PKINIT_SERVER_MATCHING_SAN_FOUND(context); + *valid_san = 1; + retval = 0; + goto out; +@@ -252,7 +253,7 @@ verify_client_san(krb5_context context, + krb5_free_unparsed_name(context, san_string); + #endif + if (cb->match_client(context, rock, upns[i])) { +- pkiDebug("%s: upn san match found\n", __FUNCTION__); ++ TRACE_PKINIT_SERVER_MATCHING_UPN_FOUND(context); + *valid_san = 1; + retval = 0; + goto out; +@@ -300,7 +301,7 @@ verify_client_eku(krb5_context context, + *eku_accepted = 0; + + if (plgctx->opts->require_eku == 0) { +- pkiDebug("%s: configuration requests no EKU checking\n", __FUNCTION__); ++ TRACE_PKINIT_SERVER_EKU_SKIP(context); + *eku_accepted = 1; + retval = 0; + goto out; +@@ -364,6 +365,7 @@ authorize_cert(krb5_context context, certauth_handle *certauth_modules, + ret = KRB5_PLUGIN_NO_HANDLE; + for (i = 0; certauth_modules != NULL && certauth_modules[i] != NULL; i++) { + h = certauth_modules[i]; ++ TRACE_PKINIT_SERVER_CERT_AUTH(context, h->vt.name); + ret = h->vt.authorize(context, h->moddata, cert, cert_len, client, + &opts, db_ent, &ais); + if (ret == 0) +@@ -449,7 +451,7 @@ pkinit_server_verify_padata(krb5_context context, + + switch ((int)data->pa_type) { + case KRB5_PADATA_PK_AS_REQ: +- pkiDebug("processing KRB5_PADATA_PK_AS_REQ\n"); ++ TRACE_PKINIT_SERVER_PADATA_VERIFY(context); + retval = k5int_decode_krb5_pa_pk_as_req(&k5data, &reqp); + if (retval) { + pkiDebug("decode_krb5_pa_pk_as_req failed\n"); +@@ -472,7 +474,7 @@ pkinit_server_verify_padata(krb5_context context, + break; + case KRB5_PADATA_PK_AS_REP_OLD: + case KRB5_PADATA_PK_AS_REQ_OLD: +- pkiDebug("processing KRB5_PADATA_PK_AS_REQ_OLD\n"); ++ TRACE_PKINIT_SERVER_PADATA_VERIFY_OLD(context); + retval = k5int_decode_krb5_pa_pk_as_req_draft9(&k5data, &reqp9); + if (retval) { + pkiDebug("decode_krb5_pa_pk_as_req_draft9 failed\n"); +@@ -500,7 +502,7 @@ pkinit_server_verify_padata(krb5_context context, + goto cleanup; + } + if (retval) { +- pkiDebug("pkcs7_signeddata_verify failed\n"); ++ TRACE_PKINIT_SERVER_PADATA_VERIFY_FAIL(context); + goto cleanup; + } + if (is_signed) { +@@ -830,7 +832,7 @@ pkinit_server_return_padata(krb5_context context, + return ENOENT; + } + +- pkiDebug("pkinit_return_padata: entered!\n"); ++ TRACE_PKINIT_SERVER_RETURN_PADATA(context); + reqctx = (pkinit_kdc_req_context)modreq; + + if (encrypting_key->contents) { +@@ -1463,8 +1465,7 @@ pkinit_san_authorize(krb5_context context, krb5_certauth_moddata moddata, + return ret; + + if (!valid_san) { +- pkiDebug("%s: did not find an acceptable SAN in user certificate\n", +- __FUNCTION__); ++ TRACE_PKINIT_SERVER_SAN_REJECT(context); + return KRB5KDC_ERR_CLIENT_NAME_MISMATCH; + } + +@@ -1490,8 +1491,7 @@ pkinit_eku_authorize(krb5_context context, krb5_certauth_moddata moddata, + return ret; + + if (!valid_eku) { +- pkiDebug("%s: did not find an acceptable EKU in user certificate\n", +- __FUNCTION__); ++ TRACE_PKINIT_SERVER_EKU_REJECT(context); + return KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE; + } + +@@ -1617,7 +1617,7 @@ pkinit_server_plugin_init(krb5_context context, + return ENOMEM; + + for (i = 0, j = 0; i < numrealms; i++) { +- pkiDebug("%s: processing realm '%s'\n", __FUNCTION__, realmnames[i]); ++ TRACE_PKINIT_SERVER_INIT_REALM(context, realmnames[i]); + retval = pkinit_server_plugin_init_realm(context, realmnames[i], &plgctx); + if (retval == 0 && plgctx != NULL) + realm_contexts[j++] = plgctx; +diff --git a/src/plugins/preauth/pkinit/pkinit_trace.h b/src/plugins/preauth/pkinit/pkinit_trace.h +index 458d0961e..6abe28c0c 100644 +--- a/src/plugins/preauth/pkinit/pkinit_trace.h ++++ b/src/plugins/preauth/pkinit/pkinit_trace.h +@@ -52,7 +52,7 @@ + #define TRACE_PKINIT_CLIENT_REP_CHECKSUM_FAIL(c, expected, received) \ + TRACE(c, "PKINIT client checksum mismatch: expected {cksum}, " \ + "received {cksum}", expected, received) +-#define TRACE_PKINIT_CLIENT_REP_DH(c) \ ++#define TRACE_PKINIT_CLIENT_REP_DH(c) \ + TRACE(c, "PKINIT client verified DH reply") + #define TRACE_PKINIT_CLIENT_REP_DH_FAIL(c) \ + TRACE(c, "PKINIT client could not verify DH reply") +@@ -91,6 +91,72 @@ + #define TRACE_PKINIT_OPENSSL_ERROR(c, msg) \ + TRACE(c, "PKINIT OpenSSL error: {str}", msg) + ++#define TRACE_PKINIT_SERVER_CERT_AUTH(c, modname) \ ++ TRACE(c, "PKINIT server authorizing cert with module {str}", \ ++ modname) ++#define TRACE_PKINIT_SERVER_EKU_REJECT(c) \ ++ TRACE(c, "PKINIT server found no acceptable EKU in client cert") ++#define TRACE_PKINIT_SERVER_EKU_SKIP(c) \ ++ TRACE(c, "PKINIT server skipping EKU check due to configuration") ++#define TRACE_PKINIT_SERVER_INIT_REALM(c, realm) \ ++ TRACE(c, "PKINIT server initializing realm {str}", realm) ++#define TRACE_PKINIT_SERVER_MATCHING_UPN_FOUND(c) \ ++ TRACE(c, "PKINIT server found a matching UPN SAN in client cert") ++#define TRACE_PKINIT_SERVER_MATCHING_SAN_FOUND(c) \ ++ TRACE(c, "PKINIT server found a matching SAN in client cert") ++#define TRACE_PKINIT_SERVER_NO_SAN(c) \ ++ TRACE(c, "PKINIT server found no SAN in client cert") ++#define TRACE_PKINIT_SERVER_PADATA_VERIFY(c) \ ++ TRACE(c, "PKINIT server verifying KRB5_PADATA_PK_AS_REQ") ++#define TRACE_PKINIT_SERVER_PADATA_VERIFY_OLD(c) \ ++ TRACE(c, "PKINIT server verifying KRB5_PADATA_PK_AS_REQ_OLD") ++#define TRACE_PKINIT_SERVER_PADATA_VERIFY_FAIL(c) \ ++ TRACE(c, "PKINIT server failed to verify PA data") ++#define TRACE_PKINIT_SERVER_RETURN_PADATA(c) \ ++ TRACE(c, "PKINIT server returning PA data") ++#define TRACE_PKINIT_SERVER_SAN_REJECT(c) \ ++ TRACE(c, "PKINIT server found no acceptable SAN in client cert") ++ ++#define TRACE_PKINIT_EKU(c) \ ++ TRACE(c, "PKINIT found acceptable EKU and digitalSignature KU") ++#define TRACE_PKINIT_EKU_NO_KU(c) \ ++ TRACE(c, "PKINIT found acceptable EKU but no digitalSignature KU") ++#define TRACE_PKINIT_LOADED_CERT(c, name) \ ++ TRACE(c, "PKINIT loaded cert and key for {str}", name) ++#define TRACE_PKINIT_LOAD_FROM_FILE(c) \ ++ TRACE(c, "PKINIT loading CA certs and CRLs from FILE") ++#define TRACE_PKINIT_LOAD_FROM_DIR(c) \ ++ TRACE(c, "PKINIT loading CA certs and CRLs from DIR") ++#define TRACE_PKINIT_NO_CA_ANCHOR(c, file) \ ++ TRACE(c, "PKINIT no anchor CA in file {str}", file) ++#define TRACE_PKINIT_NO_CA_INTERMEDIATE(c, file) \ ++ TRACE(c, "PKINIT no intermediate CA in file {str}", file) ++#define TRACE_PKINIT_NO_CERT(c) \ ++ TRACE(c, "PKINIT no certificate provided") ++#define TRACE_PKINIT_NO_CERT_AND_KEY(c, dirname) \ ++ TRACE(c, "PKINIT no cert and key pair found in directory {str}", \ ++ dirname) ++#define TRACE_PKINIT_NO_CRL(c, file) \ ++ TRACE(c, "PKINIT no CRL in file {str}", file) ++#define TRACE_PKINIT_NO_DEFAULT_CERT(c, count) \ ++ TRACE(c, "PKINIT error: There are {int} certs, but there must " \ ++ "be exactly one.", count) ++#define TRACE_PKINIT_NO_MATCHING_CERT(c) \ ++ TRACE(c, "PKINIT no matching certificate found") ++#define TRACE_PKINIT_NO_PRIVKEY(c) \ ++ TRACE(c, "PKINIT no private key provided") ++#define TRACE_PKINIT_PKCS_DECODE_FAIL(c, name) \ ++ TRACE(c, "PKINIT failed to decode PKCS12 file {str} contents", name) ++#define TRACE_PKINIT_PKCS_OPEN_FAIL(c, name, err) \ ++ TRACE(c, "PKINIT failed to open PKCS12 file {str}: err {errno}", \ ++ name, err) ++#define TRACE_PKINIT_PKCS_PARSE_FAIL_FIRST(c) \ ++ TRACE(c, "PKINIT initial PKCS12_parse with no password failed") ++#define TRACE_PKINIT_PKCS_PARSE_FAIL_SECOND(c) \ ++ TRACE(c, "PKINIT second PKCS12_parse with password failed") ++#define TRACE_PKINIT_PKCS_PROMPT_FAIL(c) \ ++ TRACE(c, "PKINIT failed to prompt for PKCS12 password") ++ + #define TRACE_CERTAUTH_VTINIT_FAIL(c, ret) \ + TRACE(c, "certauth module failed to init vtable: {kerr}", ret) + #define TRACE_CERTAUTH_INIT_FAIL(c, name, ret) \ diff --git a/SOURCES/Correct-error-handling-bug-in-prior-commit.patch b/SOURCES/Correct-error-handling-bug-in-prior-commit.patch new file mode 100644 index 0000000..4ae2ec9 --- /dev/null +++ b/SOURCES/Correct-error-handling-bug-in-prior-commit.patch @@ -0,0 +1,32 @@ +From ce220f7a4c0a6bda0004626d702a2a60dd51e181 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Thu, 23 Mar 2017 13:42:55 -0400 +Subject: [PATCH] Correct error handling bug in prior commit + +In crypto_encode_der_cert(), if the second i2d_X509() invocation +fails, make sure to free the allocated pointer and not the +possibly-modified alias. + +ticket: 8561 +(cherry picked from commit 7fdaef7c3280c86b5df25ae061fb04cc56d8620c) +--- + src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index 534161b19..25bcef292 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -6089,10 +6089,10 @@ crypto_encode_der_cert(krb5_context context, pkinit_req_crypto_context reqctx, + if (len <= 0) + return EINVAL; + p = der = malloc(len); +- if (p == NULL) ++ if (der == NULL) + return ENOMEM; + if (i2d_X509(reqctx->received_cert, &p) <= 0) { +- free(p); ++ free(der); + return EINVAL; + } + *der_out = der; diff --git a/SOURCES/Correct-kpasswd_server-description-in-krb5.conf-5.patch b/SOURCES/Correct-kpasswd_server-description-in-krb5.conf-5.patch new file mode 100644 index 0000000..2406545 --- /dev/null +++ b/SOURCES/Correct-kpasswd_server-description-in-krb5.conf-5.patch @@ -0,0 +1,28 @@ +From fce9cdd8b264343a30b37bea8442da03b258ce45 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Tue, 16 Oct 2018 17:32:29 -0400 +Subject: [PATCH] Correct kpasswd_server description in krb5.conf(5) + +ticket: 8754 (new) +tags: pullup +target_version: 1.16-next + +(cherry picked from commit 762d804701f78fc76f728ec05a205eea6a2b2dd7) +--- + doc/admin/conf_files/krb5_conf.rst | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst +index a959e0e60..cc996f11a 100644 +--- a/doc/admin/conf_files/krb5_conf.rst ++++ b/doc/admin/conf_files/krb5_conf.rst +@@ -496,7 +496,8 @@ following tags may be specified in the realm's subsection: + + **kpasswd_server** + Points to the server where all the password changes are performed. +- If there is no such entry, the port 464 on the **admin_server** ++ If there is no such entry, DNS will be queried (unless forbidden ++ by **dns_lookup_kdc**). Finally, port 464 on the **admin_server** + host will be tried. + + **master_kdc** diff --git a/SOURCES/Deindent-crypto_retrieve_X509_sans.patch b/SOURCES/Deindent-crypto_retrieve_X509_sans.patch new file mode 100644 index 0000000..d9878d7 --- /dev/null +++ b/SOURCES/Deindent-crypto_retrieve_X509_sans.patch @@ -0,0 +1,264 @@ +From 54c5bec8deb2d4e972795e37273ad17a0b1e2f4f Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Wed, 4 Jan 2017 11:33:57 -0500 +Subject: [PATCH] Deindent crypto_retrieve_X509_sans() + +Fix some long lines in crypto_retrieve_X509_sans() by returning early +if X509_get_ext_by_NID() returns a negative result. Also ensure that +return parameters are always initialized. + +(cherry picked from commit c6b772523db9d7791ee1c56eb512c4626556a4e7) +(cherry picked from commit 23086ac768a32db1e40a9b63684dbcfd76aba033) +--- + .../preauth/pkinit/pkinit_crypto_openssl.c | 224 +++++++++--------- + 1 file changed, 114 insertions(+), 110 deletions(-) + +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index bc6e7662e..8def8c542 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -2101,11 +2101,21 @@ crypto_retrieve_X509_sans(krb5_context context, + { + krb5_error_code retval = EINVAL; + char buf[DN_BUF_LEN]; +- int p = 0, u = 0, d = 0, l; ++ int p = 0, u = 0, d = 0, ret = 0, l; + krb5_principal *princs = NULL; + krb5_principal *upns = NULL; + unsigned char **dnss = NULL; +- unsigned int i, num_found = 0; ++ unsigned int i, num_found = 0, num_sans = 0; ++ X509_EXTENSION *ext = NULL; ++ GENERAL_NAMES *ialt = NULL; ++ GENERAL_NAME *gen = NULL; ++ ++ if (princs_ret != NULL) ++ *princs_ret = NULL; ++ if (upn_ret != NULL) ++ *upn_ret = NULL; ++ if (dns_ret != NULL) ++ *dns_ret = NULL; + + if (princs_ret == NULL && upn_ret == NULL && dns_ret == NULL) { + pkiDebug("%s: nowhere to return any values!\n", __FUNCTION__); +@@ -2121,118 +2131,112 @@ crypto_retrieve_X509_sans(krb5_context context, + buf, sizeof(buf)); + pkiDebug("%s: looking for SANs in cert = %s\n", __FUNCTION__, buf); + +- if ((l = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1)) >= 0) { +- X509_EXTENSION *ext = NULL; +- GENERAL_NAMES *ialt = NULL; +- GENERAL_NAME *gen = NULL; +- int ret = 0; +- unsigned int num_sans = 0; ++ l = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1); ++ if (l < 0) ++ return 0; + +- if (!(ext = X509_get_ext(cert, l)) || !(ialt = X509V3_EXT_d2i(ext))) { +- pkiDebug("%s: found no subject alt name extensions\n", +- __FUNCTION__); ++ if (!(ext = X509_get_ext(cert, l)) || !(ialt = X509V3_EXT_d2i(ext))) { ++ pkiDebug("%s: found no subject alt name extensions\n", __FUNCTION__); ++ goto cleanup; ++ } ++ num_sans = sk_GENERAL_NAME_num(ialt); ++ ++ pkiDebug("%s: found %d subject alt name extension(s)\n", __FUNCTION__, ++ num_sans); ++ ++ /* OK, we're likely returning something. Allocate return values */ ++ if (princs_ret != NULL) { ++ princs = calloc(num_sans + 1, sizeof(krb5_principal)); ++ if (princs == NULL) { ++ retval = ENOMEM; + goto cleanup; + } +- num_sans = sk_GENERAL_NAME_num(ialt); +- +- pkiDebug("%s: found %d subject alt name extension(s)\n", +- __FUNCTION__, num_sans); +- +- /* OK, we're likely returning something. Allocate return values */ +- if (princs_ret != NULL) { +- princs = calloc(num_sans + 1, sizeof(krb5_principal)); +- if (princs == NULL) { +- retval = ENOMEM; +- goto cleanup; +- } +- } +- if (upn_ret != NULL) { +- upns = calloc(num_sans + 1, sizeof(krb5_principal)); +- if (upns == NULL) { +- retval = ENOMEM; +- goto cleanup; +- } +- } +- if (dns_ret != NULL) { +- dnss = calloc(num_sans + 1, sizeof(*dnss)); +- if (dnss == NULL) { +- retval = ENOMEM; +- goto cleanup; +- } +- } +- +- for (i = 0; i < num_sans; i++) { +- krb5_data name = { 0, 0, NULL }; +- +- gen = sk_GENERAL_NAME_value(ialt, i); +- switch (gen->type) { +- case GEN_OTHERNAME: +- name.length = gen->d.otherName->value->value.sequence->length; +- name.data = (char *)gen->d.otherName->value->value.sequence->data; +- if (princs != NULL +- && OBJ_cmp(plgctx->id_pkinit_san, +- gen->d.otherName->type_id) == 0) { +-#ifdef DEBUG_ASN1 +- print_buffer_bin((unsigned char *)name.data, name.length, +- "/tmp/pkinit_san"); +-#endif +- ret = k5int_decode_krb5_principal_name(&name, &princs[p]); +- if (ret) { +- pkiDebug("%s: failed decoding pkinit san value\n", +- __FUNCTION__); +- } else { +- p++; +- num_found++; +- } +- } else if (upns != NULL +- && OBJ_cmp(plgctx->id_ms_san_upn, +- gen->d.otherName->type_id) == 0) { +- /* Prevent abuse of embedded null characters. */ +- if (memchr(name.data, '\0', name.length)) +- break; +- ret = krb5_parse_name_flags(context, name.data, +- KRB5_PRINCIPAL_PARSE_ENTERPRISE, +- &upns[u]); +- if (ret) { +- pkiDebug("%s: failed parsing ms-upn san value\n", +- __FUNCTION__); +- } else { +- u++; +- num_found++; +- } +- } else { +- pkiDebug("%s: unrecognized othername oid in SAN\n", +- __FUNCTION__); +- continue; +- } +- +- break; +- case GEN_DNS: +- if (dnss != NULL) { +- /* Prevent abuse of embedded null characters. */ +- if (memchr(gen->d.dNSName->data, '\0', +- gen->d.dNSName->length)) +- break; +- pkiDebug("%s: found dns name = %s\n", +- __FUNCTION__, gen->d.dNSName->data); +- dnss[d] = (unsigned char *) +- strdup((char *)gen->d.dNSName->data); +- if (dnss[d] == NULL) { +- pkiDebug("%s: failed to duplicate dns name\n", +- __FUNCTION__); +- } else { +- d++; +- num_found++; +- } +- } +- break; +- default: +- pkiDebug("%s: SAN type = %d expecting %d\n", +- __FUNCTION__, gen->type, GEN_OTHERNAME); +- } +- } +- sk_GENERAL_NAME_pop_free(ialt, GENERAL_NAME_free); + } ++ if (upn_ret != NULL) { ++ upns = calloc(num_sans + 1, sizeof(krb5_principal)); ++ if (upns == NULL) { ++ retval = ENOMEM; ++ goto cleanup; ++ } ++ } ++ if (dns_ret != NULL) { ++ dnss = calloc(num_sans + 1, sizeof(*dnss)); ++ if (dnss == NULL) { ++ retval = ENOMEM; ++ goto cleanup; ++ } ++ } ++ ++ for (i = 0; i < num_sans; i++) { ++ krb5_data name = { 0, 0, NULL }; ++ ++ gen = sk_GENERAL_NAME_value(ialt, i); ++ switch (gen->type) { ++ case GEN_OTHERNAME: ++ name.length = gen->d.otherName->value->value.sequence->length; ++ name.data = (char *)gen->d.otherName->value->value.sequence->data; ++ if (princs != NULL && ++ OBJ_cmp(plgctx->id_pkinit_san, ++ gen->d.otherName->type_id) == 0) { ++#ifdef DEBUG_ASN1 ++ print_buffer_bin((unsigned char *)name.data, name.length, ++ "/tmp/pkinit_san"); ++#endif ++ ret = k5int_decode_krb5_principal_name(&name, &princs[p]); ++ if (ret) { ++ pkiDebug("%s: failed decoding pkinit san value\n", ++ __FUNCTION__); ++ } else { ++ p++; ++ num_found++; ++ } ++ } else if (upns != NULL && ++ OBJ_cmp(plgctx->id_ms_san_upn, ++ gen->d.otherName->type_id) == 0) { ++ /* Prevent abuse of embedded null characters. */ ++ if (memchr(name.data, '\0', name.length)) ++ break; ++ ret = krb5_parse_name_flags(context, name.data, ++ KRB5_PRINCIPAL_PARSE_ENTERPRISE, ++ &upns[u]); ++ if (ret) { ++ pkiDebug("%s: failed parsing ms-upn san value\n", ++ __FUNCTION__); ++ } else { ++ u++; ++ num_found++; ++ } ++ } else { ++ pkiDebug("%s: unrecognized othername oid in SAN\n", ++ __FUNCTION__); ++ continue; ++ } ++ ++ break; ++ case GEN_DNS: ++ if (dnss != NULL) { ++ /* Prevent abuse of embedded null characters. */ ++ if (memchr(gen->d.dNSName->data, '\0', gen->d.dNSName->length)) ++ break; ++ pkiDebug("%s: found dns name = %s\n", __FUNCTION__, ++ gen->d.dNSName->data); ++ dnss[d] = (unsigned char *) ++ strdup((char *)gen->d.dNSName->data); ++ if (dnss[d] == NULL) { ++ pkiDebug("%s: failed to duplicate dns name\n", ++ __FUNCTION__); ++ } else { ++ d++; ++ num_found++; ++ } ++ } ++ break; ++ default: ++ pkiDebug("%s: SAN type = %d expecting %d\n", __FUNCTION__, ++ gen->type, GEN_OTHERNAME); ++ } ++ } ++ sk_GENERAL_NAME_pop_free(ialt, GENERAL_NAME_free); + + retval = 0; + if (princs) diff --git a/SOURCES/Document-and-check-init_creds-context-requirement.patch b/SOURCES/Document-and-check-init_creds-context-requirement.patch new file mode 100644 index 0000000..53b2b9c --- /dev/null +++ b/SOURCES/Document-and-check-init_creds-context-requirement.patch @@ -0,0 +1,127 @@ +From 86fd6a4e1a768eff55aa3df6bc5794dfa63b801f Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Mon, 9 Jan 2017 11:44:29 -0500 +Subject: [PATCH] Document and check init_creds context requirement + +To ensure that the same clpreauth plugin modules and moddata pointers +are used for each step of an initial creds operation, the caller must +use the same library context for krb5_init_creds_init(), +krb5_init_creds_step(), and krb5_init_creds_free(). Document and +enforce this requirement. + +ticket: 7877 +(cherry picked from commit c4beb35c9ac0711ef650abc4f1e44a4c82d5f3d0) +--- + src/include/krb5/krb5.hin | 13 +++++++++++++ + src/lib/krb5/krb/get_in_tkt.c | 6 +++++- + src/lib/krb5/krb/int-proto.h | 3 +++ + src/lib/krb5/krb/preauth2.c | 13 +++++++++++++ + 4 files changed, 34 insertions(+), 1 deletion(-) + +diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin +index 53ad85384..28557659e 100644 +--- a/src/include/krb5/krb5.hin ++++ b/src/include/krb5/krb5.hin +@@ -7321,6 +7321,9 @@ typedef struct _krb5_init_creds_context *krb5_init_creds_context; + * + * @param [in] context Library context + * @param [in] ctx Initial credentials context ++ * ++ * @a context must be the same as the one passed to krb5_init_creds_init() for ++ * this initial credentials context. + */ + void KRB5_CALLCONV + krb5_init_creds_free(krb5_context context, krb5_init_creds_context ctx); +@@ -7335,6 +7338,9 @@ krb5_init_creds_free(krb5_context context, krb5_init_creds_context ctx); + * krb5_init_creds_init(). On successful return, the credentials can be + * retrieved with krb5_init_creds_get_creds(). + * ++ * @a context must be the same as the one passed to krb5_init_creds_init() for ++ * this initial credentials context. ++ * + * @retval 0 Success; otherwise - Kerberos error codes + */ + krb5_error_code KRB5_CALLCONV +@@ -7385,6 +7391,10 @@ krb5_init_creds_get_error(krb5_context context, krb5_init_creds_context ctx, + * This function creates a new context for acquiring initial credentials. Use + * krb5_init_creds_free() to free @a ctx when it is no longer needed. + * ++ * Any subsequent calls to krb5_init_creds_step(), krb5_init_creds_get(), or ++ * krb5_init_creds_free() for this initial credentials context must use the ++ * same @a context argument as the one passed to this function. ++ * + * @retval 0 Success; otherwise - Kerberos error codes + */ + krb5_error_code KRB5_CALLCONV +@@ -7434,6 +7444,9 @@ krb5_init_creds_set_keytab(krb5_context context, krb5_init_creds_context ctx, + * transmit the next request using TCP rather than UDP. If this function + * returns any other error, the initial credential exchange has failed. + * ++ * @a context must be the same as the one passed to krb5_init_creds_init() for ++ * this initial credentials context. ++ * + * @retval 0 Success; otherwise - Kerberos error codes + */ + krb5_error_code KRB5_CALLCONV +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index 80f5e1870..52e07bb67 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -1667,7 +1667,7 @@ krb5_init_creds_step(krb5_context context, + krb5_data *realm, + unsigned int *flags) + { +- krb5_error_code code = 0, code2; ++ krb5_error_code code, code2; + + *flags = 0; + +@@ -1680,6 +1680,10 @@ krb5_init_creds_step(krb5_context context, + if (ctx->complete) + return EINVAL; + ++ code = k5_preauth_check_context(context, ctx); ++ if (code) ++ return code; ++ + if (in->length != 0) { + code = init_creds_step_reply(context, ctx, in); + if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG) { +diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h +index f1667c238..628f0baa8 100644 +--- a/src/lib/krb5/krb/int-proto.h ++++ b/src/lib/krb5/krb/int-proto.h +@@ -208,6 +208,9 @@ void + k5_preauth_request_context_fini(krb5_context context, + krb5_init_creds_context ctx); + ++krb5_error_code ++k5_preauth_check_context(krb5_context context, krb5_init_creds_context ctx); ++ + krb5_error_code + k5_response_items_new(k5_response_items **ri_out); + +diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c +index 9a178f4e3..9c5d6eaa9 100644 +--- a/src/lib/krb5/krb/preauth2.c ++++ b/src/lib/krb5/krb/preauth2.c +@@ -296,6 +296,19 @@ k5_preauth_request_context_fini(krb5_context context, + ctx->preauth_reqctx = NULL; + } + ++krb5_error_code ++k5_preauth_check_context(krb5_context context, krb5_init_creds_context ctx) ++{ ++ krb5_preauth_req_context reqctx = ctx->preauth_reqctx; ++ ++ if (reqctx != NULL && reqctx->orig_context != context) { ++ k5_setmsg(context, EINVAL, ++ _("krb5_init_creds calls must use same library context")); ++ return EINVAL; ++ } ++ return 0; ++} ++ + /* Return 1 if pa_type is a real preauthentication mechanism according to the + * module h. Return 0 if it is not. */ + static int diff --git a/SOURCES/Don-t-include-all-MEMORY-ccaches-in-collection.patch b/SOURCES/Don-t-include-all-MEMORY-ccaches-in-collection.patch new file mode 100644 index 0000000..284c911 --- /dev/null +++ b/SOURCES/Don-t-include-all-MEMORY-ccaches-in-collection.patch @@ -0,0 +1,91 @@ +From 7c50ae9787c2fbfb479fbc513a2aeb2aff039d43 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Wed, 1 Aug 2018 15:53:12 -0400 +Subject: [PATCH] Don't include all MEMORY ccaches in collection + +In the MEMORY ccache implementation, only yield a cache in the +per-type cursor if it is the context default cache, matching the +behavior of FILE after commit 45360c9688ca963f75a2480f2cf818424fc3dc7b +(ticket 6955). + +ticket: 8720 (new) +(cherry picked from commit 49bb627fed70c5258c151c5135ac3d95ed1ee55d) +--- + src/lib/krb5/ccache/cc_memory.c | 25 ++++++++++--------------- + src/lib/krb5/ccache/t_cccol.py | 7 ++++--- + 2 files changed, 14 insertions(+), 18 deletions(-) + +diff --git a/src/lib/krb5/ccache/cc_memory.c b/src/lib/krb5/ccache/cc_memory.c +index 8cdaff7fb..cfd5c6389 100644 +--- a/src/lib/krb5/ccache/cc_memory.c ++++ b/src/lib/krb5/ccache/cc_memory.c +@@ -132,7 +132,7 @@ struct mcc_cursor { + + /* Iterator over memory caches. */ + struct krb5_mcc_ptcursor_data { +- struct krb5_mcc_list_node *cur; ++ krb5_boolean first; + }; + + k5_cc_mutex krb5int_mcc_mutex = K5_CC_MUTEX_PARTIAL_INITIALIZER; +@@ -693,9 +693,7 @@ krb5_mcc_ptcursor_new( + return ENOMEM; + } + n->data = cdata; +- k5_cc_mutex_lock(context, &krb5int_mcc_mutex); +- cdata->cur = mcc_head; +- k5_cc_mutex_unlock(context, &krb5int_mcc_mutex); ++ cdata->first = TRUE; + *cursor = n; + return 0; + } +@@ -707,22 +705,19 @@ krb5_mcc_ptcursor_next( + krb5_ccache *ccache) + { + struct krb5_mcc_ptcursor_data *cdata = NULL; ++ const char *defname; + + *ccache = NULL; + cdata = cursor->data; +- if (cdata->cur == NULL) ++ if (!cdata->first) ++ return 0; ++ cdata->first = FALSE; ++ ++ defname = krb5_cc_default_name(context); ++ if (defname == NULL || strncmp(defname, "MEMORY:", 7) != 0) + return 0; + +- *ccache = malloc(sizeof(**ccache)); +- if (*ccache == NULL) +- return ENOMEM; +- +- (*ccache)->ops = &krb5_mcc_ops; +- (*ccache)->data = cdata->cur->cache; +- k5_cc_mutex_lock(context, &krb5int_mcc_mutex); +- cdata->cur = cdata->cur->next; +- k5_cc_mutex_unlock(context, &krb5int_mcc_mutex); +- return 0; ++ return krb5_cc_resolve(context, defname, ccache); + } + + static krb5_error_code KRB5_CALLCONV +diff --git a/src/lib/krb5/ccache/t_cccol.py b/src/lib/krb5/ccache/t_cccol.py +index f7f178564..c6d5f514d 100755 +--- a/src/lib/krb5/ccache/t_cccol.py ++++ b/src/lib/krb5/ccache/t_cccol.py +@@ -97,10 +97,11 @@ if test_keyring: + + mfoo = 'MEMORY:foo' + mbar = 'MEMORY:bar' +-cursor_test('filemem', [fccname, mfoo, mbar], [fccname, mfoo, mbar]) +-cursor_test('dirmem', [dccname, mfoo], [duser, dalice, dbob, mfoo]) ++cursor_test('filemem', [fccname, mfoo], [fccname]) ++cursor_test('dirmem', [dccname, mfoo], [duser, dalice, dbob]) ++cursor_test('mem', [mfoo, mbar], [mfoo]) + if test_keyring: +- cursor_test('keyringmem', [krccname, mfoo], [kruser, kralice, krbob, mfoo]) ++ cursor_test('keyringmem', [krccname, mfoo], [kruser, kralice, krbob]) + + # Test krb5_cccol_have_content. + realm.run(['./t_cccursor', dccname, 'CONTENT']) diff --git a/SOURCES/Echo-KDC-cookies-in-preauth-tryagain.patch b/SOURCES/Echo-KDC-cookies-in-preauth-tryagain.patch new file mode 100644 index 0000000..19fa3e8 --- /dev/null +++ b/SOURCES/Echo-KDC-cookies-in-preauth-tryagain.patch @@ -0,0 +1,76 @@ +From 7439bb967c7c7d860bc69b6b4eaa290a7fe7f530 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Sat, 21 Jan 2017 13:20:38 -0500 +Subject: [PATCH] Echo KDC cookies in preauth tryagain + +When trying again after a mechanism-specific error, we should send the +KDC cookie for conformance with RFC 6113. + +ticket: 8539 +(cherry picked from commit 25f12e90d98b677d0a72893b3c6eb859377aee68) +[rharwood@redhat.com: backport around expected_trace] +--- + src/lib/krb5/krb/preauth2.c | 8 +++++++- + src/tests/t_pkinit.py | 19 +++++++++---------- + 2 files changed, 16 insertions(+), 11 deletions(-) + +diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c +index 9c5d6eaa9..cfe3dd5b0 100644 +--- a/src/lib/krb5/krb/preauth2.c ++++ b/src/lib/krb5/krb/preauth2.c +@@ -923,7 +923,7 @@ k5_preauth_tryagain(krb5_context context, krb5_init_creds_context ctx, + krb5_pa_data **mod_pa; + krb5_clpreauth_modreq modreq; + clpreauth_handle h; +- int i; ++ int i, count; + + *padata_out = NULL; + +@@ -942,6 +942,12 @@ k5_preauth_tryagain(krb5_context context, krb5_init_creds_context ctx, + ctx->err_reply, ctx->err_padata, + ctx->prompter, ctx->prompter_data, &mod_pa); + if (ret == 0 && mod_pa != NULL) { ++ for (count = 0; mod_pa[count] != NULL; count++); ++ ret = copy_cookie(context, ctx->err_padata, &mod_pa, &count); ++ if (ret) { ++ krb5_free_pa_data(context, mod_pa); ++ return ret; ++ } + TRACE_PREAUTH_TRYAGAIN_OUTPUT(context, mod_pa); + *padata_out = mod_pa; + return 0; +diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py +index 183977750..38424932b 100755 +--- a/src/tests/t_pkinit.py ++++ b/src/tests/t_pkinit.py +@@ -175,20 +175,19 @@ realm.kinit(realm.user_princ, + realm.klist(realm.user_princ) + + # Test a DH parameter renegotiation by temporarily setting a 4096-bit +-# minimum on the KDC. +-tracefile = os.path.join(realm.testdir, 'trace') ++# minimum on the KDC. (Preauth type 16 is PKINIT PA_PK_AS_REQ; ++# 133 is FAST PA-FX-COOKIE.) + minbits_kdc_conf = {'realms': {'$realm': {'pkinit_dh_min_bits': '4096'}}} + minbits_env = realm.special_env('restrict', True, kdc_conf=minbits_kdc_conf) + realm.stop_kdc() + realm.start_kdc(env=minbits_env) +-realm.run(['env', 'KRB5_TRACE=' + tracefile, kinit, '-X', +- 'X509_user_identity=' + file_identity, realm.user_princ]) +-with open(tracefile, 'r') as f: +- trace = f.read() +-if ('Key parameters not accepted' not in trace or +- 'Preauth tryagain input types' not in trace or +- 'trying again with KDC-provided parameters' not in trace): +- fail('DH renegotiation steps not found in kinit trace log') ++expected_trace = ('Key parameters not accepted', ++ 'Preauth tryagain input types', ++ 'trying again with KDC-provided parameters', ++ 'Followup preauth for next request: 16, 133') ++realm.kinit(realm.user_princ, ++ flags=['-X', 'X509_user_identity=%s' % file_identity], ++ expected_trace=expected_trace) + realm.stop_kdc() + realm.start_kdc() + diff --git a/SOURCES/Exit-with-status-0-from-kadmind.patch b/SOURCES/Exit-with-status-0-from-kadmind.patch new file mode 100644 index 0000000..b2a7317 --- /dev/null +++ b/SOURCES/Exit-with-status-0-from-kadmind.patch @@ -0,0 +1,32 @@ +From 987d80aba6a59dae5242cb544864e23785098106 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Wed, 14 Mar 2018 14:31:22 -0400 +Subject: [PATCH] Exit with status 0 from kadmind + +Typically, 0 denotes successful exit. In particular, init systems +will complain if another different value is returned. This presents a +problem for automated installation jobs which want to restart kadmind. + +`service kadmin stop` typically sends SIGTERM, which is caught by +verto and passed to our handler. Besides cleanup, we then call +verto_break(), which causes the verto_run() event loop to return. The +weird return code has been present since the addition of the kadmin +code, which used a similar event model for signals. + +(cherry picked from commit f970ad412aca36f8a7d3addb1cd4026ed22e5592) +(cherry picked from commit 3bfe632c7011c335362d78356232507d9ee26f73) +--- + src/kadmin/server/ovsec_kadmd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/kadmin/server/ovsec_kadmd.c b/src/kadmin/server/ovsec_kadmd.c +index a3edd3b00..9fc49f1e6 100644 +--- a/src/kadmin/server/ovsec_kadmd.c ++++ b/src/kadmin/server/ovsec_kadmd.c +@@ -558,5 +558,5 @@ main(int argc, char *argv[]) + + krb5_klog_close(context); + krb5_free_context(context); +- exit(2); ++ exit(0); + } diff --git a/SOURCES/Expose-context-errors-in-pkinit_server_plugin_init.patch b/SOURCES/Expose-context-errors-in-pkinit_server_plugin_init.patch new file mode 100644 index 0000000..05b880c --- /dev/null +++ b/SOURCES/Expose-context-errors-in-pkinit_server_plugin_init.patch @@ -0,0 +1,73 @@ +From 97a39c0048344c43af4006a4b9e7da609095510d Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Mon, 13 Nov 2017 13:32:37 -0500 +Subject: [PATCH] Expose context errors in pkinit_server_plugin_init + +Commit 3ff426b9048a8024e5c175256c63cd0ad0572320 attempted to display +an error when OCSP support was requested, but this error message was +suppressed in pkinit_server_plugin_init(). Add a trace log for each +realm initialization error, and pass through the realm initialization +error when the KDC serves only one realm. Other error messages from +pkinit_init_kdc_profile(), such as missing pkinit_identity or +pkinit_anchors, are also now exposted. + +[ghudson@mit.edu: clarified commit message] + +ticket: 8621 (new) +target_version: 1.16 +tags: pullup + +(cherry picked from commit 225aab3540c13c6289b22022d5e110f6fc26151d) +--- + src/plugins/preauth/pkinit/pkinit_srv.c | 19 +++++++++++++------ + src/plugins/preauth/pkinit/pkinit_trace.h | 3 +++ + 2 files changed, 16 insertions(+), 6 deletions(-) + +diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c +index 8e77606f8..143d331a2 100644 +--- a/src/plugins/preauth/pkinit/pkinit_srv.c ++++ b/src/plugins/preauth/pkinit/pkinit_srv.c +@@ -1622,16 +1622,23 @@ pkinit_server_plugin_init(krb5_context context, + + for (i = 0, j = 0; i < numrealms; i++) { + TRACE_PKINIT_SERVER_INIT_REALM(context, realmnames[i]); +- retval = pkinit_server_plugin_init_realm(context, realmnames[i], &plgctx); +- if (retval == 0 && plgctx != NULL) ++ krb5_clear_error_message(context); ++ retval = pkinit_server_plugin_init_realm(context, realmnames[i], ++ &plgctx); ++ if (retval) ++ TRACE_PKINIT_SERVER_INIT_FAIL(context, realmnames[i], retval); ++ else + realm_contexts[j++] = plgctx; + } + + if (j == 0) { +- retval = EINVAL; +- krb5_set_error_message(context, retval, +- _("No realms configured correctly for pkinit " +- "support")); ++ if (numrealms == 1) { ++ k5_prependmsg(context, retval, "PKINIT initialization failed"); ++ } else { ++ retval = EINVAL; ++ k5_setmsg(context, retval, ++ _("No realms configured correctly for pkinit support")); ++ } + goto errout; + } + +diff --git a/src/plugins/preauth/pkinit/pkinit_trace.h b/src/plugins/preauth/pkinit/pkinit_trace.h +index 6abe28c0c..8d489469f 100644 +--- a/src/plugins/preauth/pkinit/pkinit_trace.h ++++ b/src/plugins/preauth/pkinit/pkinit_trace.h +@@ -100,6 +100,9 @@ + TRACE(c, "PKINIT server skipping EKU check due to configuration") + #define TRACE_PKINIT_SERVER_INIT_REALM(c, realm) \ + TRACE(c, "PKINIT server initializing realm {str}", realm) ++#define TRACE_PKINIT_SERVER_INIT_FAIL(c, realm, retval) \ ++ TRACE(c, "PKINIT server initialization failed for realm {str}: {kerr}", \ ++ realm, retval) + #define TRACE_PKINIT_SERVER_MATCHING_UPN_FOUND(c) \ + TRACE(c, "PKINIT server found a matching UPN SAN in client cert") + #define TRACE_PKINIT_SERVER_MATCHING_SAN_FOUND(c) \ diff --git a/SOURCES/Fix-PKINIT-cert-matching-data-construction.patch b/SOURCES/Fix-PKINIT-cert-matching-data-construction.patch new file mode 100644 index 0000000..da24ba8 --- /dev/null +++ b/SOURCES/Fix-PKINIT-cert-matching-data-construction.patch @@ -0,0 +1,115 @@ +From 62eb62a3db7d40a44f26c3e563cfa22b1f05d93d Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Tue, 17 Oct 2017 18:50:15 -0400 +Subject: [PATCH] Fix PKINIT cert matching data construction + +Rewrite X509_NAME_oneline_ex() and its call sites to use dynamic +allocation and to perform proper error checking. + +ticket: 8617 +target_version: 1.16 +target_version: 1.15-next +target_version: 1.14-next +tags: pullup + +(cherry picked from commit fbb687db1088ddd894d975996e5f6a4252b9a2b4) +--- + .../preauth/pkinit/pkinit_crypto_openssl.c | 67 +++++++------------ + 1 file changed, 25 insertions(+), 42 deletions(-) + +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index f70aab5b3..34ed7afaf 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -5052,33 +5052,29 @@ out: + return retval; + } + +-/* +- * Return a string format of an X509_NAME in buf where +- * size is an in/out parameter. On input it is the size +- * of the buffer, and on output it is the actual length +- * of the name. +- * If buf is NULL, returns the length req'd to hold name +- */ +-static char * +-X509_NAME_oneline_ex(X509_NAME * a, +- char *buf, +- unsigned int *size, +- unsigned long flag) ++static krb5_error_code ++rfc2253_name(X509_NAME *name, char **str_out) + { +- BIO *out = NULL; ++ BIO *b = NULL; ++ char *str; + +- out = BIO_new(BIO_s_mem ()); +- if (X509_NAME_print_ex(out, a, 0, flag) > 0) { +- if (buf != NULL && (*size) > (unsigned int) BIO_number_written(out)) { +- memset(buf, 0, *size); +- BIO_read(out, buf, (int) BIO_number_written(out)); +- } +- else { +- *size = BIO_number_written(out); +- } +- } +- BIO_free(out); +- return (buf); ++ *str_out = NULL; ++ b = BIO_new(BIO_s_mem()); ++ if (b == NULL) ++ return ENOMEM; ++ if (X509_NAME_print_ex(b, name, 0, XN_FLAG_SEP_COMMA_PLUS) < 0) ++ goto error; ++ str = calloc(BIO_number_written(b) + 1, 1); ++ if (str == NULL) ++ goto error; ++ BIO_read(b, str, BIO_number_written(b)); ++ BIO_free(b); ++ *str_out = str; ++ return 0; ++ ++error: ++ BIO_free(b); ++ return ENOMEM; + } + + /* +@@ -5144,8 +5140,6 @@ get_matching_data(krb5_context context, + pkinit_cert_matching_data *md = NULL; + krb5_principal *pkinit_sans = NULL, *upn_sans = NULL; + size_t i, j; +- char buf[DN_BUF_LEN]; +- unsigned int bufsize = sizeof(buf); + + *md_out = NULL; + +@@ -5153,23 +5147,12 @@ get_matching_data(krb5_context context, + if (md == NULL) + goto cleanup; + +- /* Get the subject name (in rfc2253 format). */ +- X509_NAME_oneline_ex(X509_get_subject_name(cert), buf, &bufsize, +- XN_FLAG_SEP_COMMA_PLUS); +- md->subject_dn = strdup(buf); +- if (md->subject_dn == NULL) { +- ret = ENOMEM; ++ ret = rfc2253_name(X509_get_subject_name(cert), &md->subject_dn); ++ if (ret) + goto cleanup; +- } +- +- /* Get the issuer name (in rfc2253 format). */ +- X509_NAME_oneline_ex(X509_get_issuer_name(cert), buf, &bufsize, +- XN_FLAG_SEP_COMMA_PLUS); +- md->issuer_dn = strdup(buf); +- if (md->issuer_dn == NULL) { +- ret = ENOMEM; ++ ret = rfc2253_name(X509_get_issuer_name(cert), &md->issuer_dn); ++ if (ret) + goto cleanup; +- } + + /* Get the SAN data. */ + ret = crypto_retrieve_X509_sans(context, plg_cryptoctx, req_cryptoctx, diff --git a/SOURCES/Fix-bugs-in-kdcpolicy-commit.patch b/SOURCES/Fix-bugs-in-kdcpolicy-commit.patch new file mode 100644 index 0000000..1d87c25 --- /dev/null +++ b/SOURCES/Fix-bugs-in-kdcpolicy-commit.patch @@ -0,0 +1,130 @@ +From ffd715b98da026a6a9b3aac48de42e4f19860ce4 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Sat, 19 Aug 2017 19:09:24 -0400 +Subject: [PATCH] Fix bugs in kdcpolicy commit + +Commit d0969f6a8170344031ef58fd2a161190f1edfb96 added tests using +"klist ccachname -e", which does not work with a POSIX-conformant +getopt() implementation such as the one in Solaris. Fix +t_kdcpolicy.py to use "klist -e ccachename" instead. + +The tests could fail if the clock second rolled over between kinit and +kvno. Divide service ticket maximum lifetimes by 2 in the test module +to correctly exercise TGS policy restrictions and ensure that service +tickets are not constrained by the TGT end time. + +Also use the correct trace macro when a kdcpolicy module declines to +initialize (my mistake when revising the commit, noted by rharwood). + +ticket: 8606 +(cherry picked from commit 09acbd91efc6df54e1572285ffc94c6acb3a9113) +--- + src/kdc/policy.c | 2 +- + src/plugins/kdcpolicy/test/main.c | 10 +++++----- + src/tests/t_kdcpolicy.py | 13 +++++++++---- + 3 files changed, 15 insertions(+), 10 deletions(-) + +diff --git a/src/kdc/policy.c b/src/kdc/policy.c +index e49644e06..26c16f97c 100644 +--- a/src/kdc/policy.c ++++ b/src/kdc/policy.c +@@ -222,7 +222,7 @@ load_kdcpolicy_plugins(krb5_context context) + if (h->vt.init != NULL) { + ret = h->vt.init(context, &h->moddata); + if (ret == KRB5_PLUGIN_NO_HANDLE) { +- TRACE_KADM5_AUTH_INIT_SKIP(context, h->vt.name); ++ TRACE_KDCPOLICY_INIT_SKIP(context, h->vt.name); + free(h); + continue; + } +diff --git a/src/plugins/kdcpolicy/test/main.c b/src/plugins/kdcpolicy/test/main.c +index eb8fde053..86c808958 100644 +--- a/src/plugins/kdcpolicy/test/main.c ++++ b/src/plugins/kdcpolicy/test/main.c +@@ -35,7 +35,7 @@ + #include + + static krb5_error_code +-output_from_indicator(const char *const *auth_indicators, ++output_from_indicator(const char *const *auth_indicators, int divisor, + krb5_deltat *lifetime_out, + krb5_deltat *renew_lifetime_out, + const char **status) +@@ -46,11 +46,11 @@ output_from_indicator(const char *const *auth_indicators, + } + + if (strcmp(auth_indicators[0], "ONE_HOUR") == 0) { +- *lifetime_out = 3600; ++ *lifetime_out = 3600 / divisor; + *renew_lifetime_out = *lifetime_out * 2; + return 0; + } else if (strcmp(auth_indicators[0], "SEVEN_HOURS") == 0) { +- *lifetime_out = 7 * 3600; ++ *lifetime_out = 7 * 3600 / divisor; + *renew_lifetime_out = *lifetime_out * 2; + return 0; + } +@@ -71,7 +71,7 @@ test_check_as(krb5_context context, krb5_kdcpolicy_moddata moddata, + *status = "LOCAL_POLICY"; + return KRB5KDC_ERR_POLICY; + } +- return output_from_indicator(auth_indicators, lifetime_out, ++ return output_from_indicator(auth_indicators, 1, lifetime_out, + renew_lifetime_out, status); + } + +@@ -87,7 +87,7 @@ test_check_tgs(krb5_context context, krb5_kdcpolicy_moddata moddata, + *status = "LOCAL_POLICY"; + return KRB5KDC_ERR_POLICY; + } +- return output_from_indicator(auth_indicators, lifetime_out, ++ return output_from_indicator(auth_indicators, 2, lifetime_out, + renew_lifetime_out, status); + } + +diff --git a/src/tests/t_kdcpolicy.py b/src/tests/t_kdcpolicy.py +index 6a745b959..b5d308461 100644 +--- a/src/tests/t_kdcpolicy.py ++++ b/src/tests/t_kdcpolicy.py +@@ -18,16 +18,21 @@ realm.run([kadminl, 'addprinc', '-pw', password('fail'), 'fail']) + def verify_time(out, target_time): + times = re.findall(r'\d\d/\d\d/\d\d \d\d:\d\d:\d\d', out) + times = [datetime.strptime(t, '%m/%d/%y %H:%M:%S') for t in times] ++ divisor = 1 + while len(times) > 0: + starttime = times.pop(0) + endtime = times.pop(0) + renewtime = times.pop(0) + +- if str(endtime - starttime) != target_time: ++ if str((endtime - starttime) * divisor) != target_time: + fail('unexpected lifetime value') +- if str(renewtime - endtime) != target_time: ++ if str((renewtime - endtime) * divisor) != target_time: + fail('unexpected renewable value') + ++ # Service tickets should have half the lifetime of initial ++ # tickets. ++ divisor = 2 ++ + rflags = ['-r', '1d', '-l', '12h'] + + # Test AS+TGS success path. +@@ -35,7 +40,7 @@ realm.kinit(realm.user_princ, password('user'), + rflags + ['-X', 'indicators=SEVEN_HOURS']) + realm.run([kvno, realm.host_princ]) + realm.run(['./adata', realm.host_princ], expected_msg='+97: [SEVEN_HOURS]') +-out = realm.run([klist, realm.ccache, '-e']) ++out = realm.run([klist, '-e', realm.ccache]) + verify_time(out, '7:00:00') + + # Test AS+TGS success path with different values. +@@ -43,7 +48,7 @@ realm.kinit(realm.user_princ, password('user'), + rflags + ['-X', 'indicators=ONE_HOUR']) + realm.run([kvno, realm.host_princ]) + realm.run(['./adata', realm.host_princ], expected_msg='+97: [ONE_HOUR]') +-out = realm.run([klist, realm.ccache, '-e']) ++out = realm.run([klist, '-e', realm.ccache]) + verify_time(out, '1:00:00') + + # Test TGS failure path (using previous creds). diff --git a/SOURCES/Fix-bugs-with-concurrent-use-of-MEMORY-ccaches.patch b/SOURCES/Fix-bugs-with-concurrent-use-of-MEMORY-ccaches.patch new file mode 100644 index 0000000..99e0f7b --- /dev/null +++ b/SOURCES/Fix-bugs-with-concurrent-use-of-MEMORY-ccaches.patch @@ -0,0 +1,396 @@ +From 8cb69a3657064ff6bb90a208cfad5fb91e30c307 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Sun, 1 Jul 2018 00:12:25 -0400 +Subject: [PATCH] Fix bugs with concurrent use of MEMORY ccaches + +A memory ccache iterator stores an alias into the cache object's +linked list of credentials. If the cache is reinitialized while the +iterator is active, the alias becomes invalid. Also, multiple handles +referencing the same memory ccache all use aliases to the same data +object; if one of the handles is destroyed, the other contains a +dangling pointer. + +Fix the first issue by adding a generation counter to the cache and to +cursors, incremented each time the cache is initialized or destroyed. +Check the generation on each cursor step and end the iteration if the +list was invalidated. Fix the second issue by adding a reference +count to the cache object, counting one reference for the table slot +and one for each open handle. Empty the cache object on each destroy +operation, but only release the object when the last handle to it is +destroyed or closed. + +Add regression tests for the two issues to t_cc.c. + +The first issue was reported by Sorin Manolache. + +ticket: 8202 +tags: pullup +target_version: 1.16-next +target_version: 1.15-next + +(cherry picked from commit 146dadec8fe7ccc4149eb2e3f577cc320aee6efb) +--- + src/lib/krb5/ccache/cc_memory.c | 164 ++++++++++++++++++++------------ + src/lib/krb5/ccache/t_cc.c | 51 ++++++++++ + 2 files changed, 154 insertions(+), 61 deletions(-) + +diff --git a/src/lib/krb5/ccache/cc_memory.c b/src/lib/krb5/ccache/cc_memory.c +index c5425eb3a..8cdaff7fb 100644 +--- a/src/lib/krb5/ccache/cc_memory.c ++++ b/src/lib/krb5/ccache/cc_memory.c +@@ -102,18 +102,20 @@ extern krb5_error_code krb5_change_cache (void); + typedef struct _krb5_mcc_link { + struct _krb5_mcc_link *next; + krb5_creds *creds; +-} krb5_mcc_link, *krb5_mcc_cursor; ++} krb5_mcc_link; + + /* Per-cache data header. */ + typedef struct _krb5_mcc_data { + char *name; + k5_cc_mutex lock; + krb5_principal prin; +- krb5_mcc_cursor link; ++ krb5_mcc_link *link; + krb5_timestamp changetime; + /* Time offsets for clock-skewed clients. */ + krb5_int32 time_offset; + krb5_int32 usec_offset; ++ int refcount; /* One for the table slot, one per handle */ ++ int generation; /* Incremented at each initialize */ + } krb5_mcc_data; + + /* List of memory caches. */ +@@ -122,6 +124,12 @@ typedef struct krb5_mcc_list_node { + krb5_mcc_data *cache; + } krb5_mcc_list_node; + ++/* Iterator over credentials in a memory cache. */ ++struct mcc_cursor { ++ int generation; ++ krb5_mcc_link *next_link; ++}; ++ + /* Iterator over memory caches. */ + struct krb5_mcc_ptcursor_data { + struct krb5_mcc_list_node *cur; +@@ -132,7 +140,23 @@ static krb5_mcc_list_node *mcc_head = 0; + + static void update_mcc_change_time(krb5_mcc_data *); + +-static void krb5_mcc_free (krb5_context context, krb5_ccache id); ++/* Remove creds from d, invalidate any existing cursors, and unset the client ++ * principal. The caller is responsible for locking. */ ++static void ++empty_mcc_cache(krb5_context context, krb5_mcc_data *d) ++{ ++ krb5_mcc_link *curr, *next; ++ ++ for (curr = d->link; curr != NULL; curr = next) { ++ next = curr->next; ++ krb5_free_creds(context, curr->creds); ++ free(curr); ++ } ++ d->link = NULL; ++ d->generation++; ++ krb5_free_principal(context, d->prin); ++ d->prin = NULL; ++} + + /* + * Modifies: +@@ -150,16 +174,12 @@ krb5_mcc_initialize(krb5_context context, krb5_ccache id, krb5_principal princ) + { + krb5_os_context os_ctx = &context->os_context; + krb5_error_code ret; +- krb5_mcc_data *d; ++ krb5_mcc_data *d = id->data; + +- d = (krb5_mcc_data *)id->data; + k5_cc_mutex_lock(context, &d->lock); ++ empty_mcc_cache(context, d); + +- krb5_mcc_free(context, id); +- +- d = (krb5_mcc_data *)id->data; +- ret = krb5_copy_principal(context, princ, +- &d->prin); ++ ret = krb5_copy_principal(context, princ, &d->prin); + update_mcc_change_time(d); + + if (os_ctx->os_flags & KRB5_OS_TOFFSET_VALID) { +@@ -185,61 +205,59 @@ krb5_mcc_initialize(krb5_context context, krb5_ccache id, krb5_principal princ) + krb5_error_code KRB5_CALLCONV + krb5_mcc_close(krb5_context context, krb5_ccache id) + { ++ krb5_mcc_data *d = id->data; ++ int count; ++ + free(id); +- return KRB5_OK; +-} +- +-static void +-krb5_mcc_free(krb5_context context, krb5_ccache id) +-{ +- krb5_mcc_cursor curr,next; +- krb5_mcc_data *d; +- +- d = (krb5_mcc_data *) id->data; +- for (curr = d->link; curr;) { +- krb5_free_creds(context, curr->creds); +- next = curr->next; +- free(curr); +- curr = next; ++ k5_cc_mutex_lock(context, &d->lock); ++ count = --d->refcount; ++ k5_cc_mutex_unlock(context, &d->lock); ++ if (count == 0) { ++ /* This is the last active handle referencing d and d has been removed ++ * from the table, so we can release it. */ ++ empty_mcc_cache(context, d); ++ free(d->name); ++ k5_cc_mutex_destroy(&d->lock); ++ free(d); + } +- d->link = NULL; +- krb5_free_principal(context, d->prin); ++ return KRB5_OK; + } + + /* + * Effects: + * Destroys the contents of id. id is invalid after call. +- * +- * Errors: +- * system errors (locks related) + */ + krb5_error_code KRB5_CALLCONV + krb5_mcc_destroy(krb5_context context, krb5_ccache id) + { + krb5_mcc_list_node **curr, *node; +- krb5_mcc_data *d; ++ krb5_mcc_data *d = id->data; ++ krb5_boolean removed_from_table = FALSE; + + k5_cc_mutex_lock(context, &krb5int_mcc_mutex); + +- d = (krb5_mcc_data *)id->data; + for (curr = &mcc_head; *curr; curr = &(*curr)->next) { + if ((*curr)->cache == d) { + node = *curr; + *curr = node->next; + free(node); ++ removed_from_table = TRUE; + break; + } + } + k5_cc_mutex_unlock(context, &krb5int_mcc_mutex); + ++ /* Empty the cache and remove the reference for the table slot. There will ++ * always be at least one reference left for the handle being destroyed. */ + k5_cc_mutex_lock(context, &d->lock); +- +- krb5_mcc_free(context, id); +- free(d->name); ++ empty_mcc_cache(context, d); ++ if (removed_from_table) ++ d->refcount--; + k5_cc_mutex_unlock(context, &d->lock); +- k5_cc_mutex_destroy(&d->lock); +- free(d); +- free(id); ++ ++ /* Invalidate the handle, possibly removing the last reference to d and ++ * freeing it. */ ++ krb5_mcc_close(context, id); + + krb5_change_cache (); + return KRB5_OK; +@@ -279,9 +297,12 @@ krb5_mcc_resolve (krb5_context context, krb5_ccache *id, const char *residual) + for (ptr = mcc_head; ptr; ptr=ptr->next) + if (!strcmp(ptr->cache->name, residual)) + break; +- if (ptr) ++ if (ptr != NULL) { + d = ptr->cache; +- else { ++ k5_cc_mutex_lock(context, &d->lock); ++ d->refcount++; ++ k5_cc_mutex_unlock(context, &d->lock); ++ } else { + err = new_mcc_data(residual, &d); + if (err) { + k5_cc_mutex_unlock(context, &krb5int_mcc_mutex); +@@ -326,14 +347,18 @@ krb5_error_code KRB5_CALLCONV + krb5_mcc_start_seq_get(krb5_context context, krb5_ccache id, + krb5_cc_cursor *cursor) + { +- krb5_mcc_cursor mcursor; ++ struct mcc_cursor *mcursor; + krb5_mcc_data *d; + ++ mcursor = malloc(sizeof(*mcursor)); ++ if (mcursor == NULL) ++ return KRB5_CC_NOMEM; + d = id->data; + k5_cc_mutex_lock(context, &d->lock); +- mcursor = d->link; ++ mcursor->generation = d->generation; ++ mcursor->next_link = d->link; + k5_cc_mutex_unlock(context, &d->lock); +- *cursor = (krb5_cc_cursor) mcursor; ++ *cursor = mcursor; + return KRB5_OK; + } + +@@ -361,23 +386,34 @@ krb5_error_code KRB5_CALLCONV + krb5_mcc_next_cred(krb5_context context, krb5_ccache id, + krb5_cc_cursor *cursor, krb5_creds *creds) + { +- krb5_mcc_cursor mcursor; ++ struct mcc_cursor *mcursor; + krb5_error_code retval; ++ krb5_mcc_data *d = id->data; + +- /* Once the node in the linked list is created, it's never +- modified, so we don't need to worry about locking here. (Note +- that we don't support _remove_cred.) */ +- mcursor = (krb5_mcc_cursor) *cursor; +- if (mcursor == NULL) +- return KRB5_CC_END; + memset(creds, 0, sizeof(krb5_creds)); +- if (mcursor->creds) { +- retval = k5_copy_creds_contents(context, mcursor->creds, creds); +- if (retval) +- return retval; ++ mcursor = *cursor; ++ if (mcursor->next_link == NULL) ++ return KRB5_CC_END; ++ ++ /* ++ * Check the cursor generation against the cache generation in case the ++ * cache has been reinitialized or destroyed, freeing the pointer in the ++ * cursor. Keep the cache locked while we copy the creds and advance the ++ * pointer, in case another thread reinitializes the cache after we check ++ * the generation. ++ */ ++ k5_cc_mutex_lock(context, &d->lock); ++ if (mcursor->generation != d->generation) { ++ k5_cc_mutex_unlock(context, &d->lock); ++ return KRB5_CC_END; + } +- *cursor = (krb5_cc_cursor)mcursor->next; +- return KRB5_OK; ++ ++ retval = k5_copy_creds_contents(context, mcursor->next_link->creds, creds); ++ if (retval == 0) ++ mcursor->next_link = mcursor->next_link->next; ++ ++ k5_cc_mutex_unlock(context, &d->lock); ++ return retval; + } + + /* +@@ -396,14 +432,18 @@ krb5_mcc_next_cred(krb5_context context, krb5_ccache id, + krb5_error_code KRB5_CALLCONV + krb5_mcc_end_seq_get(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) + { +- *cursor = 0L; ++ free(*cursor); ++ *cursor = NULL; + return KRB5_OK; + } + +-/* Utility routine: Creates the back-end data for a memory cache, and +- threads it into the global linked list. +- +- Call with the global list lock held. */ ++/* ++ * Utility routine: Creates the back-end data for a memory cache, and threads ++ * it into the global linked list. Give the new object two references, one for ++ * the table slot and one for the caller's handle. ++ * ++ * Call with the global list lock held. ++ */ + static krb5_error_code + new_mcc_data (const char *name, krb5_mcc_data **dataptr) + { +@@ -432,6 +472,8 @@ new_mcc_data (const char *name, krb5_mcc_data **dataptr) + d->changetime = 0; + d->time_offset = 0; + d->usec_offset = 0; ++ d->refcount = 2; ++ d->generation = 0; + update_mcc_change_time(d); + + n = malloc(sizeof(krb5_mcc_list_node)); +diff --git a/src/lib/krb5/ccache/t_cc.c b/src/lib/krb5/ccache/t_cc.c +index 6069cabd3..cd4569c4c 100644 +--- a/src/lib/krb5/ccache/t_cc.c ++++ b/src/lib/krb5/ccache/t_cc.c +@@ -386,6 +386,55 @@ test_misc(krb5_context context) + krb5_cc_dfl_ops = ops_save; + + } ++ ++/* ++ * Regression tests for #8202. Because memory ccaches share objects between ++ * different handles to the same cache and between iterators and caches, ++ * historically there have been some bugs when those objects are released. ++ */ ++static void ++test_memory_concurrent(krb5_context context) ++{ ++ krb5_error_code kret; ++ krb5_ccache id1, id2; ++ krb5_cc_cursor cursor; ++ krb5_creds creds; ++ ++ /* Create two handles to the same memory ccache and destroy them. */ ++ kret = krb5_cc_resolve(context, "MEMORY:x", &id1); ++ CHECK(kret, "resolve 1"); ++ kret = krb5_cc_resolve(context, "MEMORY:x", &id2); ++ CHECK(kret, "resolve 2"); ++ kret = krb5_cc_destroy(context, id1); ++ CHECK(kret, "destroy 1"); ++ kret = krb5_cc_destroy(context, id2); ++ CHECK(kret, "destroy 2"); ++ ++ kret = init_test_cred(context); ++ CHECK(kret, "init_creds"); ++ ++ /* Reinitialize the cache after creating an iterator for it, and verify ++ * that the iterator ends gracefully. */ ++ kret = krb5_cc_resolve(context, "MEMORY:x", &id1); ++ CHECK(kret, "resolve"); ++ kret = krb5_cc_initialize(context, id1, test_creds.client); ++ CHECK(kret, "initialize"); ++ kret = krb5_cc_store_cred(context, id1, &test_creds); ++ CHECK(kret, "store"); ++ kret = krb5_cc_start_seq_get(context, id1, &cursor); ++ CHECK(kret, "start_seq_get"); ++ kret = krb5_cc_initialize(context, id1, test_creds.client); ++ CHECK(kret, "initialize again"); ++ kret = krb5_cc_next_cred(context, id1, &cursor, &creds); ++ CHECK_BOOL(kret != KRB5_CC_END, "iterator should end", "next_cred"); ++ kret = krb5_cc_end_seq_get(context, id1, &cursor); ++ CHECK(kret, "end_seq_get"); ++ kret = krb5_cc_destroy(context, id1); ++ CHECK(kret, "destroy"); ++ ++ free_test_cred(context); ++} ++ + extern const krb5_cc_ops krb5_mcc_ops; + extern const krb5_cc_ops krb5_fcc_ops; + +@@ -434,6 +483,8 @@ main(void) + do_test(context, "MEMORY:"); + do_test(context, "FILE:"); + ++ test_memory_concurrent(context); ++ + krb5_free_context(context); + return 0; + } diff --git a/SOURCES/Fix-certauth-built-in-module-returns.patch b/SOURCES/Fix-certauth-built-in-module-returns.patch new file mode 100644 index 0000000..6b3adbb --- /dev/null +++ b/SOURCES/Fix-certauth-built-in-module-returns.patch @@ -0,0 +1,124 @@ +From 5fbdf62de3883be137ed9a1a2eff3985e4ca05ae Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Thu, 24 Aug 2017 11:11:46 -0400 +Subject: [PATCH] Fix certauth built-in module returns + +The PKINIT certauth eku module should never authoritatively authorize +a certificate, because an extended key usage does not establish a +relationship between the certificate and any specific user; it only +establishes that the certificate was created for PKINIT client +authentication. Therefore, pkinit_eku_authorize() should return +KRB5_PLUGIN_NO_HANDLE on success, not 0. + +The certauth san module should pass if it does not find any SANs of +the types it can match against; the presence of other types of SANs +should not cause it to explicitly deny a certificate. Check for an +empty result from crypto_retrieve_cert_sans() in verify_client_san(), +instead of returning ENOENT from crypto_retrieve_cert_sans() when +there are no SANs at all. + +ticket: 8561 +(cherry picked from commit 07243f85a760fb37f0622d7ff0177db3f19ab025) +--- + .../preauth/pkinit/pkinit_crypto_openssl.c | 39 +++++++++---------- + src/plugins/preauth/pkinit/pkinit_srv.c | 14 ++++--- + 2 files changed, 27 insertions(+), 26 deletions(-) + +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index 792a2f771..85ca8885d 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -2137,7 +2137,6 @@ crypto_retrieve_X509_sans(krb5_context context, + + if (!(ext = X509_get_ext(cert, l)) || !(ialt = X509V3_EXT_d2i(ext))) { + pkiDebug("%s: found no subject alt name extensions\n", __FUNCTION__); +- retval = ENOENT; + goto cleanup; + } + num_sans = sk_GENERAL_NAME_num(ialt); +@@ -2240,31 +2239,29 @@ crypto_retrieve_X509_sans(krb5_context context, + sk_GENERAL_NAME_pop_free(ialt, GENERAL_NAME_free); + + retval = 0; +- if (princs) ++ if (princs != NULL && *princs != NULL) { + *princs_ret = princs; +- if (upns) ++ princs = NULL; ++ } ++ if (upns != NULL && *upns != NULL) { + *upn_ret = upns; +- if (dnss) ++ upns = NULL; ++ } ++ if (dnss != NULL && *dnss != NULL) { + *dns_ret = dnss; ++ dnss = NULL; ++ } + + cleanup: +- if (retval) { +- if (princs != NULL) { +- for (i = 0; princs[i] != NULL; i++) +- krb5_free_principal(context, princs[i]); +- free(princs); +- } +- if (upns != NULL) { +- for (i = 0; upns[i] != NULL; i++) +- krb5_free_principal(context, upns[i]); +- free(upns); +- } +- if (dnss != NULL) { +- for (i = 0; dnss[i] != NULL; i++) +- free(dnss[i]); +- free(dnss); +- } +- } ++ for (i = 0; princs != NULL && princs[i] != NULL; i++) ++ krb5_free_principal(context, princs[i]); ++ free(princs); ++ for (i = 0; upns != NULL && upns[i] != NULL; i++) ++ krb5_free_principal(context, upns[i]); ++ free(upns); ++ for (i = 0; dnss != NULL && dnss[i] != NULL; i++) ++ free(dnss[i]); ++ free(dnss); + return retval; + } + +diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c +index 9c6e96c9e..8e77606f8 100644 +--- a/src/plugins/preauth/pkinit/pkinit_srv.c ++++ b/src/plugins/preauth/pkinit/pkinit_srv.c +@@ -187,14 +187,18 @@ verify_client_san(krb5_context context, + &princs, + plgctx->opts->allow_upn ? &upns : NULL, + NULL); +- if (retval == ENOENT) { +- TRACE_PKINIT_SERVER_NO_SAN(context); +- goto out; +- } else if (retval) { ++ if (retval) { + pkiDebug("%s: error from retrieve_certificate_sans()\n", __FUNCTION__); + retval = KRB5KDC_ERR_CLIENT_NAME_MISMATCH; + goto out; + } ++ ++ if (princs == NULL && upns == NULL) { ++ TRACE_PKINIT_SERVER_NO_SAN(context); ++ retval = ENOENT; ++ goto out; ++ } ++ + /* XXX Verify this is consistent with client side XXX */ + #if 0 + retval = call_san_checking_plugins(context, plgctx, reqctx, princs, +@@ -1495,7 +1499,7 @@ pkinit_eku_authorize(krb5_context context, krb5_certauth_moddata moddata, + return KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE; + } + +- return 0; ++ return KRB5_PLUGIN_NO_HANDLE; + } + + static krb5_error_code diff --git a/SOURCES/Fix-flaws-in-LDAP-DN-checking.patch b/SOURCES/Fix-flaws-in-LDAP-DN-checking.patch new file mode 100644 index 0000000..d823a0b --- /dev/null +++ b/SOURCES/Fix-flaws-in-LDAP-DN-checking.patch @@ -0,0 +1,350 @@ +From bc1ff677dcb45c59107c39465b032f555e3d99f6 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Fri, 12 Jan 2018 11:43:01 -0500 +Subject: [PATCH] Fix flaws in LDAP DN checking + +KDB_TL_USER_INFO tl-data is intended to be internal to the LDAP KDB +module, and not used in disk or wire principal entries. Prevent +kadmin clients from sending KDB_TL_USER_INFO tl-data by giving it a +type number less than 256 and filtering out type numbers less than 256 +in kadm5_create_principal_3(). (We already filter out low type +numbers in kadm5_modify_principal()). + +In the LDAP KDB module, if containerdn and linkdn are both specified +in a put_principal operation, check both linkdn and the computed +standalone_principal_dn for container membership. To that end, factor +out the checks into helper functions and call them on all applicable +client-influenced DNs. + +CVE-2018-5729: + +In MIT krb5 1.6 or later, an authenticated kadmin user with permission +to add principals to an LDAP Kerberos database can cause a null +dereference in kadmind, or circumvent a DN container check, by +supplying tagged data intended to be internal to the database module. +Thanks to Sharwan Ram and Pooja Anil for discovering the potential +null dereference. + +CVE-2018-5730: + +In MIT krb5 1.6 or later, an authenticated kadmin user with permission +to add principals to an LDAP Kerberos database can circumvent a DN +containership check by supplying both a "linkdn" and "containerdn" +database argument, or by supplying a DN string which is a left +extension of a container DN string but is not hierarchically within +the container DN. + +ticket: 8643 (new) +tags: pullup +target_version: 1.16-next +target_version: 1.15-next + +(cherry picked from commit e1caf6fb74981da62039846931ebdffed71309d1) +[rharwood@redhat.com fuzz - didn't port tests to expected_msg] +--- + src/lib/kadm5/srv/svr_principal.c | 7 + + src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h | 2 +- + .../kdb/ldap/libkdb_ldap/ldap_principal2.c | 200 ++++++++++-------- + src/tests/t_kdb.py | 14 ++ + 4 files changed, 128 insertions(+), 95 deletions(-) + +diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c +index 0d4f0a632..64a4a2e97 100644 +--- a/src/lib/kadm5/srv/svr_principal.c ++++ b/src/lib/kadm5/srv/svr_principal.c +@@ -330,6 +330,13 @@ kadm5_create_principal_3(void *server_handle, + return KADM5_BAD_MASK; + if((mask & ~ALL_PRINC_MASK)) + return KADM5_BAD_MASK; ++ if (mask & KADM5_TL_DATA) { ++ for (tl_data_tail = entry->tl_data; tl_data_tail != NULL; ++ tl_data_tail = tl_data_tail->tl_data_next) { ++ if (tl_data_tail->tl_data_type < 256) ++ return KADM5_BAD_TL_TYPE; ++ } ++ } + + /* + * Check to see if the principal exists +diff --git a/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h b/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h +index 06b477537..0c19804ad 100644 +--- a/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h ++++ b/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h +@@ -141,7 +141,7 @@ extern int set_ldap_error (krb5_context ctx, int st, int op); + #define UNSTORE16_INT(ptr, val) (val = load_16_be(ptr)) + #define UNSTORE32_INT(ptr, val) (val = load_32_be(ptr)) + +-#define KDB_TL_USER_INFO 0x7ffe ++#define KDB_TL_USER_INFO 0xff + + #define KDB_TL_PRINCTYPE 0x01 + #define KDB_TL_PRINCCOUNT 0x02 +diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c +index 88a170495..b7c9212cb 100644 +--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c ++++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c +@@ -651,6 +651,107 @@ cleanup: + return ret; + } + ++static krb5_error_code ++check_dn_in_container(krb5_context context, const char *dn, ++ char *const *subtrees, unsigned int ntrees) ++{ ++ unsigned int i; ++ size_t dnlen = strlen(dn), stlen; ++ ++ for (i = 0; i < ntrees; i++) { ++ if (subtrees[i] == NULL || *subtrees[i] == '\0') ++ return 0; ++ stlen = strlen(subtrees[i]); ++ if (dnlen >= stlen && ++ strcasecmp(dn + dnlen - stlen, subtrees[i]) == 0 && ++ (dnlen == stlen || dn[dnlen - stlen - 1] == ',')) ++ return 0; ++ } ++ ++ k5_setmsg(context, EINVAL, _("DN is out of the realm subtree")); ++ return EINVAL; ++} ++ ++static krb5_error_code ++check_dn_exists(krb5_context context, ++ krb5_ldap_server_handle *ldap_server_handle, ++ const char *dn, krb5_boolean nonkrb_only) ++{ ++ krb5_error_code st = 0, tempst; ++ krb5_ldap_context *ldap_context = context->dal_handle->db_context; ++ LDAP *ld = ldap_server_handle->ldap_handle; ++ LDAPMessage *result = NULL, *ent; ++ char *attrs[] = { "krbticketpolicyreference", "krbprincipalname", NULL }; ++ char **values; ++ ++ LDAP_SEARCH_1(dn, LDAP_SCOPE_BASE, 0, attrs, IGNORE_STATUS); ++ if (st != LDAP_SUCCESS) ++ return set_ldap_error(context, st, OP_SEARCH); ++ ++ ent = ldap_first_entry(ld, result); ++ CHECK_NULL(ent); ++ ++ values = ldap_get_values(ld, ent, "krbticketpolicyreference"); ++ if (values != NULL) ++ ldap_value_free(values); ++ ++ values = ldap_get_values(ld, ent, "krbprincipalname"); ++ if (values != NULL) { ++ ldap_value_free(values); ++ if (nonkrb_only) { ++ st = EINVAL; ++ k5_setmsg(context, st, _("ldap object is already kerberized")); ++ goto cleanup; ++ } ++ } ++ ++cleanup: ++ ldap_msgfree(result); ++ return st; ++} ++ ++static krb5_error_code ++validate_xargs(krb5_context context, ++ krb5_ldap_server_handle *ldap_server_handle, ++ const xargs_t *xargs, const char *standalone_dn, ++ char *const *subtrees, unsigned int ntrees) ++{ ++ krb5_error_code st; ++ ++ if (xargs->dn != NULL) { ++ /* The supplied dn must be within a realm container. */ ++ st = check_dn_in_container(context, xargs->dn, subtrees, ntrees); ++ if (st) ++ return st; ++ /* The supplied dn must exist without Kerberos attributes. */ ++ st = check_dn_exists(context, ldap_server_handle, xargs->dn, TRUE); ++ if (st) ++ return st; ++ } ++ ++ if (xargs->linkdn != NULL) { ++ /* The supplied linkdn must be within a realm container. */ ++ st = check_dn_in_container(context, xargs->linkdn, subtrees, ntrees); ++ if (st) ++ return st; ++ /* The supplied linkdn must exist. */ ++ st = check_dn_exists(context, ldap_server_handle, xargs->linkdn, ++ FALSE); ++ if (st) ++ return st; ++ } ++ ++ if (xargs->containerdn != NULL && standalone_dn != NULL) { ++ /* standalone_dn (likely composed using containerdn) must be within a ++ * container. */ ++ st = check_dn_in_container(context, standalone_dn, subtrees, ntrees); ++ if (st) ++ return st; ++ } ++ ++ return 0; ++} ++ + krb5_error_code + krb5_ldap_put_principal(krb5_context context, krb5_db_entry *entry, + char **db_args) +@@ -662,12 +763,12 @@ krb5_ldap_put_principal(krb5_context context, krb5_db_entry *entry, + LDAPMessage *result=NULL, *ent=NULL; + char **subtreelist = NULL; + char *user=NULL, *subtree=NULL, *principal_dn=NULL; +- char **values=NULL, *strval[10]={NULL}, errbuf[1024]; ++ char *strval[10]={NULL}, errbuf[1024]; + char *filtuser=NULL; + struct berval **bersecretkey=NULL; + LDAPMod **mods=NULL; + krb5_boolean create_standalone=FALSE; +- krb5_boolean krb_identity_exists=FALSE, establish_links=FALSE; ++ krb5_boolean establish_links=FALSE; + char *standalone_principal_dn=NULL; + krb5_tl_data *tl_data=NULL; + krb5_key_data **keys=NULL; +@@ -860,24 +961,6 @@ krb5_ldap_put_principal(krb5_context context, krb5_db_entry *entry, + * any of the subtrees + */ + if (xargs.dn_from_kbd == TRUE) { +- /* make sure the DN falls in the subtree */ +- int dnlen=0, subtreelen=0; +- char *dn=NULL; +- krb5_boolean outofsubtree=TRUE; +- +- if (xargs.dn != NULL) { +- dn = xargs.dn; +- } else if (xargs.linkdn != NULL) { +- dn = xargs.linkdn; +- } else if (standalone_principal_dn != NULL) { +- /* +- * Even though the standalone_principal_dn is constructed +- * within this function, there is the containerdn input +- * from the user that can become part of the it. +- */ +- dn = standalone_principal_dn; +- } +- + /* Get the current subtree list if we haven't already done so. */ + if (subtreelist == NULL) { + st = krb5_get_subtree_info(ldap_context, &subtreelist, &ntrees); +@@ -885,81 +968,10 @@ krb5_ldap_put_principal(krb5_context context, krb5_db_entry *entry, + goto cleanup; + } + +- for (tre=0; tre= subtreelen) && (strcasecmp((dn + dnlen - subtreelen), subtreelist[tre]) == 0)) { +- outofsubtree = FALSE; +- break; +- } +- } +- } +- +- if (outofsubtree == TRUE) { +- st = EINVAL; +- k5_setmsg(context, st, _("DN is out of the realm subtree")); ++ st = validate_xargs(context, ldap_server_handle, &xargs, ++ standalone_principal_dn, subtreelist, ntrees); ++ if (st) + goto cleanup; +- } +- +- /* +- * dn value will be set either by dn, linkdn or the standalone_principal_dn +- * In the first 2 cases, the dn should be existing and in the last case we +- * are supposed to create the ldap object. so the below should not be +- * executed for the last case. +- */ +- +- if (standalone_principal_dn == NULL) { +- /* +- * If the ldap object is missing, this results in an error. +- */ +- +- /* +- * Search for krbprincipalname attribute here. +- * This is to find if a kerberos identity is already present +- * on the ldap object, in which case adding a kerberos identity +- * on the ldap object should result in an error. +- */ +- char *attributes[]={"krbticketpolicyreference", "krbprincipalname", NULL}; +- +- ldap_msgfree(result); +- result = NULL; +- LDAP_SEARCH_1(dn, LDAP_SCOPE_BASE, 0, attributes, IGNORE_STATUS); +- if (st == LDAP_SUCCESS) { +- ent = ldap_first_entry(ld, result); +- if (ent != NULL) { +- if ((values=ldap_get_values(ld, ent, "krbticketpolicyreference")) != NULL) { +- ldap_value_free(values); +- } +- +- if ((values=ldap_get_values(ld, ent, "krbprincipalname")) != NULL) { +- krb_identity_exists = TRUE; +- ldap_value_free(values); +- } +- } +- } else { +- st = set_ldap_error(context, st, OP_SEARCH); +- goto cleanup; +- } +- } +- } +- +- /* +- * If xargs.dn is set then the request is to add a +- * kerberos principal on a ldap object, but if +- * there is one already on the ldap object this +- * should result in an error. +- */ +- +- if (xargs.dn != NULL && krb_identity_exists == TRUE) { +- st = EINVAL; +- snprintf(errbuf, sizeof(errbuf), +- _("ldap object is already kerberized")); +- k5_setmsg(context, st, "%s", errbuf); +- goto cleanup; + } + + if (xargs.linkdn != NULL) { +diff --git a/src/tests/t_kdb.py b/src/tests/t_kdb.py +index c0eeb0118..319687ff3 100755 +--- a/src/tests/t_kdb.py ++++ b/src/tests/t_kdb.py +@@ -171,6 +171,14 @@ out = realm.run([kadminl, 'ank', '-randkey', '-x', 'dn=cn=krb5', 'princ1'], + expected_code=1) + if 'DN is out of the realm subtree' not in out: + fail('Unexpected kadmin.local output for out-of-realm dn') ++ ++# Check that the DN container check is a hierarchy test, not a simple ++# suffix match (CVE-2018-5730). We expect this operation to fail ++# either way (because "xcn" isn't a valid DN tag) but the container ++# check should happen before the DN is parsed. ++realm.run([kadminl, 'ank', '-randkey', '-x', 'dn=xcn=t1,cn=krb5', 'princ1'], ++ expected_code=1, expected_msg='DN is out of the realm subtree') ++ + realm.run([kadminl, 'ank', '-randkey', '-x', 'dn=cn=t2,cn=krb5', 'princ1']) + out = realm.run([kadminl, 'getprinc', 'princ1']) + if 'Principal: princ1' not in out: +@@ -209,6 +217,12 @@ out = realm.run([kadminl, 'modprinc', '-x', 'containerdn=cn=t2,cn=krb5', + if 'containerdn option not supported' not in out: + fail('Unexpected kadmin.local output trying to reset containerdn') + ++# Verify that containerdn is checked when linkdn is also supplied ++# (CVE-2018-5730). ++realm.run([kadminl, 'ank', '-randkey', '-x', 'containerdn=cn=krb5', ++ '-x', 'linkdn=cn=t2,cn=krb5', 'princ4'], expected_code=1, ++ expected_msg='DN is out of the realm subtree') ++ + # Create and modify a ticket policy. + kldaputil(['create_policy', '-maxtktlife', '3hour', '-maxrenewlife', '6hour', + '-allow_forwardable', 'tktpol']) diff --git a/SOURCES/Fix-hex-conversion-of-PKINIT-certid-strings.patch b/SOURCES/Fix-hex-conversion-of-PKINIT-certid-strings.patch new file mode 100644 index 0000000..792219e --- /dev/null +++ b/SOURCES/Fix-hex-conversion-of-PKINIT-certid-strings.patch @@ -0,0 +1,92 @@ +From 73c156f998e848c5e383ddd715193d84d95e5c39 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 26 Jan 2018 11:47:50 -0500 +Subject: [PATCH] Fix hex conversion of PKINIT certid strings + +When parsing a PKCS11 token specification, correctly convert from hex +to binary instead of using OpenSSL bignum functions (which would strip +leading zeros). + +[ghudson@mit.edu: made hex_string_to_bin() a bit less verbose; wrote +commit message] + +ticket: 8636 +(cherry picked from commit 63e8b8142fd7b3931a7bf2d6448978ca536bafc0) +--- + .../preauth/pkinit/pkinit_crypto_openssl.c | 55 +++++++++++++++---- + 1 file changed, 44 insertions(+), 11 deletions(-) + +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index 85ca8885d..6098acc6a 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -4640,6 +4640,43 @@ reassemble_pkcs11_name(pkinit_identity_opts *idopts) + return ret; + } + ++static int ++hex_string_to_bin(const char *str, int *bin_len_out, CK_BYTE **bin_out) ++{ ++ size_t str_len, i; ++ CK_BYTE *bin; ++ char *endptr, tmp[3] = { '\0', '\0', '\0' }; ++ long val; ++ ++ *bin_len_out = 0; ++ *bin_out = NULL; ++ ++ str_len = strlen(str); ++ if (str_len % 2 != 0) ++ return EINVAL; ++ bin = malloc(str_len / 2); ++ if (bin == NULL) ++ return ENOMEM; ++ ++ errno = 0; ++ for (i = 0; i < str_len / 2; i++) { ++ tmp[0] = str[i * 2]; ++ tmp[1] = str[i * 2 + 1]; ++ ++ val = strtol(tmp, &endptr, 16); ++ if (val < 0 || val > 255 || errno != 0 || endptr != &tmp[2]) { ++ free(bin); ++ return EINVAL; ++ } ++ ++ bin[i] = (CK_BYTE)val; ++ } ++ ++ *bin_len_out = str_len / 2; ++ *bin_out = bin; ++ return 0; ++} ++ + static krb5_error_code + pkinit_get_certs_pkcs11(krb5_context context, + pkinit_plg_crypto_context plg_cryptoctx, +@@ -4682,18 +4719,14 @@ pkinit_get_certs_pkcs11(krb5_context context, + } + /* Convert the ascii cert_id string into a binary blob */ + if (idopts->cert_id_string != NULL) { +- BIGNUM *bn = NULL; +- BN_hex2bn(&bn, idopts->cert_id_string); +- if (bn == NULL) +- return ENOMEM; +- id_cryptoctx->cert_id_len = BN_num_bytes(bn); +- id_cryptoctx->cert_id = malloc((size_t) id_cryptoctx->cert_id_len); +- if (id_cryptoctx->cert_id == NULL) { +- BN_free(bn); +- return ENOMEM; ++ r = hex_string_to_bin(idopts->cert_id_string, ++ &id_cryptoctx->cert_id_len, ++ &id_cryptoctx->cert_id); ++ if (r != 0) { ++ pkiDebug("Failed to convert certid string [%s]\n", ++ idopts->cert_id_string); ++ return r; + } +- BN_bn2bin(bn, id_cryptoctx->cert_id); +- BN_free(bn); + } + id_cryptoctx->slotid = idopts->slotid; + id_cryptoctx->pkcs11_method = 1; diff --git a/SOURCES/Fix-in_clock_skew-and-use-it-in-AS-client-code.patch b/SOURCES/Fix-in_clock_skew-and-use-it-in-AS-client-code.patch new file mode 100644 index 0000000..e11a490 --- /dev/null +++ b/SOURCES/Fix-in_clock_skew-and-use-it-in-AS-client-code.patch @@ -0,0 +1,58 @@ +From 4d42f950965f16a9eb77444a99abe76a8b4ac12c Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Mon, 24 Apr 2017 02:02:36 -0400 +Subject: [PATCH] Fix in_clock_skew() and use it in AS client code + +Add a context parameter to the in_clock_skew() macro so that it isn't +implicitly relying on a local variable. Use it in +get_in_tkt.c:verify_as_reply(). + +(cherry picked from commit 28a07a6461bb443b7fa75cc5cb859ad0db4cbb5a) +--- + src/lib/krb5/krb/gc_via_tkt.c | 2 +- + src/lib/krb5/krb/get_in_tkt.c | 4 ++-- + src/lib/krb5/krb/int-proto.h | 3 ++- + 3 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/src/lib/krb5/krb/gc_via_tkt.c b/src/lib/krb5/krb/gc_via_tkt.c +index 4c0a1a461..c85d8b8d8 100644 +--- a/src/lib/krb5/krb/gc_via_tkt.c ++++ b/src/lib/krb5/krb/gc_via_tkt.c +@@ -305,7 +305,7 @@ krb5int_process_tgs_reply(krb5_context context, + goto cleanup; + + if (!in_cred->times.starttime && +- !in_clock_skew(dec_rep->enc_part2->times.starttime, ++ !in_clock_skew(context, dec_rep->enc_part2->times.starttime, + timestamp)) { + retval = KRB5_KDCREP_SKEW; + goto cleanup; +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index 54badbbc3..a058f5bd7 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -287,8 +287,8 @@ verify_as_reply(krb5_context context, + return retval; + } else { + if ((request->from == 0) && +- (labs(as_reply->enc_part2->times.starttime - time_now) +- > context->clockskew)) ++ !in_clock_skew(context, as_reply->enc_part2->times.starttime, ++ time_now)) + return (KRB5_KDCREP_SKEW); + } + return 0; +diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h +index 6da74858e..44eca359f 100644 +--- a/src/lib/krb5/krb/int-proto.h ++++ b/src/lib/krb5/krb/int-proto.h +@@ -83,7 +83,8 @@ krb5int_construct_matching_creds(krb5_context context, krb5_flags options, + krb5_creds *in_creds, krb5_creds *mcreds, + krb5_flags *fields); + +-#define in_clock_skew(date, now) (labs((date)-(now)) < context->clockskew) ++#define in_clock_skew(context, date, now) \ ++ (labs((date) - (now)) < (context)->clockskew) + + #define IS_TGS_PRINC(p) ((p)->length == 2 && \ + data_eq_string((p)->data[0], KRB5_TGS_NAME)) diff --git a/SOURCES/Fix-make-certs.sh-for-OpenSSL-1.1.patch b/SOURCES/Fix-make-certs.sh-for-OpenSSL-1.1.patch new file mode 100644 index 0000000..26ab1d5 --- /dev/null +++ b/SOURCES/Fix-make-certs.sh-for-OpenSSL-1.1.patch @@ -0,0 +1,70 @@ +From 7113cdfa8b06d1f2a9512a1a69c5313a79509298 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Wed, 6 Sep 2017 12:56:37 -0400 +Subject: [PATCH] Fix make-certs.sh for OpenSSL 1.1 + +The openssl req commands in make-certs.sh contain -subj options which +were ignored in favor of the config file prior to OpenSSL 1.1. When +they are used, they remove elements of the subject which are now +required by t_pkinit.py. + +(cherry picked from commit b0473da67d72e43b9f03b703869069348e872efc) +[rharwood@redhat.com: remove newer sections in make-certs.sh] +--- + src/tests/dejagnu/pkinit-certs/make-certs.sh | 19 +++++++++---------- + 1 file changed, 9 insertions(+), 10 deletions(-) + +diff --git a/src/tests/dejagnu/pkinit-certs/make-certs.sh b/src/tests/dejagnu/pkinit-certs/make-certs.sh +index 0f07709b0..0d8c2019a 100755 +--- a/src/tests/dejagnu/pkinit-certs/make-certs.sh ++++ b/src/tests/dejagnu/pkinit-certs/make-certs.sh +@@ -122,15 +122,14 @@ SUBJECT=ca openssl req -config openssl.cnf -new -x509 -extensions exts_ca \ + -set_serial 1 -days $DAYS -key privkey.pem -out ca.pem + + # Generate a KDC certificate. +-SUBJECT=kdc openssl req -config openssl.cnf -new -subj /CN=kdc \ +- -key privkey.pem -out kdc.csr ++SUBJECT=kdc openssl req -config openssl.cnf -new -key privkey.pem -out kdc.csr + SUBJECT=kdc openssl x509 -extfile openssl.cnf -extensions exts_kdc \ + -set_serial 2 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ + -out kdc.pem -in kdc.csr + + # Generate a client certificate and PKCS#12 bundles. +-SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \ +- -key privkey.pem -out user.csr ++SUBJECT=user openssl req -config openssl.cnf -new -key privkey.pem \ ++ -out user.csr + SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_client \ + -set_serial 3 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ + -out user.pem -in user.csr +@@ -140,24 +139,24 @@ openssl pkcs12 -export -in user.pem -inkey privkey.pem -out user-enc.p12 \ + -passout pass:encrypted + + # Generate a client certificate and PKCS#12 bundles with a UPN SAN. +-SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \ +- -key privkey.pem -out user-upn.csr ++SUBJECT=user openssl req -config openssl.cnf -new -key privkey.pem \ ++ -out user-upn.csr + SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn_client \ + -set_serial 4 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ + -out user-upn.pem -in user-upn.csr + openssl pkcs12 -export -in user-upn.pem -inkey privkey.pem -out user-upn.p12 \ + -passout pass: + +-SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \ +- -key privkey.pem -out user-upn2.csr ++SUBJECT=user openssl req -config openssl.cnf -new -key privkey.pem \ ++ -out user-upn2.csr + SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn2_client \ + -set_serial 5 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ + -out user-upn2.pem -in user-upn2.csr + openssl pkcs12 -export -in user-upn2.pem -inkey privkey.pem \ + -out user-upn2.p12 -passout pass: + +-SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \ +- -key privkey.pem -out user-upn3.csr ++SUBJECT=user openssl req -config openssl.cnf -new -key privkey.pem \ ++ -out user-upn3.csr + SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn3_client \ + -set_serial 6 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ + -out user-upn3.pem -in user-upn3.csr diff --git a/SOURCES/Fix-more-time-manipulations-for-y2038.patch b/SOURCES/Fix-more-time-manipulations-for-y2038.patch new file mode 100644 index 0000000..e796c92 --- /dev/null +++ b/SOURCES/Fix-more-time-manipulations-for-y2038.patch @@ -0,0 +1,83 @@ +From 5fd12bd6e550bc178923b25abc30d8f7c250837a Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Wed, 17 May 2017 14:52:09 -0400 +Subject: [PATCH] Fix more time manipulations for y2038 + +Use timestamp helper functions to ensure that more operations are safe +after y2038, and display the current timestamp as unsigned in +krb5int_trace(). + +ticket: 8352 +(cherry picked from commit a60db180211a383bd382afe729e9309acb8dcf53) +--- + src/kadmin/server/misc.c | 2 +- + src/kdc/dispatch.c | 2 +- + src/lib/krb5/os/c_ustime.c | 8 ++++---- + src/lib/krb5/os/trace.c | 2 +- + 4 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/src/kadmin/server/misc.c b/src/kadmin/server/misc.c +index 27a6376af..a75b65a26 100644 +--- a/src/kadmin/server/misc.c ++++ b/src/kadmin/server/misc.c +@@ -184,7 +184,7 @@ check_min_life(void *server_handle, krb5_principal principal, + (void) kadm5_free_principal_ent(handle->lhandle, &princ); + return (ret == KADM5_UNK_POLICY) ? 0 : ret; + } +- if((now - princ.last_pwd_change) < pol.pw_min_life && ++ if(ts_delta(now, princ.last_pwd_change) < pol.pw_min_life && + !(princ.attributes & KRB5_KDB_REQUIRES_PWCHANGE)) { + if (msg_ret != NULL) { + time_t until; +diff --git a/src/kdc/dispatch.c b/src/kdc/dispatch.c +index 3a169ebc7..16a35d2be 100644 +--- a/src/kdc/dispatch.c ++++ b/src/kdc/dispatch.c +@@ -104,7 +104,7 @@ reseed_random(krb5_context kdc_err_context) + if (last_os_random == 0) + last_os_random = now; + /* Grab random data from OS every hour*/ +- if (now-last_os_random >= 60 * 60) { ++ if (ts_delta(now, last_os_random) >= 60 * 60) { + krb5_c_random_os_entropy(kdc_err_context, 0, NULL); + last_os_random = now; + } +diff --git a/src/lib/krb5/os/c_ustime.c b/src/lib/krb5/os/c_ustime.c +index 871d72183..68fb381f4 100644 +--- a/src/lib/krb5/os/c_ustime.c ++++ b/src/lib/krb5/os/c_ustime.c +@@ -102,17 +102,17 @@ krb5_crypto_us_timeofday(krb5_int32 *seconds, krb5_int32 *microseconds) + putting now.sec in the past. But don't just use '<' because we + need to properly handle the case where the administrator intentionally + adjusted time backwards. */ +- if ((now.sec == last_time.sec-1) || +- ((now.sec == last_time.sec) && (now.usec <= last_time.usec))) { ++ if (now.sec == ts_incr(last_time.sec, -1) || ++ (now.sec == last_time.sec && !ts_after(last_time.usec, now.usec))) { + /* Correct 'now' to be exactly one microsecond later than 'last_time'. + Note that _because_ we perform this hack, 'now' may be _earlier_ + than 'last_time', even though the system time is monotonically + increasing. */ + + now.sec = last_time.sec; +- now.usec = ++last_time.usec; ++ now.usec = ts_incr(last_time.usec, 1); + if (now.usec >= 1000000) { +- ++now.sec; ++ now.sec = ts_incr(now.sec, 1); + now.usec = 0; + } + } +diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c +index a19246128..74c315c90 100644 +--- a/src/lib/krb5/os/trace.c ++++ b/src/lib/krb5/os/trace.c +@@ -350,7 +350,7 @@ krb5int_trace(krb5_context context, const char *fmt, ...) + goto cleanup; + if (krb5_crypto_us_timeofday(&sec, &usec) != 0) + goto cleanup; +- if (asprintf(&msg, "[%d] %d.%d: %s\n", (int) getpid(), (int) sec, ++ if (asprintf(&msg, "[%d] %u.%d: %s\n", (int) getpid(), (unsigned int) sec, + (int) usec, str) < 0) + goto cleanup; + info.message = msg; diff --git a/SOURCES/Fix-segfault-in-finish_dispatch.patch b/SOURCES/Fix-segfault-in-finish_dispatch.patch new file mode 100644 index 0000000..dc6a7f0 --- /dev/null +++ b/SOURCES/Fix-segfault-in-finish_dispatch.patch @@ -0,0 +1,135 @@ +From 9680ab4bd9f38c67ffeb249cf1572d30a1475d28 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Wed, 18 Apr 2018 14:13:28 -0400 +Subject: [PATCH] Fix segfault in finish_dispatch() + +dispatch() doesn't necessarily initialize state->active_realm which +led to an explicit NULL dereference in finish_dispatch(). + +Additionally, fix make_too_big_error() so that it won't subsequently +dereference state->active_realm. + +tags: pullup +target_version: 1.16-next +target_version: 1.15-next + +(cherry picked from commit c822bacc1b33970a2a20d9eae80f43307e783516) +--- + src/kdc/dispatch.c | 79 ++++++++++++++++++++++++---------------------- + 1 file changed, 42 insertions(+), 37 deletions(-) + +diff --git a/src/kdc/dispatch.c b/src/kdc/dispatch.c +index 4ecc23481..1f4b70874 100644 +--- a/src/kdc/dispatch.c ++++ b/src/kdc/dispatch.c +@@ -35,9 +35,6 @@ + + static krb5_int32 last_usec = 0, last_os_random = 0; + +-static krb5_error_code make_too_big_error(kdc_realm_t *kdc_active_realm, +- krb5_data **out); +- + struct dispatch_state { + loop_respond_fn respond; + void *arg; +@@ -47,6 +44,41 @@ struct dispatch_state { + krb5_context kdc_err_context; + }; + ++ ++static krb5_error_code ++make_too_big_error(krb5_context context, krb5_principal tgsprinc, ++ krb5_data **out) ++{ ++ krb5_error errpkt; ++ krb5_error_code retval; ++ krb5_data *scratch; ++ ++ *out = NULL; ++ memset(&errpkt, 0, sizeof(errpkt)); ++ ++ retval = krb5_us_timeofday(context, &errpkt.stime, &errpkt.susec); ++ if (retval) ++ return retval; ++ errpkt.error = KRB_ERR_RESPONSE_TOO_BIG; ++ errpkt.server = tgsprinc; ++ errpkt.client = NULL; ++ errpkt.text.length = 0; ++ errpkt.text.data = 0; ++ errpkt.e_data.length = 0; ++ errpkt.e_data.data = 0; ++ scratch = malloc(sizeof(*scratch)); ++ if (scratch == NULL) ++ return ENOMEM; ++ retval = krb5_mk_error(context, &errpkt, scratch); ++ if (retval) { ++ free(scratch); ++ return retval; ++ } ++ ++ *out = scratch; ++ return 0; ++} ++ + static void + finish_dispatch(struct dispatch_state *state, krb5_error_code code, + krb5_data *response) +@@ -54,12 +86,17 @@ finish_dispatch(struct dispatch_state *state, krb5_error_code code, + loop_respond_fn oldrespond = state->respond; + void *oldarg = state->arg; + kdc_realm_t *kdc_active_realm = state->active_realm; ++ krb5_principal tgsprinc = NULL; ++ ++ if (kdc_active_realm != NULL) ++ tgsprinc = kdc_active_realm->realm_tgsprinc; + + if (state->is_tcp == 0 && response && + response->length > (unsigned int)max_dgram_reply_size) { +- krb5_free_data(kdc_context, response); ++ krb5_free_data(state->kdc_err_context, response); + response = NULL; +- code = make_too_big_error(kdc_active_realm, &response); ++ code = make_too_big_error(state->kdc_err_context, tgsprinc, ++ &response); + if (code) + krb5_klog_syslog(LOG_ERR, "error constructing " + "KRB_ERR_RESPONSE_TOO_BIG error: %s", +@@ -201,38 +238,6 @@ dispatch(void *cb, struct sockaddr *local_saddr, + finish_dispatch_cache(state, retval, response); + } + +-static krb5_error_code +-make_too_big_error(kdc_realm_t *kdc_active_realm, krb5_data **out) +-{ +- krb5_error errpkt; +- krb5_error_code retval; +- krb5_data *scratch; +- +- *out = NULL; +- memset(&errpkt, 0, sizeof(errpkt)); +- +- retval = krb5_us_timeofday(kdc_context, &errpkt.stime, &errpkt.susec); +- if (retval) +- return retval; +- errpkt.error = KRB_ERR_RESPONSE_TOO_BIG; +- errpkt.server = tgs_server; +- errpkt.client = NULL; +- errpkt.text.length = 0; +- errpkt.text.data = 0; +- errpkt.e_data.length = 0; +- errpkt.e_data.data = 0; +- scratch = malloc(sizeof(*scratch)); +- if (scratch == NULL) +- return ENOMEM; +- retval = krb5_mk_error(kdc_context, &errpkt, scratch); +- if (retval) { +- free(scratch); +- return retval; +- } +- +- *out = scratch; +- return 0; +-} + + krb5_context get_context(void *handle) + { diff --git a/SOURCES/Ignore-dotfiles-in-profile-includedir.patch b/SOURCES/Ignore-dotfiles-in-profile-includedir.patch new file mode 100644 index 0000000..1237061 --- /dev/null +++ b/SOURCES/Ignore-dotfiles-in-profile-includedir.patch @@ -0,0 +1,61 @@ +From df09bfffaf5a8e5a3c646838f7d87b16a2680cfe Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Fri, 24 Mar 2017 11:07:21 -0400 +Subject: [PATCH] Ignore dotfiles in profile includedir + +Editors and filesystems may create artifacts related to .conf files +which don't change the file suffix; these artifacts generally begin +with "." so that they don't appear in normal directory listings +(e.g. ".#filename" for emacs interlock files). Make sure to ignore +any such artifacts when processing a profile includedir directive. + +ticket: 8563 (new) +target_version: 1.15-next +tags: pullup + +(cherry picked from commit e8e1d841f8e43e4f441b451d91333a01e43c1b6f) +--- + doc/admin/conf_files/krb5_conf.rst | 7 ++++--- + src/util/profile/prof_parse.c | 6 +++++- + 2 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst +index c0e4349c0..1d9bc9e34 100644 +--- a/doc/admin/conf_files/krb5_conf.rst ++++ b/doc/admin/conf_files/krb5_conf.rst +@@ -55,9 +55,10 @@ following directives at the beginning of a line:: + directory must exist and be readable. Including a directory includes + all files within the directory whose names consist solely of + alphanumeric characters, dashes, or underscores. Starting in release +-1.15, files with names ending in ".conf" are also included. Included +-profile files are syntactically independent of their parents, so each +-included file must begin with a section header. ++1.15, files with names ending in ".conf" are also included, unless the ++name begins with ".". Included profile files are syntactically ++independent of their parents, so each included file must begin with a ++section header. + + The krb5.conf file can specify that configuration should be obtained + from a loadable module, rather than the file itself, using the +diff --git a/src/util/profile/prof_parse.c b/src/util/profile/prof_parse.c +index e7c1f65aa..1baceea9e 100644 +--- a/src/util/profile/prof_parse.c ++++ b/src/util/profile/prof_parse.c +@@ -222,12 +222,16 @@ static errcode_t parse_include_file(const char *filename, + } + + /* Return non-zero if filename contains only alphanumeric characters, dashes, +- * and underscores, or if the filename ends in ".conf". */ ++ * and underscores, or if the filename ends in ".conf" and is not a dotfile. */ + static int valid_name(const char *filename) + { + const char *p; + size_t len = strlen(filename); + ++ /* Ignore dotfiles, which might be editor or filesystem artifacts. */ ++ if (*filename == '.') ++ return 0; ++ + if (len >= 5 && !strcmp(filename + len - 5, ".conf")) + return 1; + diff --git a/SOURCES/Improve-PKINIT-UPN-SAN-matching.patch b/SOURCES/Improve-PKINIT-UPN-SAN-matching.patch new file mode 100644 index 0000000..73c9740 --- /dev/null +++ b/SOURCES/Improve-PKINIT-UPN-SAN-matching.patch @@ -0,0 +1,151 @@ +From 802cf0263965eef725208f00eccb62df0b082319 Mon Sep 17 00:00:00 2001 +From: Matt Rogers +Date: Mon, 5 Dec 2016 12:17:59 -0500 +Subject: [PATCH] Improve PKINIT UPN SAN matching + +Add the match_client() kdcpreauth callback and use it in +verify_client_san(). match_client() preserves the direct UPN to +request principal comparison and adds a direct comparison to the +client principal, falling back to an alias DB search and comparison +against the client principal. Change crypto_retreive_X509_sans() to +parse UPN values as enterprise principals. + +[ghudson@mit.edu: use match_client for both kinds of SANs] + +ticket: 8528 (new) +(cherry picked from commit 46ff765e1fb8cbec2bb602b43311269e695dbedc) +--- + src/include/krb5/kdcpreauth_plugin.h | 13 +++++++++ + src/kdc/kdc_preauth.c | 28 +++++++++++++++++-- + .../preauth/pkinit/pkinit_crypto_openssl.c | 4 ++- + src/plugins/preauth/pkinit/pkinit_srv.c | 10 ++++--- + 4 files changed, 48 insertions(+), 7 deletions(-) + +diff --git a/src/include/krb5/kdcpreauth_plugin.h b/src/include/krb5/kdcpreauth_plugin.h +index f455effae..92aa5a5a5 100644 +--- a/src/include/krb5/kdcpreauth_plugin.h ++++ b/src/include/krb5/kdcpreauth_plugin.h +@@ -221,6 +221,19 @@ typedef struct krb5_kdcpreauth_callbacks_st { + + /* End of version 3 kdcpreauth callbacks. */ + ++ /* ++ * Return true if princ matches the principal named in the request or the ++ * client principal (possibly canonicalized). If princ does not match, ++ * attempt a database lookup of princ with aliases allowed and compare the ++ * result to the client principal, returning true if it matches. ++ * Otherwise, return false. ++ */ ++ krb5_boolean (*match_client)(krb5_context context, ++ krb5_kdcpreauth_rock rock, ++ krb5_principal princ); ++ ++ /* End of version 4 kdcpreauth callbacks. */ ++ + } *krb5_kdcpreauth_callbacks; + + /* Optional: preauth plugin initialization function. */ +diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c +index 605fcb7ad..0ce79c667 100644 +--- a/src/kdc/kdc_preauth.c ++++ b/src/kdc/kdc_preauth.c +@@ -568,8 +568,31 @@ set_cookie(krb5_context context, krb5_kdcpreauth_rock rock, + return kdc_fast_set_cookie(rock->rstate, pa_type, data); + } + ++static krb5_boolean ++match_client(krb5_context context, krb5_kdcpreauth_rock rock, ++ krb5_principal princ) ++{ ++ krb5_db_entry *ent; ++ krb5_boolean match = FALSE; ++ krb5_principal req_client = rock->request->client; ++ krb5_principal client = rock->client->princ; ++ ++ /* Check for a direct match against the request principal or ++ * the post-canon client principal. */ ++ if (krb5_principal_compare_flags(context, princ, req_client, ++ KRB5_PRINCIPAL_COMPARE_ENTERPRISE) || ++ krb5_principal_compare(context, princ, client)) ++ return TRUE; ++ ++ if (krb5_db_get_principal(context, princ, KRB5_KDB_FLAG_ALIAS_OK, &ent)) ++ return FALSE; ++ match = krb5_principal_compare(context, ent->princ, client); ++ krb5_db_free_principal(context, ent); ++ return match; ++} ++ + static struct krb5_kdcpreauth_callbacks_st callbacks = { +- 3, ++ 4, + max_time_skew, + client_keys, + free_keys, +@@ -583,7 +606,8 @@ static struct krb5_kdcpreauth_callbacks_st callbacks = { + client_keyblock, + add_auth_indicator, + get_cookie, +- set_cookie ++ set_cookie, ++ match_client + }; + + static krb5_error_code +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index 74fffbf32..bc6e7662e 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -2190,7 +2190,9 @@ crypto_retrieve_X509_sans(krb5_context context, + /* Prevent abuse of embedded null characters. */ + if (memchr(name.data, '\0', name.length)) + break; +- ret = krb5_parse_name(context, name.data, &upns[u]); ++ ret = krb5_parse_name_flags(context, name.data, ++ KRB5_PRINCIPAL_PARSE_ENTERPRISE, ++ &upns[u]); + if (ret) { + pkiDebug("%s: failed parsing ms-upn san value\n", + __FUNCTION__); +diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c +index 295be25e1..b5638a367 100644 +--- a/src/plugins/preauth/pkinit/pkinit_srv.c ++++ b/src/plugins/preauth/pkinit/pkinit_srv.c +@@ -121,6 +121,8 @@ static krb5_error_code + verify_client_san(krb5_context context, + pkinit_kdc_context plgctx, + pkinit_kdc_req_context reqctx, ++ krb5_kdcpreauth_callbacks cb, ++ krb5_kdcpreauth_rock rock, + krb5_principal client, + int *valid_san) + { +@@ -171,7 +173,7 @@ verify_client_san(krb5_context context, + __FUNCTION__, client_string, san_string); + krb5_free_unparsed_name(context, san_string); + #endif +- if (krb5_principal_compare(context, princs[i], client)) { ++ if (cb->match_client(context, rock, princs[i])) { + pkiDebug("%s: pkinit san match found\n", __FUNCTION__); + *valid_san = 1; + retval = 0; +@@ -199,7 +201,7 @@ verify_client_san(krb5_context context, + __FUNCTION__, client_string, san_string); + krb5_free_unparsed_name(context, san_string); + #endif +- if (krb5_principal_compare(context, upns[i], client)) { ++ if (cb->match_client(context, rock, upns[i])) { + pkiDebug("%s: upn san match found\n", __FUNCTION__); + *valid_san = 1; + retval = 0; +@@ -387,8 +389,8 @@ pkinit_server_verify_padata(krb5_context context, + } + if (is_signed) { + +- retval = verify_client_san(context, plgctx, reqctx, request->client, +- &valid_san); ++ retval = verify_client_san(context, plgctx, reqctx, cb, rock, ++ request->client, &valid_san); + if (retval) + goto cleanup; + if (!valid_san) { diff --git a/SOURCES/In-FIPS-mode-add-plaintext-fallback-for-RC4-usages-a.patch b/SOURCES/In-FIPS-mode-add-plaintext-fallback-for-RC4-usages-a.patch new file mode 100644 index 0000000..98c2bcc --- /dev/null +++ b/SOURCES/In-FIPS-mode-add-plaintext-fallback-for-RC4-usages-a.patch @@ -0,0 +1,327 @@ +From c1f14d371be42cbe851c573d26e425ebecc2ea35 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Tue, 31 Jul 2018 13:47:26 -0400 +Subject: [PATCH] In FIPS mode, add plaintext fallback for RC4 usages and taint + +--- + src/lib/krad/attr.c | 38 ++++++++++++++++++++++++++++---------- + src/lib/krad/attrset.c | 5 +++-- + src/lib/krad/internal.h | 13 +++++++++++-- + src/lib/krad/packet.c | 18 +++++++++--------- + src/lib/krad/remote.c | 10 ++++++++-- + src/lib/krad/t_attr.c | 3 ++- + src/lib/krad/t_attrset.c | 4 +++- + 7 files changed, 64 insertions(+), 27 deletions(-) + +diff --git a/src/lib/krad/attr.c b/src/lib/krad/attr.c +index 9c13d9d75..f96153e2e 100644 +--- a/src/lib/krad/attr.c ++++ b/src/lib/krad/attr.c +@@ -38,7 +38,8 @@ + typedef krb5_error_code + (*attribute_transform_fn)(krb5_context ctx, const char *secret, + const unsigned char *auth, const krb5_data *in, +- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen); ++ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen, ++ krb5_boolean *is_fips); + + typedef struct { + const char *name; +@@ -51,12 +52,14 @@ typedef struct { + static krb5_error_code + user_password_encode(krb5_context ctx, const char *secret, + const unsigned char *auth, const krb5_data *in, +- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen); ++ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen, ++ krb5_boolean *is_fips); + + static krb5_error_code + user_password_decode(krb5_context ctx, const char *secret, + const unsigned char *auth, const krb5_data *in, +- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen); ++ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen, ++ krb5_boolean *ignored); + + static const attribute_record attributes[UCHAR_MAX] = { + {"User-Name", 1, MAX_ATTRSIZE, NULL, NULL}, +@@ -128,7 +131,8 @@ static const attribute_record attributes[UCHAR_MAX] = { + static krb5_error_code + user_password_encode(krb5_context ctx, const char *secret, + const unsigned char *auth, const krb5_data *in, +- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen) ++ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen, ++ krb5_boolean *is_fips) + { + const unsigned char *indx; + krb5_error_code retval; +@@ -156,7 +160,12 @@ user_password_encode(krb5_context ctx, const char *secret, + + retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &tmp, + &sum); +- if (retval != 0) { ++ if (retval == ENOMEM) { ++ /* I'm Linux, so we know this is a FIPS failure. RSA_MD5 doesn't ++ * provide security so let's move on. */ ++ *is_fips = TRUE; ++ sum.contents = calloc(1, BLOCKSIZE); ++ } else if (retval != 0) { + zap(tmp.data, tmp.length); + zap(outbuf, len); + krb5_free_data_contents(ctx, &tmp); +@@ -180,7 +189,8 @@ user_password_encode(krb5_context ctx, const char *secret, + static krb5_error_code + user_password_decode(krb5_context ctx, const char *secret, + const unsigned char *auth, const krb5_data *in, +- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen) ++ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen, ++ krb5_boolean *is_fips) + { + const unsigned char *indx; + krb5_error_code retval; +@@ -206,7 +216,12 @@ user_password_decode(krb5_context ctx, const char *secret, + + retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, + &tmp, &sum); +- if (retval != 0) { ++ if (retval == ENOMEM) { ++ /* I'm Linux, so we know this is a FIPS failure. Assume the ++ * other side is running locally and move on. */ ++ *is_fips = TRUE; ++ sum.contents = calloc(1, BLOCKSIZE); ++ } else if (retval != 0) { + zap(tmp.data, tmp.length); + zap(outbuf, in->length); + krb5_free_data_contents(ctx, &tmp); +@@ -248,7 +263,7 @@ krb5_error_code + kr_attr_encode(krb5_context ctx, const char *secret, + const unsigned char *auth, krad_attr type, + const krb5_data *in, unsigned char outbuf[MAX_ATTRSIZE], +- size_t *outlen) ++ size_t *outlen, krb5_boolean *is_fips) + { + krb5_error_code retval; + +@@ -265,7 +280,8 @@ kr_attr_encode(krb5_context ctx, const char *secret, + return 0; + } + +- return attributes[type - 1].encode(ctx, secret, auth, in, outbuf, outlen); ++ return attributes[type - 1].encode(ctx, secret, auth, in, outbuf, outlen, ++ is_fips); + } + + krb5_error_code +@@ -274,6 +290,7 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth, + unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen) + { + krb5_error_code retval; ++ krb5_boolean ignored; + + retval = kr_attr_valid(type, in); + if (retval != 0) +@@ -288,7 +305,8 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth, + return 0; + } + +- return attributes[type - 1].decode(ctx, secret, auth, in, outbuf, outlen); ++ return attributes[type - 1].decode(ctx, secret, auth, in, outbuf, outlen, ++ &ignored); + } + + krad_attr +diff --git a/src/lib/krad/attrset.c b/src/lib/krad/attrset.c +index 03c613716..d89982a13 100644 +--- a/src/lib/krad/attrset.c ++++ b/src/lib/krad/attrset.c +@@ -167,7 +167,8 @@ krad_attrset_copy(const krad_attrset *set, krad_attrset **copy) + krb5_error_code + kr_attrset_encode(const krad_attrset *set, const char *secret, + const unsigned char *auth, +- unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen) ++ unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen, ++ krb5_boolean *is_fips) + { + unsigned char buffer[MAX_ATTRSIZE]; + krb5_error_code retval; +@@ -181,7 +182,7 @@ kr_attrset_encode(const krad_attrset *set, const char *secret, + + K5_TAILQ_FOREACH(a, &set->list, list) { + retval = kr_attr_encode(set->ctx, secret, auth, a->type, &a->attr, +- buffer, &attrlen); ++ buffer, &attrlen, is_fips); + if (retval != 0) + return retval; + +diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h +index 996a89372..a53ce31ce 100644 +--- a/src/lib/krad/internal.h ++++ b/src/lib/krad/internal.h +@@ -49,6 +49,13 @@ + + typedef struct krad_remote_st krad_remote; + ++struct krad_packet_st { ++ char buffer[KRAD_PACKET_SIZE_MAX]; ++ krad_attrset *attrset; ++ krb5_data pkt; ++ krb5_boolean is_fips; ++}; ++ + /* Validate constraints of an attribute. */ + krb5_error_code + kr_attr_valid(krad_attr type, const krb5_data *data); +@@ -57,7 +64,8 @@ kr_attr_valid(krad_attr type, const krb5_data *data); + krb5_error_code + kr_attr_encode(krb5_context ctx, const char *secret, const unsigned char *auth, + krad_attr type, const krb5_data *in, +- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen); ++ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen, ++ krb5_boolean *is_fips); + + /* Decode an attribute. */ + krb5_error_code +@@ -69,7 +77,8 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth, + krb5_error_code + kr_attrset_encode(const krad_attrset *set, const char *secret, + const unsigned char *auth, +- unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen); ++ unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen, ++ krb5_boolean *is_fips); + + /* Decode attributes from a buffer. */ + krb5_error_code +diff --git a/src/lib/krad/packet.c b/src/lib/krad/packet.c +index c597174b6..2fbf0ee1e 100644 +--- a/src/lib/krad/packet.c ++++ b/src/lib/krad/packet.c +@@ -53,12 +53,6 @@ typedef unsigned char uchar; + #define pkt_auth(p) ((uchar *)offset(&(p)->pkt, OFFSET_AUTH)) + #define pkt_attr(p) ((unsigned char *)offset(&(p)->pkt, OFFSET_ATTR)) + +-struct krad_packet_st { +- char buffer[KRAD_PACKET_SIZE_MAX]; +- krad_attrset *attrset; +- krb5_data pkt; +-}; +- + typedef struct { + uchar x[(UCHAR_MAX + 1) / 8]; + } idmap; +@@ -190,7 +184,11 @@ auth_generate_response(krb5_context ctx, const char *secret, + retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &data, + &hash); + free(data.data); +- if (retval != 0) ++ if (retval == ENOMEM) { ++ /* We're on Linux, so this is a FIPS failure, and this checksum ++ * does very little security-wise anyway, so don't taint. */ ++ hash.contents = calloc(1, AUTH_FIELD_SIZE); ++ } else if (retval != 0) + return retval; + + memcpy(rauth, hash.contents, AUTH_FIELD_SIZE); +@@ -276,7 +274,7 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code, + + /* Encode the attributes. */ + retval = kr_attrset_encode(set, secret, pkt_auth(pkt), pkt_attr(pkt), +- &attrset_len); ++ &attrset_len, &pkt->is_fips); + if (retval != 0) + goto error; + +@@ -314,7 +312,7 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code, + + /* Encode the attributes. */ + retval = kr_attrset_encode(set, secret, pkt_auth(request), pkt_attr(pkt), +- &attrset_len); ++ &attrset_len, &pkt->is_fips); + if (retval != 0) + goto error; + +@@ -451,6 +449,8 @@ krad_packet_decode_response(krb5_context ctx, const char *secret, + const krb5_data * + krad_packet_encode(const krad_packet *pkt) + { ++ if (pkt->is_fips) ++ return NULL; + return &pkt->pkt; + } + +diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c +index 437f7e91a..0f90443ce 100644 +--- a/src/lib/krad/remote.c ++++ b/src/lib/krad/remote.c +@@ -263,7 +263,7 @@ on_io_write(krad_remote *rr) + request *r; + + K5_TAILQ_FOREACH(r, &rr->list, list) { +- tmp = krad_packet_encode(r->request); ++ tmp = &r->request->pkt; + + /* If the packet has already been sent, do nothing. */ + if (r->sent == tmp->length) +@@ -359,7 +359,7 @@ on_io_read(krad_remote *rr) + if (req != NULL) { + K5_TAILQ_FOREACH(r, &rr->list, list) { + if (r->request == req && +- r->sent == krad_packet_encode(req)->length) { ++ r->sent == req->pkt.length) { + request_finish(r, 0, rsp); + break; + } +@@ -455,6 +455,12 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs, + (krad_packet_iter_cb)iterator, &r, &tmp); + if (retval != 0) + goto error; ++ else if (tmp->is_fips && rr->info->ai_family != AF_LOCAL && ++ rr->info->ai_family != AF_UNIX) { ++ /* This would expose cleartext passwords, so abort. */ ++ retval = ESOCKTNOSUPPORT; ++ goto error; ++ } + + K5_TAILQ_FOREACH(r, &rr->list, list) { + if (r->request == tmp) { +diff --git a/src/lib/krad/t_attr.c b/src/lib/krad/t_attr.c +index eb2a780c8..4d285ad9d 100644 +--- a/src/lib/krad/t_attr.c ++++ b/src/lib/krad/t_attr.c +@@ -50,6 +50,7 @@ main() + const char *tmp; + krb5_data in; + size_t len; ++ krb5_boolean is_fips = FALSE; + + noerror(krb5_init_context(&ctx)); + +@@ -73,7 +74,7 @@ main() + in = string2data((char *)decoded); + retval = kr_attr_encode(ctx, secret, auth, + krad_attr_name2num("User-Password"), +- &in, outbuf, &len); ++ &in, outbuf, &len, &is_fips); + insist(retval == 0); + insist(len == sizeof(encoded)); + insist(memcmp(outbuf, encoded, len) == 0); +diff --git a/src/lib/krad/t_attrset.c b/src/lib/krad/t_attrset.c +index 7928335ca..0f9576253 100644 +--- a/src/lib/krad/t_attrset.c ++++ b/src/lib/krad/t_attrset.c +@@ -49,6 +49,7 @@ main() + krb5_context ctx; + size_t len = 0, encode_len; + krb5_data tmp; ++ krb5_boolean is_fips = FALSE; + + noerror(krb5_init_context(&ctx)); + noerror(krad_attrset_new(ctx, &set)); +@@ -62,7 +63,8 @@ main() + noerror(krad_attrset_add(set, krad_attr_name2num("User-Password"), &tmp)); + + /* Encode attrset. */ +- noerror(kr_attrset_encode(set, "foo", auth, buffer, &encode_len)); ++ noerror(kr_attrset_encode(set, "foo", auth, buffer, &encode_len, ++ &is_fips)); + krad_attrset_free(set); + + /* Manually encode User-Name. */ diff --git a/SOURCES/Include-preauth-name-in-trace-output-if-possible.patch b/SOURCES/Include-preauth-name-in-trace-output-if-possible.patch new file mode 100644 index 0000000..a78f166 --- /dev/null +++ b/SOURCES/Include-preauth-name-in-trace-output-if-possible.patch @@ -0,0 +1,506 @@ +From c9b74036064b7f3aebbd3c482703ce97ff868bb6 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Thu, 15 Mar 2018 14:37:28 -0400 +Subject: [PATCH] Include preauth name in trace output if possible + +Add a {patype} trace format specifier for a single pa-type value. Add +a krb5_preauthtype to string conversion function to trace machinery +and use it when formatting {patype} or {patypes}. + +[ghudson@mit.edu: wrote conversion function; edited commit message] + +ticket: 8653 (new) +(cherry picked from commit 9c68fe39b018666eabe033b639c1f35d03ba51c7) +[rharwood@redhat.com: freshness, expected_msg] +--- + src/include/k5-trace.h | 17 +-- + src/lib/krb5/os/t_trace.ref | 2 +- + src/lib/krb5/os/trace.c | 60 +++++++++- + src/tests/t_pkinit.py | 36 +++--- + src/tests/t_preauth.py | 216 ++++++++++++++++++------------------ + 5 files changed, 199 insertions(+), 132 deletions(-) + +diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h +index e60ee0b75..49b1b6756 100644 +--- a/src/include/k5-trace.h ++++ b/src/include/k5-trace.h +@@ -75,6 +75,7 @@ + * {cksum} const krb5_checksum *, display cksumtype and hex checksum + * {princ} krb5_principal, unparse and display + * {ptype} krb5_int32, krb5_principal type, display name ++ * {patype} krb5_preauthtype, a single padata type number + * {patypes} krb5_pa_data **, display list of padata type numbers + * {etype} krb5_enctype, display shortest name of enctype + * {etypes} krb5_enctype *, display list of enctypes +@@ -218,14 +219,14 @@ void krb5int_trace(krb5_context context, const char *fmt, ...); + #define TRACE_INIT_CREDS_PREAUTH_DECRYPT_FAIL(c, code) \ + TRACE(c, "Decrypt with preauth AS key failed: {kerr}", code) + #define TRACE_INIT_CREDS_PREAUTH_MORE(c, patype) \ +- TRACE(c, "Continuing preauth mech {int}", (int)patype) ++ TRACE(c, "Continuing preauth mech {patype}", patype) + #define TRACE_INIT_CREDS_PREAUTH_NONE(c) \ + TRACE(c, "Sending unauthenticated request") + #define TRACE_INIT_CREDS_PREAUTH_OPTIMISTIC(c) \ + TRACE(c, "Attempting optimistic preauth") + #define TRACE_INIT_CREDS_PREAUTH_TRYAGAIN(c, patype, code) \ +- TRACE(c, "Recovering from KDC error {int} using preauth mech {int}", \ +- (int)patype, (int)code) ++ TRACE(c, "Recovering from KDC error {int} using preauth mech {patype}", \ ++ patype, (int)code) + #define TRACE_INIT_CREDS_RESTART_FAST(c) \ + TRACE(c, "Restarting to upgrade to FAST") + #define TRACE_INIT_CREDS_RESTART_PREAUTH_FAILED(c) \ +@@ -269,7 +270,7 @@ void krb5int_trace(krb5_context context, const char *fmt, ...); + + #define TRACE_PREAUTH_CONFLICT(c, name1, name2, patype) \ + TRACE(c, "Preauth module {str} conflicts with module {str} for pa " \ +- "type {int}", name1, name2, (int) patype) ++ "type {patype}", name1, name2, patype) + #define TRACE_PREAUTH_COOKIE(c, len, data) \ + TRACE(c, "Received cookie: {lenstr}", (size_t) len, data) + #define TRACE_PREAUTH_ENC_TS_KEY_GAK(c, keyblock) \ +@@ -281,8 +282,8 @@ void krb5int_trace(krb5_context context, const char *fmt, ...); + TRACE(c, "Selected etype info: etype {etype}, salt \"{data}\", " \ + "params \"{data}\"", etype, salt, s2kparams) + #define TRACE_PREAUTH_INFO_FAIL(c, patype, code) \ +- TRACE(c, "Preauth builtin info function failure, type={int}: {kerr}", \ +- (int) patype, code) ++ TRACE(c, "Preauth builtin info function failure, type={patype}: {kerr}", \ ++ patype, code) + #define TRACE_PREAUTH_INPUT(c, padata) \ + TRACE(c, "Processing preauth types: {patypes}", padata) + #define TRACE_PREAUTH_OUTPUT(c, padata) \ +@@ -293,8 +294,8 @@ void krb5int_trace(krb5_context context, const char *fmt, ...); + #define TRACE_PREAUTH_SAM_KEY_GAK(c, keyblock) \ + TRACE(c, "AS key obtained for SAM: {keyblock}", keyblock) + #define TRACE_PREAUTH_SALT(c, salt, patype) \ +- TRACE(c, "Received salt \"{data}\" via padata type {int}", salt, \ +- (int) patype) ++ TRACE(c, "Received salt \"{data}\" via padata type {patype}", salt, \ ++ patype) + #define TRACE_PREAUTH_SKIP(c, name, patype) \ + TRACE(c, "Skipping previously used preauth module {str} ({int})", \ + name, (int) patype) +diff --git a/src/lib/krb5/os/t_trace.ref b/src/lib/krb5/os/t_trace.ref +index ca5818a1e..bd5d9b6b6 100644 +--- a/src/lib/krb5/os/t_trace.ref ++++ b/src/lib/krb5/os/t_trace.ref +@@ -38,7 +38,7 @@ int, krb5_principal type: Windows 2000 UPN and SID + int, krb5_principal type: NT 4 style name + int, krb5_principal type: NT 4 style name and SID + int, krb5_principal type: ? +-krb5_pa_data **, display list of padata type numbers: 3, 0 ++krb5_pa_data **, display list of padata type numbers: PA-PW-SALT (3), 0 + krb5_pa_data **, display list of padata type numbers: (empty) + krb5_enctype, display shortest name of enctype: des-cbc-crc + krb5_enctype *, display list of enctypes: 5, rc4-hmac-exp, 511 +diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c +index 8750b7650..5a80f5518 100644 +--- a/src/lib/krb5/os/trace.c ++++ b/src/lib/krb5/os/trace.c +@@ -123,6 +123,49 @@ principal_type_string(krb5_int32 type) + } + } + ++static char * ++padata_type_string(krb5_preauthtype type) ++{ ++ switch (type) { ++ case KRB5_PADATA_TGS_REQ: return "PA-TGS-REQ"; ++ case KRB5_PADATA_ENC_TIMESTAMP: return "PA-ENC-TIMESTAMP"; ++ case KRB5_PADATA_PW_SALT: return "PA-PW-SALT"; ++ case KRB5_PADATA_ENC_UNIX_TIME: return "PA-ENC-UNIX-TIME"; ++ case KRB5_PADATA_ENC_SANDIA_SECURID: return "PA-SANDIA-SECUREID"; ++ case KRB5_PADATA_SESAME: return "PA-SESAME"; ++ case KRB5_PADATA_OSF_DCE: return "PA-OSF-DCE"; ++ case KRB5_CYBERSAFE_SECUREID: return "PA-CYBERSAFE-SECUREID"; ++ case KRB5_PADATA_AFS3_SALT: return "PA-AFS3-SALT"; ++ case KRB5_PADATA_ETYPE_INFO: return "PA-ETYPE-INFO"; ++ case KRB5_PADATA_SAM_CHALLENGE: return "PA-SAM-CHALLENGE"; ++ case KRB5_PADATA_SAM_RESPONSE: return "PA-SAM-RESPONSE"; ++ case KRB5_PADATA_PK_AS_REQ_OLD: return "PA-PK-AS-REQ_OLD"; ++ case KRB5_PADATA_PK_AS_REP_OLD: return "PA-PK-AS-REP_OLD"; ++ case KRB5_PADATA_PK_AS_REQ: return "PA-PK-AS-REQ"; ++ case KRB5_PADATA_PK_AS_REP: return "PA-PK-AS-REP"; ++ case KRB5_PADATA_ETYPE_INFO2: return "PA-ETYPE-INFO2"; ++ case KRB5_PADATA_SVR_REFERRAL_INFO: return "PA-SVR-REFERRAL-INFO"; ++ case KRB5_PADATA_SAM_REDIRECT: return "PA-SAM-REDIRECT"; ++ case KRB5_PADATA_GET_FROM_TYPED_DATA: return "PA-GET-FROM-TYPED-DATA"; ++ case KRB5_PADATA_SAM_CHALLENGE_2: return "PA-SAM-CHALLENGE2"; ++ case KRB5_PADATA_SAM_RESPONSE_2: return "PA-SAM-RESPONSE2"; ++ case KRB5_PADATA_PAC_REQUEST: return "PA-PAC-REQUEST"; ++ case KRB5_PADATA_FOR_USER: return "PA-FOR_USER"; ++ case KRB5_PADATA_S4U_X509_USER: return "PA-FOR-X509-USER"; ++ case KRB5_PADATA_AS_CHECKSUM: return "PA-AS-CHECKSUM"; ++ case KRB5_PADATA_FX_COOKIE: return "PA-FX-COOKIE"; ++ case KRB5_PADATA_FX_FAST: return "PA-FX-FAST"; ++ case KRB5_PADATA_FX_ERROR: return "PA-FX-ERROR"; ++ case KRB5_PADATA_ENCRYPTED_CHALLENGE: return "PA-ENCRYPTED-CHALLENGE"; ++ case KRB5_PADATA_OTP_CHALLENGE: return "PA-OTP-CHALLENGE"; ++ case KRB5_PADATA_OTP_REQUEST: return "PA-OTP-REQUEST"; ++ case KRB5_PADATA_OTP_PIN_CHANGE: return "PA-OTP-PIN-CHANGE"; ++ case KRB5_PADATA_PKINIT_KX: return "PA-PKINIT-KX"; ++ case KRB5_ENCPADATA_REQ_ENC_PA_REP: return "PA-REQ-ENC-PA-REP"; ++ default: return NULL; ++ } ++} ++ + static char * + trace_format(krb5_context context, const char *fmt, va_list ap) + { +@@ -140,6 +183,8 @@ trace_format(krb5_context context, const char *fmt, va_list ap) + krb5_key key; + const krb5_checksum *cksum; + krb5_pa_data **padata; ++ krb5_preauthtype pa_type; ++ const char *name; + krb5_ccache ccache; + krb5_keytab keytab; + krb5_creds *creds; +@@ -271,10 +316,23 @@ trace_format(krb5_context context, const char *fmt, va_list ap) + if (padata == NULL || *padata == NULL) + k5_buf_add(&buf, "(empty)"); + for (; padata != NULL && *padata != NULL; padata++) { +- k5_buf_add_fmt(&buf, "%d", (int)(*padata)->pa_type); ++ pa_type = (*padata)->pa_type; ++ name = padata_type_string(pa_type); ++ if (name != NULL) ++ k5_buf_add_fmt(&buf, "%s (%d)", name, (int)pa_type); ++ else ++ k5_buf_add_fmt(&buf, "%d", (int)pa_type); ++ + if (*(padata + 1) != NULL) + k5_buf_add(&buf, ", "); + } ++ } else if (strcmp(tmpbuf, "patype") == 0) { ++ pa_type = va_arg(ap, krb5_preauthtype); ++ name = padata_type_string(pa_type); ++ if (name != NULL) ++ k5_buf_add_fmt(&buf, "%s (%d)", name, (int)pa_type); ++ else ++ k5_buf_add_fmt(&buf, "%d", (int)pa_type); + } else if (strcmp(tmpbuf, "etype") == 0) { + etype = va_arg(ap, krb5_enctype); + if (krb5_enctype_to_name(etype, TRUE, tmpbuf, sizeof(tmpbuf)) == 0) +diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py +index c25475096..64ff2393a 100755 +--- a/src/tests/t_pkinit.py ++++ b/src/tests/t_pkinit.py +@@ -161,10 +161,18 @@ realm.start_kdc() + realm.run([kadminl, 'delprinc', 'WELLKNOWN/ANONYMOUS']) + + # Run the basic test - PKINIT with FILE: identity, with no password on the key. +-realm.run(['./responder', '-x', 'pkinit=', +- '-X', 'X509_user_identity=%s' % file_identity, realm.user_princ]) ++msgs = ('Sending unauthenticated request', ++ '/Additional pre-authentication required', ++ 'Preauthenticating using KDC method data', ++ 'PKINIT loading CA certs and CRLs from FILE', ++ 'PKINIT client making DH request', ++ ' preauth for next request: PA-FX-COOKIE (133), PA-PK-AS-REQ (16)', ++ 'PKINIT client verified DH reply', ++ 'PKINIT client found id-pkinit-san in KDC cert', ++ 'PKINIT client matched KDC principal krbtgt/') + realm.kinit(realm.user_princ, +- flags=['-X', 'X509_user_identity=%s' % file_identity]) ++ flags=['-X', 'X509_user_identity=%s' % file_identity], ++ expected_trace=msgs) + realm.klist(realm.user_princ) + realm.run([kvno, realm.host_princ]) + +@@ -181,19 +189,19 @@ minbits_kdc_conf = {'realms': {'$realm': {'pkinit_dh_min_bits': '4096'}}} + minbits_env = realm.special_env('restrict', True, kdc_conf=minbits_kdc_conf) + realm.stop_kdc() + realm.start_kdc(env=minbits_env) +-expected_trace = ('Sending unauthenticated request', +- '/Additional pre-authentication required', +- 'Preauthenticating using KDC method data', +- 'Preauth module pkinit (16) (real) returned: 0/Success', +- 'Produced preauth for next request: 133, 16', +- '/Key parameters not accepted', +- 'Preauth tryagain input types (16): 109, 133', +- 'trying again with KDC-provided parameters', +- 'Preauth module pkinit (16) tryagain returned: 0/Success', +- 'Followup preauth for next request: 16, 133') ++msgs = ('Sending unauthenticated request', ++ '/Additional pre-authentication required', ++ 'Preauthenticating using KDC method data', ++ 'Preauth module pkinit (16) (real) returned: 0/Success', ++ ' preauth for next request: PA-FX-COOKIE (133), PA-PK-AS-REQ (16)', ++ '/Key parameters not accepted', ++ 'Preauth tryagain input types (16): 109, PA-FX-COOKIE (133)', ++ 'trying again with KDC-provided parameters', ++ 'Preauth module pkinit (16) tryagain returned: 0/Success', ++ ' preauth for next request: PA-PK-AS-REQ (16), PA-FX-COOKIE (133)') + realm.kinit(realm.user_princ, + flags=['-X', 'X509_user_identity=%s' % file_identity], +- expected_trace=expected_trace) ++ expected_trace=msgs) + realm.stop_kdc() + realm.start_kdc() + +diff --git a/src/tests/t_preauth.py b/src/tests/t_preauth.py +index 7d4d299dc..b2b0983aa 100644 +--- a/src/tests/t_preauth.py ++++ b/src/tests/t_preauth.py +@@ -22,15 +22,15 @@ if 'no key' not in out: + # PA-FX-COOKIE; 2 is encrypted timestamp. + + # Test normal preauth flow. +-expected_trace = ('Sending unauthenticated request', +- '/Additional pre-authentication required', +- 'Preauthenticating using KDC method data', +- 'Processing preauth types:', +- 'Preauth module test (-123) (real) returned: 0/Success', +- 'Produced preauth for next request: 133, -123', +- 'Decrypted AS reply') ++msgs = ('Sending unauthenticated request', ++ '/Additional pre-authentication required', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: PA-FX-COOKIE (133), -123', ++ 'Decrypted AS reply') + realm.run(['./icred', realm.user_princ, password('user')], +- expected_msg='testval', expected_trace=expected_trace) ++ expected_msg='testval', expected_trace=msgs) + + # Test successful optimistic preauth. + expected_trace = ('Attempting optimistic preauth', +@@ -43,136 +43,136 @@ realm.run(['./icred', '-o', '-123', realm.user_princ, password('user')], + + # Test optimistic preauth failing on client, followed by successful + # preauth using the same module. +-expected_trace = ('Attempting optimistic preauth', +- 'Processing preauth types: -123', +- '/induced optimistic fail', +- 'Sending unauthenticated request', +- '/Additional pre-authentication required', +- 'Preauthenticating using KDC method data', +- 'Processing preauth types:', +- 'Preauth module test (-123) (real) returned: 0/Success', +- 'Produced preauth for next request: 133, -123', +- 'Decrypted AS reply') ++msgs = ('Attempting optimistic preauth', ++ 'Processing preauth types: -123', ++ '/induced optimistic fail', ++ 'Sending unauthenticated request', ++ '/Additional pre-authentication required', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: PA-FX-COOKIE (133), -123', ++ 'Decrypted AS reply') + realm.run(['./icred', '-o', '-123', '-X', 'fail_optimistic', realm.user_princ, + password('user')], expected_msg='testval', +- expected_trace=expected_trace) ++ expected_trace=msgs) + + # Test optimistic preauth failing on KDC, followed by successful preauth + # using the same module. + realm.run([kadminl, 'setstr', realm.user_princ, 'failopt', 'yes']) +-expected_trace = ('Attempting optimistic preauth', +- 'Processing preauth types: -123', +- 'Preauth module test (-123) (real) returned: 0/Success', +- 'Produced preauth for next request: -123', +- '/Preauthentication failed', +- 'Preauthenticating using KDC method data', +- 'Processing preauth types:', +- 'Preauth module test (-123) (real) returned: 0/Success', +- 'Produced preauth for next request: 133, -123', +- 'Decrypted AS reply') ++msgs = ('Attempting optimistic preauth', ++ 'Processing preauth types: -123', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: -123', ++ '/Preauthentication failed', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: PA-FX-COOKIE (133), -123', ++ 'Decrypted AS reply') + realm.run(['./icred', '-o', '-123', realm.user_princ, password('user')], +- expected_msg='testval', expected_trace=expected_trace) ++ expected_msg='testval', expected_trace=msgs) + realm.run([kadminl, 'delstr', realm.user_princ, 'failopt']) + + # Test KDC_ERR_MORE_PREAUTH_DATA_REQUIRED and secure cookies. + realm.run([kadminl, 'setstr', realm.user_princ, '2rt', 'secondtrip']) +-expected_trace = ('Sending unauthenticated request', +- '/Additional pre-authentication required', +- 'Preauthenticating using KDC method data', +- 'Processing preauth types:', +- 'Preauth module test (-123) (real) returned: 0/Success', +- 'Produced preauth for next request: 133, -123', +- '/More preauthentication data is required', +- 'Continuing preauth mech -123', +- 'Processing preauth types: -123, 133', +- 'Produced preauth for next request: 133, -123', +- 'Decrypted AS reply') ++msgs = ('Sending unauthenticated request', ++ '/Additional pre-authentication required', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: PA-FX-COOKIE (133), -123', ++ '/More preauthentication data is required', ++ 'Continuing preauth mech -123', ++ 'Processing preauth types: -123, PA-FX-COOKIE (133)', ++ 'Produced preauth for next request: PA-FX-COOKIE (133), -123', ++ 'Decrypted AS reply') + realm.run(['./icred', realm.user_princ, password('user')], +- expected_msg='2rt: secondtrip', expected_trace=expected_trace) ++ expected_msg='2rt: secondtrip', expected_trace=msgs) + + # Test client-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, + # falling back to encrypted timestamp. +-expected_trace = ('Sending unauthenticated request', +- '/Additional pre-authentication required', +- 'Preauthenticating using KDC method data', +- 'Processing preauth types:', +- 'Preauth module test (-123) (real) returned: 0/Success', +- 'Produced preauth for next request: 133, -123', +- '/More preauthentication data is required', +- 'Continuing preauth mech -123', +- 'Processing preauth types: -123, 133', +- '/induced 2rt fail', +- 'Preauthenticating using KDC method data', +- 'Processing preauth types:', +- 'Encrypted timestamp (for ', +- 'module encrypted_timestamp (2) (real) returned: 0/Success', +- 'Produced preauth for next request: 133, 2', +- 'Decrypted AS reply') ++msgs = ('Sending unauthenticated request', ++ '/Additional pre-authentication required', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: PA-FX-COOKIE (133), -123', ++ '/More preauthentication data is required', ++ 'Continuing preauth mech -123', ++ 'Processing preauth types: -123, PA-FX-COOKIE (133)', ++ '/induced 2rt fail', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Encrypted timestamp (for ', ++ 'module encrypted_timestamp (2) (real) returned: 0/Success', ++ 'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)', ++ 'Decrypted AS reply') + realm.run(['./icred', '-X', 'fail_2rt', realm.user_princ, password('user')], +- expected_msg='2rt: secondtrip', expected_trace=expected_trace) ++ expected_msg='2rt: secondtrip', expected_trace=msgs) + + # Test KDC-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, + # falling back to encrypted timestamp. + realm.run([kadminl, 'setstr', realm.user_princ, 'fail2rt', 'yes']) +-expected_trace = ('Sending unauthenticated request', +- '/Additional pre-authentication required', +- 'Preauthenticating using KDC method data', +- 'Processing preauth types:', +- 'Preauth module test (-123) (real) returned: 0/Success', +- 'Produced preauth for next request: 133, -123', +- '/More preauthentication data is required', +- 'Continuing preauth mech -123', +- 'Processing preauth types: -123, 133', +- 'Preauth module test (-123) (real) returned: 0/Success', +- 'Produced preauth for next request: 133, -123', +- '/Preauthentication failed', +- 'Preauthenticating using KDC method data', +- 'Processing preauth types:', +- 'Encrypted timestamp (for ', +- 'module encrypted_timestamp (2) (real) returned: 0/Success', +- 'Produced preauth for next request: 133, 2', +- 'Decrypted AS reply') ++msgs = ('Sending unauthenticated request', ++ '/Additional pre-authentication required', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: PA-FX-COOKIE (133), -123', ++ '/More preauthentication data is required', ++ 'Continuing preauth mech -123', ++ 'Processing preauth types: -123, PA-FX-COOKIE (133)', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: PA-FX-COOKIE (133), -123', ++ '/Preauthentication failed', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Encrypted timestamp (for ', ++ 'module encrypted_timestamp (2) (real) returned: 0/Success', ++ 'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)', ++ 'Decrypted AS reply') + realm.run(['./icred', realm.user_princ, password('user')], +- expected_msg='2rt: secondtrip', expected_trace=expected_trace) ++ expected_msg='2rt: secondtrip', expected_trace=msgs) + realm.run([kadminl, 'delstr', realm.user_princ, 'fail2rt']) + + # Test tryagain flow by inducing a KDC_ERR_ENCTYPE_NOSUPP error on the KDC. + realm.run([kadminl, 'setstr', realm.user_princ, 'err', 'testagain']) +-expected_trace = ('Sending unauthenticated request', +- '/Additional pre-authentication required', +- 'Preauthenticating using KDC method data', +- 'Processing preauth types:', +- 'Preauth module test (-123) (real) returned: 0/Success', +- 'Produced preauth for next request: 133, -123', +- '/KDC has no support for encryption type', +- 'Recovering from KDC error 14 using preauth mech -123', +- 'Preauth tryagain input types (-123): -123, 133', +- 'Preauth module test (-123) tryagain returned: 0/Success', +- 'Followup preauth for next request: -123, 133', +- 'Decrypted AS reply') ++msgs = ('Sending unauthenticated request', ++ '/Additional pre-authentication required', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: PA-FX-COOKIE (133), -123', ++ '/KDC has no support for encryption type', ++ 'Recovering from KDC error 14 using preauth mech -123', ++ 'Preauth tryagain input types (-123): -123, PA-FX-COOKIE (133)', ++ 'Preauth module test (-123) tryagain returned: 0/Success', ++ 'Followup preauth for next request: -123, PA-FX-COOKIE (133)', ++ 'Decrypted AS reply') + realm.run(['./icred', realm.user_princ, password('user')], +- expected_msg='tryagain: testagain', expected_trace=expected_trace) ++ expected_msg='tryagain: testagain', expected_trace=msgs) + + # Test a client-side tryagain failure, falling back to encrypted + # timestamp. +-expected_trace = ('Sending unauthenticated request', +- '/Additional pre-authentication required', +- 'Preauthenticating using KDC method data', +- 'Processing preauth types:', +- 'Preauth module test (-123) (real) returned: 0/Success', +- 'Produced preauth for next request: 133, -123', +- '/KDC has no support for encryption type', +- 'Recovering from KDC error 14 using preauth mech -123', +- 'Preauth tryagain input types (-123): -123, 133', +- '/induced tryagain fail', +- 'Preauthenticating using KDC method data', +- 'Processing preauth types:', +- 'Encrypted timestamp (for ', +- 'module encrypted_timestamp (2) (real) returned: 0/Success', +- 'Produced preauth for next request: 133, 2', +- 'Decrypted AS reply') ++msgs = ('Sending unauthenticated request', ++ '/Additional pre-authentication required', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Preauth module test (-123) (real) returned: 0/Success', ++ 'Produced preauth for next request: PA-FX-COOKIE (133), -123', ++ '/KDC has no support for encryption type', ++ 'Recovering from KDC error 14 using preauth mech -123', ++ 'Preauth tryagain input types (-123): -123, PA-FX-COOKIE (133)', ++ '/induced tryagain fail', ++ 'Preauthenticating using KDC method data', ++ 'Processing preauth types:', ++ 'Encrypted timestamp (for ', ++ 'module encrypted_timestamp (2) (real) returned: 0/Success', ++ 'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)', ++ 'Decrypted AS reply') + realm.run(['./icred', '-X', 'fail_tryagain', realm.user_princ, +- password('user')], expected_trace=expected_trace) ++ password('user')], expected_trace=msgs) + + # Test that multiple stepwise initial creds operations can be + # performed with the same krb5_context, with proper tracking of diff --git a/SOURCES/Limit-ticket-lifetime-to-2-31-1-seconds.patch b/SOURCES/Limit-ticket-lifetime-to-2-31-1-seconds.patch new file mode 100644 index 0000000..71cea7a --- /dev/null +++ b/SOURCES/Limit-ticket-lifetime-to-2-31-1-seconds.patch @@ -0,0 +1,203 @@ +From 5802408ab53a524f40f9a83a104f1d5f19ce5db0 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Thu, 24 Aug 2017 16:00:33 -0400 +Subject: [PATCH] Limit ticket lifetime to 2^31-1 seconds + +Although timestamps above 2^31-1 are now valid, intervals exceeding +2^31-1 seconds may be treated incorrectly by comparison operations. + +The initially computed interval in kdc_get_ticket_endtime() could be +negative if the requested end time is far in the future, causing the +function to yield an incorrect result. (With the new larger value of +kdc_infinity, this could specifically happen if a KDC-REQ contains a +zero till field.) Cap the interval at the maximum valid value. +Reported by Weijun Wang. + +Avoid delta comparisons in favor of timestamp comparions in +krb5int_validate_times(), ksu's krb5_check_exp(), and clockskew +checks. + +Also use a y2038-safe timestamp comparison in set_request_times() when +comparing the requested renewable end time to the requested ticket end +time. + +ticket: 8352 +(cherry picked from commit 54e58755368b58ba5894a14c1d02626da42d8003) +--- + src/clients/ksu/ccache.c | 2 +- + src/include/k5-int.h | 7 +++++++ + src/kdc/kdc_util.c | 7 ++++++- + src/kdc/replay.c | 2 +- + src/kdc/t_replay.c | 2 +- + src/lib/krb5/krb/gc_via_tkt.c | 4 ++-- + src/lib/krb5/krb/get_in_tkt.c | 6 +++--- + src/lib/krb5/krb/int-proto.h | 3 --- + src/lib/krb5/krb/valid_times.c | 4 ++-- + src/lib/krb5/os/timeofday.c | 2 +- + 10 files changed, 24 insertions(+), 15 deletions(-) + +diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c +index 236313b7b..2a99521d4 100644 +--- a/src/clients/ksu/ccache.c ++++ b/src/clients/ksu/ccache.c +@@ -282,7 +282,7 @@ krb5_error_code krb5_check_exp(context, tkt_time) + + } + +- if (ts_delta(currenttime, tkt_time.endtime) > context->clockskew) { ++ if (ts_after(currenttime, ts_incr(tkt_time.endtime, context->clockskew))) { + retval = KRB5KRB_AP_ERR_TKT_EXPIRED ; + return retval; + } +diff --git a/src/include/k5-int.h b/src/include/k5-int.h +index 39ffb9568..e31004a7c 100644 +--- a/src/include/k5-int.h ++++ b/src/include/k5-int.h +@@ -2386,6 +2386,13 @@ ts_after(krb5_timestamp a, krb5_timestamp b) + return (uint32_t)a > (uint32_t)b; + } + ++/* Return true if a and b are within d seconds. */ ++static inline krb5_boolean ++ts_within(krb5_timestamp a, krb5_timestamp b, krb5_deltat d) ++{ ++ return !ts_after(a, ts_incr(b, d)) && !ts_after(b, ts_incr(a, d)); ++} ++ + krb5_error_code KRB5_CALLCONV + krb5_get_credentials_for_user(krb5_context context, krb5_flags options, + krb5_ccache ccache, +diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c +index 5455e2a67..770163b94 100644 +--- a/src/kdc/kdc_util.c ++++ b/src/kdc/kdc_util.c +@@ -1759,14 +1759,19 @@ kdc_get_ticket_endtime(kdc_realm_t *kdc_active_realm, + krb5_db_entry *server, + krb5_timestamp *out_endtime) + { +- krb5_timestamp until, life; ++ krb5_timestamp until; ++ krb5_deltat life; + + if (till == 0) + till = kdc_infinity; + + until = ts_min(till, endtime); + ++ /* Determine the requested lifetime, capped at the maximum valid time ++ * interval. */ + life = ts_delta(until, starttime); ++ if (ts_after(until, starttime) && life < 0) ++ life = INT32_MAX; + + if (client != NULL && client->max_life != 0) + life = min(life, client->max_life); +diff --git a/src/kdc/replay.c b/src/kdc/replay.c +index fab39cf88..caca783bf 100644 +--- a/src/kdc/replay.c ++++ b/src/kdc/replay.c +@@ -61,7 +61,7 @@ static size_t total_size = 0; + static krb5_ui_4 seed; + + #define STALE_TIME (2*60) /* two minutes */ +-#define STALE(ptr, now) (labs(ts_delta((ptr)->timein, now)) >= STALE_TIME) ++#define STALE(ptr, now) (ts_after(now, ts_incr((ptr)->timein, STALE_TIME))) + + /* Return x rotated to the left by r bits. */ + static inline krb5_ui_4 +diff --git a/src/kdc/t_replay.c b/src/kdc/t_replay.c +index 1442e0e8c..bb7e2faff 100644 +--- a/src/kdc/t_replay.c ++++ b/src/kdc/t_replay.c +@@ -903,7 +903,7 @@ test_kdc_insert_lookaside_cache_expire(void **state) + assert_non_null(e); + e->num_hits = 5; + +- time_return(STALE_TIME, 0); ++ time_return(STALE_TIME + 1, 0); + kdc_insert_lookaside(context, &req2, NULL); + + assert_null(K5_LIST_FIRST(&hash_table[req_hash1])); +diff --git a/src/lib/krb5/krb/gc_via_tkt.c b/src/lib/krb5/krb/gc_via_tkt.c +index cf1ea361f..5b9bb9573 100644 +--- a/src/lib/krb5/krb/gc_via_tkt.c ++++ b/src/lib/krb5/krb/gc_via_tkt.c +@@ -306,8 +306,8 @@ krb5int_process_tgs_reply(krb5_context context, + goto cleanup; + + if (!in_cred->times.starttime && +- !in_clock_skew(context, dec_rep->enc_part2->times.starttime, +- timestamp)) { ++ !ts_within(dec_rep->enc_part2->times.starttime, timestamp, ++ context->clockskew)) { + retval = KRB5_KDCREP_SKEW; + goto cleanup; + } +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index 7178bd87b..ed15550f0 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -269,8 +269,8 @@ verify_as_reply(krb5_context context, + return retval; + } else { + if ((request->from == 0) && +- !in_clock_skew(context, as_reply->enc_part2->times.starttime, +- time_now)) ++ !ts_within(as_reply->enc_part2->times.starttime, time_now, ++ context->clockskew)) + return (KRB5_KDCREP_SKEW); + } + return 0; +@@ -781,7 +781,7 @@ set_request_times(krb5_context context, krb5_init_creds_context ctx) + if (ctx->renew_life > 0) { + /* Don't ask for a smaller renewable time than the lifetime. */ + ctx->request->rtime = ts_incr(from, ctx->renew_life); +- if (ctx->request->rtime < ctx->request->till) ++ if (ts_after(ctx->request->till, ctx->request->rtime)) + ctx->request->rtime = ctx->request->till; + ctx->request->kdc_options &= ~KDC_OPT_RENEWABLE_OK; + } else { +diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h +index 48bd9f8f7..9c746d05b 100644 +--- a/src/lib/krb5/krb/int-proto.h ++++ b/src/lib/krb5/krb/int-proto.h +@@ -83,9 +83,6 @@ krb5int_construct_matching_creds(krb5_context context, krb5_flags options, + krb5_creds *in_creds, krb5_creds *mcreds, + krb5_flags *fields); + +-#define in_clock_skew(context, date, now) \ +- (labs(ts_delta(date, now)) < (context)->clockskew) +- + #define IS_TGS_PRINC(p) ((p)->length == 2 && \ + data_eq_string((p)->data[0], KRB5_TGS_NAME)) + +diff --git a/src/lib/krb5/krb/valid_times.c b/src/lib/krb5/krb/valid_times.c +index 9e509b2dd..294761a88 100644 +--- a/src/lib/krb5/krb/valid_times.c ++++ b/src/lib/krb5/krb/valid_times.c +@@ -47,10 +47,10 @@ krb5int_validate_times(krb5_context context, krb5_ticket_times *times) + else + starttime = times->authtime; + +- if (ts_delta(starttime, currenttime) > context->clockskew) ++ if (ts_after(starttime, ts_incr(currenttime, context->clockskew))) + return KRB5KRB_AP_ERR_TKT_NYV; /* ticket not yet valid */ + +- if (ts_delta(currenttime, times->endtime) > context->clockskew) ++ if (ts_after(currenttime, ts_incr(times->endtime, context->clockskew))) + return KRB5KRB_AP_ERR_TKT_EXPIRED; /* ticket expired */ + + return 0; +diff --git a/src/lib/krb5/os/timeofday.c b/src/lib/krb5/os/timeofday.c +index 887f24c22..d4e36b1c7 100644 +--- a/src/lib/krb5/os/timeofday.c ++++ b/src/lib/krb5/os/timeofday.c +@@ -60,7 +60,7 @@ krb5_check_clockskew(krb5_context context, krb5_timestamp date) + retval = krb5_timeofday(context, ¤ttime); + if (retval) + return retval; +- if (labs(ts_delta(date, currenttime)) >= context->clockskew) ++ if (!ts_within(date, currenttime, context->clockskew)) + return KRB5KRB_AP_ERR_SKEW; + + return 0; diff --git a/SOURCES/Log-when-non-root-ksu-authorization-fails.patch b/SOURCES/Log-when-non-root-ksu-authorization-fails.patch new file mode 100644 index 0000000..dc631ba --- /dev/null +++ b/SOURCES/Log-when-non-root-ksu-authorization-fails.patch @@ -0,0 +1,35 @@ +From d5f22f9982dca7fa157d1d9b7488a671e0df72b8 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Mon, 7 May 2018 16:42:59 -0400 +Subject: [PATCH] Log when non-root ksu authorization fails + +If non-root user attempts to ksu but is denied by policy, log to +syslog at LOG_WARNING in keeping with other failure messages. + +ticket: 8270 +(cherry picked from commit 6cfa5c113e981f14f70ccafa20abfa5c46b665ba) +--- + src/clients/ksu/main.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c +index cab0c1806..7959a0cba 100644 +--- a/src/clients/ksu/main.c ++++ b/src/clients/ksu/main.c +@@ -417,6 +417,16 @@ main (argc, argv) + if (hp){ + if (gb_err) fprintf(stderr, "%s", gb_err); + fprintf(stderr, _("account %s: authorization failed\n"), target_user); ++ ++ if (cmd != NULL) { ++ syslog(LOG_WARNING, ++ "Account %s: authorization for %s for execution of %s failed", ++ target_user, source_user, cmd); ++ } else { ++ syslog(LOG_WARNING, "Account %s: authorization of %s failed", ++ target_user, source_user); ++ } ++ + exit(1); + } + diff --git a/SOURCES/Make-krb5_preauth_context-a-pointer-type.patch b/SOURCES/Make-krb5_preauth_context-a-pointer-type.patch new file mode 100644 index 0000000..aa7b15d --- /dev/null +++ b/SOURCES/Make-krb5_preauth_context-a-pointer-type.patch @@ -0,0 +1,140 @@ +From 3645da2a06ee69c846823e8335b5fd8a608f059a Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Tue, 20 Dec 2016 15:25:29 -0500 +Subject: [PATCH] Make krb5_preauth_context a pointer type + +For consistency with krb5_context and krb5_init_creds_context, make +krb5_preauth_context a pointer type. In preauth2.c, use the typedef +name rather than the structure tag except when defining the structure. + +(cherry picked from commit 459a081dec6e91ae480a37acb805631742afe1e2) +--- + src/include/k5-int.h | 4 ++-- + src/lib/krb5/krb/preauth2.c | 22 +++++++++++----------- + 2 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/src/include/k5-int.h b/src/include/k5-int.h +index e31004a7c..10b034037 100644 +--- a/src/include/k5-int.h ++++ b/src/include/k5-int.h +@@ -1198,7 +1198,7 @@ k5_plugin_free_context(krb5_context context); + struct _kdb5_dal_handle; /* private, in kdb5.h */ + typedef struct _kdb5_dal_handle kdb5_dal_handle; + struct _kdb_log_context; +-typedef struct krb5_preauth_context_st krb5_preauth_context; ++typedef struct krb5_preauth_context_st *krb5_preauth_context; + struct ccselect_module_handle; + struct localauth_module_handle; + struct hostrealm_module_handle; +@@ -1235,7 +1235,7 @@ struct _krb5_context { + struct plugin_dir_handle libkrb5_plugins; + + /* preauth module stuff */ +- krb5_preauth_context *preauth_context; ++ krb5_preauth_context preauth_context; + + /* cache module stuff */ + struct ccselect_module_handle **ccselect_handles; +diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c +index ca26fb0e3..b04d14829 100644 +--- a/src/lib/krb5/krb/preauth2.c ++++ b/src/lib/krb5/krb/preauth2.c +@@ -161,7 +161,7 @@ k5_init_preauth_context(krb5_context context) + list[count] = NULL; + + /* Place the constructed preauth context into the krb5 context. */ +- context->preauth_context = malloc(sizeof(struct krb5_preauth_context_st)); ++ context->preauth_context = malloc(sizeof(*context->preauth_context)); + if (context->preauth_context == NULL) + goto cleanup; + context->preauth_context->tried = NULL; +@@ -181,7 +181,7 @@ cleanup: + void + k5_reset_preauth_types_tried(krb5_context context) + { +- struct krb5_preauth_context_st *pctx = context->preauth_context; ++ krb5_preauth_context pctx = context->preauth_context; + + if (pctx == NULL) + return; +@@ -196,7 +196,7 @@ k5_reset_preauth_types_tried(krb5_context context) + void + k5_free_preauth_context(krb5_context context) + { +- struct krb5_preauth_context_st *pctx = context->preauth_context; ++ krb5_preauth_context pctx = context->preauth_context; + + if (pctx == NULL) + return; +@@ -211,7 +211,7 @@ k5_free_preauth_context(krb5_context context) + void + k5_preauth_request_context_init(krb5_context context) + { +- struct krb5_preauth_context_st *pctx = context->preauth_context; ++ krb5_preauth_context pctx = context->preauth_context; + clpreauth_handle *hp, h; + + if (pctx == NULL) { +@@ -233,7 +233,7 @@ k5_preauth_request_context_init(krb5_context context) + void + k5_preauth_request_context_fini(krb5_context context) + { +- struct krb5_preauth_context_st *pctx = context->preauth_context; ++ krb5_preauth_context pctx = context->preauth_context; + clpreauth_handle *hp, h; + + if (pctx == NULL) +@@ -495,7 +495,7 @@ void + k5_preauth_prepare_request(krb5_context context, krb5_get_init_creds_opt *opt, + krb5_kdc_req *req) + { +- struct krb5_preauth_context_st *pctx = context->preauth_context; ++ krb5_preauth_context pctx = context->preauth_context; + clpreauth_handle *hp, h; + krb5_enctype *ep; + +@@ -556,7 +556,7 @@ pa_type_allowed(krb5_init_creds_context ctx, krb5_preauthtype pa_type) + static krb5_boolean + already_tried(krb5_context context, krb5_preauthtype pa_type) + { +- struct krb5_preauth_context_st *pctx = context->preauth_context; ++ krb5_preauth_context pctx = context->preauth_context; + size_t count; + krb5_preauthtype *newptr; + +@@ -580,7 +580,7 @@ process_pa_data(krb5_context context, krb5_init_creds_context ctx, + krb5_pa_data ***out_pa_list, int *out_pa_list_size, + krb5_preauthtype *out_type) + { +- struct krb5_preauth_context_st *pctx = context->preauth_context; ++ krb5_preauth_context pctx = context->preauth_context; + struct errinfo save = EMPTY_ERRINFO; + krb5_pa_data *pa, **pa_ptr, **mod_pa; + krb5_error_code ret = 0; +@@ -858,7 +858,7 @@ krb5_error_code + k5_preauth_tryagain(krb5_context context, krb5_init_creds_context ctx, + krb5_pa_data **in_padata, krb5_pa_data ***padata_out) + { +- struct krb5_preauth_context_st *pctx = context->preauth_context; ++ krb5_preauth_context pctx = context->preauth_context; + krb5_error_code ret; + krb5_pa_data **mod_pa; + clpreauth_handle h; +@@ -897,7 +897,7 @@ static krb5_error_code + fill_response_items(krb5_context context, krb5_init_creds_context ctx, + krb5_pa_data **in_padata) + { +- struct krb5_preauth_context_st *pctx = context->preauth_context; ++ krb5_preauth_context pctx = context->preauth_context; + krb5_error_code ret; + krb5_pa_data *pa; + clpreauth_handle h; +@@ -1004,7 +1004,7 @@ krb5_preauth_supply_preauth_data(krb5_context context, + krb5_get_init_creds_opt *opt, + const char *attr, const char *value) + { +- struct krb5_preauth_context_st *pctx = context->preauth_context; ++ krb5_preauth_context pctx = context->preauth_context; + clpreauth_handle *hp, h; + krb5_error_code ret; + diff --git a/SOURCES/Make-timestamp-manipulations-y2038-safe.patch b/SOURCES/Make-timestamp-manipulations-y2038-safe.patch new file mode 100644 index 0000000..486d831 --- /dev/null +++ b/SOURCES/Make-timestamp-manipulations-y2038-safe.patch @@ -0,0 +1,1844 @@ +From e7358d93fa1cbe5db52e217d466894b1af96d95c Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Sat, 22 Apr 2017 12:52:17 -0400 +Subject: [PATCH] Make timestamp manipulations y2038-safe + +Wherever we manipulate krb5_timestamp values using arithmetic, +comparison operations, or conversion to time_t, use the new helper +functions in k5-int.h to ensure that the operations work after y2038 +and do not exhibit undefined behavior. (Relying on +implementation-defined conversion to signed values is okay as we test +that in configure.in.) + +In printf format strings, use %u instead of signed types. When +exporting creds with k5_json_array_fmt(), use a long long so that +timestamps after y2038 aren't marshalled as negative numbers. When +parsing timestamps in test programs, use atoll() instead of atol() so +that positive timestamps after y2038 can be used as input. + +In ksu and klist, make printtime() take a krb5_timestamp parameter to +avoid an unnecessary conversion to time_t and back. + +As Leash does not use k5-int.h, use time_t values internally and +safely convert from libkrb5 timestamp values. + +ticket: 8352 +(cherry picked from commit a9cbbf0899f270fbb14f63ffbed1b6d542333641) +--- + src/clients/kinit/kinit.c | 2 +- + src/clients/klist/klist.c | 20 ++++------ + src/clients/ksu/ccache.c | 20 +++------- + src/clients/ksu/ksu.h | 2 +- + src/kadmin/cli/getdate.y | 2 +- + src/kadmin/cli/kadmin.c | 5 +-- + src/kadmin/dbutil/dump.c | 27 +++++++------ + src/kadmin/dbutil/kdb5_mkey.c | 6 +-- + src/kadmin/dbutil/tabdump.c | 2 +- + src/kadmin/testing/util/tcl_kadm5.c | 12 +++--- + src/kdc/do_as_req.c | 2 +- + src/kdc/do_tgs_req.c | 6 +-- + src/kdc/extern.c | 4 +- + src/kdc/fast_util.c | 4 +- + src/kdc/kdc_log.c | 14 +++---- + src/kdc/kdc_util.c | 20 +++++----- + src/kdc/kdc_util.h | 2 + + src/kdc/replay.c | 2 +- + src/kdc/tgs_policy.c | 7 ++-- + src/lib/gssapi/krb5/accept_sec_context.c | 8 ++-- + src/lib/gssapi/krb5/acquire_cred.c | 13 +++--- + src/lib/gssapi/krb5/context_time.c | 2 +- + src/lib/gssapi/krb5/export_cred.c | 5 ++- + src/lib/gssapi/krb5/iakerb.c | 4 +- + src/lib/gssapi/krb5/init_sec_context.c | 9 +++-- + src/lib/gssapi/krb5/inq_context.c | 2 +- + src/lib/gssapi/krb5/inq_cred.c | 5 ++- + src/lib/gssapi/krb5/s4u_gss_glue.c | 2 +- + src/lib/kadm5/chpass_util.c | 8 +--- + src/lib/kadm5/srv/server_acl.c | 5 ++- + src/lib/kadm5/srv/svr_principal.c | 12 +++--- + src/lib/kdb/kdb5.c | 2 +- + src/lib/krb5/asn.1/asn1_k_encode.c | 3 +- + src/lib/krb5/ccache/cc_keyring.c | 14 ++++--- + src/lib/krb5/ccache/cc_memory.c | 4 +- + src/lib/krb5/ccache/cc_retr.c | 4 +- + src/lib/krb5/ccache/ccapi/stdcc_util.c | 40 +++++++++---------- + src/lib/krb5/ccache/cccursor.c | 2 +- + src/lib/krb5/keytab/kt_file.c | 6 ++- + src/lib/krb5/krb/gc_via_tkt.c | 7 ++-- + src/lib/krb5/krb/get_creds.c | 2 +- + src/lib/krb5/krb/get_in_tkt.c | 38 +++++------------- + src/lib/krb5/krb/gic_pwd.c | 4 +- + src/lib/krb5/krb/int-proto.h | 2 +- + src/lib/krb5/krb/pac.c | 2 +- + src/lib/krb5/krb/str_conv.c | 4 +- + src/lib/krb5/krb/t_kerb.c | 12 +----- + src/lib/krb5/krb/valid_times.c | 4 +- + src/lib/krb5/krb/vfy_increds.c | 2 +- + src/lib/krb5/os/timeofday.c | 2 +- + src/lib/krb5/os/toffset.c | 2 +- + src/lib/krb5/os/ustime.c | 6 +-- + src/lib/krb5/rcache/rc_dfl.c | 3 +- + src/lib/krb5/rcache/t_replay.c | 8 ++-- + src/plugins/kdb/db2/lockout.c | 8 ++-- + .../kdb/ldap/libkdb_ldap/ldap_principal2.c | 2 +- + src/plugins/kdb/ldap/libkdb_ldap/lockout.c | 8 ++-- + src/windows/cns/tktlist.c | 10 +++-- + src/windows/include/leashwin.h | 12 +++--- + src/windows/leash/KrbListTickets.cpp | 12 +++--- + src/windows/leash/LeashView.cpp | 22 +++++----- + src/windows/leashdll/lshfunc.c | 2 +- + src/windows/ms2mit/ms2mit.c | 2 +- + 63 files changed, 230 insertions(+), 255 deletions(-) + +diff --git a/src/clients/kinit/kinit.c b/src/clients/kinit/kinit.c +index f1cd1b73d..50065e32e 100644 +--- a/src/clients/kinit/kinit.c ++++ b/src/clients/kinit/kinit.c +@@ -318,7 +318,7 @@ parse_options(argc, argv, opts) + fprintf(stderr, _("Bad start time value %s\n"), optarg); + errflg++; + } else { +- opts->starttime = abs_starttime - time(0); ++ opts->starttime = ts_delta(abs_starttime, time(NULL)); + } + } + break; +diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c +index ba19788a2..ffeecc394 100644 +--- a/src/clients/klist/klist.c ++++ b/src/clients/klist/klist.c +@@ -72,7 +72,7 @@ void do_ccache_name (char *); + int show_ccache (krb5_ccache); + int check_ccache (krb5_ccache); + void do_keytab (char *); +-void printtime (time_t); ++void printtime (krb5_timestamp); + void one_addr (krb5_address *); + void fillit (FILE *, unsigned int, int); + +@@ -538,10 +538,10 @@ check_ccache(krb5_ccache cache) + while (!(ret = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) { + if (is_local_tgt(creds.server, &princ->realm)) { + found_tgt = TRUE; +- if (creds.times.endtime > now) ++ if (ts_after(creds.times.endtime, now)) + found_current_tgt = TRUE; + } else if (!krb5_is_config_principal(kcontext, creds.server) && +- creds.times.endtime > now) { ++ ts_after(creds.times.endtime, now)) { + found_current_cred = TRUE; + } + krb5_free_cred_contents(kcontext, &creds); +@@ -623,19 +623,13 @@ flags_string(cred) + } + + void +-printtime(tv) +- time_t tv; ++printtime(krb5_timestamp ts) + { +- char timestring[BUFSIZ]; +- char fill; ++ char timestring[BUFSIZ], fill = ' '; + +- fill = ' '; +- if (!krb5_timestamp_to_sfstring((krb5_timestamp) tv, +- timestring, +- timestamp_width+1, +- &fill)) { ++ if (!krb5_timestamp_to_sfstring(ts, timestring, timestamp_width + 1, ++ &fill)) + printf("%s", timestring); +- } + } + + static void +diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c +index a0736f2da..236313b7b 100644 +--- a/src/clients/ksu/ccache.c ++++ b/src/clients/ksu/ccache.c +@@ -278,11 +278,11 @@ krb5_error_code krb5_check_exp(context, tkt_time) + context->clockskew); + + fprintf(stderr,"krb5_check_exp: currenttime - endtime %d \n", +- (currenttime - tkt_time.endtime )); ++ ts_delta(currenttime, tkt_time.endtime)); + + } + +- if (currenttime - tkt_time.endtime > context->clockskew){ ++ if (ts_delta(currenttime, tkt_time.endtime) > context->clockskew) { + retval = KRB5KRB_AP_ERR_TKT_EXPIRED ; + return retval; + } +@@ -323,21 +323,11 @@ char *flags_string(cred) + return(buf); + } + +-void printtime(tv) +- time_t tv; ++void printtime(krb5_timestamp ts) + { +- char fmtbuf[18]; +- char fill; +- krb5_timestamp tstamp; ++ char fmtbuf[18], fill = ' '; + +- /* XXXX ASSUMES sizeof(krb5_timestamp) >= sizeof(time_t) */ +- (void) localtime((time_t *)&tv); +- tstamp = tv; +- fill = ' '; +- if (!krb5_timestamp_to_sfstring(tstamp, +- fmtbuf, +- sizeof(fmtbuf), +- &fill)) ++ if (!krb5_timestamp_to_sfstring(ts, fmtbuf, sizeof(fmtbuf), &fill)) + printf("%s", fmtbuf); + } + +diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h +index ee8e9d6a0..3bf0bd438 100644 +--- a/src/clients/ksu/ksu.h ++++ b/src/clients/ksu/ksu.h +@@ -150,7 +150,7 @@ extern krb5_boolean krb5_find_princ_in_cred_list + extern krb5_error_code krb5_find_princ_in_cache + (krb5_context, krb5_ccache, krb5_principal, krb5_boolean *); + +-extern void printtime (time_t); ++extern void printtime (krb5_timestamp); + + /* authorization.c */ + extern krb5_boolean fowner (FILE *, uid_t); +diff --git a/src/kadmin/cli/getdate.y b/src/kadmin/cli/getdate.y +index 4f0c56f7e..0a19c5648 100644 +--- a/src/kadmin/cli/getdate.y ++++ b/src/kadmin/cli/getdate.y +@@ -118,7 +118,7 @@ static int getdate_yyerror (char *); + + + #define EPOCH 1970 +-#define EPOCH_END 2038 /* assumes 32 bits */ ++#define EPOCH_END 2106 /* assumes unsigned 32-bit range */ + #define HOUR(x) ((time_t)(x) * 60) + #define SECSPERDAY (24L * 60L * 60L) + +diff --git a/src/kadmin/cli/kadmin.c b/src/kadmin/cli/kadmin.c +index c53c677a8..aee5c83b9 100644 +--- a/src/kadmin/cli/kadmin.c ++++ b/src/kadmin/cli/kadmin.c +@@ -31,8 +31,7 @@ + * library */ + + /* for "_" macro */ +-#include "k5-platform.h" +-#include ++#include "k5-int.h" + #include + #include + #include +@@ -144,8 +143,8 @@ strdate(krb5_timestamp when) + { + struct tm *tm; + static char out[40]; ++ time_t lcltim = ts2tt(when); + +- time_t lcltim = when; + tm = localtime(&lcltim); + strftime(out, sizeof(out), "%a %b %d %H:%M:%S %Z %Y", tm); + return out; +diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c +index cad53cfbf..a6fc4ea77 100644 +--- a/src/kadmin/dbutil/dump.c ++++ b/src/kadmin/dbutil/dump.c +@@ -379,11 +379,12 @@ k5beta7_common(krb5_context context, krb5_db_entry *entry, + fprintf(fp, "princ\t%d\t%lu\t%d\t%d\t%d\t%s\t", (int)entry->len, + (unsigned long)strlen(name), counter, (int)entry->n_key_data, + (int)entry->e_length, name); +- fprintf(fp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d", entry->attributes, +- entry->max_life, entry->max_renewable_life, entry->expiration, +- entry->pw_expiration, +- omit_nra ? 0 : entry->last_success, +- omit_nra ? 0 : entry->last_failed, ++ fprintf(fp, "%d\t%d\t%d\t%u\t%u\t%u\t%u\t%d", entry->attributes, ++ entry->max_life, entry->max_renewable_life, ++ (unsigned int)entry->expiration, ++ (unsigned int)entry->pw_expiration, ++ (unsigned int)(omit_nra ? 0 : entry->last_success), ++ (unsigned int)(omit_nra ? 0 : entry->last_failed), + omit_nra ? 0 : entry->fail_auth_count); + + /* Write out tagged data. */ +@@ -717,7 +718,7 @@ process_k5beta7_princ(krb5_context context, const char *fname, FILE *filep, + { + int retval, nread, i, j; + krb5_db_entry *dbentry; +- int t1, t2, t3, t4, t5, t6, t7; ++ int t1, t2, t3, t4; + unsigned int u1, u2, u3, u4, u5; + char *name = NULL; + krb5_key_data *kp = NULL, *kd; +@@ -773,8 +774,8 @@ process_k5beta7_princ(krb5_context context, const char *fname, FILE *filep, + } + + /* Get the fixed principal attributes */ +- nread = fscanf(filep, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t", +- &t1, &t2, &t3, &t4, &t5, &t6, &t7, &u1); ++ nread = fscanf(filep, "%d\t%d\t%d\t%u\t%u\t%d\t%d\t%d\t", ++ &t1, &t2, &t3, &u1, &u2, &u3, &u4, &u5); + if (nread != 8) { + load_err(fname, *linenop, _("cannot read principal attributes")); + goto fail; +@@ -782,11 +783,11 @@ process_k5beta7_princ(krb5_context context, const char *fname, FILE *filep, + dbentry->attributes = t1; + dbentry->max_life = t2; + dbentry->max_renewable_life = t3; +- dbentry->expiration = t4; +- dbentry->pw_expiration = t5; +- dbentry->last_success = t6; +- dbentry->last_failed = t7; +- dbentry->fail_auth_count = u1; ++ dbentry->expiration = u1; ++ dbentry->pw_expiration = u2; ++ dbentry->last_success = u3; ++ dbentry->last_failed = u4; ++ dbentry->fail_auth_count = u5; + dbentry->mask = KADM5_LOAD | KADM5_PRINCIPAL | KADM5_ATTRIBUTES | + KADM5_MAX_LIFE | KADM5_MAX_RLIFE | + KADM5_PRINC_EXPIRE_TIME | KADM5_LAST_SUCCESS | +diff --git a/src/kadmin/dbutil/kdb5_mkey.c b/src/kadmin/dbutil/kdb5_mkey.c +index 7df8cbc83..2efe3176e 100644 +--- a/src/kadmin/dbutil/kdb5_mkey.c ++++ b/src/kadmin/dbutil/kdb5_mkey.c +@@ -44,8 +44,8 @@ static char *strdate(krb5_timestamp when) + { + struct tm *tm; + static char out[40]; ++ time_t lcltim = ts2tt(when); + +- time_t lcltim = when; + tm = localtime(&lcltim); + strftime(out, sizeof(out), "%a %b %d %H:%M:%S %Z %Y", tm); + return out; +@@ -481,7 +481,7 @@ kdb5_use_mkey(int argc, char *argv[]) + cur_actkvno != NULL; + prev_actkvno = cur_actkvno, cur_actkvno = cur_actkvno->next) { + +- if (new_actkvno->act_time < cur_actkvno->act_time) { ++ if (ts_after(cur_actkvno->act_time, new_actkvno->act_time)) { + if (prev_actkvno) { + prev_actkvno->next = new_actkvno; + new_actkvno->next = cur_actkvno; +@@ -499,7 +499,7 @@ kdb5_use_mkey(int argc, char *argv[]) + } + } + +- if (actkvno_list->act_time > now) { ++ if (ts_after(actkvno_list->act_time, now)) { + com_err(progname, EINVAL, + _("there must be one master key currently active")); + exit_status++; +diff --git a/src/kadmin/dbutil/tabdump.c b/src/kadmin/dbutil/tabdump.c +index 69a3482ec..fb36b060a 100644 +--- a/src/kadmin/dbutil/tabdump.c ++++ b/src/kadmin/dbutil/tabdump.c +@@ -148,7 +148,7 @@ write_date_iso(struct rec_args *args, krb5_timestamp when) + struct tm *tm = NULL; + struct rechandle *h = args->rh; + +- t = when; ++ t = ts2tt(when); + tm = gmtime(&t); + if (tm == NULL) { + errno = EINVAL; +diff --git a/src/kadmin/testing/util/tcl_kadm5.c b/src/kadmin/testing/util/tcl_kadm5.c +index a4997c60c..9dde579ef 100644 +--- a/src/kadmin/testing/util/tcl_kadm5.c ++++ b/src/kadmin/testing/util/tcl_kadm5.c +@@ -697,13 +697,13 @@ static Tcl_DString *unparse_principal_ent(kadm5_principal_ent_t princ, + } else + Tcl_DStringAppendElement(str, "null"); + +- sprintf(buf, "%d", princ->princ_expire_time); ++ sprintf(buf, "%u", (unsigned int)princ->princ_expire_time); + Tcl_DStringAppendElement(str, buf); + +- sprintf(buf, "%d", princ->last_pwd_change); ++ sprintf(buf, "%u", (unsigned int)princ->last_pwd_change); + Tcl_DStringAppendElement(str, buf); + +- sprintf(buf, "%d", princ->pw_expiration); ++ sprintf(buf, "%u", (unsigned int)princ->pw_expiration); + Tcl_DStringAppendElement(str, buf); + + sprintf(buf, "%d", princ->max_life); +@@ -722,7 +722,7 @@ static Tcl_DString *unparse_principal_ent(kadm5_principal_ent_t princ, + } else + Tcl_DStringAppendElement(str, "null"); + +- sprintf(buf, "%d", princ->mod_date); ++ sprintf(buf, "%u", (unsigned int)princ->mod_date); + Tcl_DStringAppendElement(str, buf); + + if (mask & KADM5_ATTRIBUTES) { +@@ -758,10 +758,10 @@ static Tcl_DString *unparse_principal_ent(kadm5_principal_ent_t princ, + sprintf(buf, "%d", princ->max_renewable_life); + Tcl_DStringAppendElement(str, buf); + +- sprintf(buf, "%d", princ->last_success); ++ sprintf(buf, "%u", (unsigned int)princ->last_success); + Tcl_DStringAppendElement(str, buf); + +- sprintf(buf, "%d", princ->last_failed); ++ sprintf(buf, "%u", (unsigned int)princ->last_failed); + Tcl_DStringAppendElement(str, buf); + + sprintf(buf, "%d", princ->fail_auth_count); +diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c +index 712ccb794..59a39cd30 100644 +--- a/src/kdc/do_as_req.c ++++ b/src/kdc/do_as_req.c +@@ -87,7 +87,7 @@ get_key_exp(krb5_db_entry *entry) + return entry->pw_expiration; + if (entry->pw_expiration == 0) + return entry->expiration; +- return min(entry->expiration, entry->pw_expiration); ++ return ts_min(entry->expiration, entry->pw_expiration); + } + + /* +diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c +index 547a41441..aacd2f20d 100644 +--- a/src/kdc/do_tgs_req.c ++++ b/src/kdc/do_tgs_req.c +@@ -500,12 +500,12 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt, + + old_starttime = enc_tkt_reply.times.starttime ? + enc_tkt_reply.times.starttime : enc_tkt_reply.times.authtime; +- old_life = enc_tkt_reply.times.endtime - old_starttime; ++ old_life = ts_delta(enc_tkt_reply.times.endtime, old_starttime); + + enc_tkt_reply.times.starttime = kdc_time; + enc_tkt_reply.times.endtime = +- min(header_ticket->enc_part2->times.renew_till, +- kdc_time + old_life); ++ ts_min(header_ticket->enc_part2->times.renew_till, ++ ts_incr(kdc_time, old_life)); + } else { + /* not a renew request */ + enc_tkt_reply.times.starttime = kdc_time; +diff --git a/src/kdc/extern.c b/src/kdc/extern.c +index fe627494b..84b5c6ad5 100644 +--- a/src/kdc/extern.c ++++ b/src/kdc/extern.c +@@ -37,6 +37,8 @@ + kdc_realm_t **kdc_realmlist = (kdc_realm_t **) NULL; + int kdc_numrealms = 0; + krb5_data empty_string = {0, 0, ""}; +-krb5_timestamp kdc_infinity = KRB5_INT32_MAX; /* XXX */ + krb5_keyblock psr_key; + krb5_int32 max_dgram_reply_size = MAX_DGRAM_SIZE; ++ ++/* With ts_after(), this is the largest timestamp value. */ ++krb5_timestamp kdc_infinity = -1; +diff --git a/src/kdc/fast_util.c b/src/kdc/fast_util.c +index 9df940219..e05107ef3 100644 +--- a/src/kdc/fast_util.c ++++ b/src/kdc/fast_util.c +@@ -607,7 +607,7 @@ kdc_fast_read_cookie(krb5_context context, struct kdc_request_state *state, + ret = krb5_timeofday(context, &now); + if (ret) + goto cleanup; +- if (now - COOKIE_LIFETIME > cookie->time) { ++ if (ts2tt(now) > cookie->time + COOKIE_LIFETIME) { + /* Don't accept the cookie contents. Only return an error if the + * cookie is relevant to the request. */ + if (is_relevant(cookie->data, req->padata)) +@@ -700,7 +700,7 @@ kdc_fast_make_cookie(krb5_context context, struct kdc_request_state *state, + ret = krb5_timeofday(context, &now); + if (ret) + goto cleanup; +- cookie.time = now; ++ cookie.time = ts2tt(now); + cookie.data = contents; + ret = encode_krb5_secure_cookie(&cookie, &der_cookie); + if (ret) +diff --git a/src/kdc/kdc_log.c b/src/kdc/kdc_log.c +index 94a2a1c87..c044a3553 100644 +--- a/src/kdc/kdc_log.c ++++ b/src/kdc/kdc_log.c +@@ -79,9 +79,9 @@ log_as_req(krb5_context context, const krb5_fulladdr *from, + /* success */ + char rep_etypestr[128]; + rep_etypes2str(rep_etypestr, sizeof(rep_etypestr), reply); +- krb5_klog_syslog(LOG_INFO, _("AS_REQ (%s) %s: ISSUE: authtime %d, %s, " ++ krb5_klog_syslog(LOG_INFO, _("AS_REQ (%s) %s: ISSUE: authtime %u, %s, " + "%s for %s"), +- ktypestr, fromstring, authtime, ++ ktypestr, fromstring, (unsigned int)authtime, + rep_etypestr, cname2, sname2); + } else { + /* fail */ +@@ -156,10 +156,10 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from, + name (useful), and doesn't log ktypestr (probably not + important). */ + if (errcode != KRB5KDC_ERR_SERVER_NOMATCH) { +- krb5_klog_syslog(LOG_INFO, _("TGS_REQ (%s) %s: %s: authtime %d, %s%s " ++ krb5_klog_syslog(LOG_INFO, _("TGS_REQ (%s) %s: %s: authtime %u, %s%s " + "%s for %s%s%s"), +- ktypestr, fromstring, status, authtime, rep_etypestr, +- !errcode ? "," : "", logcname, logsname, ++ ktypestr, fromstring, status, (unsigned int)authtime, ++ rep_etypestr, !errcode ? "," : "", logcname, logsname, + errcode ? ", " : "", errcode ? emsg : ""); + if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION)) + krb5_klog_syslog(LOG_INFO, +@@ -171,9 +171,9 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from, + logaltcname); + + } else +- krb5_klog_syslog(LOG_INFO, _("TGS_REQ %s: %s: authtime %d, %s for %s, " ++ krb5_klog_syslog(LOG_INFO, _("TGS_REQ %s: %s: authtime %u, %s for %s, " + "2nd tkt client %s"), +- fromstring, status, authtime, ++ fromstring, status, (unsigned int)authtime, + logcname, logsname, logaltcname); + + /* OpenSolaris: audit_krb5kdc_tgs_req(...) or +diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c +index 29f9dbbf0..778a629e5 100644 +--- a/src/kdc/kdc_util.c ++++ b/src/kdc/kdc_util.c +@@ -654,7 +654,7 @@ validate_as_request(kdc_realm_t *kdc_active_realm, + } + + /* The client must not be expired */ +- if (client.expiration && client.expiration < kdc_time) { ++ if (client.expiration && ts_after(kdc_time, client.expiration)) { + *status = "CLIENT EXPIRED"; + if (vague_errors) + return(KRB_ERR_GENERIC); +@@ -664,7 +664,7 @@ validate_as_request(kdc_realm_t *kdc_active_realm, + + /* The client's password must not be expired, unless the server is + a KRB5_KDC_PWCHANGE_SERVICE. */ +- if (client.pw_expiration && client.pw_expiration < kdc_time && ++ if (client.pw_expiration && ts_after(kdc_time, client.pw_expiration) && + !isflagset(server.attributes, KRB5_KDB_PWCHANGE_SERVICE)) { + *status = "CLIENT KEY EXPIRED"; + if (vague_errors) +@@ -674,7 +674,7 @@ validate_as_request(kdc_realm_t *kdc_active_realm, + } + + /* The server must not be expired */ +- if (server.expiration && server.expiration < kdc_time) { ++ if (server.expiration && ts_after(kdc_time, server.expiration)) { + *status = "SERVICE EXPIRED"; + return(KDC_ERR_SERVICE_EXP); + } +@@ -1765,9 +1765,9 @@ kdc_get_ticket_endtime(kdc_realm_t *kdc_active_realm, + if (till == 0) + till = kdc_infinity; + +- until = min(till, endtime); ++ until = ts_min(till, endtime); + +- life = until - starttime; ++ life = ts_delta(until, starttime); + + if (client != NULL && client->max_life != 0) + life = min(life, client->max_life); +@@ -1776,7 +1776,7 @@ kdc_get_ticket_endtime(kdc_realm_t *kdc_active_realm, + if (kdc_active_realm->realm_maxlife != 0) + life = min(life, kdc_active_realm->realm_maxlife); + +- *out_endtime = starttime + life; ++ *out_endtime = ts_incr(starttime, life); + } + + /* +@@ -1806,22 +1806,22 @@ kdc_get_ticket_renewtime(kdc_realm_t *realm, krb5_kdc_req *request, + if (isflagset(request->kdc_options, KDC_OPT_RENEWABLE)) + rtime = request->rtime ? request->rtime : kdc_infinity; + else if (isflagset(request->kdc_options, KDC_OPT_RENEWABLE_OK) && +- tkt->times.endtime < request->till) ++ ts_after(request->till, tkt->times.endtime)) + rtime = request->till; + else + return; + + /* Truncate it to the allowable renewable time. */ + if (tgt != NULL) +- rtime = min(rtime, tgt->times.renew_till); ++ rtime = ts_min(rtime, tgt->times.renew_till); + max_rlife = min(server->max_renewable_life, realm->realm_maxrlife); + if (client != NULL) + max_rlife = min(max_rlife, client->max_renewable_life); +- rtime = min(rtime, tkt->times.starttime + max_rlife); ++ rtime = ts_min(rtime, ts_incr(tkt->times.starttime, max_rlife)); + + /* Make the ticket renewable if the truncated requested time is larger than + * the ticket end time. */ +- if (rtime > tkt->times.endtime) { ++ if (ts_after(rtime, tkt->times.endtime)) { + setflag(tkt->flags, TKT_FLG_RENEWABLE); + tkt->times.renew_till = rtime; + } +diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h +index bcf05fc27..672f94380 100644 +--- a/src/kdc/kdc_util.h ++++ b/src/kdc/kdc_util.h +@@ -452,6 +452,8 @@ struct krb5_kdcpreauth_rock_st { + #define max(a, b) ((a) > (b) ? (a) : (b)) + #endif + ++#define ts_min(a, b) (ts_after(a, b) ? (b) : (a)) ++ + #define ADDRTYPE2FAMILY(X) \ + ((X) == ADDRTYPE_INET6 ? AF_INET6 : (X) == ADDRTYPE_INET ? AF_INET : -1) + +diff --git a/src/kdc/replay.c b/src/kdc/replay.c +index 8da7ac19a..fab39cf88 100644 +--- a/src/kdc/replay.c ++++ b/src/kdc/replay.c +@@ -61,7 +61,7 @@ static size_t total_size = 0; + static krb5_ui_4 seed; + + #define STALE_TIME (2*60) /* two minutes */ +-#define STALE(ptr, now) (abs((ptr)->timein - (now)) >= STALE_TIME) ++#define STALE(ptr, now) (labs(ts_delta((ptr)->timein, now)) >= STALE_TIME) + + /* Return x rotated to the left by r bits. */ + static inline krb5_ui_4 +diff --git a/src/kdc/tgs_policy.c b/src/kdc/tgs_policy.c +index a30cacc66..d0f25d1b7 100644 +--- a/src/kdc/tgs_policy.c ++++ b/src/kdc/tgs_policy.c +@@ -186,7 +186,7 @@ static int + check_tgs_svc_time(krb5_kdc_req *req, krb5_db_entry server, krb5_ticket *tkt, + krb5_timestamp kdc_time, const char **status) + { +- if (server.expiration && server.expiration < kdc_time) { ++ if (server.expiration && ts_after(kdc_time, server.expiration)) { + *status = "SERVICE EXPIRED"; + return KDC_ERR_SERVICE_EXP; + } +@@ -222,7 +222,7 @@ check_tgs_times(krb5_kdc_req *req, krb5_ticket_times *times, + KDC time. */ + if (req->kdc_options & KDC_OPT_VALIDATE) { + starttime = times->starttime ? times->starttime : times->authtime; +- if (starttime > kdc_time) { ++ if (ts_after(starttime, kdc_time)) { + *status = "NOT_YET_VALID"; + return KRB_AP_ERR_TKT_NYV; + } +@@ -231,7 +231,8 @@ check_tgs_times(krb5_kdc_req *req, krb5_ticket_times *times, + * Check the renew_till time. The endtime was already + * been checked in the initial authentication check. + */ +- if ((req->kdc_options & KDC_OPT_RENEW) && times->renew_till < kdc_time) { ++ if ((req->kdc_options & KDC_OPT_RENEW) && ++ ts_after(kdc_time, times->renew_till)) { + *status = "TKT_EXPIRED"; + return KRB_AP_ERR_TKT_EXPIRED; + } +diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c +index 580d08cbf..06967aa27 100644 +--- a/src/lib/gssapi/krb5/accept_sec_context.c ++++ b/src/lib/gssapi/krb5/accept_sec_context.c +@@ -351,8 +351,10 @@ kg_accept_dce(minor_status, context_handle, verifier_cred_handle, + if (mech_type) + *mech_type = ctx->mech_used; + +- if (time_rec) +- *time_rec = ctx->krb_times.endtime + ctx->k5_context->clockskew - now; ++ if (time_rec) { ++ *time_rec = ts_delta(ctx->krb_times.endtime, now) + ++ ctx->k5_context->clockskew; ++ } + + /* Never return GSS_C_DELEG_FLAG since we don't support DCE credential + * delegation yet. */ +@@ -1146,7 +1148,7 @@ kg_accept_krb5(minor_status, context_handle, + /* Add the maximum allowable clock skew as a grace period for context + * expiration, just as we do for the ticket. */ + if (time_rec) +- *time_rec = ctx->krb_times.endtime + context->clockskew - now; ++ *time_rec = ts_delta(ctx->krb_times.endtime, now) + context->clockskew; + + if (ret_flags) + *ret_flags = ctx->gss_flags; +diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c +index 03ee25ec1..362ba9d86 100644 +--- a/src/lib/gssapi/krb5/acquire_cred.c ++++ b/src/lib/gssapi/krb5/acquire_cred.c +@@ -550,7 +550,7 @@ set_refresh_time(krb5_context context, krb5_ccache ccache, + char buf[128]; + krb5_data d; + +- snprintf(buf, sizeof(buf), "%ld", (long)refresh_time); ++ snprintf(buf, sizeof(buf), "%u", (unsigned int)ts2tt(refresh_time)); + d = string2data(buf); + (void)krb5_cc_set_config(context, ccache, NULL, KRB5_CC_CONF_REFRESH_TIME, + &d); +@@ -566,8 +566,9 @@ kg_cred_time_to_refresh(krb5_context context, krb5_gss_cred_id_rec *cred) + + if (krb5_timeofday(context, &now)) + return FALSE; +- if (cred->refresh_time != 0 && now >= cred->refresh_time) { +- set_refresh_time(context, cred->ccache, cred->refresh_time + 30); ++ if (cred->refresh_time != 0 && !ts_after(cred->refresh_time, now)) { ++ set_refresh_time(context, cred->ccache, ++ ts_incr(cred->refresh_time, 30)); + return TRUE; + } + return FALSE; +@@ -586,7 +587,8 @@ kg_cred_set_initial_refresh(krb5_context context, krb5_gss_cred_id_rec *cred, + return; + + /* Make a note to refresh these when they are halfway to expired. */ +- refresh = times->starttime + (times->endtime - times->starttime) / 2; ++ refresh = ts_incr(times->starttime, ++ ts_delta(times->endtime, times->starttime) / 2); + set_refresh_time(context, cred->ccache, refresh); + } + +@@ -848,7 +850,8 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status, + GSS_C_NO_NAME); + if (GSS_ERROR(ret)) + goto error_out; +- *time_rec = (cred->expire > now) ? (cred->expire - now) : 0; ++ *time_rec = ts_after(cred->expire, now) ? ++ ts_delta(cred->expire, now) : 0; + k5_mutex_unlock(&cred->lock); + } + } +diff --git a/src/lib/gssapi/krb5/context_time.c b/src/lib/gssapi/krb5/context_time.c +index 450593288..1fdb5a16f 100644 +--- a/src/lib/gssapi/krb5/context_time.c ++++ b/src/lib/gssapi/krb5/context_time.c +@@ -51,7 +51,7 @@ krb5_gss_context_time(minor_status, context_handle, time_rec) + return(GSS_S_FAILURE); + } + +- lifetime = ctx->krb_times.endtime - now; ++ lifetime = ts_delta(ctx->krb_times.endtime, now); + if (!ctx->initiate) + lifetime += ctx->k5_context->clockskew; + if (lifetime <= 0) { +diff --git a/src/lib/gssapi/krb5/export_cred.c b/src/lib/gssapi/krb5/export_cred.c +index 652b2604b..8054e4a77 100644 +--- a/src/lib/gssapi/krb5/export_cred.c ++++ b/src/lib/gssapi/krb5/export_cred.c +@@ -410,10 +410,11 @@ json_kgcred(krb5_context context, krb5_gss_cred_id_t cred, + if (ret) + goto cleanup; + +- ret = k5_json_array_fmt(&array, "ivvbbvvvvbiivs", cred->usage, name, imp, ++ ret = k5_json_array_fmt(&array, "ivvbbvvvvbLLvs", cred->usage, name, imp, + cred->default_identity, cred->iakerb_mech, keytab, + rcache, ccache, ckeytab, cred->have_tgt, +- cred->expire, cred->refresh_time, etypes, ++ (long long)ts2tt(cred->expire), ++ (long long)ts2tt(cred->refresh_time), etypes, + cred->password); + if (ret) + goto cleanup; +diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c +index 2dc4d0c1a..bb1072fe4 100644 +--- a/src/lib/gssapi/krb5/iakerb.c ++++ b/src/lib/gssapi/krb5/iakerb.c +@@ -494,7 +494,7 @@ iakerb_tkt_creds_ctx(iakerb_ctx_id_t ctx, + if (code != 0) + goto cleanup; + +- creds.times.endtime = now + time_req; ++ creds.times.endtime = ts_incr(now, time_req); + } + + if (cred->name->ad_context != NULL) { +@@ -669,7 +669,7 @@ iakerb_get_initial_state(iakerb_ctx_id_t ctx, + if (code != 0) + goto cleanup; + +- in_creds.times.endtime = now + time_req; ++ in_creds.times.endtime = ts_incr(now, time_req); + } + + /* Make an AS request if we have no creds or it's time to refresh them. */ +diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c +index 70f7955ae..8e5cc37fb 100644 +--- a/src/lib/gssapi/krb5/init_sec_context.c ++++ b/src/lib/gssapi/krb5/init_sec_context.c +@@ -214,7 +214,8 @@ static krb5_error_code get_credentials(context, cred, server, now, + * boundaries) because accept_sec_context code is also similarly + * non-forgiving. + */ +- if (!krb5_gss_dbg_client_expcreds && result_creds->times.endtime < now) { ++ if (!krb5_gss_dbg_client_expcreds && ++ ts_after(now, result_creds->times.endtime)) { + code = KRB5KRB_AP_ERR_TKT_EXPIRED; + goto cleanup; + } +@@ -575,7 +576,7 @@ kg_new_connection( + if (time_req == 0 || time_req == GSS_C_INDEFINITE) { + ctx->krb_times.endtime = 0; + } else { +- ctx->krb_times.endtime = now + time_req; ++ ctx->krb_times.endtime = ts_incr(now, time_req); + } + + if ((code = kg_duplicate_name(context, cred->name, &ctx->here))) +@@ -659,7 +660,7 @@ kg_new_connection( + if (time_rec) { + if ((code = krb5_timeofday(context, &now))) + goto cleanup; +- *time_rec = ctx->krb_times.endtime - now; ++ *time_rec = ts_delta(ctx->krb_times.endtime, now); + } + + /* set the other returns */ +@@ -873,7 +874,7 @@ mutual_auth( + if (time_rec) { + if ((code = krb5_timeofday(context, &now))) + goto fail; +- *time_rec = ctx->krb_times.endtime - now; ++ *time_rec = ts_delta(ctx->krb_times.endtime, now); + } + + if (ret_flags) +diff --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c +index d2e466e60..cac024da1 100644 +--- a/src/lib/gssapi/krb5/inq_context.c ++++ b/src/lib/gssapi/krb5/inq_context.c +@@ -120,7 +120,7 @@ krb5_gss_inquire_context(minor_status, context_handle, initiator_name, + + /* Add the maximum allowable clock skew as a grace period for context + * expiration, just as we do for the ticket during authentication. */ +- lifetime = ctx->krb_times.endtime - now; ++ lifetime = ts_delta(ctx->krb_times.endtime, now); + if (!ctx->initiate) + lifetime += context->clockskew; + if (lifetime < 0) +diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c +index 4e35a0563..e662ae53a 100644 +--- a/src/lib/gssapi/krb5/inq_cred.c ++++ b/src/lib/gssapi/krb5/inq_cred.c +@@ -130,8 +130,9 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret, + goto fail; + } + +- if (cred->expire > 0) { +- if ((lifetime = cred->expire - now) < 0) ++ if (cred->expire != 0) { ++ lifetime = ts_delta(cred->expire, now); ++ if (lifetime < 0) + lifetime = 0; + } + else +diff --git a/src/lib/gssapi/krb5/s4u_gss_glue.c b/src/lib/gssapi/krb5/s4u_gss_glue.c +index ff1c310bc..10848c1df 100644 +--- a/src/lib/gssapi/krb5/s4u_gss_glue.c ++++ b/src/lib/gssapi/krb5/s4u_gss_glue.c +@@ -284,7 +284,7 @@ kg_compose_deleg_cred(OM_uint32 *minor_status, + if (code != 0) + goto cleanup; + +- *time_rec = cred->expire - now; ++ *time_rec = ts_delta(cred->expire, now); + } + + major_status = GSS_S_COMPLETE; +diff --git a/src/lib/kadm5/chpass_util.c b/src/lib/kadm5/chpass_util.c +index 408b0eb31..1680a5504 100644 +--- a/src/lib/kadm5/chpass_util.c ++++ b/src/lib/kadm5/chpass_util.c +@@ -4,15 +4,11 @@ + */ + + +-#include "autoconf.h" +-#include +-#include +-#include ++#include "k5-int.h" + + #include + #include "admin_internal.h" + +-#include + + #define string_text error_message + +@@ -218,7 +214,7 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle, + time_t until; + char *time_string, *ptr; + +- until = princ_ent.last_pwd_change + policy_ent.pw_min_life; ++ until = ts_incr(princ_ent.last_pwd_change, policy_ent.pw_min_life); + + time_string = ctime(&until); + if (*(ptr = &time_string[strlen(time_string)-1]) == '\n') +diff --git a/src/lib/kadm5/srv/server_acl.c b/src/lib/kadm5/srv/server_acl.c +index 59ed0b975..656dddff5 100644 +--- a/src/lib/kadm5/srv/server_acl.c ++++ b/src/lib/kadm5/srv/server_acl.c +@@ -408,13 +408,14 @@ kadm5int_acl_impose_restrictions(kcontext, recp, maskp, rp) + } + if (rp->mask & KADM5_PRINC_EXPIRE_TIME) { + if (!(*maskp & KADM5_PRINC_EXPIRE_TIME) +- || (recp->princ_expire_time > (now + rp->princ_lifetime))) ++ || ts_after(recp->princ_expire_time, ++ ts_incr(now, rp->princ_lifetime))) + recp->princ_expire_time = now + rp->princ_lifetime; + *maskp |= KADM5_PRINC_EXPIRE_TIME; + } + if (rp->mask & KADM5_PW_EXPIRATION) { + if (!(*maskp & KADM5_PW_EXPIRATION) +- || (recp->pw_expiration > (now + rp->pw_lifetime))) ++ || ts_after(recp->pw_expiration, ts_incr(now, rp->pw_lifetime))) + recp->pw_expiration = now + rp->pw_lifetime; + *maskp |= KADM5_PW_EXPIRATION; + } +diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c +index 0640b47c4..f4a9a2ad2 100644 +--- a/src/lib/kadm5/srv/svr_principal.c ++++ b/src/lib/kadm5/srv/svr_principal.c +@@ -400,7 +400,7 @@ kadm5_create_principal_3(void *server_handle, + kdb->pw_expiration = 0; + if (have_polent) { + if(polent.pw_max_life) +- kdb->pw_expiration = now + polent.pw_max_life; ++ kdb->pw_expiration = ts_incr(now, polent.pw_max_life); + else + kdb->pw_expiration = 0; + } +@@ -612,7 +612,7 @@ kadm5_modify_principal(void *server_handle, + &(kdb->pw_expiration)); + if (ret) + goto done; +- kdb->pw_expiration += pol.pw_max_life; ++ kdb->pw_expiration = ts_incr(kdb->pw_expiration, pol.pw_max_life); + } else { + kdb->pw_expiration = 0; + } +@@ -1445,7 +1445,7 @@ kadm5_chpass_principal_3(void *server_handle, + } + + if (pol.pw_max_life) +- kdb->pw_expiration = now + pol.pw_max_life; ++ kdb->pw_expiration = ts_incr(now, pol.pw_max_life); + else + kdb->pw_expiration = 0; + } else { +@@ -1624,7 +1624,7 @@ kadm5_randkey_principal_3(void *server_handle, + #endif + + if (pol.pw_max_life) +- kdb->pw_expiration = now + pol.pw_max_life; ++ kdb->pw_expiration = ts_incr(now, pol.pw_max_life); + else + kdb->pw_expiration = 0; + } else { +@@ -1774,7 +1774,7 @@ kadm5_setv4key_principal(void *server_handle, + #endif + + if (pol.pw_max_life) +- kdb->pw_expiration = now + pol.pw_max_life; ++ kdb->pw_expiration = ts_incr(now, pol.pw_max_life); + else + kdb->pw_expiration = 0; + } else { +@@ -2024,7 +2024,7 @@ kadm5_setkey_principal_4(void *server_handle, krb5_principal principal, + } + if (have_pol) { + if (pol.pw_max_life) +- kdb->pw_expiration = now + pol.pw_max_life; ++ kdb->pw_expiration = ts_incr(now, pol.pw_max_life); + else + kdb->pw_expiration = 0; + } else { +diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c +index 4adf0fcbb..7f33c7e68 100644 +--- a/src/lib/kdb/kdb5.c ++++ b/src/lib/kdb/kdb5.c +@@ -1296,7 +1296,7 @@ find_actkvno(krb5_actkvno_node *list, krb5_timestamp now) + * are in the future, we will return the first node; if all are in the + * past, we will return the last node. + */ +- while (list->next != NULL && list->next->act_time <= now) ++ while (list->next != NULL && !ts_after(list->next->act_time, now)) + list = list->next; + return list->act_kvno; + } +diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c +index a827ca608..889460989 100644 +--- a/src/lib/krb5/asn.1/asn1_k_encode.c ++++ b/src/lib/krb5/asn.1/asn1_k_encode.c +@@ -158,8 +158,7 @@ static asn1_error_code + encode_kerberos_time(asn1buf *buf, const void *p, taginfo *rettag, + size_t *len_out) + { +- /* Range checking for time_t vs krb5_timestamp? */ +- time_t val = *(krb5_timestamp *)p; ++ time_t val = ts2tt(*(krb5_timestamp *)p); + rettag->asn1class = UNIVERSAL; + rettag->construction = PRIMITIVE; + rettag->tagnum = ASN1_GENERALTIME; +diff --git a/src/lib/krb5/ccache/cc_keyring.c b/src/lib/krb5/ccache/cc_keyring.c +index 4fe3f0d6f..fba710b1b 100644 +--- a/src/lib/krb5/ccache/cc_keyring.c ++++ b/src/lib/krb5/ccache/cc_keyring.c +@@ -751,7 +751,7 @@ update_keyring_expiration(krb5_context context, krb5_ccache id) + for (;;) { + if (krcc_next_cred(context, id, &cursor, &creds) != 0) + break; +- if (creds.times.endtime > endtime) ++ if (ts_after(creds.times.endtime, endtime)) + endtime = creds.times.endtime; + krb5_free_cred_contents(context, &creds); + } +@@ -765,7 +765,7 @@ update_keyring_expiration(krb5_context context, krb5_ccache id) + + /* Setting the timeout to zero would reset the timeout, so we set it to one + * second instead if creds are already expired. */ +- timeout = (endtime > now) ? endtime - now : 1; ++ timeout = ts_after(endtime, now) ? ts_delta(endtime, now) : 1; + (void)keyctl_set_timeout(data->cache_id, timeout); + } + +@@ -1316,8 +1316,10 @@ krcc_store(krb5_context context, krb5_ccache id, krb5_creds *creds) + if (ret) + goto errout; + +- if (creds->times.endtime > now) +- (void)keyctl_set_timeout(cred_key, creds->times.endtime - now); ++ if (ts_after(creds->times.endtime, now)) { ++ (void)keyctl_set_timeout(cred_key, ++ ts_delta(creds->times.endtime, now)); ++ } + + update_keyring_expiration(context, id); + +@@ -1680,8 +1682,8 @@ static void + krcc_update_change_time(krcc_data *data) + { + krb5_timestamp now_time = time(NULL); +- data->changetime = (data->changetime >= now_time) ? +- data->changetime + 1 : now_time; ++ data->changetime = ts_after(now_time, data->changetime) ? ++ now_time : ts_incr(data->changetime, 1); + } + + /* +diff --git a/src/lib/krb5/ccache/cc_memory.c b/src/lib/krb5/ccache/cc_memory.c +index 0354575c5..c5425eb3a 100644 +--- a/src/lib/krb5/ccache/cc_memory.c ++++ b/src/lib/krb5/ccache/cc_memory.c +@@ -720,8 +720,8 @@ static void + update_mcc_change_time(krb5_mcc_data *d) + { + krb5_timestamp now_time = time(NULL); +- d->changetime = (d->changetime >= now_time) ? +- d->changetime + 1 : now_time; ++ d->changetime = ts_after(now_time, d->changetime) ? ++ now_time : ts_incr(d->changetime, 1); + } + + static krb5_error_code KRB5_CALLCONV +diff --git a/src/lib/krb5/ccache/cc_retr.c b/src/lib/krb5/ccache/cc_retr.c +index 1314d24bd..1a32e00c8 100644 +--- a/src/lib/krb5/ccache/cc_retr.c ++++ b/src/lib/krb5/ccache/cc_retr.c +@@ -46,11 +46,11 @@ static krb5_boolean + times_match(const krb5_ticket_times *t1, const krb5_ticket_times *t2) + { + if (t1->renew_till) { +- if (t1->renew_till > t2->renew_till) ++ if (ts_after(t1->renew_till, t2->renew_till)) + return FALSE; /* this one expires too late */ + } + if (t1->endtime) { +- if (t1->endtime > t2->endtime) ++ if (ts_after(t1->endtime, t2->endtime)) + return FALSE; /* this one expires too late */ + } + /* only care about expiration on a times_match */ +diff --git a/src/lib/krb5/ccache/ccapi/stdcc_util.c b/src/lib/krb5/ccache/ccapi/stdcc_util.c +index 9f44af3d0..6092ee432 100644 +--- a/src/lib/krb5/ccache/ccapi/stdcc_util.c ++++ b/src/lib/krb5/ccache/ccapi/stdcc_util.c +@@ -16,8 +16,8 @@ + #include + #endif + ++#include "k5-int.h" + #include "stdcc_util.h" +-#include "krb5.h" + #ifdef _WIN32 /* it's part of krb5.h everywhere else */ + #include "kv5m_err.h" + #endif +@@ -321,10 +321,10 @@ copy_cc_cred_union_to_krb5_creds (krb5_context in_context, + keyblock_contents = NULL; + + /* copy times */ +- out_creds->times.authtime = cv5->authtime + offset_seconds; +- out_creds->times.starttime = cv5->starttime + offset_seconds; +- out_creds->times.endtime = cv5->endtime + offset_seconds; +- out_creds->times.renew_till = cv5->renew_till + offset_seconds; ++ out_creds->times.authtime = ts_incr(cv5->authtime, offset_seconds); ++ out_creds->times.starttime = ts_incr(cv5->starttime, offset_seconds); ++ out_creds->times.endtime = ts_incr(cv5->endtime, offset_seconds); ++ out_creds->times.renew_till = ts_incr(cv5->renew_till, offset_seconds); + out_creds->is_skey = cv5->is_skey; + out_creds->ticket_flags = cv5->ticket_flags; + +@@ -451,11 +451,11 @@ copy_krb5_creds_to_cc_cred_union (krb5_context in_context, + cv5->keyblock.data = keyblock_data; + keyblock_data = NULL; + +- cv5->authtime = in_creds->times.authtime - offset_seconds; +- cv5->starttime = in_creds->times.starttime - offset_seconds; +- cv5->endtime = in_creds->times.endtime - offset_seconds; +- cv5->renew_till = in_creds->times.renew_till - offset_seconds; +- cv5->is_skey = in_creds->is_skey; ++ cv5->authtime = ts_incr(in_creds->times.authtime, -offset_seconds); ++ cv5->starttime = ts_incr(in_creds->times.starttime, -offset_seconds); ++ cv5->endtime = ts_incr(in_creds->times.endtime, -offset_seconds); ++ cv5->renew_till = ts_incr(in_creds->times.renew_till, -offset_seconds); ++ cv5->is_skey = in_creds->is_skey; + cv5->ticket_flags = in_creds->ticket_flags; + + if (in_creds->ticket.data) { +@@ -732,10 +732,10 @@ void dupCCtoK5(krb5_context context, cc_creds *src, krb5_creds *dest) + err = krb5_get_time_offsets(context, &offset_seconds, &offset_microseconds); + if (err) return; + #endif +- dest->times.authtime = src->authtime + offset_seconds; +- dest->times.starttime = src->starttime + offset_seconds; +- dest->times.endtime = src->endtime + offset_seconds; +- dest->times.renew_till = src->renew_till + offset_seconds; ++ dest->times.authtime = ts_incr(src->authtime, offset_seconds); ++ dest->times.starttime = ts_incr(src->starttime, offset_seconds); ++ dest->times.endtime = ts_incr(src->endtime, offset_seconds); ++ dest->times.renew_till = ts_incr(src->renew_till, offset_seconds); + dest->is_skey = src->is_skey; + dest->ticket_flags = src->ticket_flags; + +@@ -804,10 +804,10 @@ void dupK5toCC(krb5_context context, krb5_creds *creds, cred_union **cu) + err = krb5_get_time_offsets(context, &offset_seconds, &offset_microseconds); + if (err) return; + #endif +- c->authtime = creds->times.authtime - offset_seconds; +- c->starttime = creds->times.starttime - offset_seconds; +- c->endtime = creds->times.endtime - offset_seconds; +- c->renew_till = creds->times.renew_till - offset_seconds; ++ c->authtime = ts_incr(creds->times.authtime, -offset_seconds); ++ c->starttime = ts_incr(creds->times.starttime, -offset_seconds); ++ c->endtime = ts_incr(creds->times.endtime, -offset_seconds); ++ c->renew_till = ts_incr(creds->times.renew_till, -offset_seconds); + c->is_skey = creds->is_skey; + c->ticket_flags = creds->ticket_flags; + +@@ -925,11 +925,11 @@ times_match(t1, t2) + register const krb5_ticket_times *t2; + { + if (t1->renew_till) { +- if (t1->renew_till > t2->renew_till) ++ if (ts_after(t1->renew_till, t2->renew_till)) + return FALSE; /* this one expires too late */ + } + if (t1->endtime) { +- if (t1->endtime > t2->endtime) ++ if (ts_after(t1->endtime, t2->endtime)) + return FALSE; /* this one expires too late */ + } + /* only care about expiration on a times_match */ +diff --git a/src/lib/krb5/ccache/cccursor.c b/src/lib/krb5/ccache/cccursor.c +index c31a3f5f0..e631f2051 100644 +--- a/src/lib/krb5/ccache/cccursor.c ++++ b/src/lib/krb5/ccache/cccursor.c +@@ -159,7 +159,7 @@ krb5_cccol_last_change_time(krb5_context context, + ret = krb5_cccol_cursor_next(context, c, &ccache); + if (ccache) { + ret = krb5_cc_last_change_time(context, ccache, &last_time); +- if (!ret && last_time > max_change_time) { ++ if (!ret && ts_after(last_time, max_change_time)) { + max_change_time = last_time; + } + ret = 0; +diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c +index 131549ffe..b014abf0b 100644 +--- a/src/lib/krb5/keytab/kt_file.c ++++ b/src/lib/krb5/keytab/kt_file.c +@@ -264,9 +264,11 @@ more_recent(const krb5_keytab_entry *k1, const krb5_keytab_entry *k2) + * limitations (8-bit kvno storage), pre-1.14 kadmin protocol limitations + * (8-bit kvno marshalling), or KDB limitations (16-bit kvno storage). + */ +- if (k1->timestamp >= k2->timestamp && k1->vno < 128 && k2->vno > 240) ++ if (!ts_after(k2->timestamp, k1->timestamp) && ++ k1->vno < 128 && k2->vno > 240) + return TRUE; +- if (k1->timestamp <= k2->timestamp && k1->vno > 240 && k2->vno < 128) ++ if (!ts_after(k1->timestamp, k2->timestamp) && ++ k1->vno > 240 && k2->vno < 128) + return FALSE; + + /* Otherwise do a simple version comparison. */ +diff --git a/src/lib/krb5/krb/gc_via_tkt.c b/src/lib/krb5/krb/gc_via_tkt.c +index c85d8b8d8..cf1ea361f 100644 +--- a/src/lib/krb5/krb/gc_via_tkt.c ++++ b/src/lib/krb5/krb/gc_via_tkt.c +@@ -287,18 +287,19 @@ krb5int_process_tgs_reply(krb5_context context, + retval = KRB5_KDCREP_MODIFIED; + + if ((in_cred->times.endtime != 0) && +- (dec_rep->enc_part2->times.endtime > in_cred->times.endtime)) ++ ts_after(dec_rep->enc_part2->times.endtime, in_cred->times.endtime)) + retval = KRB5_KDCREP_MODIFIED; + + if ((kdcoptions & KDC_OPT_RENEWABLE) && + (in_cred->times.renew_till != 0) && +- (dec_rep->enc_part2->times.renew_till > in_cred->times.renew_till)) ++ ts_after(dec_rep->enc_part2->times.renew_till, ++ in_cred->times.renew_till)) + retval = KRB5_KDCREP_MODIFIED; + + if ((kdcoptions & KDC_OPT_RENEWABLE_OK) && + (dec_rep->enc_part2->flags & KDC_OPT_RENEWABLE) && + (in_cred->times.endtime != 0) && +- (dec_rep->enc_part2->times.renew_till > in_cred->times.endtime)) ++ ts_after(dec_rep->enc_part2->times.renew_till, in_cred->times.endtime)) + retval = KRB5_KDCREP_MODIFIED; + + if (retval != 0) +diff --git a/src/lib/krb5/krb/get_creds.c b/src/lib/krb5/krb/get_creds.c +index 110abeb2b..be5b2d18c 100644 +--- a/src/lib/krb5/krb/get_creds.c ++++ b/src/lib/krb5/krb/get_creds.c +@@ -816,7 +816,7 @@ get_cached_local_tgt(krb5_context context, krb5_tkt_creds_context ctx, + return code; + + /* Check if the TGT is expired before bothering the KDC with it. */ +- if (now > tgt->times.endtime) { ++ if (ts_after(now, tgt->times.endtime)) { + krb5_free_creds(context, tgt); + return KRB5KRB_AP_ERR_TKT_EXPIRED; + } +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index a058f5bd7..40aba1905 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -39,24 +39,6 @@ static krb5_error_code sort_krb5_padata_sequence(krb5_context context, + krb5_data *realm, + krb5_pa_data **padata); + +-/* +- * This function performs 32 bit bounded addition so we can generate +- * lifetimes without overflowing krb5_int32 +- */ +-static krb5_int32 +-krb5int_addint32 (krb5_int32 x, krb5_int32 y) +-{ +- if ((x > 0) && (y > (KRB5_INT32_MAX - x))) { +- /* sum will be be greater than KRB5_INT32_MAX */ +- return KRB5_INT32_MAX; +- } else if ((x < 0) && (y < (KRB5_INT32_MIN - x))) { +- /* sum will be less than KRB5_INT32_MIN */ +- return KRB5_INT32_MIN; +- } +- +- return x + y; +-} +- + /* + * Decrypt the AS reply in ctx, populating ctx->reply->enc_part2. If + * strengthen_key is not null, combine it with the reply key as specified in +@@ -267,21 +249,21 @@ verify_as_reply(krb5_context context, + (request->from != 0) && + (request->from != as_reply->enc_part2->times.starttime)) + || ((request->till != 0) && +- (as_reply->enc_part2->times.endtime > request->till)) ++ ts_after(as_reply->enc_part2->times.endtime, request->till)) + || ((request->kdc_options & KDC_OPT_RENEWABLE) && + (request->rtime != 0) && +- (as_reply->enc_part2->times.renew_till > request->rtime)) ++ ts_after(as_reply->enc_part2->times.renew_till, request->rtime)) + || ((request->kdc_options & KDC_OPT_RENEWABLE_OK) && + !(request->kdc_options & KDC_OPT_RENEWABLE) && + (as_reply->enc_part2->flags & KDC_OPT_RENEWABLE) && + (request->till != 0) && +- (as_reply->enc_part2->times.renew_till > request->till)) ++ ts_after(as_reply->enc_part2->times.renew_till, request->till)) + ) { + return KRB5_KDCREP_MODIFIED; + } + + if (context->library_options & KRB5_LIBOPT_SYNC_KDCTIME) { +- time_offset = as_reply->enc_part2->times.authtime - time_now; ++ time_offset = ts_delta(as_reply->enc_part2->times.authtime, time_now); + retval = krb5_set_time_offsets(context, time_offset, 0); + if (retval) + return retval; +@@ -790,15 +772,15 @@ set_request_times(krb5_context context, krb5_init_creds_context ctx) + return code; + + /* Omit request start time unless the caller explicitly asked for one. */ +- from = krb5int_addint32(now, ctx->start_time); ++ from = ts_incr(now, ctx->start_time); + if (ctx->start_time != 0) + ctx->request->from = from; + +- ctx->request->till = krb5int_addint32(from, ctx->tkt_life); ++ ctx->request->till = ts_incr(from, ctx->tkt_life); + + if (ctx->renew_life > 0) { + /* Don't ask for a smaller renewable time than the lifetime. */ +- ctx->request->rtime = krb5int_addint32(from, ctx->renew_life); ++ ctx->request->rtime = ts_incr(from, ctx->renew_life); + if (ctx->request->rtime < ctx->request->till) + ctx->request->rtime = ctx->request->till; + ctx->request->kdc_options &= ~KDC_OPT_RENEWABLE_OK; +@@ -1438,7 +1420,7 @@ note_req_timestamp(krb5_context context, krb5_init_creds_context ctx, + + if (k5_time_with_offset(0, 0, &now, &usec) != 0) + return; +- ctx->pa_offset = kdc_time - now; ++ ctx->pa_offset = ts_delta(kdc_time, now); + ctx->pa_offset_usec = kdc_usec - usec; + ctx->pa_offset_state = (ctx->fast_state->armor_key != NULL) ? + AUTH_OFFSET : UNAUTH_OFFSET; +@@ -1807,6 +1789,7 @@ k5_populate_gic_opt(krb5_context context, krb5_get_init_creds_opt **out, + { + int i; + krb5_int32 starttime; ++ krb5_deltat lifetime; + krb5_get_init_creds_opt *opt; + krb5_error_code retval; + +@@ -1838,7 +1821,8 @@ k5_populate_gic_opt(krb5_context context, krb5_get_init_creds_opt **out, + if (retval) + goto cleanup; + if (creds->times.starttime) starttime = creds->times.starttime; +- krb5_get_init_creds_opt_set_tkt_life(opt, creds->times.endtime - starttime); ++ lifetime = ts_delta(creds->times.endtime, starttime); ++ krb5_get_init_creds_opt_set_tkt_life(opt, lifetime); + } + *out = opt; + return 0; +diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c +index 6f3a29f2c..3565a7c4c 100644 +--- a/src/lib/krb5/krb/gic_pwd.c ++++ b/src/lib/krb5/krb/gic_pwd.c +@@ -211,7 +211,7 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options, + if (ret != 0) + return; + if (!is_last_req && +- (pw_exp < now || (pw_exp - now) > 7 * 24 * 60 * 60)) ++ (ts_after(now, pw_exp) || ts_delta(pw_exp, now) > 7 * 24 * 60 * 60)) + return; + + if (!prompter) +@@ -221,7 +221,7 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options, + if (ret != 0) + return; + +- delta = pw_exp - now; ++ delta = ts_delta(pw_exp, now); + if (delta < 3600) { + snprintf(banner, sizeof(banner), + _("Warning: Your password will expire in less than one hour " +diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h +index 44eca359f..48bd9f8f7 100644 +--- a/src/lib/krb5/krb/int-proto.h ++++ b/src/lib/krb5/krb/int-proto.h +@@ -84,7 +84,7 @@ krb5int_construct_matching_creds(krb5_context context, krb5_flags options, + krb5_flags *fields); + + #define in_clock_skew(context, date, now) \ +- (labs((date) - (now)) < (context)->clockskew) ++ (labs(ts_delta(date, now)) < (context)->clockskew) + + #define IS_TGS_PRINC(p) ((p)->length == 2 && \ + data_eq_string((p)->data[0], KRB5_TGS_NAME)) +diff --git a/src/lib/krb5/krb/pac.c b/src/lib/krb5/krb/pac.c +index 9098927b5..c70585a9e 100644 +--- a/src/lib/krb5/krb/pac.c ++++ b/src/lib/krb5/krb/pac.c +@@ -378,7 +378,7 @@ k5_time_to_seconds_since_1970(int64_t ntTime, krb5_timestamp *elapsedSeconds) + + abstime = ntTime > 0 ? ntTime - NT_TIME_EPOCH : -ntTime; + +- if (abstime > KRB5_INT32_MAX) ++ if (abstime > UINT32_MAX) + return ERANGE; + + *elapsedSeconds = abstime; +diff --git a/src/lib/krb5/krb/str_conv.c b/src/lib/krb5/krb/str_conv.c +index 3ab7eacac..f0a2ae20b 100644 +--- a/src/lib/krb5/krb/str_conv.c ++++ b/src/lib/krb5/krb/str_conv.c +@@ -207,7 +207,7 @@ krb5_error_code KRB5_CALLCONV + krb5_timestamp_to_string(krb5_timestamp timestamp, char *buffer, size_t buflen) + { + size_t ret; +- time_t timestamp2 = timestamp; ++ time_t timestamp2 = ts2tt(timestamp); + struct tm tmbuf; + const char *fmt = "%c"; /* This is to get around gcc -Wall warning that + the year returned might be two digits */ +@@ -229,7 +229,7 @@ krb5_timestamp_to_sfstring(krb5_timestamp timestamp, char *buffer, size_t buflen + struct tm *tmp; + size_t i; + size_t ndone; +- time_t timestamp2 = timestamp; ++ time_t timestamp2 = ts2tt(timestamp); + struct tm tmbuf; + + static const char * const sftime_format_table[] = { +diff --git a/src/lib/krb5/krb/t_kerb.c b/src/lib/krb5/krb/t_kerb.c +index 60cfb5b15..74ac14d9a 100644 +--- a/src/lib/krb5/krb/t_kerb.c ++++ b/src/lib/krb5/krb/t_kerb.c +@@ -5,16 +5,8 @@ + */ + + #include "autoconf.h" +-#include "krb5.h" +-#include +-#include +-#include +-#include ++#include "k5-int.h" + #include +-#include +-#include +-#include +-#include + + #include "com_err.h" + +@@ -37,7 +29,7 @@ test_string_to_timestamp(krb5_context ctx, char *ktime) + com_err("krb5_string_to_timestamp", retval, 0); + return; + } +- t = (time_t) timestamp; ++ t = ts2tt(timestamp); + printf("Parsed time was %s", ctime(&t)); + } + +diff --git a/src/lib/krb5/krb/valid_times.c b/src/lib/krb5/krb/valid_times.c +index d63122183..9e509b2dd 100644 +--- a/src/lib/krb5/krb/valid_times.c ++++ b/src/lib/krb5/krb/valid_times.c +@@ -47,10 +47,10 @@ krb5int_validate_times(krb5_context context, krb5_ticket_times *times) + else + starttime = times->authtime; + +- if (starttime - currenttime > context->clockskew) ++ if (ts_delta(starttime, currenttime) > context->clockskew) + return KRB5KRB_AP_ERR_TKT_NYV; /* ticket not yet valid */ + +- if ((currenttime - times->endtime) > context->clockskew) ++ if (ts_delta(currenttime, times->endtime) > context->clockskew) + return KRB5KRB_AP_ERR_TKT_EXPIRED; /* ticket expired */ + + return 0; +diff --git a/src/lib/krb5/krb/vfy_increds.c b/src/lib/krb5/krb/vfy_increds.c +index 9786d63b5..b4878ba38 100644 +--- a/src/lib/krb5/krb/vfy_increds.c ++++ b/src/lib/krb5/krb/vfy_increds.c +@@ -120,7 +120,7 @@ get_vfy_cred(krb5_context context, krb5_creds *creds, krb5_principal server, + ret = krb5_timeofday(context, &in_creds.times.endtime); + if (ret) + goto cleanup; +- in_creds.times.endtime += 5*60; ++ in_creds.times.endtime = ts_incr(in_creds.times.endtime, 5 * 60); + ret = krb5_get_credentials(context, 0, ccache, &in_creds, &out_creds); + if (ret) + goto cleanup; +diff --git a/src/lib/krb5/os/timeofday.c b/src/lib/krb5/os/timeofday.c +index fddb12142..887f24c22 100644 +--- a/src/lib/krb5/os/timeofday.c ++++ b/src/lib/krb5/os/timeofday.c +@@ -60,7 +60,7 @@ krb5_check_clockskew(krb5_context context, krb5_timestamp date) + retval = krb5_timeofday(context, ¤ttime); + if (retval) + return retval; +- if (!(labs((date)-currenttime) < context->clockskew)) ++ if (labs(ts_delta(date, currenttime)) >= context->clockskew) + return KRB5KRB_AP_ERR_SKEW; + + return 0; +diff --git a/src/lib/krb5/os/toffset.c b/src/lib/krb5/os/toffset.c +index 456193a41..37bc69f49 100644 +--- a/src/lib/krb5/os/toffset.c ++++ b/src/lib/krb5/os/toffset.c +@@ -47,7 +47,7 @@ krb5_set_real_time(krb5_context context, krb5_timestamp seconds, krb5_int32 micr + if (retval) + return retval; + +- os_ctx->time_offset = seconds - sec; ++ os_ctx->time_offset = ts_delta(seconds, sec); + os_ctx->usec_offset = (microseconds > -1) ? microseconds - usec : 0; + + os_ctx->os_flags = ((os_ctx->os_flags & ~KRB5_OS_TOFFSET_TIME) | +diff --git a/src/lib/krb5/os/ustime.c b/src/lib/krb5/os/ustime.c +index 056357683..1c1b571eb 100644 +--- a/src/lib/krb5/os/ustime.c ++++ b/src/lib/krb5/os/ustime.c +@@ -49,13 +49,13 @@ k5_time_with_offset(krb5_timestamp offset, krb5_int32 offset_usec, + usec += offset_usec; + if (usec > 1000000) { + usec -= 1000000; +- sec++; ++ sec = ts_incr(sec, 1); + } + if (usec < 0) { + usec += 1000000; +- sec--; ++ sec = ts_incr(sec, -1); + } +- sec += offset; ++ sec = ts_incr(sec, offset); + + *time_out = sec; + *usec_out = usec; +diff --git a/src/lib/krb5/rcache/rc_dfl.c b/src/lib/krb5/rcache/rc_dfl.c +index c0f12ed9d..6b043844d 100644 +--- a/src/lib/krb5/rcache/rc_dfl.c ++++ b/src/lib/krb5/rcache/rc_dfl.c +@@ -97,8 +97,7 @@ alive(krb5_int32 mytime, krb5_donot_replay *new1, krb5_deltat t) + { + if (mytime == 0) + return CMP_HOHUM; /* who cares? */ +- /* I hope we don't have to worry about overflow */ +- if (new1->ctime + t < mytime) ++ if (ts_after(mytime, ts_incr(new1->ctime, t))) + return CMP_EXPIRED; + return CMP_HOHUM; + } +diff --git a/src/lib/krb5/rcache/t_replay.c b/src/lib/krb5/rcache/t_replay.c +index db273ec2f..b99cdf1ab 100644 +--- a/src/lib/krb5/rcache/t_replay.c ++++ b/src/lib/krb5/rcache/t_replay.c +@@ -110,7 +110,7 @@ store(krb5_context ctx, char *rcspec, char *client, char *server, char *msg, + krb5_donot_replay rep; + krb5_data d; + +- if (now_timestamp > 0) ++ if (now_timestamp != 0) + krb5_set_debugging_time(ctx, now_timestamp, now_usec); + if ((retval = krb5_rc_resolve_full(ctx, &rc, rcspec))) + goto cleanup; +@@ -221,13 +221,13 @@ main(int argc, char **argv) + msg = (**argv) ? *argv : NULL; + argc--; argv++; + if (!argc) usage(progname); +- timestamp = (krb5_timestamp) atol(*argv); ++ timestamp = (krb5_timestamp) atoll(*argv); + argc--; argv++; + if (!argc) usage(progname); + usec = (krb5_int32) atol(*argv); + argc--; argv++; + if (!argc) usage(progname); +- now_timestamp = (krb5_timestamp) atol(*argv); ++ now_timestamp = (krb5_timestamp) atoll(*argv); + argc--; argv++; + if (!argc) usage(progname); + now_usec = (krb5_int32) atol(*argv); +@@ -249,7 +249,7 @@ main(int argc, char **argv) + rcspec = *argv; + argc--; argv++; + if (!argc) usage(progname); +- now_timestamp = (krb5_timestamp) atol(*argv); ++ now_timestamp = (krb5_timestamp) atoll(*argv); + argc--; argv++; + if (!argc) usage(progname); + now_usec = (krb5_int32) atol(*argv); +diff --git a/src/plugins/kdb/db2/lockout.c b/src/plugins/kdb/db2/lockout.c +index 7d151b55b..3a4f41821 100644 +--- a/src/plugins/kdb/db2/lockout.c ++++ b/src/plugins/kdb/db2/lockout.c +@@ -100,7 +100,7 @@ locked_check_p(krb5_context context, + + /* If the entry was unlocked since the last failure, it's not locked. */ + if (krb5_dbe_lookup_last_admin_unlock(context, entry, &unlock_time) == 0 && +- entry->last_failed <= unlock_time) ++ !ts_after(entry->last_failed, unlock_time)) + return FALSE; + + if (max_fail == 0 || entry->fail_auth_count < max_fail) +@@ -109,7 +109,7 @@ locked_check_p(krb5_context context, + if (lockout_duration == 0) + return TRUE; /* principal permanently locked */ + +- return (stamp < entry->last_failed + lockout_duration); ++ return ts_after(ts_incr(entry->last_failed, lockout_duration), stamp); + } + + krb5_error_code +@@ -200,13 +200,13 @@ krb5_db2_lockout_audit(krb5_context context, + status == KRB5KRB_AP_ERR_BAD_INTEGRITY)) { + if (krb5_dbe_lookup_last_admin_unlock(context, entry, + &unlock_time) == 0 && +- entry->last_failed <= unlock_time) { ++ !ts_after(entry->last_failed, unlock_time)) { + /* Reset fail_auth_count after administrative unlock. */ + entry->fail_auth_count = 0; + } + + if (failcnt_interval != 0 && +- stamp > entry->last_failed + failcnt_interval) { ++ ts_after(stamp, ts_incr(entry->last_failed, failcnt_interval))) { + /* Reset fail_auth_count after failcnt_interval. */ + entry->fail_auth_count = 0; + } +diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c +index 7ba53f959..88a170495 100644 +--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c ++++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c +@@ -1734,7 +1734,7 @@ getstringtime(krb5_timestamp epochtime) + { + struct tm tme; + char *strtime=NULL; +- time_t posixtime = epochtime; ++ time_t posixtime = ts2tt(epochtime); + + strtime = calloc (50, 1); + if (strtime == NULL) +diff --git a/src/plugins/kdb/ldap/libkdb_ldap/lockout.c b/src/plugins/kdb/ldap/libkdb_ldap/lockout.c +index 0fc56c2fe..1088ecc5a 100644 +--- a/src/plugins/kdb/ldap/libkdb_ldap/lockout.c ++++ b/src/plugins/kdb/ldap/libkdb_ldap/lockout.c +@@ -93,7 +93,7 @@ locked_check_p(krb5_context context, + + /* If the entry was unlocked since the last failure, it's not locked. */ + if (krb5_dbe_lookup_last_admin_unlock(context, entry, &unlock_time) == 0 && +- entry->last_failed <= unlock_time) ++ !ts_after(entry->last_failed, unlock_time)) + return FALSE; + + if (max_fail == 0 || entry->fail_auth_count < max_fail) +@@ -102,7 +102,7 @@ locked_check_p(krb5_context context, + if (lockout_duration == 0) + return TRUE; /* principal permanently locked */ + +- return (stamp < entry->last_failed + lockout_duration); ++ return ts_after(ts_incr(entry->last_failed, lockout_duration), stamp); + } + + krb5_error_code +@@ -196,14 +196,14 @@ krb5_ldap_lockout_audit(krb5_context context, + status == KRB5KRB_AP_ERR_BAD_INTEGRITY)) { + if (krb5_dbe_lookup_last_admin_unlock(context, entry, + &unlock_time) == 0 && +- entry->last_failed <= unlock_time) { ++ !ts_after(entry->last_failed, unlock_time)) { + /* Reset fail_auth_count after administrative unlock. */ + entry->fail_auth_count = 0; + entry->mask |= KADM5_FAIL_AUTH_COUNT; + } + + if (failcnt_interval != 0 && +- stamp > entry->last_failed + failcnt_interval) { ++ ts_after(stamp, ts_incr(entry->last_failed, failcnt_interval))) { + /* Reset fail_auth_count after failcnt_interval */ + entry->fail_auth_count = 0; + entry->mask |= KADM5_FAIL_AUTH_COUNT; +diff --git a/src/windows/cns/tktlist.c b/src/windows/cns/tktlist.c +index f2805f5cd..26e699fae 100644 +--- a/src/windows/cns/tktlist.c ++++ b/src/windows/cns/tktlist.c +@@ -35,6 +35,8 @@ + #include "cns.h" + #include "tktlist.h" + ++#define ts2tt(t) (time_t)(uint32_t)(t) ++ + /* + * Ticket information for a list line + */ +@@ -167,10 +169,10 @@ ticket_init_list (HWND hwnd) + + ncred++; + strcpy (buf, " "); +- strncat(buf, short_date (c.times.starttime - kwin_get_epoch()), ++ strncat(buf, short_date(ts2tt(c.times.starttime) - kwin_get_epoch()), + sizeof(buf) - 1 - strlen(buf)); + strncat(buf, " ", sizeof(buf) - 1 - strlen(buf)); +- strncat(buf, short_date (c.times.endtime - kwin_get_epoch()), ++ strncat(buf, short_date(ts2tt(c.times.endtime) - kwin_get_epoch()), + sizeof(buf) - 1 - strlen(buf)); + strncat(buf, " ", sizeof(buf) - 1 - strlen(buf)); + +@@ -192,8 +194,8 @@ ticket_init_list (HWND hwnd) + return -1; + + lpinfo->ticket = TRUE; +- lpinfo->issue_time = c.times.starttime - kwin_get_epoch(); +- lpinfo->lifetime = c.times.endtime - c.times.starttime; ++ lpinfo->issue_time = ts2tt(c.times.starttime) - kwin_get_epoch(); ++ lpinfo->lifetime = ts2tt(c.times.endtime) - c.times.starttime; + strcpy(lpinfo->buf, buf); + + rc = ListBox_AddItemData(hwnd, lpinfo); +diff --git a/src/windows/include/leashwin.h b/src/windows/include/leashwin.h +index 9577365a7..325dce2e9 100644 +--- a/src/windows/include/leashwin.h ++++ b/src/windows/include/leashwin.h +@@ -111,9 +111,9 @@ struct TicketList { + TicketList *next; + char *service; + char *encTypes; +- krb5_timestamp issued; +- krb5_timestamp valid_until; +- krb5_timestamp renew_until; ++ time_t issued; ++ time_t valid_until; ++ time_t renew_until; + unsigned long flags; + }; + +@@ -124,9 +124,9 @@ struct TICKETINFO { + char *ccache_name; + TicketList *ticket_list; + int btickets; /* Do we have tickets? */ +- long issued; /* The issue time */ +- long valid_until; /* */ +- long renew_until; /* The Renew time (k5 only) */ ++ time_t issued; /* The issue time */ ++ time_t valid_until; /* */ ++ time_t renew_until; /* The Renew time (k5 only) */ + unsigned long flags; + }; + +diff --git a/src/windows/leash/KrbListTickets.cpp b/src/windows/leash/KrbListTickets.cpp +index beab0ea11..5dd37b05a 100644 +--- a/src/windows/leash/KrbListTickets.cpp ++++ b/src/windows/leash/KrbListTickets.cpp +@@ -92,10 +92,10 @@ etype_string(krb5_enctype enctype) + static void + CredToTicketInfo(krb5_creds KRBv5Credentials, TICKETINFO *ticketinfo) + { +- ticketinfo->issued = KRBv5Credentials.times.starttime; +- ticketinfo->valid_until = KRBv5Credentials.times.endtime; ++ ticketinfo->issued = (DWORD)KRBv5Credentials.times.starttime; ++ ticketinfo->valid_until = (DWORD)KRBv5Credentials.times.endtime; + ticketinfo->renew_until = KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE ? +- KRBv5Credentials.times.renew_till : 0; ++ (DWORD)KRBv5Credentials.times.renew_till : (DWORD)0; + _tzset(); + if ( ticketinfo->valid_until - time(0) <= 0L ) + ticketinfo->btickets = EXPD_TICKETS; +@@ -137,10 +137,10 @@ CredToTicketList(krb5_context ctx, krb5_creds KRBv5Credentials, + functionName = "calloc()"; + goto cleanup; + } +- list->issued = KRBv5Credentials.times.starttime; +- list->valid_until = KRBv5Credentials.times.endtime; ++ list->issued = (DWORD)KRBv5Credentials.times.starttime; ++ list->valid_until = (DWORD)KRBv5Credentials.times.endtime; + if (KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE) +- list->renew_until = KRBv5Credentials.times.renew_till; ++ list->renew_until = (DWORD)KRBv5Credentials.times.renew_till; + else + list->renew_until = 0; + +diff --git a/src/windows/leash/LeashView.cpp b/src/windows/leash/LeashView.cpp +index ef2a5a3e0..253ae3f06 100644 +--- a/src/windows/leash/LeashView.cpp ++++ b/src/windows/leash/LeashView.cpp +@@ -229,22 +229,22 @@ static HFONT CreateBoldItalicFont(HFONT font) + + bool change_icon_size = true; + +-void krb5TimestampToFileTime(krb5_timestamp t, LPFILETIME pft) ++void TimestampToFileTime(time_t t, LPFILETIME pft) + { + // Note that LONGLONG is a 64-bit value +- LONGLONG ll; ++ ULONGLONG ll; + +- ll = Int32x32To64(t, 10000000) + 116444736000000000; ++ ll = UInt32x32To64((DWORD)t, 10000000) + 116444736000000000; + pft->dwLowDateTime = (DWORD)ll; + pft->dwHighDateTime = ll >> 32; + } + + // allocate outstr +-void krb5TimestampToLocalizedString(krb5_timestamp t, LPTSTR *outStr) ++void TimestampToLocalizedString(time_t t, LPTSTR *outStr) + { + FILETIME ft, lft; + SYSTEMTIME st; +- krb5TimestampToFileTime(t, &ft); ++ TimestampToFileTime(t, &ft); + FileTimeToLocalFileTime(&ft, &lft); + FileTimeToSystemTime(&lft, &st); + TCHAR timeFormat[80]; // 80 is max required for LOCALE_STIMEFORMAT +@@ -1125,9 +1125,9 @@ void CLeashView::AddDisplayItem(CListCtrl &list, + CCacheDisplayData *elem, + int iItem, + char *principal, +- long issued, +- long valid_until, +- long renew_until, ++ time_t issued, ++ time_t valid_until, ++ time_t renew_until, + char *encTypes, + unsigned long flags, + char *ccache_name) +@@ -1145,7 +1145,7 @@ void CLeashView::AddDisplayItem(CListCtrl &list, + if (issued == 0) { + list.SetItemText(iItem, iSubItem++, "Unknown"); + } else { +- krb5TimestampToLocalizedString(issued, &localTimeStr); ++ TimestampToLocalizedString(issued, &localTimeStr); + list.SetItemText(iItem, iSubItem++, localTimeStr); + } + } +@@ -1155,7 +1155,7 @@ void CLeashView::AddDisplayItem(CListCtrl &list, + } else if (valid_until < now) { + list.SetItemText(iItem, iSubItem++, "Expired"); + } else if (renew_until) { +- krb5TimestampToLocalizedString(renew_until, &localTimeStr); ++ TimestampToLocalizedString(renew_until, &localTimeStr); + DurationToString(renew_until - now, &durationStr); + if (localTimeStr && durationStr) { + _snprintf(tempStr, MAX_DURATION_STR, "%s %s", localTimeStr, durationStr); +@@ -1172,7 +1172,7 @@ void CLeashView::AddDisplayItem(CListCtrl &list, + } else if (valid_until < now) { + list.SetItemText(iItem, iSubItem++, "Expired"); + } else { +- krb5TimestampToLocalizedString(valid_until, &localTimeStr); ++ TimestampToLocalizedString(valid_until, &localTimeStr); + DurationToString(valid_until - now, &durationStr); + if (localTimeStr && durationStr) { + _snprintf(tempStr, MAX_DURATION_STR, "%s %s", localTimeStr, durationStr); +diff --git a/src/windows/leashdll/lshfunc.c b/src/windows/leashdll/lshfunc.c +index 0f76cc334..8dafb7bed 100644 +--- a/src/windows/leashdll/lshfunc.c ++++ b/src/windows/leashdll/lshfunc.c +@@ -2898,7 +2898,7 @@ static BOOL cc_have_tickets(krb5_context ctx, krb5_ccache cache) + _tzset(); + while (!(code = pkrb5_cc_next_cred(ctx, cache, &cur, &creds))) { + if ((!pkrb5_is_config_principal(ctx, creds.server)) && +- (creds.times.endtime - time(0) > 0)) ++ ((time_t)(DWORD)creds.times.endtime - time(0) > 0)) + have_tickets = TRUE; + + pkrb5_free_cred_contents(ctx, &creds); +diff --git a/src/windows/ms2mit/ms2mit.c b/src/windows/ms2mit/ms2mit.c +index c3325034a..2b4373cc1 100644 +--- a/src/windows/ms2mit/ms2mit.c ++++ b/src/windows/ms2mit/ms2mit.c +@@ -74,7 +74,7 @@ cc_has_tickets(krb5_context kcontext, krb5_ccache ccache, int *has_tickets) + break; + + if (!krb5_is_config_principal(kcontext, creds.server) && +- creds.times.endtime > now) ++ ts_after(creds.times.endtime, now)) + *has_tickets = 1; + + krb5_free_cred_contents(kcontext, &creds); diff --git a/SOURCES/Merge-duplicate-subsections-in-profile-library.patch b/SOURCES/Merge-duplicate-subsections-in-profile-library.patch new file mode 100644 index 0000000..5acd4ab --- /dev/null +++ b/SOURCES/Merge-duplicate-subsections-in-profile-library.patch @@ -0,0 +1,122 @@ +From a19917522862f26bc711fd8271940906284ff55d Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Tue, 10 Apr 2018 15:55:41 -0400 +Subject: [PATCH] Merge duplicate subsections in profile library + +Modify profile_add_node() to return the existing node, rather than +making a new one, when adding subsection configuration. + +This fixes an issue where the first instance of a subsection will hide +the second instance entirely. In particular, it was previously +impossible to split realm-specific configuration across multiple +config files. + +[ghudson@mit.edu: adjusted style, added test case] + +(cherry picked from commit efab9fa5a6d23c486467264e20b58bf5a9c60f0c) + +ticket: 7863 +version_fixed: 1.16.1 + +(cherry picked from commit 98d0061c8083af960438ad1ac088f60497694a68) +--- + src/util/profile/prof_test1 | 22 ++++++++++++++++++++++ + src/util/profile/prof_tree.c | 15 +++++++++++---- + src/util/profile/test.ini | 6 ++++++ + 3 files changed, 39 insertions(+), 4 deletions(-) + +diff --git a/src/util/profile/prof_test1 b/src/util/profile/prof_test1 +index 7e30fc12f..7d13c9389 100644 +--- a/src/util/profile/prof_test1 ++++ b/src/util/profile/prof_test1 +@@ -341,6 +341,27 @@ proc test9 {} { + puts "OK: test9: profile_flush_to_file with no changes" + } + ++proc test10 {} { ++ global wd verbose ++ ++ # Regression test for #7863: multiply-specified subsections should ++ # be merged. ++ set p [profile_init_path $wd/test2.ini] ++ set x [profile_get_values $p {{test section 2} child_section2 child}] ++ if $verbose { puts "Read $x from profile" } ++ if ![string equal $x "slick harry {john\tb } ron"] { ++ puts stderr "Error: test10: Did not get expected merged children." ++ exit 1 ++ } ++ ++ set x [profile_get_string $p {test section 2} child_section2 chores] ++ if $verbose { puts "Read $x from profile" } ++ if ![string equal $x "cleaning"] { ++ puts stderr "Error: test10: Did not find expected chores." ++ exit 1 ++ } ++} ++ + test1 + test2 + test3 +@@ -350,5 +371,6 @@ test6 + test7 + test8 + test9 ++test10 + + exit 0 +diff --git a/src/util/profile/prof_tree.c b/src/util/profile/prof_tree.c +index 081f688e4..38aadc4e5 100644 +--- a/src/util/profile/prof_tree.c ++++ b/src/util/profile/prof_tree.c +@@ -9,7 +9,7 @@ + * + * Each node may represent either a relation or a section header. + * +- * A section header must have its value field set to 0, and may a one ++ * A section header must have its value field be null, and may have one + * or more child nodes, pointed to by first_child. + * + * A relation has as its value a pointer to allocated memory +@@ -159,15 +159,22 @@ errcode_t profile_add_node(struct profile_node *section, const char *name, + return PROF_ADD_NOT_SECTION; + + /* +- * Find the place to insert the new node. We look for the +- * place *after* the last match of the node name, since ++ * Find the place to insert the new node. If we are adding a subsection ++ * and already have a subsection with that name, merge them. Otherwise, ++ * we look for the place *after* the last match of the node name, since + * order matters. + */ + for (p=section->first_child, last = 0; p; last = p, p = p->next) { + int cmp; + cmp = strcmp(p->name, name); +- if (cmp > 0) ++ if (cmp > 0) { + break; ++ } else if (value == NULL && cmp == 0 && ++ p->value == NULL && p->deleted != 1) { ++ /* Found duplicate subsection, so don't make a new one. */ ++ *ret_node = p; ++ return 0; ++ } + } + retval = profile_create_node(name, value, &new); + if (retval) +diff --git a/src/util/profile/test.ini b/src/util/profile/test.ini +index 23ca89677..6622df108 100644 +--- a/src/util/profile/test.ini ++++ b/src/util/profile/test.ini +@@ -10,6 +10,12 @@ this is a comment. Everything up to the first square brace is ignored. + } + child_section2 = foo + ++[test section 2] ++ child_section2 = { ++ child = ron ++ chores = cleaning ++ } ++ + [realms] + ATHENA.MIT.EDU = { + server = KERBEROS.MIT.EDU:88 diff --git a/SOURCES/Modernize-kerberos-7.patch b/SOURCES/Modernize-kerberos-7.patch new file mode 100644 index 0000000..a4c690f --- /dev/null +++ b/SOURCES/Modernize-kerberos-7.patch @@ -0,0 +1,429 @@ +From 2319336ac1f52e56d2549bd83ff40a3e7b2f281a Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Mon, 15 Oct 2018 13:20:30 -0400 +Subject: [PATCH] Modernize kerberos(7) + +Update environment variable descriptions, using env_variables.rst as a +guide. Replace the content in env_variables.rst with a pointer to +documentation at kerberos(7) so that we don't break external links and +don't duplicate content. + +Replace references to rlogin. Clarify and modernize other language. + +ticket: 8755 +(cherry picked from commit cdccdefa2d74d3abf5a8ae126e423af9d467d34f) +--- + doc/admin/env_variables.rst | 44 +------------ + doc/user/user_config/kerberos.rst | 106 ++++++++++++++++++------------ + src/man/kerberos.man | 104 +++++++++++++++++------------ + 3 files changed, 128 insertions(+), 126 deletions(-) + +diff --git a/doc/admin/env_variables.rst b/doc/admin/env_variables.rst +index 0c146d3e3..a2d15bea8 100644 +--- a/doc/admin/env_variables.rst ++++ b/doc/admin/env_variables.rst +@@ -1,46 +1,4 @@ + Environment variables + ===================== + +-The following environment variables can be used during runtime: +- +-**KRB5_CONFIG** +- Main Kerberos configuration file. Multiple filenames can be +- specified, separated by a colon; all files which are present will +- be read. (See :ref:`mitK5defaults` for the default path.) +- +-**KRB5_KDC_PROFILE** +- KDC configuration file. (See :ref:`mitK5defaults` for the default +- name.) +- +-**KRB5_KTNAME** +- Default keytab file name. (See :ref:`mitK5defaults` for the +- default name.) +- +-**KRB5_CLIENT_KTNAME** +- Default client keytab file name. (See :ref:`mitK5defaults` for +- the default name.) +- +-**KRB5CCNAME** +- Default name for the credentials cache file, in the form *type*\:\ +- *residual*. The type of the default cache may determine the +- availability of a cache collection. For instance, a default cache +- of type ``DIR`` causes caches within the directory to be present +- in the global cache collection. +- +-**KRB5RCACHETYPE** +- Default replay cache type. Defaults to ``dfl``. A value of +- ``none`` disables the replay cache. +- +-**KRB5RCACHEDIR** +- Default replay cache directory. (See :ref:`mitK5defaults` for the +- default location.) +- +-**KPROP_PORT** +- :ref:`kprop(8)` port to use. Defaults to 754. +- +-**KRB5_TRACE** +- Filename for trace-logging output (introduced in release 1.9). +- For example, ``env KRB5_TRACE=/dev/stdout kinit`` would send +- tracing information for kinit to ``/dev/stdout``. Some programs +- may ignore this variable (particularly setuid or login system +- programs). ++This content has moved to :ref:`kerberos(7)`. +diff --git a/doc/user/user_config/kerberos.rst b/doc/user/user_config/kerberos.rst +index 6c4453b3b..56412f099 100644 +--- a/doc/user/user_config/kerberos.rst ++++ b/doc/user/user_config/kerberos.rst +@@ -8,12 +8,12 @@ DESCRIPTION + + The Kerberos system authenticates individual users in a network + environment. After authenticating yourself to Kerberos, you can use +-Kerberos-enabled programs without having to present passwords. ++Kerberos-enabled programs without having to present passwords or ++certificates to those programs. + +-If you enter your username and :ref:`kinit(1)` responds with this +-message: ++If you receive the following response from :ref:`kinit(1)`: + +-kinit(v5): Client not found in Kerberos database while getting initial ++kinit: Client not found in Kerberos database while getting initial + credentials + + you haven't been registered as a Kerberos user. See your system +@@ -25,10 +25,13 @@ is the **instance**, which in the case of a user is usually null. + Some users may have privileged instances, however, such as ``root`` or + ``admin``. In the case of a service, the instance is the fully + qualified name of the machine on which it runs; i.e. there can be an +-rlogin service running on the machine ABC, which is different from the +-rlogin service running on the machine XYZ. The third part of a +-Kerberos name is the **realm**. The realm corresponds to the Kerberos +-service providing authentication for the principal. ++ssh service running on the machine ABC (ssh/ABC@REALM), which is ++different from the ssh service running on the machine XYZ ++(ssh/XYZ@REALM). The third part of a Kerberos name is the **realm**. ++The realm corresponds to the Kerberos service providing authentication ++for the principal. Realms are conventionally all-uppercase, and often ++match the end of hostnames in the realm (for instance, host01.example.com ++might be in realm EXAMPLE.COM). + + When writing a Kerberos name, the principal name is separated from the + instance (if not null) by a slash, and the realm (if not the local +@@ -43,64 +46,72 @@ of valid Kerberos names:: + When you authenticate yourself with Kerberos you get an initial + Kerberos **ticket**. (A Kerberos ticket is an encrypted protocol + message that provides authentication.) Kerberos uses this ticket for +-network utilities such as rlogin and rcp. The ticket transactions are +-done transparently, so you don't have to worry about their management. ++network utilities such as ssh. The ticket transactions are done ++transparently, so you don't have to worry about their management. + +-Note, however, that tickets expire. Privileged tickets, such as those +-with the instance ``root``, expire in a few minutes, while tickets +-that carry more ordinary privileges may be good for several hours or a +-day, depending on the installation's policy. If your login session +-extends beyond the time limit, you will have to re-authenticate +-yourself to Kerberos to get new tickets. Use the :ref:`kinit(1)` +-command to re-authenticate yourself. ++Note, however, that tickets expire. Administrators may configure more ++privileged tickets, such as those with service or instance of ``root`` ++or ``admin``, to expire in a few minutes, while tickets that carry ++more ordinary privileges may be good for several hours or a day. If ++your login session extends beyond the time limit, you will have to ++re-authenticate yourself to Kerberos to get new tickets using the ++:ref:`kinit(1)` command. + +-If you use the kinit command to get your tickets, make sure you use +-the kdestroy command to destroy your tickets before you end your login +-session. You should put the kdestroy command in your ``.logout`` file +-so that your tickets will be destroyed automatically when you logout. +-For more information about the kinit and kdestroy commands, see the +-:ref:`kinit(1)` and :ref:`kdestroy(1)` manual pages. ++Some tickets are **renewable** beyond their initial lifetime. This ++means that ``kinit -R`` can extend their lifetime without requiring ++you to re-authenticate. ++ ++If you wish to delete your local tickets, use the :ref:`kdestroy(1)` ++command. + + Kerberos tickets can be forwarded. In order to forward tickets, you + must request **forwardable** tickets when you kinit. Once you have + forwardable tickets, most Kerberos programs have a command line option +-to forward them to the remote host. ++to forward them to the remote host. This can be useful for, e.g., ++running kinit on your local machine and then sshing into another to do ++work. Note that this should not be done on untrusted machines since ++they will then have your tickets. + + ENVIRONMENT VARIABLES + --------------------- + + Several environment variables affect the operation of Kerberos-enabled +-programs. These inclide: ++programs. These include: + + **KRB5CCNAME** +- Specifies the location of the credential cache, in the form +- *TYPE*:*residual*. If no *type* prefix is present, the **FILE** +- type is assumed and *residual* is the pathname of the cache file. +- A collection of multiple caches may be used by specifying the +- **dir** type and the pathname of a private directory (which must +- already exist). The default cache file is /tmp/krb5cc_*uid*, +- where *uid* is the decimal user ID of the user. ++ Default name for the credentials cache file, in the form ++ *TYPE*:*residual*. The type of the default cache may determine ++ the availability of a cache collection. ``FILE`` is not a ++ collection type; ``KEYRING``, ``DIR``, and ``KCM`` are. ++ ++ If not set, the value of **default_ccache_name** from ++ configuration files (see **KRB5_CONFIG**) will be used. If that ++ is also not set, the default *type* is ``FILE``, and the ++ *residual* is the path /tmp/krb5cc_*uid*, where *uid* is the ++ decimal user ID of the user. + + **KRB5_KTNAME** +- Specifies the location of the keytab file, in the form ++ Specifies the location of the default keytab file, in the form + *TYPE*:*residual*. If no *type* is present, the **FILE** type is +- assumed and *residual* is the pathname of the keytab file. The +- default keytab file is ``/etc/krb5.keytab``. ++ assumed and *residual* is the pathname of the keytab file. If ++ unset, |keytab| will be used. + + **KRB5_CONFIG** + Specifies the location of the Kerberos configuration file. The +- default is ``/etc/krb5.conf``. ++ default is |sysconfdir|\ ``/krb5.conf``. Multiple filenames can ++ be specified, separated by a colon; all files which are present ++ will be read. + + **KRB5_KDC_PROFILE** + Specifies the location of the KDC configuration file, which + contains additional configuration directives for the Key + Distribution Center daemon and associated programs. The default +- is ``/usr/local/var/krb5kdc/kdc.conf``. ++ is |kdcdir|\ ``/kdc.conf``. + + **KRB5RCACHETYPE** + Specifies the default type of replay cache to use for servers. +- Valid types include **dfl** for the normal file type and **none** +- for no replay cache. ++ Valid types include ``dfl`` for the normal file type and ``none`` ++ for no replay cache. The default is ``dfl``. + + **KRB5RCACHEDIR** + Specifies the default directory for replay caches used by servers. +@@ -110,7 +121,17 @@ programs. These inclide: + **KRB5_TRACE** + Specifies a filename to write trace log output to. Trace logs can + help illuminate decisions made internally by the Kerberos +- libraries. The default is not to write trace log output anywhere. ++ libraries. For example, ``env KRB5_TRACE=/dev/stderr kinit`` ++ would send tracing information for :ref:`kinit(1)` to ++ ``/dev/stderr``. The default is not to write trace log output ++ anywhere. ++ ++**KRB5_CLIENT_KTNAME** ++ Default client keytab file name. If unset, |ckeytab| will be ++ used). ++ ++**KPROP_PORT** ++ :ref:`kprop(8)` port to use. Defaults to 754. + + Most environment variables are disabled for certain programs, such as + login system programs and setuid programs, which are designed to be +@@ -133,6 +154,7 @@ AUTHORS + | Steve Miller, MIT Project Athena/Digital Equipment Corporation + | Clifford Neuman, MIT Project Athena + | Greg Hudson, MIT Kerberos Consortium ++| Robbie Harwood, Red Hat, Inc. + + HISTORY + ------- +@@ -144,5 +166,5 @@ by the MIT Kerberos Consortium. + RESTRICTIONS + ------------ + +-Copyright 1985, 1986, 1989-1996, 2002, 2011 Masachusetts Institute of +-Technology ++Copyright 1985, 1986, 1989-1996, 2002, 2011, 2018 Masachusetts ++Institute of Technology +diff --git a/src/man/kerberos.man b/src/man/kerberos.man +index 7b2b5d932..026f4604a 100644 +--- a/src/man/kerberos.man ++++ b/src/man/kerberos.man +@@ -34,12 +34,12 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] + .sp + The Kerberos system authenticates individual users in a network + environment. After authenticating yourself to Kerberos, you can use +-Kerberos\-enabled programs without having to present passwords. ++Kerberos\-enabled programs without having to present passwords or ++certificates to those programs. + .sp +-If you enter your username and kinit(1) responds with this +-message: ++If you receive the following response from kinit(1): + .sp +-kinit(v5): Client not found in Kerberos database while getting initial ++kinit: Client not found in Kerberos database while getting initial + credentials + .sp + you haven\(aqt been registered as a Kerberos user. See your system +@@ -51,10 +51,13 @@ is the \fBinstance\fP, which in the case of a user is usually null. + Some users may have privileged instances, however, such as \fBroot\fP or + \fBadmin\fP\&. In the case of a service, the instance is the fully + qualified name of the machine on which it runs; i.e. there can be an +-rlogin service running on the machine ABC, which is different from the +-rlogin service running on the machine XYZ. The third part of a +-Kerberos name is the \fBrealm\fP\&. The realm corresponds to the Kerberos +-service providing authentication for the principal. ++ssh service running on the machine ABC (\fI\%ssh/ABC@REALM\fP), which is ++different from the ssh service running on the machine XYZ ++(\fI\%ssh/XYZ@REALM\fP). The third part of a Kerberos name is the \fBrealm\fP\&. ++The realm corresponds to the Kerberos service providing authentication ++for the principal. Realms are conventionally all\-uppercase, and often ++match the end of hostnames in the realm (for instance, host01.example.com ++might be in realm EXAMPLE.COM). + .sp + When writing a Kerberos name, the principal name is separated from the + instance (if not null) by a slash, and the realm (if not the local +@@ -77,63 +80,71 @@ cbrown/root@FUBAR.ORG + When you authenticate yourself with Kerberos you get an initial + Kerberos \fBticket\fP\&. (A Kerberos ticket is an encrypted protocol + message that provides authentication.) Kerberos uses this ticket for +-network utilities such as rlogin and rcp. The ticket transactions are +-done transparently, so you don\(aqt have to worry about their management. ++network utilities such as ssh. The ticket transactions are done ++transparently, so you don\(aqt have to worry about their management. + .sp +-Note, however, that tickets expire. Privileged tickets, such as those +-with the instance \fBroot\fP, expire in a few minutes, while tickets +-that carry more ordinary privileges may be good for several hours or a +-day, depending on the installation\(aqs policy. If your login session +-extends beyond the time limit, you will have to re\-authenticate +-yourself to Kerberos to get new tickets. Use the kinit(1) +-command to re\-authenticate yourself. ++Note, however, that tickets expire. Administrators may configure more ++privileged tickets, such as those with service or instance of \fBroot\fP ++or \fBadmin\fP, to expire in a few minutes, while tickets that carry ++more ordinary privileges may be good for several hours or a day. If ++your login session extends beyond the time limit, you will have to ++re\-authenticate yourself to Kerberos to get new tickets using the ++kinit(1) command. + .sp +-If you use the kinit command to get your tickets, make sure you use +-the kdestroy command to destroy your tickets before you end your login +-session. You should put the kdestroy command in your \fB\&.logout\fP file +-so that your tickets will be destroyed automatically when you logout. +-For more information about the kinit and kdestroy commands, see the +-kinit(1) and kdestroy(1) manual pages. ++Some tickets are \fBrenewable\fP beyond their initial lifetime. This ++means that \fBkinit \-R\fP can extend their lifetime without requiring ++you to re\-authenticate. ++.sp ++If you wish to delete your local tickets, use the kdestroy(1) ++command. + .sp + Kerberos tickets can be forwarded. In order to forward tickets, you + must request \fBforwardable\fP tickets when you kinit. Once you have + forwardable tickets, most Kerberos programs have a command line option +-to forward them to the remote host. ++to forward them to the remote host. This can be useful for, e.g., ++running kinit on your local machine and then sshing into another to do ++work. Note that this should not be done on untrusted machines since ++they will then have your tickets. + .SH ENVIRONMENT VARIABLES + .sp + Several environment variables affect the operation of Kerberos\-enabled +-programs. These inclide: ++programs. These include: + .INDENT 0.0 + .TP + \fBKRB5CCNAME\fP +-Specifies the location of the credential cache, in the form +-\fITYPE\fP:\fIresidual\fP\&. If no \fItype\fP prefix is present, the \fBFILE\fP +-type is assumed and \fIresidual\fP is the pathname of the cache file. +-A collection of multiple caches may be used by specifying the +-\fBdir\fP type and the pathname of a private directory (which must +-already exist). The default cache file is /tmp/krb5cc_*uid*, +-where \fIuid\fP is the decimal user ID of the user. ++Default name for the credentials cache file, in the form ++\fITYPE\fP:\fIresidual\fP\&. The type of the default cache may determine ++the availability of a cache collection. \fBFILE\fP is not a ++collection type; \fBKEYRING\fP, \fBDIR\fP, and \fBKCM\fP are. ++.sp ++If not set, the value of \fBdefault_ccache_name\fP from ++configuration files (see \fBKRB5_CONFIG\fP) will be used. If that ++is also not set, the default \fItype\fP is \fBFILE\fP, and the ++\fIresidual\fP is the path /tmp/krb5cc_*uid*, where \fIuid\fP is the ++decimal user ID of the user. + .TP + \fBKRB5_KTNAME\fP +-Specifies the location of the keytab file, in the form ++Specifies the location of the default keytab file, in the form + \fITYPE\fP:\fIresidual\fP\&. If no \fItype\fP is present, the \fBFILE\fP type is +-assumed and \fIresidual\fP is the pathname of the keytab file. The +-default keytab file is \fB/etc/krb5.keytab\fP\&. ++assumed and \fIresidual\fP is the pathname of the keytab file. If ++unset, \fB@KTNAME@\fP will be used. + .TP + \fBKRB5_CONFIG\fP + Specifies the location of the Kerberos configuration file. The +-default is \fB/etc/krb5.conf\fP\&. ++default is \fB@SYSCONFDIR@\fP\fB/krb5.conf\fP\&. Multiple filenames can ++be specified, separated by a colon; all files which are present ++will be read. + .TP + \fBKRB5_KDC_PROFILE\fP + Specifies the location of the KDC configuration file, which + contains additional configuration directives for the Key + Distribution Center daemon and associated programs. The default +-is \fB/usr/local/var/krb5kdc/kdc.conf\fP\&. ++is \fB@LOCALSTATEDIR@\fP\fB/krb5kdc\fP\fB/kdc.conf\fP\&. + .TP + \fBKRB5RCACHETYPE\fP + Specifies the default type of replay cache to use for servers. + Valid types include \fBdfl\fP for the normal file type and \fBnone\fP +-for no replay cache. ++for no replay cache. The default is \fBdfl\fP\&. + .TP + \fBKRB5RCACHEDIR\fP + Specifies the default directory for replay caches used by servers. +@@ -143,7 +154,17 @@ or \fB/var/tmp\fP if \fBTMPDIR\fP is not set. + \fBKRB5_TRACE\fP + Specifies a filename to write trace log output to. Trace logs can + help illuminate decisions made internally by the Kerberos +-libraries. The default is not to write trace log output anywhere. ++libraries. For example, \fBenv KRB5_TRACE=/dev/stderr kinit\fP ++would send tracing information for kinit(1) to ++\fB/dev/stderr\fP\&. The default is not to write trace log output ++anywhere. ++.TP ++\fBKRB5_CLIENT_KTNAME\fP ++Default client keytab file name. If unset, \fB@CKTNAME@\fP will be ++used). ++.TP ++\fBKPROP_PORT\fP ++kprop(8) port to use. Defaults to 754. + .UNINDENT + .sp + Most environment variables are disabled for certain programs, such as +@@ -161,6 +182,7 @@ kadmind(8), kdb5_util(8), krb5kdc(8) + Steve Miller, MIT Project Athena/Digital Equipment Corporation + Clifford Neuman, MIT Project Athena + Greg Hudson, MIT Kerberos Consortium ++Robbie Harwood, Red Hat, Inc. + .fi + .sp + .SH HISTORY +@@ -170,8 +192,8 @@ contributions from many outside parties. It is currently maintained + by the MIT Kerberos Consortium. + .SH RESTRICTIONS + .sp +-Copyright 1985, 1986, 1989\-1996, 2002, 2011 Masachusetts Institute of +-Technology ++Copyright 1985, 1986, 1989\-1996, 2002, 2011, 2018 Masachusetts ++Institute of Technology + .SH AUTHOR + MIT + .SH COPYRIGHT diff --git a/SOURCES/Prefer-TCP-to-UDP-for-password-changes.patch b/SOURCES/Prefer-TCP-to-UDP-for-password-changes.patch new file mode 100644 index 0000000..31e62d1 --- /dev/null +++ b/SOURCES/Prefer-TCP-to-UDP-for-password-changes.patch @@ -0,0 +1,168 @@ +From aa346834947ef65c293a29300b0f98b1825d8508 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Mon, 8 Oct 2018 16:02:12 -0400 +Subject: [PATCH] Prefer TCP to UDP for password changes + +When password changes are performed over UDP, spotty networks may +cause the client to retransmit. This leads to replay errors if the +kpasswd server receives both requests, which hide the actual request +status and make it appear that the password has not been changed, when +it may in fact have been. Use TCP instead with UDP fallback to avoid +this issue. + +ticket: 7905 +(cherry picked from commit d7b3018d338fc9c989c3fa17505870f23c3759a8) +--- + src/lib/krb5/os/changepw.c | 110 ++++++++++++++----------------------- + 1 file changed, 42 insertions(+), 68 deletions(-) + +diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c +index e4db57084..9f968da7f 100644 +--- a/src/lib/krb5/os/changepw.c ++++ b/src/lib/krb5/os/changepw.c +@@ -59,13 +59,12 @@ struct sendto_callback_context { + + static krb5_error_code + locate_kpasswd(krb5_context context, const krb5_data *realm, +- struct serverlist *serverlist, krb5_boolean no_udp) ++ struct serverlist *serverlist) + { + krb5_error_code code; + + code = k5_locate_server(context, realm, serverlist, locate_service_kpasswd, +- no_udp); +- ++ FALSE); + if (code == KRB5_REALM_CANT_RESOLVE || code == KRB5_REALM_UNKNOWN) { + code = k5_locate_server(context, realm, serverlist, + locate_service_kadmin, TRUE); +@@ -76,7 +75,7 @@ locate_kpasswd(krb5_context context, const krb5_data *realm, + for (i = 0; i < serverlist->nservers; i++) { + struct server_entry *s = &serverlist->servers[i]; + +- if (!no_udp && s->transport == TCP) ++ if (s->transport == TCP) + s->transport = TCP_OR_UDP; + if (s->hostname != NULL) + s->port = DEFAULT_KPASSWD_PORT; +@@ -214,7 +213,6 @@ change_set_password(krb5_context context, + krb5_data *result_string) + { + krb5_data chpw_rep; +- krb5_boolean no_udp = FALSE; + GETSOCKNAME_ARG3_TYPE addrlen; + krb5_error_code code = 0; + char *code_string; +@@ -246,73 +244,49 @@ change_set_password(krb5_context context, + callback_ctx.remote_seq_num = callback_ctx.auth_context->remote_seq_number; + callback_ctx.local_seq_num = callback_ctx.auth_context->local_seq_number; + +- do { +- k5_transport_strategy strategy = no_udp ? NO_UDP : UDP_FIRST; ++ code = locate_kpasswd(callback_ctx.context, &creds->server->realm, &sl); ++ if (code) ++ goto cleanup; + +- code = locate_kpasswd(callback_ctx.context, &creds->server->realm, &sl, +- no_udp); ++ addrlen = sizeof(remote_addr); ++ ++ callback_info.data = &callback_ctx; ++ callback_info.pfn_callback = kpasswd_sendto_msg_callback; ++ callback_info.pfn_cleanup = kpasswd_sendto_msg_cleanup; ++ krb5_free_data_contents(callback_ctx.context, &chpw_rep); ++ ++ code = k5_sendto(callback_ctx.context, NULL, &creds->server->realm, ++ &sl, UDP_LAST, &callback_info, &chpw_rep, ++ ss2sa(&remote_addr), &addrlen, NULL, NULL, NULL); ++ if (code) ++ goto cleanup; ++ ++ code = krb5int_rd_chpw_rep(callback_ctx.context, ++ callback_ctx.auth_context, ++ &chpw_rep, &local_result_code, ++ result_string); ++ ++ if (code) ++ goto cleanup; ++ ++ if (result_code) ++ *result_code = local_result_code; ++ ++ if (result_code_string) { ++ code = krb5_chpw_result_code_string(callback_ctx.context, ++ local_result_code, ++ &code_string); + if (code) +- break; ++ goto cleanup; + +- addrlen = sizeof(remote_addr); +- +- callback_info.data = &callback_ctx; +- callback_info.pfn_callback = kpasswd_sendto_msg_callback; +- callback_info.pfn_cleanup = kpasswd_sendto_msg_cleanup; +- krb5_free_data_contents(callback_ctx.context, &chpw_rep); +- +- code = k5_sendto(callback_ctx.context, NULL, &creds->server->realm, +- &sl, strategy, &callback_info, &chpw_rep, +- ss2sa(&remote_addr), &addrlen, NULL, NULL, NULL); +- if (code) { +- /* +- * Here we may want to switch to TCP on some errors. +- * right? +- */ +- break; ++ result_code_string->length = strlen(code_string); ++ result_code_string->data = malloc(result_code_string->length); ++ if (result_code_string->data == NULL) { ++ code = ENOMEM; ++ goto cleanup; + } +- +- code = krb5int_rd_chpw_rep(callback_ctx.context, +- callback_ctx.auth_context, +- &chpw_rep, &local_result_code, +- result_string); +- +- if (code) { +- if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG && !no_udp) { +- k5_free_serverlist(&sl); +- no_udp = 1; +- continue; +- } +- +- break; +- } +- +- if (result_code) +- *result_code = local_result_code; +- +- if (result_code_string) { +- code = krb5_chpw_result_code_string(callback_ctx.context, +- local_result_code, +- &code_string); +- if (code) +- goto cleanup; +- +- result_code_string->length = strlen(code_string); +- result_code_string->data = malloc(result_code_string->length); +- if (result_code_string->data == NULL) { +- code = ENOMEM; +- goto cleanup; +- } +- strncpy(result_code_string->data, code_string, result_code_string->length); +- } +- +- if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG && !no_udp) { +- k5_free_serverlist(&sl); +- no_udp = 1; +- } else { +- break; +- } +- } while (TRUE); ++ strncpy(result_code_string->data, code_string, result_code_string->length); ++ } + + cleanup: + if (callback_ctx.auth_context != NULL) diff --git a/SOURCES/Preserve-method-data-in-get_in_tkt.c.patch b/SOURCES/Preserve-method-data-in-get_in_tkt.c.patch new file mode 100644 index 0000000..189845f --- /dev/null +++ b/SOURCES/Preserve-method-data-in-get_in_tkt.c.patch @@ -0,0 +1,222 @@ +From 5b52d5b4b1e65699dac6a53f0b6dbe545af4f689 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Fri, 13 Jan 2017 15:35:48 -0500 +Subject: [PATCH] Preserve method data in get_in_tkt.c + +To continue after preauth failures, we need a persistent field in +krb5_init_creds_context containing the METHOD-DATA from a +KDC_PREAUTH_REQUIRED or KDC_PREAUTH_FAILED error. If we overwrite +this field with the padata in a KDC_MORE_PREAUTH_DATA_REQUIRED error, +or conflate it with an optimistic padata list, we won't be able to +correctly continue after a preauth failure. + +In krb5_init_creds_context, split the preauth_to_use field into +optimistic_padata, method_padata, and more_padata. Separately handle +KDC_ERR_MORE_PREAUTH_DATA_REQUIRED in init_creds_step_request() and +init_creds_step_reply(), and separately handle optimistic preauth in +init_creds_step_request(). Do not call k5_preauth() if none of the +padata lists are set. + +Also stop clearing ctx->err_reply when processing a +KDC_ERR_PREAUTH_REQUIRED response. Instead look for that error code +in init_creds_step_request(). Eliminate the preauth_required field of +krb5_init_creds_context as it can be inferred from whether we are +performing optimistic preauth. + +ticket: 8537 +(cherry picked from commit 97a9b0c4ef3fc7b20e6ae592201bcb132d58bbe5) +--- + src/include/k5-trace.h | 11 +++++ + src/lib/krb5/krb/get_in_tkt.c | 71 +++++++++++++++++++++---------- + src/lib/krb5/krb/init_creds_ctx.h | 5 ++- + 3 files changed, 62 insertions(+), 25 deletions(-) + +diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h +index 814da3195..e60ee0b75 100644 +--- a/src/include/k5-trace.h ++++ b/src/include/k5-trace.h +@@ -213,8 +213,19 @@ void krb5int_trace(krb5_context context, const char *fmt, ...); + TRACE(c, "Looked up etypes in keytab: {etypes}", etypes) + #define TRACE_INIT_CREDS_KEYTAB_LOOKUP_FAILED(c, code) \ + TRACE(c, "Couldn't lookup etypes in keytab: {kerr}", code) ++#define TRACE_INIT_CREDS_PREAUTH(c) \ ++ TRACE(c, "Preauthenticating using KDC method data") + #define TRACE_INIT_CREDS_PREAUTH_DECRYPT_FAIL(c, code) \ + TRACE(c, "Decrypt with preauth AS key failed: {kerr}", code) ++#define TRACE_INIT_CREDS_PREAUTH_MORE(c, patype) \ ++ TRACE(c, "Continuing preauth mech {int}", (int)patype) ++#define TRACE_INIT_CREDS_PREAUTH_NONE(c) \ ++ TRACE(c, "Sending unauthenticated request") ++#define TRACE_INIT_CREDS_PREAUTH_OPTIMISTIC(c) \ ++ TRACE(c, "Attempting optimistic preauth") ++#define TRACE_INIT_CREDS_PREAUTH_TRYAGAIN(c, patype, code) \ ++ TRACE(c, "Recovering from KDC error {int} using preauth mech {int}", \ ++ (int)patype, (int)code) + #define TRACE_INIT_CREDS_RESTART_FAST(c) \ + TRACE(c, "Restarting to upgrade to FAST") + #define TRACE_INIT_CREDS_RESTART_PREAUTH_FAILED(c) \ +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index bc903b6e9..8c7919e65 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -575,7 +575,9 @@ krb5_init_creds_free(krb5_context context, + krb5_free_data(context, ctx->inner_request_body); + krb5_free_data(context, ctx->encoded_previous_request); + krb5int_fast_free_state(context, ctx->fast_state); +- krb5_free_pa_data(context, ctx->preauth_to_use); ++ krb5_free_pa_data(context, ctx->optimistic_padata); ++ krb5_free_pa_data(context, ctx->method_padata); ++ krb5_free_pa_data(context, ctx->more_padata); + krb5_free_data_contents(context, &ctx->salt); + krb5_free_data_contents(context, &ctx->s2kparams); + krb5_free_keyblock_contents(context, &ctx->as_key); +@@ -827,10 +829,13 @@ restart_init_creds_loop(krb5_context context, krb5_init_creds_context ctx, + { + krb5_error_code code = 0; + +- krb5_free_pa_data(context, ctx->preauth_to_use); ++ krb5_free_pa_data(context, ctx->optimistic_padata); ++ krb5_free_pa_data(context, ctx->method_padata); ++ krb5_free_pa_data(context, ctx->more_padata); + krb5_free_pa_data(context, ctx->err_padata); + krb5_free_error(context, ctx->err_reply); +- ctx->preauth_to_use = ctx->err_padata = NULL; ++ ctx->optimistic_padata = ctx->method_padata = ctx->more_padata = NULL; ++ ctx->err_padata = NULL; + ctx->err_reply = NULL; + ctx->selected_preauth_type = KRB5_PADATA_NONE; + +@@ -849,7 +854,7 @@ restart_init_creds_loop(krb5_context context, krb5_init_creds_context ctx, + if (ctx->opt->flags & KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST) { + code = make_preauth_list(context, ctx->opt->preauth_list, + ctx->opt->preauth_list_length, +- &ctx->preauth_to_use); ++ &ctx->optimistic_padata); + if (code) + goto cleanup; + } +@@ -1301,6 +1306,7 @@ init_creds_step_request(krb5_context context, + krb5_data *out) + { + krb5_error_code code; ++ krb5_preauthtype pa_type; + + if (ctx->loopcount >= MAX_IN_TKT_LOOPS) { + code = KRB5_GET_IN_TKT_LOOP; +@@ -1331,17 +1337,36 @@ init_creds_step_request(krb5_context context, + read_cc_config_in_data(context, ctx); + clear_cc_config_out_data(context, ctx); + +- if (ctx->err_reply == NULL) { +- /* Either our first attempt, or retrying after KDC_ERR_PREAUTH_REQUIRED +- * or KDC_ERR_MORE_PREAUTH_DATA_REQUIRED. */ +- code = k5_preauth(context, ctx, ctx->preauth_to_use, +- ctx->preauth_required, &ctx->request->padata, +- &ctx->selected_preauth_type); ++ ctx->request->padata = NULL; ++ if (ctx->optimistic_padata != NULL) { ++ /* Our first attempt, using an optimistic padata list. */ ++ TRACE_INIT_CREDS_PREAUTH_OPTIMISTIC(context); ++ code = k5_preauth(context, ctx, ctx->optimistic_padata, FALSE, ++ &ctx->request->padata, &ctx->selected_preauth_type); ++ krb5_free_pa_data(context, ctx->optimistic_padata); ++ ctx->optimistic_padata = NULL; + if (code != 0) + goto cleanup; +- } else { +- /* Retry after an error other than PREAUTH_NEEDED, using error padata ++ } if (ctx->more_padata != NULL) { ++ /* Continuing after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED. */ ++ TRACE_INIT_CREDS_PREAUTH_MORE(context, ctx->selected_preauth_type); ++ code = k5_preauth(context, ctx, ctx->more_padata, TRUE, ++ &ctx->request->padata, &pa_type); ++ if (code != 0) ++ goto cleanup; ++ } else if (ctx->err_reply != NULL && ++ ctx->err_reply->error == KDC_ERR_PREAUTH_REQUIRED) { ++ /* Continuing after KDC_ERR_PREAUTH_REQUIRED, using method data. */ ++ TRACE_INIT_CREDS_PREAUTH(context); ++ code = k5_preauth(context, ctx, ctx->method_padata, TRUE, ++ &ctx->request->padata, &ctx->selected_preauth_type); ++ if (code != 0) ++ goto cleanup; ++ } else if (ctx->err_reply != NULL) { ++ /* Retry after an error other than PREAUTH_REQUIRED, using error padata + * to figure out what to change. */ ++ TRACE_INIT_CREDS_PREAUTH_TRYAGAIN(context, ctx->err_reply->error, ++ ctx->selected_preauth_type); + code = k5_preauth_tryagain(context, ctx, ctx->selected_preauth_type, + ctx->err_reply, ctx->err_padata, + &ctx->request->padata); +@@ -1351,6 +1376,8 @@ init_creds_step_request(krb5_context context, + goto cleanup; + } + } ++ if (ctx->request->padata == NULL) ++ TRACE_INIT_CREDS_PREAUTH_NONE(context); + + /* Remember when we sent this request (after any preauth delay). */ + ctx->request_time = time(NULL); +@@ -1467,8 +1494,9 @@ init_creds_step_reply(krb5_context context, + ctx->request->client->type == KRB5_NT_ENTERPRISE_PRINCIPAL; + + if (ctx->err_reply != NULL) { ++ krb5_free_pa_data(context, ctx->more_padata); + krb5_free_pa_data(context, ctx->err_padata); +- ctx->err_padata = NULL; ++ ctx->more_padata = ctx->err_padata = NULL; + code = krb5int_fast_process_error(context, ctx->fast_state, + &ctx->err_reply, &ctx->err_padata, + &retry); +@@ -1494,21 +1522,18 @@ init_creds_step_reply(krb5_context context, + * FAST upgrade. */ + ctx->restarted = FALSE; + code = restart_init_creds_loop(context, ctx, FALSE); +- } else if ((reply_code == KDC_ERR_MORE_PREAUTH_DATA_REQUIRED || +- reply_code == KDC_ERR_PREAUTH_REQUIRED) && retry) { +- krb5_free_pa_data(context, ctx->preauth_to_use); +- ctx->preauth_to_use = ctx->err_padata; ++ } else if (reply_code == KDC_ERR_PREAUTH_REQUIRED && retry) { ++ krb5_free_pa_data(context, ctx->method_padata); ++ ctx->method_padata = ctx->err_padata; + ctx->err_padata = NULL; + note_req_timestamp(context, ctx, ctx->err_reply->stime, + ctx->err_reply->susec); +- /* This will trigger a new call to k5_preauth(). */ +- krb5_free_error(context, ctx->err_reply); +- ctx->err_reply = NULL; + code = sort_krb5_padata_sequence(context, + &ctx->request->client->realm, +- ctx->preauth_to_use); +- ctx->preauth_required = TRUE; +- ++ ctx->method_padata); ++ } else if (reply_code == KDC_ERR_MORE_PREAUTH_DATA_REQUIRED && retry) { ++ ctx->more_padata = ctx->err_padata; ++ ctx->err_padata = NULL; + } else if (canon_flag && is_referral(context, ctx->err_reply, + ctx->request->client)) { + TRACE_INIT_CREDS_REFERRAL(context, &ctx->err_reply->client->realm); +diff --git a/src/lib/krb5/krb/init_creds_ctx.h b/src/lib/krb5/krb/init_creds_ctx.h +index 8c8b7494b..fe769685b 100644 +--- a/src/lib/krb5/krb/init_creds_ctx.h ++++ b/src/lib/krb5/krb/init_creds_ctx.h +@@ -50,7 +50,9 @@ struct _krb5_init_creds_context { + krb5_data *inner_request_body; /**< For preauth */ + krb5_data *encoded_previous_request; + struct krb5int_fast_request_state *fast_state; +- krb5_pa_data **preauth_to_use; ++ krb5_pa_data **optimistic_padata; /* from gic options */ ++ krb5_pa_data **method_padata; /* from PREAUTH_REQUIRED or PREAUTH_FAILED */ ++ krb5_pa_data **more_padata; /* from MORE_PREAUTH_DATA_REQUIRED */ + krb5_boolean default_salt; + krb5_data salt; + krb5_data s2kparams; +@@ -58,7 +60,6 @@ struct _krb5_init_creds_context { + krb5_enctype etype; + krb5_boolean enc_pa_rep_permitted; + krb5_boolean restarted; +- krb5_boolean preauth_required; + struct krb5_responder_context_st rctx; + krb5_preauthtype selected_preauth_type; + krb5_preauthtype allowed_preauth_type; diff --git a/SOURCES/Prevent-KDC-unset-status-assertion-failures.patch b/SOURCES/Prevent-KDC-unset-status-assertion-failures.patch new file mode 100644 index 0000000..abc663e --- /dev/null +++ b/SOURCES/Prevent-KDC-unset-status-assertion-failures.patch @@ -0,0 +1,109 @@ +From 3b9e328664c92d95e7e3ec3c14cb6c7cbac4c05d Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Thu, 13 Jul 2017 12:14:20 -0400 +Subject: [PATCH] Prevent KDC unset status assertion failures + +Assign status values if S4U2Self padata fails to decode, if an +S4U2Proxy request uses invalid KDC options, or if an S4U2Proxy request +uses an evidence ticket which does not match the canonicalized request +server principal name. Reported by Samuel Cabrero. + +If a status value is not assigned during KDC processing, default to +"UNKNOWN_REASON" rather than failing an assertion. This change will +prevent future denial of service bugs due to similar mistakes, and +will allow us to omit assigning status values for unlikely errors such +as small memory allocation failures. + +CVE-2017-11368: + +In MIT krb5 1.7 and later, an authenticated attacker can cause an +assertion failure in krb5kdc by sending an invalid S4U2Self or +S4U2Proxy request. + + CVSSv3 Vector: AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H/E:H/RL:O/RC:C + +ticket: 8599 (new) +target_version: 1.15-next +target_version: 1.14-next +tags: pullup + +(cherry picked from commit ffb35baac6981f9e8914f8f3bffd37f284b85970) +--- + src/kdc/do_as_req.c | 4 ++-- + src/kdc/do_tgs_req.c | 3 ++- + src/kdc/kdc_util.c | 10 ++++++++-- + 3 files changed, 12 insertions(+), 5 deletions(-) + +diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c +index 241b05b40..f5cf8ad89 100644 +--- a/src/kdc/do_as_req.c ++++ b/src/kdc/do_as_req.c +@@ -372,8 +372,8 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode) + did_log = 1; + + egress: +- if (errcode != 0) +- assert (state->status != 0); ++ if (errcode != 0 && state->status == NULL) ++ state->status = "UNKNOWN_REASON"; + + au_state->status = state->status; + au_state->reply = &state->reply; +diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c +index 4c722a4a3..0009a9319 100644 +--- a/src/kdc/do_tgs_req.c ++++ b/src/kdc/do_tgs_req.c +@@ -829,7 +829,8 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt, + free(reply.enc_part.ciphertext.data); + + cleanup: +- assert(status != NULL); ++ if (status == NULL) ++ status = "UNKNOWN_REASON"; + if (reply_key) + krb5_free_keyblock(kdc_context, reply_key); + if (errcode) +diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c +index 8cbdf2c5b..5455e2a67 100644 +--- a/src/kdc/kdc_util.c ++++ b/src/kdc/kdc_util.c +@@ -1213,8 +1213,10 @@ kdc_process_for_user(kdc_realm_t *kdc_active_realm, + req_data.data = (char *)pa_data->contents; + + code = decode_krb5_pa_for_user(&req_data, &for_user); +- if (code) ++ if (code) { ++ *status = "DECODE_PA_FOR_USER"; + return code; ++ } + + code = verify_for_user_checksum(kdc_context, tgs_session, for_user); + if (code) { +@@ -1313,8 +1315,10 @@ kdc_process_s4u_x509_user(krb5_context context, + req_data.data = (char *)pa_data->contents; + + code = decode_krb5_pa_s4u_x509_user(&req_data, s4u_x509_user); +- if (code) ++ if (code) { ++ *status = "DECODE_PA_S4U_X509_USER"; + return code; ++ } + + code = verify_s4u_x509_user_checksum(context, + tgs_subkey ? tgs_subkey : +@@ -1617,6 +1621,7 @@ kdc_process_s4u2proxy_req(kdc_realm_t *kdc_active_realm, + * that is validated previously in validate_tgs_request(). + */ + if (request->kdc_options & (NON_TGT_OPTION | KDC_OPT_ENC_TKT_IN_SKEY)) { ++ *status = "INVALID_S4U2PROXY_OPTIONS"; + return KRB5KDC_ERR_BADOPTION; + } + +@@ -1624,6 +1629,7 @@ kdc_process_s4u2proxy_req(kdc_realm_t *kdc_active_realm, + if (!krb5_principal_compare(kdc_context, + server->princ, /* after canon */ + server_princ)) { ++ *status = "EVIDENCE_TICKET_MISMATCH"; + return KRB5KDC_ERR_SERVER_NOMATCH; + } + diff --git a/SOURCES/Process-profile-includedir-in-sorted-order.patch b/SOURCES/Process-profile-includedir-in-sorted-order.patch new file mode 100644 index 0000000..577bfca --- /dev/null +++ b/SOURCES/Process-profile-includedir-in-sorted-order.patch @@ -0,0 +1,115 @@ +From f1f6eabb88391b796ee0eec1bb5d207002696f3e Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Wed, 6 Jun 2018 17:58:41 -0400 +Subject: [PATCH] Process profile includedir in sorted order + +In the profile library, use k5_dir_filenames() so that files within an +included directory are read in a predictable order (alphanumeric +within the C locale). + +ticket: 8686 +(cherry picked from commit f574eda48740ad192f51e9a382a205e2ea0e60ad) +(cherry picked from commit 5d868264bca1771aa16abbc8cc0aefb0e1750a73) +--- + doc/admin/conf_files/krb5_conf.rst | 4 ++- + src/util/profile/prof_parse.c | 56 +++++------------------------- + 2 files changed, 12 insertions(+), 48 deletions(-) + +diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst +index 1d9bc9e34..a959e0e60 100644 +--- a/doc/admin/conf_files/krb5_conf.rst ++++ b/doc/admin/conf_files/krb5_conf.rst +@@ -58,7 +58,9 @@ alphanumeric characters, dashes, or underscores. Starting in release + 1.15, files with names ending in ".conf" are also included, unless the + name begins with ".". Included profile files are syntactically + independent of their parents, so each included file must begin with a +-section header. ++section header. Starting in release 1.17, files are read in ++alphanumeric order; in previous releases, they may be read in any ++order. + + The krb5.conf file can specify that configuration should be obtained + from a loadable module, rather than the file itself, using the +diff --git a/src/util/profile/prof_parse.c b/src/util/profile/prof_parse.c +index 1baceea9e..531e4a099 100644 +--- a/src/util/profile/prof_parse.c ++++ b/src/util/profile/prof_parse.c +@@ -246,59 +246,22 @@ static int valid_name(const char *filename) + * Include files within dirname. Only files with names ending in ".conf", or + * consisting entirely of alphanumeric characters, dashes, and underscores are + * included. This restriction avoids including editor backup files, .rpmsave +- * files, and the like. ++ * files, and the like. Files are processed in alphanumeric order. + */ + static errcode_t parse_include_dir(const char *dirname, + struct profile_node *root_section) + { +-#ifdef _WIN32 +- char *wildcard = NULL, *pathname; +- WIN32_FIND_DATA ffd; +- HANDLE handle; + errcode_t retval = 0; ++ char **fnames, *pathname; ++ int i; + +- if (asprintf(&wildcard, "%s\\*", dirname) < 0) +- return ENOMEM; +- +- handle = FindFirstFile(wildcard, &ffd); +- if (handle == INVALID_HANDLE_VALUE) { +- retval = PROF_FAIL_INCLUDE_DIR; +- goto cleanup; +- } +- +- do { +- if (!valid_name(ffd.cFileName)) +- continue; +- if (asprintf(&pathname, "%s\\%s", dirname, ffd.cFileName) < 0) { +- retval = ENOMEM; +- break; +- } +- retval = parse_include_file(pathname, root_section); +- free(pathname); +- if (retval) +- break; +- } while (FindNextFile(handle, &ffd) != 0); +- +- FindClose(handle); +- +-cleanup: +- free(wildcard); +- return retval; +- +-#else /* not _WIN32 */ +- +- DIR *dir; +- char *pathname; +- errcode_t retval = 0; +- struct dirent *ent; +- +- dir = opendir(dirname); +- if (dir == NULL) ++ if (k5_dir_filenames(dirname, &fnames) != 0) + return PROF_FAIL_INCLUDE_DIR; +- while ((ent = readdir(dir)) != NULL) { +- if (!valid_name(ent->d_name)) ++ ++ for (i = 0; fnames != NULL && fnames[i] != NULL; i++) { ++ if (!valid_name(fnames[i])) + continue; +- if (asprintf(&pathname, "%s/%s", dirname, ent->d_name) < 0) { ++ if (asprintf(&pathname, "%s/%s", dirname, fnames[i]) < 0) { + retval = ENOMEM; + break; + } +@@ -307,9 +270,8 @@ cleanup: + if (retval) + break; + } +- closedir(dir); ++ k5_free_filenames(fnames); + return retval; +-#endif /* not _WIN32 */ + } + + static errcode_t parse_line(char *line, struct parse_state *state, diff --git a/SOURCES/Properly-scope-per-request-preauth-data.patch b/SOURCES/Properly-scope-per-request-preauth-data.patch new file mode 100644 index 0000000..adc77ed --- /dev/null +++ b/SOURCES/Properly-scope-per-request-preauth-data.patch @@ -0,0 +1,533 @@ +From b3472e687181719dec6561c96aca6036b34865a5 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Tue, 20 Dec 2016 16:06:24 -0500 +Subject: [PATCH] Properly scope per-request preauth data + +It should be possible to successfully use multiple initial credentials +contexts with the same library context. Create a new internal type +krb5_preauth_req_context containing per-request preauth state, +including the clpreauth modreq handles and the list of preauth types +already tried. Remove this state from clpreauth_handle and +krb5_preauth_context. + +ticket: 7877 +(cherry picked from commit b061f419cfc9653b7549b905e54fbbd78deea49e) +--- + src/include/k5-trace.h | 3 + + src/lib/krb5/krb/get_in_tkt.c | 12 +- + src/lib/krb5/krb/init_creds_ctx.h | 3 + + src/lib/krb5/krb/int-proto.h | 8 +- + src/lib/krb5/krb/preauth2.c | 190 +++++++++++++++++++----------- + 5 files changed, 135 insertions(+), 81 deletions(-) + +diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h +index 2885408a2..f44f162d3 100644 +--- a/src/include/k5-trace.h ++++ b/src/include/k5-trace.h +@@ -291,6 +291,9 @@ void krb5int_trace(krb5_context context, const char *fmt, ...); + TRACE(c, "Preauth tryagain input types: {patypes}", padata) + #define TRACE_PREAUTH_TRYAGAIN_OUTPUT(c, padata) \ + TRACE(c, "Followup preauth for next request: {patypes}", padata) ++#define TRACE_PREAUTH_WRONG_CONTEXT(c) \ ++ TRACE(c, "Wrong context passed to krb5_init_creds_free(); leaking " \ ++ "modreq objects") + + #define TRACE_PROFILE_ERR(c,subsection, section, retval) \ + TRACE(c, "Bad value of {str} from [{str}] in conf file: {kerr}", \ +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index ed15550f0..80f5e1870 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -565,7 +565,7 @@ krb5_init_creds_free(krb5_context context, + k5_response_items_free(ctx->rctx.items); + free(ctx->in_tkt_service); + zapfree(ctx->gakpw.storage.data, ctx->gakpw.storage.length); +- k5_preauth_request_context_fini(context); ++ k5_preauth_request_context_fini(context, ctx); + krb5_free_error(context, ctx->err_reply); + krb5_free_pa_data(context, ctx->err_padata); + krb5_free_cred_contents(context, &ctx->cred); +@@ -816,8 +816,8 @@ restart_init_creds_loop(krb5_context context, krb5_init_creds_context ctx, + if (fast_upgrade) + ctx->fast_state->fast_state_flags |= KRB5INT_FAST_DO_FAST; + +- k5_preauth_request_context_fini(context); +- k5_preauth_request_context_init(context); ++ k5_preauth_request_context_fini(context, ctx); ++ k5_preauth_request_context_init(context, ctx); + krb5_free_data(context, ctx->outer_request_body); + ctx->outer_request_body = NULL; + if (ctx->opt->flags & KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST) { +@@ -1504,7 +1504,7 @@ init_creds_step_reply(krb5_context context, + } else if ((reply_code == KDC_ERR_MORE_PREAUTH_DATA_REQUIRED || + reply_code == KDC_ERR_PREAUTH_REQUIRED) && retry) { + /* reset the list of preauth types to try */ +- k5_reset_preauth_types_tried(context); ++ k5_reset_preauth_types_tried(ctx); + krb5_free_pa_data(context, ctx->preauth_to_use); + ctx->preauth_to_use = ctx->err_padata; + ctx->err_padata = NULL; +@@ -1555,7 +1555,7 @@ init_creds_step_reply(krb5_context context, + goto cleanup; + + /* process any preauth data in the as_reply */ +- k5_reset_preauth_types_tried(context); ++ k5_reset_preauth_types_tried(ctx); + code = krb5int_fast_process_response(context, ctx->fast_state, + ctx->reply, &strengthen_key); + if (code != 0) +@@ -1640,7 +1640,7 @@ init_creds_step_reply(krb5_context context, + k5_prependmsg(context, code, _("Failed to store credentials")); + } + +- k5_preauth_request_context_fini(context); ++ k5_preauth_request_context_fini(context, ctx); + + /* success */ + ctx->complete = TRUE; +diff --git a/src/lib/krb5/krb/init_creds_ctx.h b/src/lib/krb5/krb/init_creds_ctx.h +index 38c01c775..a7cded942 100644 +--- a/src/lib/krb5/krb/init_creds_ctx.h ++++ b/src/lib/krb5/krb/init_creds_ctx.h +@@ -6,6 +6,8 @@ + #include "k5-json.h" + #include "int-proto.h" + ++typedef struct krb5_preauth_req_context_st *krb5_preauth_req_context; ++ + struct krb5_responder_context_st { + k5_response_items *items; + }; +@@ -67,6 +69,7 @@ struct _krb5_init_creds_context { + krb5_timestamp pa_offset; + krb5_int32 pa_offset_usec; + enum { NO_OFFSET = 0, UNAUTH_OFFSET, AUTH_OFFSET } pa_offset_state; ++ krb5_preauth_req_context preauth_reqctx; + }; + + krb5_error_code +diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h +index 9c746d05b..f1667c238 100644 +--- a/src/lib/krb5/krb/int-proto.h ++++ b/src/lib/krb5/krb/int-proto.h +@@ -194,17 +194,19 @@ void + k5_free_preauth_context(krb5_context context); + + void +-k5_reset_preauth_types_tried(krb5_context context); ++k5_reset_preauth_types_tried(krb5_init_creds_context ctx); + + void + k5_preauth_prepare_request(krb5_context context, krb5_get_init_creds_opt *opt, + krb5_kdc_req *request); + + void +-k5_preauth_request_context_init(krb5_context context); ++k5_preauth_request_context_init(krb5_context context, ++ krb5_init_creds_context ctx); + + void +-k5_preauth_request_context_fini(krb5_context context); ++k5_preauth_request_context_fini(krb5_context context, ++ krb5_init_creds_context ctx); + + krb5_error_code + k5_response_items_new(k5_response_items **ri_out); +diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c +index b04d14829..9a178f4e3 100644 +--- a/src/lib/krb5/krb/preauth2.c ++++ b/src/lib/krb5/krb/preauth2.c +@@ -46,14 +46,18 @@ + typedef struct { + struct krb5_clpreauth_vtable_st vt; + krb5_clpreauth_moddata data; +- krb5_clpreauth_modreq req; + } *clpreauth_handle; + + struct krb5_preauth_context_st { +- krb5_preauthtype *tried; + clpreauth_handle *handles; + }; + ++struct krb5_preauth_req_context_st { ++ krb5_context orig_context; ++ krb5_preauthtype *tried; ++ krb5_clpreauth_modreq *modreqs; ++}; ++ + /* Release the memory used by a list of handles. */ + static void + free_handles(krb5_context context, clpreauth_handle *handles) +@@ -71,21 +75,44 @@ free_handles(krb5_context context, clpreauth_handle *handles) + free(handles); + } + +-/* Find the handle in handles which can process pa_type. */ +-static clpreauth_handle +-find_module(clpreauth_handle *handles, krb5_preauthtype pa_type) ++/* Return an index into handles which can process pa_type, or -1 if none is ++ * found found. */ ++static int ++search_module_list(clpreauth_handle *handles, krb5_preauthtype pa_type) + { +- clpreauth_handle *hp, h; +- krb5_preauthtype *tp; ++ clpreauth_handle h; ++ int i, j; + +- for (hp = handles; *hp != NULL; hp++) { +- h = *hp; +- for (tp = h->vt.pa_type_list; *tp != 0; tp++) { +- if (*tp == pa_type) +- return h; ++ for (i = 0; handles[i] != NULL; i++) { ++ h = handles[i]; ++ for (j = 0; h->vt.pa_type_list[j] != 0; j++) { ++ if (h->vt.pa_type_list[j] == pa_type) ++ return i; + } + } +- return FALSE; ++ return -1; ++} ++ ++/* Find the handle which can process pa_type, or NULL if none is found. On ++ * success, set *modreq_out to the corresponding per-request module data. */ ++static clpreauth_handle ++find_module(krb5_context context, krb5_init_creds_context ctx, ++ krb5_preauthtype pa_type, krb5_clpreauth_modreq *modreq_out) ++{ ++ krb5_preauth_context pctx = context->preauth_context; ++ krb5_preauth_req_context reqctx = ctx->preauth_reqctx; ++ int i; ++ ++ *modreq_out = NULL; ++ if (pctx == NULL || reqctx == NULL) ++ return NULL; ++ ++ i = search_module_list(pctx->handles, pa_type); ++ if (i == -1) ++ return NULL; ++ ++ *modreq_out = reqctx->modreqs[i]; ++ return pctx->handles[i]; + } + + /* Initialize the preauth state for a krb5 context. */ +@@ -93,7 +120,8 @@ void + k5_init_preauth_context(krb5_context context) + { + krb5_plugin_initvt_fn *modules = NULL, *mod; +- clpreauth_handle *list = NULL, h, h2; ++ clpreauth_handle *list = NULL, h; ++ int i; + size_t count; + krb5_preauthtype *tp; + +@@ -140,9 +168,10 @@ k5_init_preauth_context(krb5_context context) + + /* Check for a preauth type conflict with an existing module. */ + for (tp = h->vt.pa_type_list; *tp != 0; tp++) { +- h2 = find_module(list, *tp); +- if (h2 != NULL) { +- TRACE_PREAUTH_CONFLICT(context, h->vt.name, h2->vt.name, *tp); ++ i = search_module_list(list, *tp); ++ if (i != -1) { ++ TRACE_PREAUTH_CONFLICT(context, h->vt.name, list[i]->vt.name, ++ *tp); + break; + } + } +@@ -164,7 +193,6 @@ k5_init_preauth_context(krb5_context context) + context->preauth_context = malloc(sizeof(*context->preauth_context)); + if (context->preauth_context == NULL) + goto cleanup; +- context->preauth_context->tried = NULL; + context->preauth_context->handles = list; + list = NULL; + +@@ -179,14 +207,14 @@ cleanup: + * AS-REP). + */ + void +-k5_reset_preauth_types_tried(krb5_context context) ++k5_reset_preauth_types_tried(krb5_init_creds_context ctx) + { +- krb5_preauth_context pctx = context->preauth_context; ++ krb5_preauth_req_context reqctx = ctx->preauth_reqctx; + +- if (pctx == NULL) ++ if (reqctx == NULL) + return; +- free(pctx->tried); +- pctx->tried = NULL; ++ free(reqctx->tried); ++ reqctx->tried = NULL; + } + + +@@ -200,7 +228,6 @@ k5_free_preauth_context(krb5_context context) + + if (pctx == NULL) + return; +- free(pctx->tried); + free_handles(context, pctx->handles); + free(pctx); + context->preauth_context = NULL; +@@ -209,10 +236,13 @@ k5_free_preauth_context(krb5_context context) + /* Initialize the per-AS-REQ context. This means calling the client_req_init + * function to give the plugin a chance to allocate a per-request context. */ + void +-k5_preauth_request_context_init(krb5_context context) ++k5_preauth_request_context_init(krb5_context context, ++ krb5_init_creds_context ctx) + { + krb5_preauth_context pctx = context->preauth_context; +- clpreauth_handle *hp, h; ++ clpreauth_handle h; ++ krb5_preauth_req_context reqctx; ++ size_t count, i; + + if (pctx == NULL) { + k5_init_preauth_context(context); +@@ -220,30 +250,50 @@ k5_preauth_request_context_init(krb5_context context) + if (pctx == NULL) + return; + } +- k5_reset_preauth_types_tried(context); +- for (hp = pctx->handles; *hp != NULL; hp++) { +- h = *hp; ++ ++ reqctx = calloc(1, sizeof(*reqctx)); ++ if (reqctx == NULL) ++ return; ++ reqctx->orig_context = context; ++ ++ /* Create an array of per-request module data objects corresponding to the ++ * preauth context's array of handles. */ ++ for (count = 0; pctx->handles[count] != NULL; count++); ++ reqctx->modreqs = calloc(count, sizeof(*reqctx->modreqs)); ++ for (i = 0; i < count; i++) { ++ h = pctx->handles[i]; + if (h->vt.request_init != NULL) +- h->vt.request_init(context, h->data, &h->req); ++ h->vt.request_init(context, h->data, &reqctx->modreqs[i]); + } ++ ctx->preauth_reqctx = reqctx; + } + + /* Free the per-AS-REQ context. This means clearing any request-specific + * context which the plugin may have created. */ + void +-k5_preauth_request_context_fini(krb5_context context) ++k5_preauth_request_context_fini(krb5_context context, ++ krb5_init_creds_context ctx) + { + krb5_preauth_context pctx = context->preauth_context; +- clpreauth_handle *hp, h; ++ krb5_preauth_req_context reqctx = ctx->preauth_reqctx; ++ size_t i; ++ clpreauth_handle h; + +- if (pctx == NULL) ++ if (reqctx == NULL) + return; +- for (hp = pctx->handles; *hp != NULL; hp++) { +- h = *hp; +- if (h->req != NULL && h->vt.request_fini != NULL) +- h->vt.request_fini(context, h->data, h->req); +- h->req = NULL; ++ if (reqctx->orig_context == context && pctx != NULL) { ++ for (i = 0; pctx->handles[i] != NULL; i++) { ++ h = pctx->handles[i]; ++ if (reqctx->modreqs[i] != NULL && h->vt.request_fini != NULL) ++ h->vt.request_fini(context, h->data, reqctx->modreqs[i]); ++ } ++ } else { ++ TRACE_PREAUTH_WRONG_CONTEXT(context); + } ++ free(reqctx->modreqs); ++ free(reqctx->tried); ++ free(reqctx); ++ ctx->preauth_reqctx = NULL; + } + + /* Return 1 if pa_type is a real preauthentication mechanism according to the +@@ -259,6 +309,7 @@ clpreauth_is_real(krb5_context context, clpreauth_handle h, + + static krb5_error_code + clpreauth_prep_questions(krb5_context context, clpreauth_handle h, ++ krb5_clpreauth_modreq modreq, + krb5_get_init_creds_opt *opt, + krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock, + krb5_kdc_req *req, krb5_data *req_body, +@@ -266,35 +317,35 @@ clpreauth_prep_questions(krb5_context context, clpreauth_handle h, + { + if (h->vt.prep_questions == NULL) + return 0; +- return h->vt.prep_questions(context, h->data, h->req, opt, cb, rock, req, ++ return h->vt.prep_questions(context, h->data, modreq, opt, cb, rock, req, + req_body, prev_req, pa_data); + } + + static krb5_error_code + clpreauth_process(krb5_context context, clpreauth_handle h, +- krb5_get_init_creds_opt *opt, krb5_clpreauth_callbacks cb, +- krb5_clpreauth_rock rock, krb5_kdc_req *req, +- krb5_data *req_body, krb5_data *prev_req, ++ krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt, ++ krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock, ++ krb5_kdc_req *req, krb5_data *req_body, krb5_data *prev_req, + krb5_pa_data *pa_data, krb5_prompter_fct prompter, + void *prompter_data, krb5_pa_data ***pa_data_out) + { +- return h->vt.process(context, h->data, h->req, opt, cb, rock, req, ++ return h->vt.process(context, h->data, modreq, opt, cb, rock, req, + req_body, prev_req, pa_data, prompter, prompter_data, + pa_data_out); + } + + static krb5_error_code + clpreauth_tryagain(krb5_context context, clpreauth_handle h, +- krb5_get_init_creds_opt *opt, krb5_clpreauth_callbacks cb, +- krb5_clpreauth_rock rock, krb5_kdc_req *req, +- krb5_data *req_body, krb5_data *prev_req, ++ krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt, ++ krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock, ++ krb5_kdc_req *req, krb5_data *req_body, krb5_data *prev_req, + krb5_preauthtype pa_type, krb5_error *error, + krb5_pa_data **error_padata, krb5_prompter_fct prompter, + void *prompter_data, krb5_pa_data ***pa_data_out) + { + if (h->vt.tryagain == NULL) + return 0; +- return h->vt.tryagain(context, h->data, h->req, opt, cb, rock, req, ++ return h->vt.tryagain(context, h->data, modreq, opt, cb, rock, req, + req_body, prev_req, pa_type, error, error_padata, + prompter, prompter_data, pa_data_out); + } +@@ -554,22 +605,22 @@ pa_type_allowed(krb5_init_creds_context ctx, krb5_preauthtype pa_type) + * types and return false. + */ + static krb5_boolean +-already_tried(krb5_context context, krb5_preauthtype pa_type) ++already_tried(krb5_init_creds_context ctx, krb5_preauthtype pa_type) + { +- krb5_preauth_context pctx = context->preauth_context; +- size_t count; ++ krb5_preauth_req_context reqctx = ctx->preauth_reqctx; ++ size_t i; + krb5_preauthtype *newptr; + +- for (count = 0; pctx->tried != NULL && pctx->tried[count] != 0; count++) { +- if (pctx->tried[count] == pa_type) ++ for (i = 0; reqctx->tried != NULL && reqctx->tried[i] != 0; i++) { ++ if (reqctx->tried[i] == pa_type) + return TRUE; + } +- newptr = realloc(pctx->tried, (count + 2) * sizeof(*newptr)); ++ newptr = realloc(reqctx->tried, (i + 2) * sizeof(*newptr)); + if (newptr == NULL) + return FALSE; +- pctx->tried = newptr; +- pctx->tried[count] = pa_type; +- pctx->tried[count + 1] = ENCTYPE_NULL; ++ reqctx->tried = newptr; ++ reqctx->tried[i] = pa_type; ++ reqctx->tried[i + 1] = ENCTYPE_NULL; + return FALSE; + } + +@@ -580,16 +631,13 @@ process_pa_data(krb5_context context, krb5_init_creds_context ctx, + krb5_pa_data ***out_pa_list, int *out_pa_list_size, + krb5_preauthtype *out_type) + { +- krb5_preauth_context pctx = context->preauth_context; + struct errinfo save = EMPTY_ERRINFO; + krb5_pa_data *pa, **pa_ptr, **mod_pa; + krb5_error_code ret = 0; ++ krb5_clpreauth_modreq modreq; + clpreauth_handle h; + int real, i; + +- if (pctx == NULL) +- return ENOENT; +- + /* Process all informational padata types, then the first real preauth type + * we succeed on. */ + for (real = 0; real <= 1; real++) { +@@ -598,17 +646,17 @@ process_pa_data(krb5_context context, krb5_init_creds_context ctx, + /* Restrict real mechanisms to the chosen one if we have one. */ + if (real && !pa_type_allowed(ctx, pa->pa_type)) + continue; +- h = find_module(pctx->handles, pa->pa_type); ++ h = find_module(context, ctx, pa->pa_type, &modreq); + if (h == NULL) + continue; + /* Make sure this type is for the current pass. */ + if (clpreauth_is_real(context, h, pa->pa_type) != real) + continue; + /* Only try a real mechanism once per authentication. */ +- if (real && already_tried(context, pa->pa_type)) ++ if (real && already_tried(ctx, pa->pa_type)) + continue; + mod_pa = NULL; +- ret = clpreauth_process(context, h, ctx->opt, &callbacks, ++ ret = clpreauth_process(context, h, modreq, ctx->opt, &callbacks, + (krb5_clpreauth_rock)ctx, ctx->request, + ctx->inner_request_body, + ctx->encoded_previous_request, pa, +@@ -858,24 +906,22 @@ krb5_error_code + k5_preauth_tryagain(krb5_context context, krb5_init_creds_context ctx, + krb5_pa_data **in_padata, krb5_pa_data ***padata_out) + { +- krb5_preauth_context pctx = context->preauth_context; + krb5_error_code ret; + krb5_pa_data **mod_pa; ++ krb5_clpreauth_modreq modreq; + clpreauth_handle h; + int i; + + *padata_out = NULL; +- if (pctx == NULL) +- return KRB5KRB_ERR_GENERIC; + + TRACE_PREAUTH_TRYAGAIN_INPUT(context, in_padata); + + for (i = 0; in_padata[i] != NULL; i++) { +- h = find_module(pctx->handles, in_padata[i]->pa_type); ++ h = find_module(context, ctx, in_padata[i]->pa_type, &modreq); + if (h == NULL) + continue; + mod_pa = NULL; +- ret = clpreauth_tryagain(context, h, ctx->opt, &callbacks, ++ ret = clpreauth_tryagain(context, h, modreq, ctx->opt, &callbacks, + (krb5_clpreauth_rock)ctx, ctx->request, + ctx->inner_request_body, + ctx->encoded_previous_request, +@@ -897,9 +943,9 @@ static krb5_error_code + fill_response_items(krb5_context context, krb5_init_creds_context ctx, + krb5_pa_data **in_padata) + { +- krb5_preauth_context pctx = context->preauth_context; + krb5_error_code ret; + krb5_pa_data *pa; ++ krb5_clpreauth_modreq modreq; + clpreauth_handle h; + int i; + +@@ -908,11 +954,11 @@ fill_response_items(krb5_context context, krb5_init_creds_context ctx, + pa = in_padata[i]; + if (!pa_type_allowed(ctx, pa->pa_type)) + continue; +- h = find_module(pctx->handles, pa->pa_type); ++ h = find_module(context, ctx, pa->pa_type, &modreq); + if (h == NULL) + continue; +- ret = clpreauth_prep_questions(context, h, ctx->opt, &callbacks, +- (krb5_clpreauth_rock)ctx, ++ ret = clpreauth_prep_questions(context, h, modreq, ctx->opt, ++ &callbacks, (krb5_clpreauth_rock)ctx, + ctx->request, ctx->inner_request_body, + ctx->encoded_previous_request, pa); + if (ret) diff --git a/SOURCES/Remove-incomplete-PKINIT-OCSP-support.patch b/SOURCES/Remove-incomplete-PKINIT-OCSP-support.patch new file mode 100644 index 0000000..17bb5e5 --- /dev/null +++ b/SOURCES/Remove-incomplete-PKINIT-OCSP-support.patch @@ -0,0 +1,134 @@ +From 771f85f6d84f1cce95c5246b700bd950295d8fb3 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Mon, 31 Jul 2017 16:03:41 -0400 +Subject: [PATCH] Remove incomplete PKINIT OCSP support + +pkinit_kdc_ocsp is non-functional in the PKINIT OpenSSL crypto +implementation, so remove most traces of it, including its man page +entry. If it is present in kdc.conf, error out of PKINIT +initialization instead of silently ignoring the realm entirely. + +ticket: 8603 (new) +(cherry picked from commit 3ff426b9048a8024e5c175256c63cd0ad0572320) +--- + doc/admin/conf_files/kdc_conf.rst | 3 --- + src/man/kdc.conf.man | 3 --- + src/plugins/preauth/pkinit/pkinit.h | 2 +- + src/plugins/preauth/pkinit/pkinit_identity.c | 11 ----------- + src/plugins/preauth/pkinit/pkinit_srv.c | 12 ++++++++++-- + 5 files changed, 11 insertions(+), 20 deletions(-) + +diff --git a/doc/admin/conf_files/kdc_conf.rst b/doc/admin/conf_files/kdc_conf.rst +index 13077ecf4..a4b2a5432 100644 +--- a/doc/admin/conf_files/kdc_conf.rst ++++ b/doc/admin/conf_files/kdc_conf.rst +@@ -765,9 +765,6 @@ For information about the syntax of some of these options, see + pkinit is used to authenticate. This option may be specified + multiple times. (New in release 1.14.) + +-**pkinit_kdc_ocsp** +- Specifies the location of the KDC's OCSP. +- + **pkinit_pool** + Specifies the location of intermediate certificates which may be + used by the KDC to complete the trust chain between a client's +diff --git a/src/man/kdc.conf.man b/src/man/kdc.conf.man +index 10b333c38..166e68f9a 100644 +--- a/src/man/kdc.conf.man ++++ b/src/man/kdc.conf.man +@@ -886,9 +886,6 @@ Specifies an authentication indicator to include in the ticket if + pkinit is used to authenticate. This option may be specified + multiple times. (New in release 1.14.) + .TP +-.B \fBpkinit_kdc_ocsp\fP +-Specifies the location of the KDC\(aqs OCSP. +-.TP + .B \fBpkinit_pool\fP + Specifies the location of intermediate certificates which may be + used by the KDC to complete the trust chain between a client\(aqs +diff --git a/src/plugins/preauth/pkinit/pkinit.h b/src/plugins/preauth/pkinit/pkinit.h +index 876db94c3..a49f3078e 100644 +--- a/src/plugins/preauth/pkinit/pkinit.h ++++ b/src/plugins/preauth/pkinit/pkinit.h +@@ -73,6 +73,7 @@ + #define KRB5_CONF_PKINIT_IDENTITIES "pkinit_identities" + #define KRB5_CONF_PKINIT_IDENTITY "pkinit_identity" + #define KRB5_CONF_PKINIT_KDC_HOSTNAME "pkinit_kdc_hostname" ++/* pkinit_kdc_ocsp has been removed */ + #define KRB5_CONF_PKINIT_KDC_OCSP "pkinit_kdc_ocsp" + #define KRB5_CONF_PKINIT_POOL "pkinit_pool" + #define KRB5_CONF_PKINIT_REQUIRE_CRL_CHECKING "pkinit_require_crl_checking" +@@ -173,7 +174,6 @@ typedef struct _pkinit_identity_opts { + char **anchors; + char **intermediates; + char **crls; +- char *ocsp; + int idtype; + char *cert_filename; + char *key_filename; +diff --git a/src/plugins/preauth/pkinit/pkinit_identity.c b/src/plugins/preauth/pkinit/pkinit_identity.c +index 177a2cad8..a897efa25 100644 +--- a/src/plugins/preauth/pkinit/pkinit_identity.c ++++ b/src/plugins/preauth/pkinit/pkinit_identity.c +@@ -125,7 +125,6 @@ pkinit_init_identity_opts(pkinit_identity_opts **idopts) + opts->anchors = NULL; + opts->intermediates = NULL; + opts->crls = NULL; +- opts->ocsp = NULL; + + opts->cert_filename = NULL; + opts->key_filename = NULL; +@@ -174,12 +173,6 @@ pkinit_dup_identity_opts(pkinit_identity_opts *src_opts, + if (retval) + goto cleanup; + +- if (src_opts->ocsp != NULL) { +- newopts->ocsp = strdup(src_opts->ocsp); +- if (newopts->ocsp == NULL) +- goto cleanup; +- } +- + if (src_opts->cert_filename != NULL) { + newopts->cert_filename = strdup(src_opts->cert_filename); + if (newopts->cert_filename == NULL) +@@ -674,10 +667,6 @@ pkinit_identity_prompt(krb5_context context, + if (retval) + goto errout; + } +- if (idopts->ocsp != NULL) { +- retval = ENOTSUP; +- goto errout; +- } + + errout: + return retval; +diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c +index 731d14eb8..32ca122f2 100644 +--- a/src/plugins/preauth/pkinit/pkinit_srv.c ++++ b/src/plugins/preauth/pkinit/pkinit_srv.c +@@ -1252,7 +1252,7 @@ static krb5_error_code + pkinit_init_kdc_profile(krb5_context context, pkinit_kdc_context plgctx) + { + krb5_error_code retval; +- char *eku_string = NULL; ++ char *eku_string = NULL, *ocsp_check = NULL; + + pkiDebug("%s: entered for realm %s\n", __FUNCTION__, plgctx->realmname); + retval = pkinit_kdcdefault_string(context, plgctx->realmname, +@@ -1287,7 +1287,15 @@ pkinit_init_kdc_profile(krb5_context context, pkinit_kdc_context plgctx) + + pkinit_kdcdefault_string(context, plgctx->realmname, + KRB5_CONF_PKINIT_KDC_OCSP, +- &plgctx->idopts->ocsp); ++ &ocsp_check); ++ if (ocsp_check != NULL) { ++ free(ocsp_check); ++ retval = ENOTSUP; ++ krb5_set_error_message(context, retval, ++ _("OCSP is not supported: (realm: %s)"), ++ plgctx->realmname); ++ goto errout; ++ } + + pkinit_kdcdefault_integer(context, plgctx->realmname, + KRB5_CONF_PKINIT_DH_MIN_BITS, diff --git a/SOURCES/Remove-incorrect-KDC-assertion.patch b/SOURCES/Remove-incorrect-KDC-assertion.patch new file mode 100644 index 0000000..f4f84c8 --- /dev/null +++ b/SOURCES/Remove-incorrect-KDC-assertion.patch @@ -0,0 +1,60 @@ +From ba85fb83677b6e46cf35e090fbb58129adbc048b Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Sat, 15 Dec 2018 11:56:36 +0200 +Subject: [PATCH] Remove incorrect KDC assertion + +The assertion in return_enc_padata() is reachable because +kdc_make_s4u2self_rep() may have previously added encrypted padata. +It is no longer necessary because the code uses add_pa_data_element() +instead of allocating a new list. + +CVE-2018-20217: + +In MIT krb5 1.8 or later, an authenticated user who can obtain a TGT +using an older encryption type (DES, DES3, or RC4) can cause an +assertion failure in the KDC by sending an S4U2Self request. + +[ghudson@mit.edu: rewrote commit message with CVE description] + +(cherry picked from commit 94e5eda5bb94d1d44733a49c3d9b6d1e42c74def) + +ticket: 8767 +version_fixed: 1.16.3 + +(cherry picked from commit 56870f9456da78d77a667dfc03a6d90f948dc3a5) +(cherry picked from commit 2a96564f6fd53f2e1e8424d865c02349bfe5b818) +--- + src/kdc/kdc_preauth.c | 1 - + src/tests/gssapi/t_s4u.py | 7 +++++++ + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c +index 81d0b8cff..787a09684 100644 +--- a/src/kdc/kdc_preauth.c ++++ b/src/kdc/kdc_preauth.c +@@ -1640,7 +1640,6 @@ return_enc_padata(krb5_context context, krb5_data *req_pkt, + krb5_error_code code = 0; + /* This should be initialized and only used for Win2K compat and other + * specific standardized uses such as FAST negotiation. */ +- assert(reply_encpart->enc_padata == NULL); + if (is_referral) { + code = return_referral_enc_padata(context, reply_encpart, server); + if (code) +diff --git a/src/tests/gssapi/t_s4u.py b/src/tests/gssapi/t_s4u.py +index 7366e3915..9f8591f6c 100755 +--- a/src/tests/gssapi/t_s4u.py ++++ b/src/tests/gssapi/t_s4u.py +@@ -144,6 +144,13 @@ if 'auth1: user@' not in out or 'auth2: user@' not in out: + + realm.stop() + ++for realm in multipass_realms(create_host=False, get_creds=False): ++ service1 = 'service/1@%s' % realm.realm ++ realm.addprinc(service1) ++ realm.extract_keytab(service1, realm.keytab) ++ realm.kinit(service1, None, ['-k']) ++ realm.run(['./t_s4u', 'p:user', '-']) ++ + # Exercise cross-realm S4U2Self. The query in the foreign realm will + # fail, but we can check that the right server principal was used. + r1, r2 = cross_realms(2, create_user=False) diff --git a/SOURCES/Remove-nodes-option-from-make-certs-scripts.patch b/SOURCES/Remove-nodes-option-from-make-certs-scripts.patch new file mode 100644 index 0000000..572f91e --- /dev/null +++ b/SOURCES/Remove-nodes-option-from-make-certs-scripts.patch @@ -0,0 +1,46 @@ +From db667872d9a4103ffc30d4bd570a378a184d7c7f Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Thu, 3 May 2018 14:40:45 -0400 +Subject: [PATCH] Remove "-nodes" option from make-certs scripts + +The openssl command does not recognize options after positional +arguments, so in "openssl genrsa $KEYSIZE -nodes", the "-nodes" was +ignored as a excess positional argument prior to OpenSSL 1.1.0h, and +now causes an error. "-nodes" is an option to the openssl req and +pkcs12 subcommands, but genrsa creates unencrypted keys by default. + +[ghudson@mit.edu: edited commit message] + +(cherry picked from commit 928a36aae326d496c9a73f2cd41b4da45eef577c) +(cherry picked from commit 83da5675551dba13fee837adc26ce885a061dbc1) +--- + src/tests/dejagnu/pkinit-certs/make-certs.sh | 2 +- + src/tests/dejagnu/proxy-certs/make-certs.sh | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/tests/dejagnu/pkinit-certs/make-certs.sh b/src/tests/dejagnu/pkinit-certs/make-certs.sh +index 23426af8a..fa937f449 100755 +--- a/src/tests/dejagnu/pkinit-certs/make-certs.sh ++++ b/src/tests/dejagnu/pkinit-certs/make-certs.sh +@@ -114,7 +114,7 @@ extendedKeyUsage = $CLIENT_EKU_LIST + EOF + + # Generate a private key. +-openssl genrsa $KEYSIZE -nodes > privkey.pem ++openssl genrsa $KEYSIZE > privkey.pem + openssl rsa -in privkey.pem -out privkey-enc.pem -des3 -passout pass:encrypted + + # Generate a "CA" certificate. +diff --git a/src/tests/dejagnu/proxy-certs/make-certs.sh b/src/tests/dejagnu/proxy-certs/make-certs.sh +index 1191bf05e..24ef91bde 100755 +--- a/src/tests/dejagnu/proxy-certs/make-certs.sh ++++ b/src/tests/dejagnu/proxy-certs/make-certs.sh +@@ -79,7 +79,7 @@ extendedKeyUsage = $PROXY_EKU_LIST + EOF + + # Generate a private key. +-openssl genrsa $KEYSIZE -nodes > privkey.pem ++openssl genrsa $KEYSIZE > privkey.pem + + # Generate a "CA" certificate. + SUBJECT=signer openssl req -config openssl.cnf -new -x509 -extensions exts_ca \ diff --git a/SOURCES/Remove-sent_nontrivial_preauth-field.patch b/SOURCES/Remove-sent_nontrivial_preauth-field.patch new file mode 100644 index 0000000..f210bb9 --- /dev/null +++ b/SOURCES/Remove-sent_nontrivial_preauth-field.patch @@ -0,0 +1,56 @@ +From fd44fa60948a58634a3757be7c5c52fc671e48c7 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Mon, 16 Jan 2017 13:42:18 -0500 +Subject: [PATCH] Remove sent_nontrivial_preauth field + +In krb5_init_creds_context, the selected_preauth_type field subsumes +the need for sent_nontrivial_preauth. Use it instead. + +(cherry picked from commit 5fef7aa7e43e45d227f2d53c661a23c932caafca) +--- + src/lib/krb5/krb/get_in_tkt.c | 5 +---- + src/lib/krb5/krb/init_creds_ctx.h | 1 - + 2 files changed, 1 insertion(+), 5 deletions(-) + +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index 988fca233..48dc00ea6 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -1359,8 +1359,6 @@ init_creds_step_request(krb5_context context, + krb5_free_data(context, ctx->encoded_previous_request); + ctx->encoded_previous_request = NULL; + } +- if (ctx->request->padata) +- ctx->sent_nontrivial_preauth = TRUE; + if (ctx->enc_pa_rep_permitted) { + code = add_padata(&ctx->request->padata, KRB5_ENCPADATA_REQ_ENC_PA_REP, + NULL, 0); +@@ -1485,7 +1483,7 @@ init_creds_step_reply(krb5_context context, + ctx->restarted = TRUE; + code = restart_init_creds_loop(context, ctx, TRUE); + } else if (!ctx->restarted && reply_code == KDC_ERR_PREAUTH_FAILED && +- !ctx->sent_nontrivial_preauth) { ++ ctx->selected_preauth_type == KRB5_PADATA_NONE) { + /* The KDC didn't like our informational padata (probably a pre-1.7 + * MIT krb5 KDC). Retry without it. */ + ctx->enc_pa_rep_permitted = FALSE; +@@ -1525,7 +1523,6 @@ init_creds_step_reply(krb5_context context, + goto cleanup; + /* Reset per-realm negotiation state. */ + ctx->restarted = FALSE; +- ctx->sent_nontrivial_preauth = FALSE; + ctx->enc_pa_rep_permitted = TRUE; + code = restart_init_creds_loop(context, ctx, FALSE); + } else { +diff --git a/src/lib/krb5/krb/init_creds_ctx.h b/src/lib/krb5/krb/init_creds_ctx.h +index a7cded942..8c8b7494b 100644 +--- a/src/lib/krb5/krb/init_creds_ctx.h ++++ b/src/lib/krb5/krb/init_creds_ctx.h +@@ -58,7 +58,6 @@ struct _krb5_init_creds_context { + krb5_enctype etype; + krb5_boolean enc_pa_rep_permitted; + krb5_boolean restarted; +- krb5_boolean sent_nontrivial_preauth; + krb5_boolean preauth_required; + struct krb5_responder_context_st rctx; + krb5_preauthtype selected_preauth_type; diff --git a/SOURCES/Return-UPN-SANs-as-strings.patch b/SOURCES/Return-UPN-SANs-as-strings.patch new file mode 100644 index 0000000..1823f9e --- /dev/null +++ b/SOURCES/Return-UPN-SANs-as-strings.patch @@ -0,0 +1,204 @@ +From 0f94f224f16f196d8d3fb56cfcf4a65bdd0f20c7 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Thu, 22 Mar 2018 20:07:17 -0400 +Subject: [PATCH] Return UPN SANs as strings + +(cherry picked from commit fd3c824e3be56a1fa77d140fd7e93934bfd6e565) +--- + src/plugins/preauth/pkinit/pkinit_crypto.h | 4 +-- + .../preauth/pkinit/pkinit_crypto_openssl.c | 28 +++++++------------ + src/plugins/preauth/pkinit/pkinit_matching.c | 16 ++--------- + src/plugins/preauth/pkinit/pkinit_srv.c | 21 +++++++++----- + 4 files changed, 29 insertions(+), 40 deletions(-) + +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h +index c14f4456a..b6e4e0ac3 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto.h ++++ b/src/plugins/preauth/pkinit/pkinit_crypto.h +@@ -101,7 +101,7 @@ typedef struct _pkinit_cert_matching_data { + unsigned int ku_bits; /* key usage information */ + unsigned int eku_bits; /* extended key usage information */ + krb5_principal *sans; /* Null-terminated array of PKINIT SANs */ +- krb5_principal *upns; /* Null-terimnated array of UPN SANs */ ++ char **upns; /* Null-terimnated array of UPN SANs */ + } pkinit_cert_matching_data; + + /* +@@ -253,7 +253,7 @@ krb5_error_code crypto_retrieve_cert_sans + if non-NULL, a null-terminated array of + id-pkinit-san values found in the certificate + are returned */ +- krb5_principal **upn_sans, /* OUT ++ char ***upn_sans, /* OUT + if non-NULL, a null-terminated array of + id-ms-upn-san values found in the certificate + are returned */ +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index cf2f16294..3949eb9c2 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -29,6 +29,7 @@ + * SUCH DAMAGES. + */ + ++#include "k5-int.h" + #include "pkinit_crypto_openssl.h" + #include "k5-buf.h" + #include +@@ -2095,15 +2096,14 @@ crypto_retrieve_X509_sans(krb5_context context, + pkinit_plg_crypto_context plgctx, + pkinit_req_crypto_context reqctx, + X509 *cert, +- krb5_principal **princs_ret, +- krb5_principal **upn_ret, ++ krb5_principal **princs_ret, char ***upn_ret, + unsigned char ***dns_ret) + { + krb5_error_code retval = EINVAL; + char buf[DN_BUF_LEN]; + int p = 0, u = 0, d = 0, ret = 0, l; + krb5_principal *princs = NULL; +- krb5_principal *upns = NULL; ++ char **upns = NULL; + unsigned char **dnss = NULL; + unsigned int i, num_found = 0, num_sans = 0; + X509_EXTENSION *ext = NULL; +@@ -2153,7 +2153,7 @@ crypto_retrieve_X509_sans(krb5_context context, + } + } + if (upn_ret != NULL) { +- upns = calloc(num_sans + 1, sizeof(krb5_principal)); ++ upns = calloc(num_sans + 1, sizeof(*upns)); + if (upns == NULL) { + retval = ENOMEM; + goto cleanup; +@@ -2196,16 +2196,9 @@ crypto_retrieve_X509_sans(krb5_context context, + /* Prevent abuse of embedded null characters. */ + if (memchr(name.data, '\0', name.length)) + break; +- ret = krb5_parse_name_flags(context, name.data, +- KRB5_PRINCIPAL_PARSE_ENTERPRISE, +- &upns[u]); +- if (ret) { +- pkiDebug("%s: failed parsing ms-upn san value\n", +- __FUNCTION__); +- } else { +- u++; +- num_found++; +- } ++ upns[u] = k5memdup0(name.data, name.length, &ret); ++ if (upns[u] == NULL) ++ goto cleanup; + } else { + pkiDebug("%s: unrecognized othername oid in SAN\n", + __FUNCTION__); +@@ -2257,7 +2250,7 @@ cleanup: + krb5_free_principal(context, princs[i]); + free(princs); + for (i = 0; upns != NULL && upns[i] != NULL; i++) +- krb5_free_principal(context, upns[i]); ++ free(upns[i]); + free(upns); + for (i = 0; dnss != NULL && dnss[i] != NULL; i++) + free(dnss[i]); +@@ -2281,8 +2274,7 @@ crypto_retrieve_cert_sans(krb5_context context, + pkinit_plg_crypto_context plgctx, + pkinit_req_crypto_context reqctx, + pkinit_identity_crypto_context idctx, +- krb5_principal **princs_ret, +- krb5_principal **upn_ret, ++ krb5_principal **princs_ret, char ***upn_ret, + unsigned char ***dns_ret) + { + krb5_error_code retval = EINVAL; +@@ -5111,7 +5103,7 @@ crypto_cert_free_matching_data(krb5_context context, + krb5_free_principal(context, md->sans[i]); + free(md->sans); + for (i = 0; md->upns != NULL && md->upns[i] != NULL; i++) +- krb5_free_principal(context, md->upns[i]); ++ free(md->upns[i]); + free(md->upns); + free(md); + } +diff --git a/src/plugins/preauth/pkinit/pkinit_matching.c b/src/plugins/preauth/pkinit/pkinit_matching.c +index fe1e0f386..d929fb3c0 100644 +--- a/src/plugins/preauth/pkinit/pkinit_matching.c ++++ b/src/plugins/preauth/pkinit/pkinit_matching.c +@@ -490,11 +490,7 @@ component_match(krb5_context context, + break; + } + for (i = 0; md->upns != NULL && md->upns[i] != NULL; i++) { +- krb5_unparse_name_flags(context, md->upns[i], +- KRB5_PRINCIPAL_UNPARSE_NO_REALM, +- &princ_string); +- match = regexp_match(context, rc, princ_string); +- krb5_free_unparsed_name(context, princ_string); ++ match = regexp_match(context, rc, md->upns[i]); + if (match) + break; + } +@@ -584,14 +580,8 @@ check_all_certs(krb5_context context, + pkiDebug("%s: PKINIT san: '%s'\n", __FUNCTION__, san_string); + krb5_free_unparsed_name(context, san_string); + } +- for (j = 0; md->upns != NULL && md->upns[j] != NULL; j++) { +- char *san_string; +- krb5_unparse_name_flags(context, md->upns[j], +- KRB5_PRINCIPAL_UNPARSE_NO_REALM, +- &san_string); +- pkiDebug("%s: UPN san: '%s'\n", __FUNCTION__, san_string); +- krb5_free_unparsed_name(context, san_string); +- } ++ for (j = 0; md->upns != NULL && md->upns[j] != NULL; j++) ++ pkiDebug("%s: UPN san: '%s'\n", __FUNCTION__, md->upns[j]); + #endif + certs_checked++; + for (rc = rs->crs; rc != NULL; rc = rc->next) { +diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c +index 143d331a2..42ad45fe4 100644 +--- a/src/plugins/preauth/pkinit/pkinit_srv.c ++++ b/src/plugins/preauth/pkinit/pkinit_srv.c +@@ -174,8 +174,9 @@ verify_client_san(krb5_context context, + int *valid_san) + { + krb5_error_code retval; +- krb5_principal *princs = NULL; +- krb5_principal *upns = NULL; ++ krb5_principal *princs = NULL, upn; ++ krb5_boolean match; ++ char **upns = NULL; + int i; + #ifdef DEBUG_SAN_INFO + char *client_string = NULL, *san_string; +@@ -251,12 +252,18 @@ verify_client_san(krb5_context context, + pkiDebug("%s: Checking upn sans\n", __FUNCTION__); + for (i = 0; upns[i] != NULL; i++) { + #ifdef DEBUG_SAN_INFO +- krb5_unparse_name(context, upns[i], &san_string); + pkiDebug("%s: Comparing client '%s' to upn san value '%s'\n", +- __FUNCTION__, client_string, san_string); +- krb5_free_unparsed_name(context, san_string); ++ __FUNCTION__, client_string, upns[i]); + #endif +- if (cb->match_client(context, rock, upns[i])) { ++ retval = krb5_parse_name_flags(context, upns[i], ++ KRB5_PRINCIPAL_PARSE_ENTERPRISE, &upn); ++ if (retval) { ++ /* XXX trace */ ++ continue; ++ } ++ match = cb->match_client(context, rock, upn); ++ krb5_free_principal(context, upn); ++ if (match) { + TRACE_PKINIT_SERVER_MATCHING_UPN_FOUND(context); + *valid_san = 1; + retval = 0; +@@ -282,7 +289,7 @@ out: + } + if (upns != NULL) { + for (i = 0; upns[i] != NULL; i++) +- krb5_free_principal(context, upns[i]); ++ free(upns[i]); + free(upns); + } + #ifdef DEBUG_SAN_INFO diff --git a/SOURCES/Save-SANs-separately-and-unparse-them-with-NO_REALM.patch b/SOURCES/Save-SANs-separately-and-unparse-them-with-NO_REALM.patch new file mode 100644 index 0000000..3930589 --- /dev/null +++ b/SOURCES/Save-SANs-separately-and-unparse-them-with-NO_REALM.patch @@ -0,0 +1,148 @@ +From c796a84ffa455b60e08508f4b706f7ecae0054de Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Thu, 22 Mar 2018 19:46:22 -0400 +Subject: [PATCH] Save SANs separately and unparse them with NO_REALM + +(cherry picked from commit 23ea8d6a9617d17ae5a529c23174d77adac39055) +--- + src/plugins/preauth/pkinit/pkinit_crypto.h | 4 +- + .../preauth/pkinit/pkinit_crypto_openssl.c | 37 ++----------------- + src/plugins/preauth/pkinit/pkinit_matching.c | 30 +++++++++++---- + 3 files changed, 28 insertions(+), 43 deletions(-) + +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h +index a0176acad..c14f4456a 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto.h ++++ b/src/plugins/preauth/pkinit/pkinit_crypto.h +@@ -100,8 +100,8 @@ typedef struct _pkinit_cert_matching_data { + char *issuer_dn; /* rfc2253-style issuer name string */ + unsigned int ku_bits; /* key usage information */ + unsigned int eku_bits; /* extended key usage information */ +- krb5_principal *sans; /* Null-terminated array of subject alternative +- name info (pkinit and ms-upn) */ ++ krb5_principal *sans; /* Null-terminated array of PKINIT SANs */ ++ krb5_principal *upns; /* Null-terimnated array of UPN SANs */ + } pkinit_cert_matching_data; + + /* +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index 34ed7afaf..cf2f16294 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -5110,6 +5110,9 @@ crypto_cert_free_matching_data(krb5_context context, + for (i = 0; md->sans != NULL && md->sans[i] != NULL; i++) + krb5_free_principal(context, md->sans[i]); + free(md->sans); ++ for (i = 0; md->upns != NULL && md->upns[i] != NULL; i++) ++ krb5_free_principal(context, md->upns[i]); ++ free(md->upns); + free(md); + } + +@@ -5138,8 +5141,6 @@ get_matching_data(krb5_context context, + { + krb5_error_code ret = ENOMEM; + pkinit_cert_matching_data *md = NULL; +- krb5_principal *pkinit_sans = NULL, *upn_sans = NULL; +- size_t i, j; + + *md_out = NULL; + +@@ -5156,40 +5157,10 @@ get_matching_data(krb5_context context, + + /* Get the SAN data. */ + ret = crypto_retrieve_X509_sans(context, plg_cryptoctx, req_cryptoctx, +- cert, &pkinit_sans, &upn_sans, NULL); ++ cert, &md->sans, &md->upns, NULL); + if (ret) + goto cleanup; + +- j = 0; +- if (pkinit_sans != NULL) { +- for (i = 0; pkinit_sans[i] != NULL; i++) +- j++; +- } +- if (upn_sans != NULL) { +- for (i = 0; upn_sans[i] != NULL; i++) +- j++; +- } +- if (j != 0) { +- md->sans = calloc((size_t)j+1, sizeof(*md->sans)); +- if (md->sans == NULL) { +- ret = ENOMEM; +- goto cleanup; +- } +- j = 0; +- if (pkinit_sans != NULL) { +- for (i = 0; pkinit_sans[i] != NULL; i++) +- md->sans[j++] = pkinit_sans[i]; +- free(pkinit_sans); +- } +- if (upn_sans != NULL) { +- for (i = 0; upn_sans[i] != NULL; i++) +- md->sans[j++] = upn_sans[i]; +- free(upn_sans); +- } +- md->sans[j] = NULL; +- } else +- md->sans = NULL; +- + /* Get the KU and EKU data. */ + ret = crypto_retrieve_X509_key_usage(context, plg_cryptoctx, + req_cryptoctx, cert, &md->ku_bits, +diff --git a/src/plugins/preauth/pkinit/pkinit_matching.c b/src/plugins/preauth/pkinit/pkinit_matching.c +index d6775dc4f..fe1e0f386 100644 +--- a/src/plugins/preauth/pkinit/pkinit_matching.c ++++ b/src/plugins/preauth/pkinit/pkinit_matching.c +@@ -470,7 +470,6 @@ component_match(krb5_context context, + { + int match = 0; + int i; +- krb5_principal p; + char *princ_string; + + switch (rc->kwval_type) { +@@ -483,10 +482,17 @@ component_match(krb5_context context, + match = regexp_match(context, rc, md->issuer_dn); + break; + case kw_san: +- if (md->sans == NULL) +- break; +- for (i = 0, p = md->sans[i]; p != NULL; p = md->sans[++i]) { +- krb5_unparse_name(context, p, &princ_string); ++ for (i = 0; md->sans != NULL && md->sans[i] != NULL; i++) { ++ krb5_unparse_name(context, md->sans[i], &princ_string); ++ match = regexp_match(context, rc, princ_string); ++ krb5_free_unparsed_name(context, princ_string); ++ if (match) ++ break; ++ } ++ for (i = 0; md->upns != NULL && md->upns[i] != NULL; i++) { ++ krb5_unparse_name_flags(context, md->upns[i], ++ KRB5_PRINCIPAL_UNPARSE_NO_REALM, ++ &princ_string); + match = regexp_match(context, rc, princ_string); + krb5_free_unparsed_name(context, princ_string); + if (match) +@@ -572,10 +578,18 @@ check_all_certs(krb5_context context, + pkiDebug("%s: subject: '%s'\n", __FUNCTION__, md->subject_dn); + #if 0 + pkiDebug("%s: issuer: '%s'\n", __FUNCTION__, md->subject_dn); +- for (j = 0, p = md->sans[j]; p != NULL; p = md->sans[++j]) { ++ for (j = 0; md->sans != NULL && md->sans[j] != NULL; j++) { + char *san_string; +- krb5_unparse_name(context, p, &san_string); +- pkiDebug("%s: san: '%s'\n", __FUNCTION__, san_string); ++ krb5_unparse_name(context, md->sans[j], &san_string); ++ pkiDebug("%s: PKINIT san: '%s'\n", __FUNCTION__, san_string); ++ krb5_free_unparsed_name(context, san_string); ++ } ++ for (j = 0; md->upns != NULL && md->upns[j] != NULL; j++) { ++ char *san_string; ++ krb5_unparse_name_flags(context, md->upns[j], ++ KRB5_PRINCIPAL_UNPARSE_NO_REALM, ++ &san_string); ++ pkiDebug("%s: UPN san: '%s'\n", __FUNCTION__, san_string); + krb5_free_unparsed_name(context, san_string); + } + #endif diff --git a/SOURCES/Simplify-PKINIT-cert-iteration-and-selection.patch b/SOURCES/Simplify-PKINIT-cert-iteration-and-selection.patch new file mode 100644 index 0000000..4035c1f --- /dev/null +++ b/SOURCES/Simplify-PKINIT-cert-iteration-and-selection.patch @@ -0,0 +1,843 @@ +From 5bca501af5e28e0a8f5194088fdaea53f5fa419f Mon Sep 17 00:00:00 2001 +From: Matt Rogers +Date: Tue, 21 Mar 2017 21:24:14 -0400 +Subject: [PATCH] Simplify PKINIT cert iteration and selection + +Remove the pkinit_cert_handle structures and iteration functions used +during certificate matching. Instead, make pkinit_matching.c obtain a +list of matching data objects from the crypto code, and then select a +cert based on the index into that list. + +Also fix a typo in the name of crypto_retrieve_X509_key_usage(). + +[ghudson@mit.edu: simplified code] + +(cherry picked from commit 01b1c0e26252a00f2215408b0e473b84aa0f6a87) +--- + src/plugins/preauth/pkinit/pkinit_crypto.h | 75 +--- + .../preauth/pkinit/pkinit_crypto_openssl.c | 383 +++++++----------- + .../preauth/pkinit/pkinit_crypto_openssl.h | 19 - + src/plugins/preauth/pkinit/pkinit_matching.c | 139 +------ + 4 files changed, 194 insertions(+), 422 deletions(-) + +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h +index 49b96b8ee..a0176acad 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto.h ++++ b/src/plugins/preauth/pkinit/pkinit_crypto.h +@@ -96,7 +96,6 @@ typedef struct _pkinit_cert_iter_info *pkinit_cert_iter_handle; + #define PKINIT_ITER_NO_MORE 0x11111111 /* XXX */ + + typedef struct _pkinit_cert_matching_data { +- pkinit_cert_handle ch; /* cert handle for this certificate */ + char *subject_dn; /* rfc2253-style subject name string */ + char *issuer_dn; /* rfc2253-style issuer name string */ + unsigned int ku_bits; /* key usage information */ +@@ -458,68 +457,38 @@ krb5_error_code crypto_free_cert_info + + + /* +- * Get number of certificates available after crypto_load_certs() ++ * Get a null-terminated list of certificate matching data objects for the ++ * certificates loaded in id_cryptoctx. + */ +-krb5_error_code crypto_cert_get_count +- (krb5_context context, /* IN */ +- pkinit_plg_crypto_context plg_cryptoctx, /* IN */ +- pkinit_req_crypto_context req_cryptoctx, /* IN */ +- pkinit_identity_crypto_context id_cryptoctx, /* IN */ +- int *cert_count); /* OUT */ ++krb5_error_code ++crypto_cert_get_matching_data(krb5_context context, ++ pkinit_plg_crypto_context plg_cryptoctx, ++ pkinit_req_crypto_context req_cryptoctx, ++ pkinit_identity_crypto_context id_cryptoctx, ++ pkinit_cert_matching_data ***md_out); + + /* +- * Begin iteration over the certs loaded in crypto_load_certs() ++ * Free a matching data object. + */ +-krb5_error_code crypto_cert_iteration_begin +- (krb5_context context, /* IN */ +- pkinit_plg_crypto_context plg_cryptoctx, /* IN */ +- pkinit_req_crypto_context req_cryptoctx, /* IN */ +- pkinit_identity_crypto_context id_cryptoctx, /* IN */ +- pkinit_cert_iter_handle *iter_handle); /* OUT */ ++void ++crypto_cert_free_matching_data(krb5_context context, ++ pkinit_cert_matching_data *md); + + /* +- * End iteration over the certs loaded in crypto_load_certs() ++ * Free a list of matching data objects. + */ +-krb5_error_code crypto_cert_iteration_end +- (krb5_context context, /* IN */ +- pkinit_cert_iter_handle iter_handle); /* IN */ ++void ++crypto_cert_free_matching_data_list(krb5_context context, ++ pkinit_cert_matching_data **matchdata); + + /* +- * Get next certificate handle ++ * Choose one of the certificates loaded in idctx to use for PKINIT client ++ * operations. cred_index must be an index into the array of matching objects ++ * returned by crypto_cert_get_matching_data(). + */ +-krb5_error_code crypto_cert_iteration_next +- (krb5_context context, /* IN */ +- pkinit_cert_iter_handle iter_handle, /* IN */ +- pkinit_cert_handle *cert_handle); /* OUT */ +- +-/* +- * Release cert handle +- */ +-krb5_error_code crypto_cert_release +- (krb5_context context, /* IN */ +- pkinit_cert_handle cert_handle); /* IN */ +- +-/* +- * Get certificate matching information +- */ +-krb5_error_code crypto_cert_get_matching_data +- (krb5_context context, /* IN */ +- pkinit_cert_handle cert_handle, /* IN */ +- pkinit_cert_matching_data **ret_data); /* OUT */ +- +-/* +- * Free certificate information +- */ +-krb5_error_code crypto_cert_free_matching_data +- (krb5_context context, /* IN */ +- pkinit_cert_matching_data *data); /* IN */ +- +-/* +- * Make the given certificate "the chosen one" +- */ +-krb5_error_code crypto_cert_select +- (krb5_context context, /* IN */ +- pkinit_cert_matching_data *data); /* IN */ ++krb5_error_code ++crypto_cert_select(krb5_context context, pkinit_identity_crypto_context idctx, ++ size_t cred_index); + + /* + * Select the default certificate as "the chosen one" +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index 6098acc6a..f70aab5b3 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -4974,136 +4974,16 @@ cleanup: + return retval; + } + +-/* +- * Get number of certificates available after crypto_load_certs() +- */ +-krb5_error_code +-crypto_cert_get_count(krb5_context context, +- pkinit_plg_crypto_context plg_cryptoctx, +- pkinit_req_crypto_context req_cryptoctx, +- pkinit_identity_crypto_context id_cryptoctx, +- int *cert_count) +-{ +- int count; +- +- if (id_cryptoctx == NULL || id_cryptoctx->creds[0] == NULL) +- return EINVAL; +- +- for (count = 0; +- count <= MAX_CREDS_ALLOWED && id_cryptoctx->creds[count] != NULL; +- count++); +- *cert_count = count; +- return 0; +-} +- +- +-/* +- * Begin iteration over the certs loaded in crypto_load_certs() +- */ +-krb5_error_code +-crypto_cert_iteration_begin(krb5_context context, +- pkinit_plg_crypto_context plg_cryptoctx, +- pkinit_req_crypto_context req_cryptoctx, +- pkinit_identity_crypto_context id_cryptoctx, +- pkinit_cert_iter_handle *ih_ret) +-{ +- struct _pkinit_cert_iter_data *id; +- +- if (id_cryptoctx == NULL || ih_ret == NULL) +- return EINVAL; +- if (id_cryptoctx->creds[0] == NULL) /* No cred info available */ +- return ENOENT; +- +- id = calloc(1, sizeof(*id)); +- if (id == NULL) +- return ENOMEM; +- id->magic = ITER_MAGIC; +- id->plgctx = plg_cryptoctx, +- id->reqctx = req_cryptoctx, +- id->idctx = id_cryptoctx; +- id->index = 0; +- *ih_ret = (pkinit_cert_iter_handle) id; +- return 0; +-} +- +-/* +- * End iteration over the certs loaded in crypto_load_certs() +- */ +-krb5_error_code +-crypto_cert_iteration_end(krb5_context context, +- pkinit_cert_iter_handle ih) +-{ +- struct _pkinit_cert_iter_data *id = (struct _pkinit_cert_iter_data *)ih; +- +- if (id == NULL || id->magic != ITER_MAGIC) +- return EINVAL; +- free(ih); +- return 0; +-} +- +-/* +- * Get next certificate handle +- */ +-krb5_error_code +-crypto_cert_iteration_next(krb5_context context, +- pkinit_cert_iter_handle ih, +- pkinit_cert_handle *ch_ret) +-{ +- struct _pkinit_cert_iter_data *id = (struct _pkinit_cert_iter_data *)ih; +- struct _pkinit_cert_data *cd; +- pkinit_identity_crypto_context id_cryptoctx; +- +- if (id == NULL || id->magic != ITER_MAGIC) +- return EINVAL; +- +- if (ch_ret == NULL) +- return EINVAL; +- +- id_cryptoctx = id->idctx; +- if (id_cryptoctx == NULL) +- return EINVAL; +- +- if (id_cryptoctx->creds[id->index] == NULL) +- return PKINIT_ITER_NO_MORE; +- +- cd = calloc(1, sizeof(*cd)); +- if (cd == NULL) +- return ENOMEM; +- +- cd->magic = CERT_MAGIC; +- cd->plgctx = id->plgctx; +- cd->reqctx = id->reqctx; +- cd->idctx = id->idctx; +- cd->index = id->index; +- cd->cred = id_cryptoctx->creds[id->index++]; +- *ch_ret = (pkinit_cert_handle)cd; +- return 0; +-} +- +-/* +- * Release cert handle +- */ +-krb5_error_code +-crypto_cert_release(krb5_context context, +- pkinit_cert_handle ch) +-{ +- struct _pkinit_cert_data *cd = (struct _pkinit_cert_data *)ch; +- if (cd == NULL || cd->magic != CERT_MAGIC) +- return EINVAL; +- free(cd); +- return 0; +-} +- + /* + * Get certificate Key Usage and Extended Key Usage + */ + static krb5_error_code +-crypto_retieve_X509_key_usage(krb5_context context, +- pkinit_plg_crypto_context plgcctx, +- pkinit_req_crypto_context reqcctx, +- X509 *x, +- unsigned int *ret_ku_bits, +- unsigned int *ret_eku_bits) ++crypto_retrieve_X509_key_usage(krb5_context context, ++ pkinit_plg_crypto_context plgcctx, ++ pkinit_req_crypto_context reqcctx, ++ X509 *x, ++ unsigned int *ret_ku_bits, ++ unsigned int *ret_eku_bits) + { + krb5_error_code retval = 0; + int i; +@@ -5202,55 +5082,99 @@ X509_NAME_oneline_ex(X509_NAME * a, + } + + /* +- * Get certificate information ++ * Get number of certificates available after crypto_load_certs() + */ +-krb5_error_code +-crypto_cert_get_matching_data(krb5_context context, +- pkinit_cert_handle ch, +- pkinit_cert_matching_data **ret_md) ++static krb5_error_code ++crypto_cert_get_count(pkinit_identity_crypto_context id_cryptoctx, ++ int *cert_count) + { +- krb5_error_code retval; +- pkinit_cert_matching_data *md; +- krb5_principal *pkinit_sans =NULL, *upn_sans = NULL; +- struct _pkinit_cert_data *cd = (struct _pkinit_cert_data *)ch; +- unsigned int i, j; ++ int count; ++ ++ *cert_count = 0; ++ if (id_cryptoctx == NULL || id_cryptoctx->creds[0] == NULL) ++ return EINVAL; ++ ++ for (count = 0; ++ count <= MAX_CREDS_ALLOWED && id_cryptoctx->creds[count] != NULL; ++ count++); ++ *cert_count = count; ++ return 0; ++} ++ ++void ++crypto_cert_free_matching_data(krb5_context context, ++ pkinit_cert_matching_data *md) ++{ ++ int i; ++ ++ if (md == NULL) ++ return; ++ free(md->subject_dn); ++ free(md->issuer_dn); ++ for (i = 0; md->sans != NULL && md->sans[i] != NULL; i++) ++ krb5_free_principal(context, md->sans[i]); ++ free(md->sans); ++ free(md); ++} ++ ++/* ++ * Free certificate matching data. ++ */ ++void ++crypto_cert_free_matching_data_list(krb5_context context, ++ pkinit_cert_matching_data **list) ++{ ++ int i; ++ ++ for (i = 0; list != NULL && list[i] != NULL; i++) ++ crypto_cert_free_matching_data(context, list[i]); ++ free(list); ++} ++ ++/* ++ * Get certificate matching data for cert. ++ */ ++static krb5_error_code ++get_matching_data(krb5_context context, ++ pkinit_plg_crypto_context plg_cryptoctx, ++ pkinit_req_crypto_context req_cryptoctx, X509 *cert, ++ pkinit_cert_matching_data **md_out) ++{ ++ krb5_error_code ret = ENOMEM; ++ pkinit_cert_matching_data *md = NULL; ++ krb5_principal *pkinit_sans = NULL, *upn_sans = NULL; ++ size_t i, j; + char buf[DN_BUF_LEN]; + unsigned int bufsize = sizeof(buf); + +- if (cd == NULL || cd->magic != CERT_MAGIC) +- return EINVAL; +- if (ret_md == NULL) +- return EINVAL; ++ *md_out = NULL; + + md = calloc(1, sizeof(*md)); + if (md == NULL) +- return ENOMEM; ++ goto cleanup; + +- md->ch = ch; +- +- /* get the subject name (in rfc2253 format) */ +- X509_NAME_oneline_ex(X509_get_subject_name(cd->cred->cert), +- buf, &bufsize, XN_FLAG_SEP_COMMA_PLUS); ++ /* Get the subject name (in rfc2253 format). */ ++ X509_NAME_oneline_ex(X509_get_subject_name(cert), buf, &bufsize, ++ XN_FLAG_SEP_COMMA_PLUS); + md->subject_dn = strdup(buf); + if (md->subject_dn == NULL) { +- retval = ENOMEM; ++ ret = ENOMEM; + goto cleanup; + } + +- /* get the issuer name (in rfc2253 format) */ +- X509_NAME_oneline_ex(X509_get_issuer_name(cd->cred->cert), +- buf, &bufsize, XN_FLAG_SEP_COMMA_PLUS); ++ /* Get the issuer name (in rfc2253 format). */ ++ X509_NAME_oneline_ex(X509_get_issuer_name(cert), buf, &bufsize, ++ XN_FLAG_SEP_COMMA_PLUS); + md->issuer_dn = strdup(buf); + if (md->issuer_dn == NULL) { +- retval = ENOMEM; ++ ret = ENOMEM; + goto cleanup; + } + +- /* get the san data */ +- retval = crypto_retrieve_X509_sans(context, cd->plgctx, cd->reqctx, +- cd->cred->cert, &pkinit_sans, +- &upn_sans, NULL); +- if (retval) ++ /* Get the SAN data. */ ++ ret = crypto_retrieve_X509_sans(context, plg_cryptoctx, req_cryptoctx, ++ cert, &pkinit_sans, &upn_sans, NULL); ++ if (ret) + goto cleanup; + + j = 0; +@@ -5265,7 +5189,7 @@ crypto_cert_get_matching_data(krb5_context context, + if (j != 0) { + md->sans = calloc((size_t)j+1, sizeof(*md->sans)); + if (md->sans == NULL) { +- retval = ENOMEM; ++ ret = ENOMEM; + goto cleanup; + } + j = 0; +@@ -5283,88 +5207,96 @@ crypto_cert_get_matching_data(krb5_context context, + } else + md->sans = NULL; + +- /* get the KU and EKU data */ +- +- retval = crypto_retieve_X509_key_usage(context, cd->plgctx, cd->reqctx, +- cd->cred->cert, +- &md->ku_bits, &md->eku_bits); +- if (retval) ++ /* Get the KU and EKU data. */ ++ ret = crypto_retrieve_X509_key_usage(context, plg_cryptoctx, ++ req_cryptoctx, cert, &md->ku_bits, ++ &md->eku_bits); ++ if (ret) + goto cleanup; + +- *ret_md = md; +- retval = 0; ++ *md_out = md; ++ md = NULL; ++ + cleanup: +- if (retval) { +- if (md) +- crypto_cert_free_matching_data(context, md); ++ crypto_cert_free_matching_data(context, md); ++ return ret; ++} ++ ++krb5_error_code ++crypto_cert_get_matching_data(krb5_context context, ++ pkinit_plg_crypto_context plg_cryptoctx, ++ pkinit_req_crypto_context req_cryptoctx, ++ pkinit_identity_crypto_context id_cryptoctx, ++ pkinit_cert_matching_data ***md_out) ++{ ++ krb5_error_code ret; ++ pkinit_cert_matching_data **md_list = NULL; ++ int count, i; ++ ++ ret = crypto_cert_get_count(id_cryptoctx, &count); ++ if (ret) ++ goto cleanup; ++ ++ md_list = calloc(count + 1, sizeof(*md_list)); ++ if (md_list == NULL) { ++ ret = ENOMEM; ++ goto cleanup; + } +- return retval; ++ ++ for (i = 0; i < count; i++) { ++ ret = get_matching_data(context, plg_cryptoctx, req_cryptoctx, ++ id_cryptoctx->creds[i]->cert, &md_list[i]); ++ if (ret) { ++ pkiDebug("%s: crypto_cert_get_matching_data error %d, %s\n", ++ __FUNCTION__, ret, error_message(ret)); ++ goto cleanup; ++ } ++ } ++ ++ *md_out = md_list; ++ md_list = NULL; ++ ++cleanup: ++ crypto_cert_free_matching_data_list(context, md_list); ++ return ret; + } + + /* +- * Free certificate information ++ * Set the certificate in idctx->creds[cred_index] as the selected certificate. + */ + krb5_error_code +-crypto_cert_free_matching_data(krb5_context context, +- pkinit_cert_matching_data *md) ++crypto_cert_select(krb5_context context, pkinit_identity_crypto_context idctx, ++ size_t cred_index) + { +- krb5_principal p; +- int i; ++ pkinit_cred_info ci = NULL; + +- if (md == NULL) +- return EINVAL; +- if (md->subject_dn) +- free(md->subject_dn); +- if (md->issuer_dn) +- free(md->issuer_dn); +- if (md->sans) { +- for (i = 0, p = md->sans[i]; p != NULL; p = md->sans[++i]) +- krb5_free_principal(context, p); +- free(md->sans); +- } +- free(md); +- return 0; +-} +- +-/* +- * Make this matching certificate "the chosen one" +- */ +-krb5_error_code +-crypto_cert_select(krb5_context context, +- pkinit_cert_matching_data *md) +-{ +- struct _pkinit_cert_data *cd; +- if (md == NULL) +- return EINVAL; +- +- cd = (struct _pkinit_cert_data *)md->ch; +- if (cd == NULL || cd->magic != CERT_MAGIC) +- return EINVAL; ++ if (cred_index >= MAX_CREDS_ALLOWED || idctx->creds[cred_index] == NULL) ++ return ENOENT; + ++ ci = idctx->creds[cred_index]; + /* copy the selected cert into our id_cryptoctx */ +- if (cd->idctx->my_certs != NULL) { +- sk_X509_pop_free(cd->idctx->my_certs, X509_free); +- } +- cd->idctx->my_certs = sk_X509_new_null(); +- sk_X509_push(cd->idctx->my_certs, cd->cred->cert); +- free(cd->idctx->identity); ++ if (idctx->my_certs != NULL) ++ sk_X509_pop_free(idctx->my_certs, X509_free); ++ idctx->my_certs = sk_X509_new_null(); ++ sk_X509_push(idctx->my_certs, ci->cert); ++ free(idctx->identity); + /* hang on to the selected credential name */ +- if (cd->idctx->creds[cd->index]->name != NULL) +- cd->idctx->identity = strdup(cd->idctx->creds[cd->index]->name); ++ if (ci->name != NULL) ++ idctx->identity = strdup(ci->name); + else +- cd->idctx->identity = NULL; +- cd->idctx->creds[cd->index]->cert = NULL; /* Don't free it twice */ +- cd->idctx->cert_index = 0; ++ idctx->identity = NULL; + +- if (cd->idctx->pkcs11_method != 1) { +- cd->idctx->my_key = cd->cred->key; +- cd->idctx->creds[cd->index]->key = NULL; /* Don't free it twice */ ++ ci->cert = NULL; /* Don't free it twice */ ++ idctx->cert_index = 0; ++ if (idctx->pkcs11_method != 1) { ++ idctx->my_key = ci->key; ++ ci->key = NULL; /* Don't free it twice */ + } + #ifndef WITHOUT_PKCS11 + else { +- cd->idctx->cert_id = cd->cred->cert_id; +- cd->idctx->creds[cd->index]->cert_id = NULL; /* Don't free it twice */ +- cd->idctx->cert_id_len = cd->cred->cert_id_len; ++ idctx->cert_id = ci->cert_id; ++ ci->cert_id = NULL; /* Don't free it twice */ ++ idctx->cert_id_len = ci->cert_id_len; + } + #endif + return 0; +@@ -5380,15 +5312,12 @@ crypto_cert_select_default(krb5_context context, + pkinit_identity_crypto_context id_cryptoctx) + { + krb5_error_code retval; +- int cert_count = 0; ++ int cert_count; + +- retval = crypto_cert_get_count(context, plg_cryptoctx, req_cryptoctx, +- id_cryptoctx, &cert_count); +- if (retval) { +- pkiDebug("%s: crypto_cert_get_count error %d, %s\n", +- __FUNCTION__, retval, error_message(retval)); ++ retval = crypto_cert_get_count(id_cryptoctx, &cert_count); ++ if (retval) + goto errout; +- } ++ + if (cert_count != 1) { + TRACE_PKINIT_NO_DEFAULT_CERT(context, cert_count); + retval = EINVAL; +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.h b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.h +index 2fe357c5e..7411348fa 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.h ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.h +@@ -115,23 +115,4 @@ struct _pkinit_req_crypto_context { + DH *dh; + }; + +-#define CERT_MAGIC 0x53534c43 +-struct _pkinit_cert_data { +- unsigned int magic; +- pkinit_plg_crypto_context plgctx; +- pkinit_req_crypto_context reqctx; +- pkinit_identity_crypto_context idctx; +- pkinit_cred_info cred; +- unsigned int index; /* Index of this cred in the creds[] array */ +-}; +- +-#define ITER_MAGIC 0x53534c49 +-struct _pkinit_cert_iter_data { +- unsigned int magic; +- pkinit_plg_crypto_context plgctx; +- pkinit_req_crypto_context reqctx; +- pkinit_identity_crypto_context idctx; +- unsigned int index; +-}; +- + #endif /* _PKINIT_CRYPTO_OPENSSL_H */ +diff --git a/src/plugins/preauth/pkinit/pkinit_matching.c b/src/plugins/preauth/pkinit/pkinit_matching.c +index cad4c2b9a..d6775dc4f 100644 +--- a/src/plugins/preauth/pkinit/pkinit_matching.c ++++ b/src/plugins/preauth/pkinit/pkinit_matching.c +@@ -544,7 +544,7 @@ check_all_certs(krb5_context context, + rule_set *rs, /* rule to check */ + pkinit_cert_matching_data **matchdata, + int *match_found, +- pkinit_cert_matching_data **matching_cert) ++ size_t *match_index) + { + krb5_error_code retval; + pkinit_cert_matching_data *md; +@@ -553,12 +553,12 @@ check_all_certs(krb5_context context, + int total_cert_matches = 0; + rule_component *rc; + int certs_checked = 0; +- pkinit_cert_matching_data *save_match = NULL; ++ size_t save_index = 0; + +- if (match_found == NULL || matching_cert == NULL) ++ if (match_found == NULL || match_index == NULL) + return EINVAL; + +- *matching_cert = NULL; ++ *match_index = 0; + *match_found = 0; + + pkiDebug("%s: matching rule relation is %s with %d components\n", +@@ -590,7 +590,7 @@ check_all_certs(krb5_context context, + pkiDebug("%s: cert matches rule (OR relation)\n", + __FUNCTION__); + total_cert_matches++; +- save_match = md; ++ save_index = i; + goto nextcert; + } + if (!comp_match && rs->relation == relation_and) { +@@ -602,7 +602,7 @@ check_all_certs(krb5_context context, + if (rc == NULL && comp_match) { + pkiDebug("%s: cert matches rule (AND relation)\n", __FUNCTION__); + total_cert_matches++; +- save_match = md; ++ save_index = i; + } + nextcert: + continue; +@@ -611,7 +611,7 @@ check_all_certs(krb5_context context, + __FUNCTION__, certs_checked, total_cert_matches); + if (total_cert_matches == 1) { + *match_found = 1; +- *matching_cert = save_match; ++ *match_index = save_index; + } + + retval = 0; +@@ -621,111 +621,6 @@ check_all_certs(krb5_context context, + return retval; + } + +-static krb5_error_code +-free_all_cert_matching_data(krb5_context context, +- pkinit_cert_matching_data **matchdata) +-{ +- krb5_error_code retval; +- pkinit_cert_matching_data *md; +- int i; +- +- if (matchdata == NULL) +- return EINVAL; +- +- for (i = 0, md = matchdata[i]; md != NULL; md = matchdata[++i]) { +- pkinit_cert_handle ch = md->ch; +- retval = crypto_cert_free_matching_data(context, md); +- if (retval) { +- pkiDebug("%s: crypto_cert_free_matching_data error %d, %s\n", +- __FUNCTION__, retval, error_message(retval)); +- goto cleanup; +- } +- retval = crypto_cert_release(context, ch); +- if (retval) { +- pkiDebug("%s: crypto_cert_release error %d, %s\n", +- __FUNCTION__, retval, error_message(retval)); +- goto cleanup; +- } +- } +- free(matchdata); +- retval = 0; +- +-cleanup: +- return retval; +-} +- +-static krb5_error_code +-obtain_all_cert_matching_data(krb5_context context, +- pkinit_plg_crypto_context plg_cryptoctx, +- pkinit_req_crypto_context req_cryptoctx, +- pkinit_identity_crypto_context id_cryptoctx, +- pkinit_cert_matching_data ***all_matching_data) +-{ +- krb5_error_code retval; +- int i, cert_count; +- pkinit_cert_iter_handle ih = NULL; +- pkinit_cert_handle ch; +- pkinit_cert_matching_data **matchdata = NULL; +- +- retval = crypto_cert_get_count(context, plg_cryptoctx, req_cryptoctx, +- id_cryptoctx, &cert_count); +- if (retval) { +- pkiDebug("%s: crypto_cert_get_count error %d, %s\n", +- __FUNCTION__, retval, error_message(retval)); +- goto cleanup; +- } +- +- pkiDebug("%s: crypto_cert_get_count says there are %d certs\n", +- __FUNCTION__, cert_count); +- +- matchdata = calloc((size_t)cert_count + 1, sizeof(*matchdata)); +- if (matchdata == NULL) +- return ENOMEM; +- +- retval = crypto_cert_iteration_begin(context, plg_cryptoctx, req_cryptoctx, +- id_cryptoctx, &ih); +- if (retval) { +- pkiDebug("%s: crypto_cert_iteration_begin returned %d, %s\n", +- __FUNCTION__, retval, error_message(retval)); +- goto cleanup; +- } +- +- for (i = 0; i < cert_count; i++) { +- retval = crypto_cert_iteration_next(context, ih, &ch); +- if (retval) { +- if (retval == PKINIT_ITER_NO_MORE) +- pkiDebug("%s: We thought there were %d certs, but " +- "crypto_cert_iteration_next stopped after %d?\n", +- __FUNCTION__, cert_count, i); +- else +- pkiDebug("%s: crypto_cert_iteration_next error %d, %s\n", +- __FUNCTION__, retval, error_message(retval)); +- goto cleanup; +- } +- +- retval = crypto_cert_get_matching_data(context, ch, &matchdata[i]); +- if (retval) { +- pkiDebug("%s: crypto_cert_get_matching_data error %d, %s\n", +- __FUNCTION__, retval, error_message(retval)); +- goto cleanup; +- } +- +- } +- +- *all_matching_data = matchdata; +- retval = 0; +-cleanup: +- if (ih != NULL) +- crypto_cert_iteration_end(context, ih); +- if (retval) { +- if (matchdata != NULL) +- free_all_cert_matching_data(context, matchdata); +- } +- pkiDebug("%s: returning %d, certinfo %p\n", +- __FUNCTION__, retval, *all_matching_data); +- return retval; +-} +- + krb5_error_code + pkinit_cert_matching(krb5_context context, + pkinit_plg_crypto_context plg_cryptoctx, +@@ -740,7 +635,7 @@ pkinit_cert_matching(krb5_context context, + rule_set *rs = NULL; + int match_found = 0; + pkinit_cert_matching_data **matchdata = NULL; +- pkinit_cert_matching_data *the_matching_cert = NULL; ++ size_t match_index = 0; + + /* If no matching rules, select the default cert and we're done */ + pkinit_libdefault_strings(context, krb5_princ_realm(context, princ), +@@ -777,7 +672,7 @@ pkinit_cert_matching(krb5_context context, + * until we are done. + */ + if (matchdata == NULL) { +- retval = obtain_all_cert_matching_data(context, plg_cryptoctx, ++ retval = crypto_cert_get_matching_data(context, plg_cryptoctx, + req_cryptoctx, id_cryptoctx, + &matchdata); + if (retval || matchdata == NULL) { +@@ -790,7 +685,7 @@ pkinit_cert_matching(krb5_context context, + + retval = check_all_certs(context, plg_cryptoctx, req_cryptoctx, + id_cryptoctx, princ, rs, matchdata, +- &match_found, &the_matching_cert); ++ &match_found, &match_index); + if (retval) { + pkiDebug("%s: Error %d, checking certs against rule '%s'\n", + __FUNCTION__, retval, rules[x]); +@@ -803,9 +698,9 @@ pkinit_cert_matching(krb5_context context, + } + } + +- if (match_found && the_matching_cert != NULL) { ++ if (match_found) { + pkiDebug("%s: Selecting the matching cert!\n", __FUNCTION__); +- retval = crypto_cert_select(context, the_matching_cert); ++ retval = crypto_cert_select(context, id_cryptoctx, match_index); + if (retval) { + pkiDebug("%s: crypto_cert_select error %d, %s\n", + __FUNCTION__, retval, error_message(retval)); +@@ -818,12 +713,10 @@ pkinit_cert_matching(krb5_context context, + } + + retval = 0; ++ + cleanup: +- if (rules != NULL) +- profile_free_list(rules); +- if (rs != NULL) +- free_rule_set(context, rs); +- if (matchdata != NULL) +- free_all_cert_matching_data(context, matchdata); ++ profile_free_list(rules); ++ free_rule_set(context, rs); ++ crypto_cert_free_matching_data_list(context, matchdata); + return retval; + } diff --git a/SOURCES/Simplify-k5_preauth_tryagain.patch b/SOURCES/Simplify-k5_preauth_tryagain.patch new file mode 100644 index 0000000..efb91ee --- /dev/null +++ b/SOURCES/Simplify-k5_preauth_tryagain.patch @@ -0,0 +1,182 @@ +From e443dfe315a38607e7c9dcba219f73253d17032b Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Fri, 13 Jan 2017 20:45:48 -0500 +Subject: [PATCH] Simplify k5_preauth_tryagain() + +When retrying pre-authentication for an error, try only the module for +the selected preauth type, not all preauth types in the original +method data. Pass the error and its padata to k5_preauth_tryagain() +explicitly, so that those fields of krb5_init_creds_context are only +referenced in get_in_tkt.c. Handle a degenerate case in +init_creds_step_reply() to simplify the code in +init_creds_step_request(). + +ticket: 8537 +(cherry picked from commit 27628e5d9d5e6fcfa73276106edbd8149d134dc0) +--- + src/include/k5-trace.h | 7 ++-- + src/lib/krb5/krb/get_in_tkt.c | 20 ++++------- + src/lib/krb5/krb/int-proto.h | 3 +- + src/lib/krb5/krb/preauth2.c | 64 +++++++++++++++++++---------------- + 4 files changed, 48 insertions(+), 46 deletions(-) + +diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h +index f44f162d3..814da3195 100644 +--- a/src/include/k5-trace.h ++++ b/src/include/k5-trace.h +@@ -287,8 +287,11 @@ void krb5int_trace(krb5_context context, const char *fmt, ...); + #define TRACE_PREAUTH_SKIP(c, name, patype) \ + TRACE(c, "Skipping previously used preauth module {str} ({int})", \ + name, (int) patype) +-#define TRACE_PREAUTH_TRYAGAIN_INPUT(c, padata) \ +- TRACE(c, "Preauth tryagain input types: {patypes}", padata) ++#define TRACE_PREAUTH_TRYAGAIN_INPUT(c, patype, padata) \ ++ TRACE(c, "Preauth tryagain input types ({int}): {patypes}", patype, padata) ++#define TRACE_PREAUTH_TRYAGAIN(c, name, patype, code) \ ++ TRACE(c, "Preauth module {str} ({int}) tryagain returned: {kerr}", \ ++ name, (int)patype, code) + #define TRACE_PREAUTH_TRYAGAIN_OUTPUT(c, padata) \ + TRACE(c, "Followup preauth for next request: {patypes}", padata) + #define TRACE_PREAUTH_WRONG_CONTEXT(c) \ +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index da12204ac..988fca233 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -1340,17 +1340,11 @@ init_creds_step_request(krb5_context context, + if (code != 0) + goto cleanup; + } else { +- if (ctx->preauth_to_use != NULL) { +- /* +- * Retry after an error other than PREAUTH_NEEDED, +- * using ctx->err_padata to figure out what to change. +- */ +- code = k5_preauth_tryagain(context, ctx, ctx->preauth_to_use, +- &ctx->request->padata); +- } else { +- /* No preauth supplied, so can't query the plugins. */ +- code = KRB5KRB_ERR_GENERIC; +- } ++ /* Retry after an error other than PREAUTH_NEEDED, using error padata ++ * to figure out what to change. */ ++ code = k5_preauth_tryagain(context, ctx, ctx->selected_preauth_type, ++ ctx->err_reply, ctx->err_padata, ++ &ctx->request->padata); + if (code != 0) { + /* couldn't come up with anything better */ + code = ctx->err_reply->error + ERROR_TABLE_BASE_krb5; +@@ -1535,10 +1529,10 @@ init_creds_step_reply(krb5_context context, + ctx->enc_pa_rep_permitted = TRUE; + code = restart_init_creds_loop(context, ctx, FALSE); + } else { +- if (retry) { ++ if (retry && ctx->selected_preauth_type != KRB5_PADATA_NONE) { + code = 0; + } else { +- /* error + no hints = give up */ ++ /* error + no hints (or no preauth mech) = give up */ + code = (krb5_error_code)reply_code + ERROR_TABLE_BASE_krb5; + } + } +diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h +index 628f0baa8..8903df232 100644 +--- a/src/lib/krb5/krb/int-proto.h ++++ b/src/lib/krb5/krb/int-proto.h +@@ -185,7 +185,8 @@ k5_preauth(krb5_context context, krb5_init_creds_context ctx, + + krb5_error_code + k5_preauth_tryagain(krb5_context context, krb5_init_creds_context ctx, +- krb5_pa_data **in_padata, krb5_pa_data ***padata_out); ++ krb5_preauthtype pa_type, krb5_error *err, ++ krb5_pa_data **err_padata, krb5_pa_data ***padata_out); + + void + k5_init_preauth_context(krb5_context context); +diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c +index cfe3dd5b0..354234a93 100644 +--- a/src/lib/krb5/krb/preauth2.c ++++ b/src/lib/krb5/krb/preauth2.c +@@ -911,49 +911,53 @@ add_s4u_x509_user_padata(krb5_context context, krb5_s4u_userid *userid, + } + + /* +- * If one of the modules can adjust its AS_REQ data using the contents of the +- * err_reply, return 0. If it's the sort of correction which requires that we +- * ask the user another question, we let the calling application deal with it. ++ * If the module for pa_type can adjust its AS_REQ data using the contents of ++ * err and err_padata, return 0 with *padata_out set to a padata list for the ++ * next request. If it's the sort of correction which requires that we ask the ++ * user another question, we let the calling application deal with it. + */ + krb5_error_code + k5_preauth_tryagain(krb5_context context, krb5_init_creds_context ctx, +- krb5_pa_data **in_padata, krb5_pa_data ***padata_out) ++ krb5_preauthtype pa_type, krb5_error *err, ++ krb5_pa_data **err_padata, krb5_pa_data ***padata_out) + { + krb5_error_code ret; + krb5_pa_data **mod_pa; + krb5_clpreauth_modreq modreq; + clpreauth_handle h; +- int i, count; ++ int count; + + *padata_out = NULL; + +- TRACE_PREAUTH_TRYAGAIN_INPUT(context, in_padata); ++ TRACE_PREAUTH_TRYAGAIN_INPUT(context, pa_type, err_padata); + +- for (i = 0; in_padata[i] != NULL; i++) { +- h = find_module(context, ctx, in_padata[i]->pa_type, &modreq); +- if (h == NULL) +- continue; +- mod_pa = NULL; +- ret = clpreauth_tryagain(context, h, modreq, ctx->opt, &callbacks, +- (krb5_clpreauth_rock)ctx, ctx->request, +- ctx->inner_request_body, +- ctx->encoded_previous_request, +- in_padata[i]->pa_type, +- ctx->err_reply, ctx->err_padata, +- ctx->prompter, ctx->prompter_data, &mod_pa); +- if (ret == 0 && mod_pa != NULL) { +- for (count = 0; mod_pa[count] != NULL; count++); +- ret = copy_cookie(context, ctx->err_padata, &mod_pa, &count); +- if (ret) { +- krb5_free_pa_data(context, mod_pa); +- return ret; +- } +- TRACE_PREAUTH_TRYAGAIN_OUTPUT(context, mod_pa); +- *padata_out = mod_pa; +- return 0; +- } ++ h = find_module(context, ctx, pa_type, &modreq); ++ if (h == NULL) ++ return KRB5KRB_ERR_GENERIC; ++ mod_pa = NULL; ++ ret = clpreauth_tryagain(context, h, modreq, ctx->opt, &callbacks, ++ (krb5_clpreauth_rock)ctx, ctx->request, ++ ctx->inner_request_body, ++ ctx->encoded_previous_request, pa_type, err, ++ err_padata, ctx->prompter, ctx->prompter_data, ++ &mod_pa); ++ TRACE_PREAUTH_TRYAGAIN(context, h->vt.name, pa_type, ret); ++ if (!ret && mod_pa == NULL) ++ ret = KRB5KRB_ERR_GENERIC; ++ if (ret) ++ return ret; ++ ++ ++ for (count = 0; mod_pa[count] != NULL; count++); ++ ret = copy_cookie(context, err_padata, &mod_pa, &count); ++ if (ret) { ++ krb5_free_pa_data(context, mod_pa); ++ return ret; + } +- return KRB5KRB_ERR_GENERIC; ++ ++ TRACE_PREAUTH_TRYAGAIN_OUTPUT(context, mod_pa); ++ *padata_out = mod_pa; ++ return 0; + } + + /* Compile the set of response items for in_padata by invoke each module's diff --git a/SOURCES/Track-preauth-failures-instead-of-tries.patch b/SOURCES/Track-preauth-failures-instead-of-tries.patch new file mode 100644 index 0000000..b18ae37 --- /dev/null +++ b/SOURCES/Track-preauth-failures-instead-of-tries.patch @@ -0,0 +1,189 @@ +From 6a69660d9415bc49948143109759f36b2ad70d1b Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Fri, 13 Jan 2017 12:16:04 -0500 +Subject: [PATCH] Track preauth failures instead of tries + +In preauth2.c, instead of noting whenever we try a real preauth mech, +note when a mechanism fails on our side. Tracking only failures +eliminates the need to reset the list for multi-step preauth exchanges +or for processing padata in the AS-REP, but we will need the function +later for continuing after optimistic preauth failures. + +ticket: 8537 +(cherry picked from commit a1dc81d22304e77edaa8388c7d7d75cade81dc80) +--- + src/lib/krb5/krb/get_in_tkt.c | 3 -- + src/lib/krb5/krb/int-proto.h | 3 ++ + src/lib/krb5/krb/preauth2.c | 65 ++++++++++++++++++++--------------- + 3 files changed, 40 insertions(+), 31 deletions(-) + +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index 48dc00ea6..bc903b6e9 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -1496,8 +1496,6 @@ init_creds_step_reply(krb5_context context, + code = restart_init_creds_loop(context, ctx, FALSE); + } else if ((reply_code == KDC_ERR_MORE_PREAUTH_DATA_REQUIRED || + reply_code == KDC_ERR_PREAUTH_REQUIRED) && retry) { +- /* reset the list of preauth types to try */ +- k5_reset_preauth_types_tried(ctx); + krb5_free_pa_data(context, ctx->preauth_to_use); + ctx->preauth_to_use = ctx->err_padata; + ctx->err_padata = NULL; +@@ -1547,7 +1545,6 @@ init_creds_step_reply(krb5_context context, + goto cleanup; + + /* process any preauth data in the as_reply */ +- k5_reset_preauth_types_tried(ctx); + code = krb5int_fast_process_response(context, ctx->fast_state, + ctx->reply, &strengthen_key); + if (code != 0) +diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h +index 8903df232..41a69c207 100644 +--- a/src/lib/krb5/krb/int-proto.h ++++ b/src/lib/krb5/krb/int-proto.h +@@ -197,6 +197,9 @@ k5_free_preauth_context(krb5_context context); + void + k5_reset_preauth_types_tried(krb5_init_creds_context ctx); + ++krb5_error_code ++k5_preauth_note_failed(krb5_init_creds_context ctx, krb5_preauthtype pa_type); ++ + void + k5_preauth_prepare_request(krb5_context context, krb5_get_init_creds_opt *opt, + krb5_kdc_req *request); +diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c +index 354234a93..17f2133b1 100644 +--- a/src/lib/krb5/krb/preauth2.c ++++ b/src/lib/krb5/krb/preauth2.c +@@ -54,7 +54,7 @@ struct krb5_preauth_context_st { + + struct krb5_preauth_req_context_st { + krb5_context orig_context; +- krb5_preauthtype *tried; ++ krb5_preauthtype *failed; + krb5_clpreauth_modreq *modreqs; + }; + +@@ -201,11 +201,7 @@ cleanup: + free_handles(context, list); + } + +-/* +- * Reset the memory of which preauth types we have already tried, because we +- * are entering a new phase of padata processing (such as the padata in an +- * AS-REP). +- */ ++/* Reset the memory of which preauth types we have already tried. */ + void + k5_reset_preauth_types_tried(krb5_init_creds_context ctx) + { +@@ -213,10 +209,27 @@ k5_reset_preauth_types_tried(krb5_init_creds_context ctx) + + if (reqctx == NULL) + return; +- free(reqctx->tried); +- reqctx->tried = NULL; ++ free(reqctx->failed); ++ reqctx->failed = NULL; + } + ++/* Add pa_type to the list of types which has previously failed. */ ++krb5_error_code ++k5_preauth_note_failed(krb5_init_creds_context ctx, krb5_preauthtype pa_type) ++{ ++ krb5_preauth_req_context reqctx = ctx->preauth_reqctx; ++ krb5_preauthtype *newptr; ++ size_t i; ++ ++ for (i = 0; reqctx->failed != NULL && reqctx->failed[i] != 0; i++); ++ newptr = realloc(reqctx->failed, (i + 2) * sizeof(*newptr)); ++ if (newptr == NULL) ++ return ENOMEM; ++ reqctx->failed = newptr; ++ reqctx->failed[i] = pa_type; ++ reqctx->failed[i + 1] = 0; ++ return 0; ++} + + /* Free the per-krb5_context preauth_context. This means clearing any + * plugin-specific context which may have been created, and then +@@ -291,7 +304,7 @@ k5_preauth_request_context_fini(krb5_context context, + TRACE_PREAUTH_WRONG_CONTEXT(context); + } + free(reqctx->modreqs); +- free(reqctx->tried); ++ free(reqctx->failed); + free(reqctx); + ctx->preauth_reqctx = NULL; + } +@@ -612,28 +625,17 @@ pa_type_allowed(krb5_init_creds_context ctx, krb5_preauthtype pa_type) + pa_type == ctx->allowed_preauth_type; + } + +-/* +- * If pa_type has already been tried as a real preauth type for this +- * authentication, return true. Otherwise ass pa_type to the list of tried +- * types and return false. +- */ ++/* Return true if pa_type previously failed during this authentication. */ + static krb5_boolean +-already_tried(krb5_init_creds_context ctx, krb5_preauthtype pa_type) ++previously_failed(krb5_init_creds_context ctx, krb5_preauthtype pa_type) + { + krb5_preauth_req_context reqctx = ctx->preauth_reqctx; + size_t i; +- krb5_preauthtype *newptr; + +- for (i = 0; reqctx->tried != NULL && reqctx->tried[i] != 0; i++) { +- if (reqctx->tried[i] == pa_type) ++ for (i = 0; reqctx->failed != NULL && reqctx->failed[i] != 0; i++) { ++ if (reqctx->failed[i] == pa_type) + return TRUE; + } +- newptr = realloc(reqctx->tried, (i + 2) * sizeof(*newptr)); +- if (newptr == NULL) +- return FALSE; +- reqctx->tried = newptr; +- reqctx->tried[i] = pa_type; +- reqctx->tried[i + 1] = ENCTYPE_NULL; + return FALSE; + } + +@@ -665,8 +667,8 @@ process_pa_data(krb5_context context, krb5_init_creds_context ctx, + /* Make sure this type is for the current pass. */ + if (clpreauth_is_real(context, h, pa->pa_type) != real) + continue; +- /* Only try a real mechanism once per authentication. */ +- if (real && already_tried(ctx, pa->pa_type)) ++ /* Don't try a real mechanism again after failure. */ ++ if (real && previously_failed(ctx, pa->pa_type)) + continue; + mod_pa = NULL; + ret = clpreauth_process(context, h, modreq, ctx->opt, &callbacks, +@@ -694,6 +696,12 @@ process_pa_data(krb5_context context, krb5_init_creds_context ctx, + /* Save the first error we get from a real preauth type. */ + k5_save_ctx_error(context, ret, &save); + } ++ if (real && ret) { ++ /* Don't try this mechanism again for this authentication. */ ++ ret = k5_preauth_note_failed(ctx, pa->pa_type); ++ if (ret) ++ goto cleanup; ++ } + } + } + +@@ -944,9 +952,10 @@ k5_preauth_tryagain(krb5_context context, krb5_init_creds_context ctx, + TRACE_PREAUTH_TRYAGAIN(context, h->vt.name, pa_type, ret); + if (!ret && mod_pa == NULL) + ret = KRB5KRB_ERR_GENERIC; +- if (ret) ++ if (ret) { ++ k5_preauth_note_failed(ctx, pa_type); + return ret; +- ++ } + + for (count = 0; mod_pa[count] != NULL; count++); + ret = copy_cookie(context, err_padata, &mod_pa, &count); diff --git a/SOURCES/Update-man-pages-to-reference-kerberos-7.patch b/SOURCES/Update-man-pages-to-reference-kerberos-7.patch new file mode 100644 index 0000000..b5cdfe6 --- /dev/null +++ b/SOURCES/Update-man-pages-to-reference-kerberos-7.patch @@ -0,0 +1,475 @@ +From 7bcff005db31c62b37ea5c364cd65526cfaecbf1 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Mon, 15 Oct 2018 15:19:12 -0400 +Subject: [PATCH] Update man pages to reference kerberos(7) + +Remove broken references to old kerberos(1). Reference kerberos(7) +from all man pages, and create/update their environment section so +that it references kerberos(7). + +ticket: 8755 +(cherry picked from commit 52cbe198d0d6f0085d4653b2f6a1ecc84d139118) +[rharwood@redhat.com: git got weird about fuzz] +--- + doc/admin/admin_commands/k5srvutil.rst | 9 ++++++++- + doc/admin/admin_commands/kadmin_local.rst | 9 ++++++++- + doc/admin/admin_commands/kadmind.rst | 9 ++++++++- + doc/admin/admin_commands/kdb5_ldap_util.rst | 9 ++++++++- + doc/admin/admin_commands/kdb5_util.rst | 9 ++++++++- + doc/admin/admin_commands/kprop.rst | 8 ++++---- + doc/admin/admin_commands/kpropd.rst | 10 +++++++++- + doc/admin/admin_commands/kproplog.rst | 7 +++---- + doc/admin/admin_commands/krb5kdc.rst | 8 +++----- + doc/admin/admin_commands/ktutil.rst | 9 ++++++++- + doc/admin/admin_commands/sserver.rst | 9 ++++++++- + doc/user/user_commands/kdestroy.rst | 13 +++---------- + doc/user/user_commands/kinit.rst | 14 +++----------- + doc/user/user_commands/klist.rst | 13 +++---------- + doc/user/user_commands/kpasswd.rst | 9 ++++++++- + doc/user/user_commands/krb5-config.rst | 2 +- + doc/user/user_commands/ksu.rst | 13 +++++++++++++ + doc/user/user_commands/kswitch.rst | 14 ++++---------- + doc/user/user_commands/kvno.rst | 9 +++------ + doc/user/user_commands/sclient.rst | 8 +++++++- + 20 files changed, 120 insertions(+), 71 deletions(-) + +diff --git a/doc/admin/admin_commands/k5srvutil.rst b/doc/admin/admin_commands/k5srvutil.rst +index b873d9077..79502cf9e 100644 +--- a/doc/admin/admin_commands/k5srvutil.rst ++++ b/doc/admin/admin_commands/k5srvutil.rst +@@ -56,7 +56,14 @@ k5srvutil uses the :ref:`kadmin(1)` program to edit the keytab in + place. + + ++ENVIRONMENT ++----------- ++ ++See :ref:`kerberos(7)` for a description of Kerberos environment ++variables. ++ ++ + SEE ALSO + -------- + +-:ref:`kadmin(1)`, :ref:`ktutil(1)` ++:ref:`kadmin(1)`, :ref:`ktutil(1)`, :ref:`kerberos(7)` +diff --git a/doc/admin/admin_commands/kadmin_local.rst b/doc/admin/admin_commands/kadmin_local.rst +index 50c3b99ea..0e955faf2 100644 +--- a/doc/admin/admin_commands/kadmin_local.rst ++++ b/doc/admin/admin_commands/kadmin_local.rst +@@ -989,7 +989,14 @@ The kadmin program was originally written by Tom Yu at MIT, as an + interface to the OpenVision Kerberos administration program. + + ++ENVIRONMENT ++----------- ++ ++See :ref:`kerberos(7)` for a description of Kerberos environment ++variables. ++ ++ + SEE ALSO + -------- + +-:ref:`kpasswd(1)`, :ref:`kadmind(8)` ++:ref:`kpasswd(1)`, :ref:`kadmind(8)`, :ref:`kerberos(7)` +diff --git a/doc/admin/admin_commands/kadmind.rst b/doc/admin/admin_commands/kadmind.rst +index f5b7733ea..8bfb48a32 100644 +--- a/doc/admin/admin_commands/kadmind.rst ++++ b/doc/admin/admin_commands/kadmind.rst +@@ -116,8 +116,15 @@ OPTIONS + ` in :ref:`kadmin(1)` for supported arguments. + + ++ENVIRONMENT ++----------- ++ ++See :ref:`kerberos(7)` for a description of Kerberos environment ++variables. ++ ++ + SEE ALSO + -------- + + :ref:`kpasswd(1)`, :ref:`kadmin(1)`, :ref:`kdb5_util(8)`, +-:ref:`kdb5_ldap_util(8)`, :ref:`kadm5.acl(5)` ++:ref:`kdb5_ldap_util(8)`, :ref:`kadm5.acl(5)`, :ref:`kerberos(7)` +diff --git a/doc/admin/admin_commands/kdb5_ldap_util.rst b/doc/admin/admin_commands/kdb5_ldap_util.rst +index cbf313f55..343df4dd9 100644 +--- a/doc/admin/admin_commands/kdb5_ldap_util.rst ++++ b/doc/admin/admin_commands/kdb5_ldap_util.rst +@@ -456,7 +456,14 @@ Example:: + .. _kdb5_ldap_util_list_policy_end: + + ++ENVIRONMENT ++----------- ++ ++See :ref:`kerberos(7)` for a description of Kerberos environment ++variables. ++ ++ + SEE ALSO + -------- + +-:ref:`kadmin(1)` ++:ref:`kadmin(1)`, :ref:`kerberos(7)` +diff --git a/doc/admin/admin_commands/kdb5_util.rst b/doc/admin/admin_commands/kdb5_util.rst +index 258498f0d..18a3fb627 100644 +--- a/doc/admin/admin_commands/kdb5_util.rst ++++ b/doc/admin/admin_commands/kdb5_util.rst +@@ -491,7 +491,14 @@ Examples:: + bar@EXAMPLE.COM 1 1 des-cbc-crc normal -1 + + ++ENVIRONMENT ++----------- ++ ++See :ref:`kerberos(7)` for a description of Kerberos environment ++variables. ++ ++ + SEE ALSO + -------- + +-:ref:`kadmin(1)` ++:ref:`kadmin(1)`, :ref:`kerberos(7)` +diff --git a/doc/admin/admin_commands/kprop.rst b/doc/admin/admin_commands/kprop.rst +index 726c8cc2f..0bc353239 100644 +--- a/doc/admin/admin_commands/kprop.rst ++++ b/doc/admin/admin_commands/kprop.rst +@@ -49,12 +49,12 @@ OPTIONS + ENVIRONMENT + ----------- + +-*kprop* uses the following environment variable: +- +-* **KRB5_CONFIG** ++See :ref:`kerberos(7)` for a description of Kerberos environment ++variables. + + + SEE ALSO + -------- + +-:ref:`kpropd(8)`, :ref:`kdb5_util(8)`, :ref:`krb5kdc(8)` ++:ref:`kpropd(8)`, :ref:`kdb5_util(8)`, :ref:`krb5kdc(8)`, ++:ref:`kerberos(7)` +diff --git a/doc/admin/admin_commands/kpropd.rst b/doc/admin/admin_commands/kpropd.rst +index 5e01e2f14..36ad3344c 100644 +--- a/doc/admin/admin_commands/kpropd.rst ++++ b/doc/admin/admin_commands/kpropd.rst +@@ -124,7 +124,15 @@ kpropd.acl + will allow Kerberos database propagation via :ref:`kprop(8)`. + + ++ENVIRONMENT ++----------- ++ ++See :ref:`kerberos(7)` for a description of Kerberos environment ++variables. ++ ++ + SEE ALSO + -------- + +-:ref:`kprop(8)`, :ref:`kdb5_util(8)`, :ref:`krb5kdc(8)`, inetd(8) ++:ref:`kprop(8)`, :ref:`kdb5_util(8)`, :ref:`krb5kdc(8)`, ++:ref:`kerberos(7)`, inetd(8) +diff --git a/doc/admin/admin_commands/kproplog.rst b/doc/admin/admin_commands/kproplog.rst +index ed906398d..b98e1b29b 100644 +--- a/doc/admin/admin_commands/kproplog.rst ++++ b/doc/admin/admin_commands/kproplog.rst +@@ -74,12 +74,11 @@ OPTIONS + ENVIRONMENT + ----------- + +-kproplog uses the following environment variables: +- +-* **KRB5_KDC_PROFILE** ++See :ref:`kerberos(7)` for a description of Kerberos environment ++variables. + + + SEE ALSO + -------- + +-:ref:`kpropd(8)` ++:ref:`kpropd(8)`, :ref:`kerberos(7)` +diff --git a/doc/admin/admin_commands/krb5kdc.rst b/doc/admin/admin_commands/krb5kdc.rst +index 7ec4ee4d3..4bf9e0150 100644 +--- a/doc/admin/admin_commands/krb5kdc.rst ++++ b/doc/admin/admin_commands/krb5kdc.rst +@@ -110,14 +110,12 @@ description for further details. + ENVIRONMENT + ----------- + +-krb5kdc uses the following environment variables: +- +-* **KRB5_CONFIG** +-* **KRB5_KDC_PROFILE** ++See :ref:`kerberos(7)` for a description of Kerberos environment ++variables. + + + SEE ALSO + -------- + + :ref:`kdb5_util(8)`, :ref:`kdc.conf(5)`, :ref:`krb5.conf(5)`, +-:ref:`kdb5_ldap_util(8)` ++:ref:`kdb5_ldap_util(8)`, :ref:`kerberos(7)` +diff --git a/doc/admin/admin_commands/ktutil.rst b/doc/admin/admin_commands/ktutil.rst +index d55ddc894..5a6fc31a8 100644 +--- a/doc/admin/admin_commands/ktutil.rst ++++ b/doc/admin/admin_commands/ktutil.rst +@@ -127,7 +127,14 @@ EXAMPLE + ktutil: + + ++ENVIRONMENT ++----------- ++ ++See :ref:`kerberos(7)` for a description of Kerberos environment ++variables. ++ ++ + SEE ALSO + -------- + +-:ref:`kadmin(1)`, :ref:`kdb5_util(8)` ++:ref:`kadmin(1)`, :ref:`kdb5_util(8)`, :ref:`kerberos(7)` +diff --git a/doc/admin/admin_commands/sserver.rst b/doc/admin/admin_commands/sserver.rst +index b4e464466..a8dcf5d5b 100644 +--- a/doc/admin/admin_commands/sserver.rst ++++ b/doc/admin/admin_commands/sserver.rst +@@ -99,7 +99,14 @@ COMMON ERROR MESSAGES + probably not installed in the proper directory. + + ++ENVIRONMENT ++----------- ++ ++See :ref:`kerberos(7)` for a description of Kerberos environment ++variables. ++ ++ + SEE ALSO + -------- + +-:ref:`sclient(1)`, services(5), inetd(8) ++:ref:`sclient(1)`, :ref:`kerberos(7)`, services(5), inetd(8) +diff --git a/doc/user/user_commands/kdestroy.rst b/doc/user/user_commands/kdestroy.rst +index b8c67aba4..c69d65667 100644 +--- a/doc/user/user_commands/kdestroy.rst ++++ b/doc/user/user_commands/kdestroy.rst +@@ -53,15 +53,8 @@ when you log out. + ENVIRONMENT + ----------- + +-kdestroy uses the following environment variable: +- +-**KRB5CCNAME** +- Location of the default Kerberos 5 credentials (ticket) cache, in +- the form *type*:*residual*. If no *type* prefix is present, the +- **FILE** type is assumed. The type of the default cache may +- determine the availability of a cache collection; for instance, a +- default cache of type **DIR** causes caches within the directory +- to be present in the collection. ++See :ref:`kerberos(7)` for a description of Kerberos environment ++variables. + + + FILES +@@ -74,4 +67,4 @@ FILES + SEE ALSO + -------- + +-:ref:`kinit(1)`, :ref:`klist(1)` ++:ref:`kinit(1)`, :ref:`klist(1)`, :ref:`kerberos(7)` +diff --git a/doc/user/user_commands/kinit.rst b/doc/user/user_commands/kinit.rst +index 3f9d5340f..33e6aa64f 100644 +--- a/doc/user/user_commands/kinit.rst ++++ b/doc/user/user_commands/kinit.rst +@@ -197,19 +197,11 @@ OPTIONS + specify use of RSA, rather than the default Diffie-Hellman + protocol + +- + ENVIRONMENT + ----------- + +-kinit uses the following environment variables: +- +-**KRB5CCNAME** +- Location of the default Kerberos 5 credentials cache, in the form +- *type*:*residual*. If no *type* prefix is present, the **FILE** +- type is assumed. The type of the default cache may determine the +- availability of a cache collection; for instance, a default cache +- of type **DIR** causes caches within the directory to be present +- in the collection. ++See :ref:`kerberos(7)` for a description of Kerberos environment ++variables. + + + FILES +@@ -225,4 +217,4 @@ FILES + SEE ALSO + -------- + +-:ref:`klist(1)`, :ref:`kdestroy(1)`, kerberos(1) ++:ref:`klist(1)`, :ref:`kdestroy(1)`, :ref:`kerberos(7)` +diff --git a/doc/user/user_commands/klist.rst b/doc/user/user_commands/klist.rst +index c24c74132..88e457846 100644 +--- a/doc/user/user_commands/klist.rst ++++ b/doc/user/user_commands/klist.rst +@@ -105,15 +105,8 @@ value is used to locate the default ticket cache. + ENVIRONMENT + ----------- + +-klist uses the following environment variable: +- +-**KRB5CCNAME** +- Location of the default Kerberos 5 credentials (ticket) cache, in +- the form *type*:*residual*. If no *type* prefix is present, the +- **FILE** type is assumed. The type of the default cache may +- determine the availability of a cache collection; for instance, a +- default cache of type **DIR** causes caches within the directory +- to be present in the collection. ++See :ref:`kerberos(7)` for a description of Kerberos environment ++variables. + + + FILES +@@ -129,4 +122,4 @@ FILES + SEE ALSO + -------- + +-:ref:`kinit(1)`, :ref:`kdestroy(1)` ++:ref:`kinit(1)`, :ref:`kdestroy(1)`, :ref:`kerberos(7)` +diff --git a/doc/user/user_commands/kpasswd.rst b/doc/user/user_commands/kpasswd.rst +index 1b6463265..0583bbd05 100644 +--- a/doc/user/user_commands/kpasswd.rst ++++ b/doc/user/user_commands/kpasswd.rst +@@ -33,7 +33,14 @@ OPTIONS + identity of the user invoking the kpasswd command. + + ++ENVIRONMENT ++----------- ++ ++See :ref:`kerberos(7)` for a description of Kerberos environment ++variables. ++ ++ + SEE ALSO + -------- + +-:ref:`kadmin(1)`, :ref:`kadmind(8)` ++:ref:`kadmin(1)`, :ref:`kadmind(8)`, :ref:`kerberos(7)` +diff --git a/doc/user/user_commands/krb5-config.rst b/doc/user/user_commands/krb5-config.rst +index ee0fceaa3..2c09141a1 100644 +--- a/doc/user/user_commands/krb5-config.rst ++++ b/doc/user/user_commands/krb5-config.rst +@@ -80,4 +80,4 @@ the following output:: + SEE ALSO + -------- + +-kerberos(1), cc(1) ++:ref:`kerberos(7)`, cc(1) +diff --git a/doc/user/user_commands/ksu.rst b/doc/user/user_commands/ksu.rst +index b2f9121f0..29487a838 100644 +--- a/doc/user/user_commands/ksu.rst ++++ b/doc/user/user_commands/ksu.rst +@@ -385,3 +385,16 @@ AUTHOR OF KSU + ------------- + + GENNADY (ARI) MEDVINSKY ++ ++ ++ENVIRONMENT ++----------- ++ ++See :ref:`kerberos(7)` for a description of Kerberos environment ++variables. ++ ++ ++SEE ALSO ++-------- ++ ++:ref:`kerberos(7)`, :ref:`kinit(1)` +diff --git a/doc/user/user_commands/kswitch.rst b/doc/user/user_commands/kswitch.rst +index 56e5915ac..010332e6a 100644 +--- a/doc/user/user_commands/kswitch.rst ++++ b/doc/user/user_commands/kswitch.rst +@@ -32,15 +32,8 @@ OPTIONS + ENVIRONMENT + ----------- + +-kswitch uses the following environment variables: +- +-**KRB5CCNAME** +- Location of the default Kerberos 5 credentials (ticket) cache, in +- the form *type*:*residual*. If no *type* prefix is present, the +- **FILE** type is assumed. The type of the default cache may +- determine the availability of a cache collection; for instance, a +- default cache of type **DIR** causes caches within the directory +- to be present in the collection. ++See :ref:`kerberos(7)` for a description of Kerberos environment ++variables. + + + FILES +@@ -53,4 +46,5 @@ FILES + SEE ALSO + -------- + +-:ref:`kinit(1)`, :ref:`kdestroy(1)`, :ref:`klist(1)`), kerberos(1) ++:ref:`kinit(1)`, :ref:`kdestroy(1)`, :ref:`klist(1)`, ++:ref:`kerberos(7)` +diff --git a/doc/user/user_commands/kvno.rst b/doc/user/user_commands/kvno.rst +index 31ca24460..f269fb3f9 100644 +--- a/doc/user/user_commands/kvno.rst ++++ b/doc/user/user_commands/kvno.rst +@@ -63,14 +63,11 @@ OPTIONS + delegation is not requested, the service name must match the + credentials cache client principal. + +- + ENVIRONMENT + ----------- + +-kvno uses the following environment variable: +- +-**KRB5CCNAME** +- Location of the credentials (ticket) cache. ++See :ref:`kerberos(7)` for a description of Kerberos environment ++variables. + + + FILES +@@ -83,4 +80,4 @@ FILES + SEE ALSO + -------- + +-:ref:`kinit(1)`, :ref:`kdestroy(1)` ++:ref:`kinit(1)`, :ref:`kdestroy(1)`, :ref:`kerberos(7)` +diff --git a/doc/user/user_commands/sclient.rst b/doc/user/user_commands/sclient.rst +index ebf797253..1e3d38f82 100644 +--- a/doc/user/user_commands/sclient.rst ++++ b/doc/user/user_commands/sclient.rst +@@ -17,8 +17,14 @@ purposes. It contacts a sample server :ref:`sserver(8)` and + authenticates to it using Kerberos version 5 tickets, then displays + the server's response. + ++ENVIRONMENT ++----------- ++ ++See :ref:`kerberos(7)` for a description of Kerberos environment ++variables. ++ + + SEE ALSO + -------- + +-:ref:`kinit(1)`, :ref:`sserver(8)` ++:ref:`kinit(1)`, :ref:`sserver(8)`, :ref:`kerberos(7)` diff --git a/SOURCES/Use-SHA-256-instead-of-MD5-for-audit-ticket-IDs.patch b/SOURCES/Use-SHA-256-instead-of-MD5-for-audit-ticket-IDs.patch new file mode 100644 index 0000000..1451c55 --- /dev/null +++ b/SOURCES/Use-SHA-256-instead-of-MD5-for-audit-ticket-IDs.patch @@ -0,0 +1,53 @@ +From c931cdfaa3539e42cfc57caca6b67fe9a03227e2 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Tue, 10 Jul 2018 16:17:15 -0400 +Subject: [PATCH] Use SHA-256 instead of MD5 for audit ticket IDs + +ticket: 8711 (new) +(cherry picked from commit c1e1bfa26bd2f045e88e6013c500fca9428c98f3) +--- + src/kdc/kdc_audit.c | 21 ++++++++++----------- + 1 file changed, 10 insertions(+), 11 deletions(-) + +diff --git a/src/kdc/kdc_audit.c b/src/kdc/kdc_audit.c +index c9a7f9f9d..f40913dc8 100644 +--- a/src/kdc/kdc_audit.c ++++ b/src/kdc/kdc_audit.c +@@ -146,7 +146,7 @@ kau_make_tkt_id(krb5_context context, + { + krb5_error_code ret = 0; + char *hash = NULL, *ptr; +- krb5_checksum cksum; ++ uint8_t hashbytes[K5_SHA256_HASHLEN]; + unsigned int i; + + *out = NULL; +@@ -154,19 +154,18 @@ kau_make_tkt_id(krb5_context context, + if (ticket == NULL) + return EINVAL; + +- ret = krb5_c_make_checksum(context, CKSUMTYPE_RSA_MD5, NULL, 0, +- &ticket->enc_part.ciphertext, &cksum); ++ ret = k5_sha256(&ticket->enc_part.ciphertext, 1, hashbytes); + if (ret) + return ret; + +- hash = k5alloc(cksum.length * 2 + 1, &ret); +- if (hash != NULL) { +- for (i = 0, ptr = hash; i < cksum.length; i++, ptr += 2) +- snprintf(ptr, 3, "%02X", cksum.contents[i]); +- *ptr = '\0'; +- *out = hash; +- } +- krb5_free_checksum_contents(context, &cksum); ++ hash = k5alloc(sizeof(hashbytes) * 2 + 1, &ret); ++ if (hash == NULL) ++ return ret; ++ ++ for (i = 0, ptr = hash; i < sizeof(hashbytes); i++, ptr += 2) ++ snprintf(ptr, 3, "%02X", hashbytes[i]); ++ *ptr = '\0'; ++ *out = hash; + + return 0; + } diff --git a/SOURCES/Use-a-hash-table-for-MEMORY-ccache-resolution.patch b/SOURCES/Use-a-hash-table-for-MEMORY-ccache-resolution.patch new file mode 100644 index 0000000..fe0a184 --- /dev/null +++ b/SOURCES/Use-a-hash-table-for-MEMORY-ccache-resolution.patch @@ -0,0 +1,185 @@ +From 6e29836f794abdd91aa03d334b72b7a7f4800e92 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Sat, 4 Aug 2018 23:55:18 -0400 +Subject: [PATCH] Use a hash table for MEMORY ccache resolution + +In cc_memory.c, replace the linked list of caches with a hash table, +for better performance with large numbers of memory caches. + +ticket: 8722 (new) +(cherry picked from commit 088ba228acce4fd55bbb7c30122fe2703b8beeb8) +--- + src/lib/krb5/ccache/cc_memory.c | 77 +++++++++++++++------------------ + 1 file changed, 34 insertions(+), 43 deletions(-) + +diff --git a/src/lib/krb5/ccache/cc_memory.c b/src/lib/krb5/ccache/cc_memory.c +index cfd5c6389..114ef6913 100644 +--- a/src/lib/krb5/ccache/cc_memory.c ++++ b/src/lib/krb5/ccache/cc_memory.c +@@ -26,6 +26,7 @@ + + #include "cc-int.h" + #include "../krb/int-proto.h" ++#include "k5-hashtab.h" + #include + + static krb5_error_code KRB5_CALLCONV krb5_mcc_close +@@ -118,12 +119,6 @@ typedef struct _krb5_mcc_data { + int generation; /* Incremented at each initialize */ + } krb5_mcc_data; + +-/* List of memory caches. */ +-typedef struct krb5_mcc_list_node { +- struct krb5_mcc_list_node *next; +- krb5_mcc_data *cache; +-} krb5_mcc_list_node; +- + /* Iterator over credentials in a memory cache. */ + struct mcc_cursor { + int generation; +@@ -136,10 +131,27 @@ struct krb5_mcc_ptcursor_data { + }; + + k5_cc_mutex krb5int_mcc_mutex = K5_CC_MUTEX_PARTIAL_INITIALIZER; +-static krb5_mcc_list_node *mcc_head = 0; ++static struct k5_hashtab *mcc_hashtab = NULL; + + static void update_mcc_change_time(krb5_mcc_data *); + ++/* Ensure that mcc_hashtab is initialized. Call with krb5int_mcc_mutex ++ * locked. */ ++static krb5_error_code ++init_table(krb5_context context) ++{ ++ krb5_error_code ret; ++ uint8_t seed[K5_HASH_SEED_LEN]; ++ krb5_data d = make_data(seed, sizeof(seed)); ++ ++ if (mcc_hashtab != NULL) ++ return 0; ++ ret = krb5_c_random_make_octets(context, &d); ++ if (ret) ++ return ret; ++ return k5_hashtab_create(seed, 64, &mcc_hashtab); ++} ++ + /* Remove creds from d, invalidate any existing cursors, and unset the client + * principal. The caller is responsible for locking. */ + static void +@@ -230,21 +242,13 @@ krb5_mcc_close(krb5_context context, krb5_ccache id) + krb5_error_code KRB5_CALLCONV + krb5_mcc_destroy(krb5_context context, krb5_ccache id) + { +- krb5_mcc_list_node **curr, *node; + krb5_mcc_data *d = id->data; + krb5_boolean removed_from_table = FALSE; + ++ /* Remove this node from the table if it is still present. */ + k5_cc_mutex_lock(context, &krb5int_mcc_mutex); +- +- for (curr = &mcc_head; *curr; curr = &(*curr)->next) { +- if ((*curr)->cache == d) { +- node = *curr; +- *curr = node->next; +- free(node); +- removed_from_table = TRUE; +- break; +- } +- } ++ if (k5_hashtab_remove(mcc_hashtab, d->name, strlen(d->name))) ++ removed_from_table = TRUE; + k5_cc_mutex_unlock(context, &krb5int_mcc_mutex); + + /* Empty the cache and remove the reference for the table slot. There will +@@ -289,16 +293,13 @@ krb5_mcc_resolve (krb5_context context, krb5_ccache *id, const char *residual) + { + krb5_os_context os_ctx = &context->os_context; + krb5_ccache lid; +- krb5_mcc_list_node *ptr; + krb5_error_code err; + krb5_mcc_data *d; + + k5_cc_mutex_lock(context, &krb5int_mcc_mutex); +- for (ptr = mcc_head; ptr; ptr=ptr->next) +- if (!strcmp(ptr->cache->name, residual)) +- break; +- if (ptr != NULL) { +- d = ptr->cache; ++ init_table(context); ++ d = k5_hashtab_get(mcc_hashtab, residual, strlen(residual)); ++ if (d != NULL) { + k5_cc_mutex_lock(context, &d->lock); + d->refcount++; + k5_cc_mutex_unlock(context, &d->lock); +@@ -438,18 +439,17 @@ krb5_mcc_end_seq_get(krb5_context context, krb5_ccache id, krb5_cc_cursor *curso + } + + /* +- * Utility routine: Creates the back-end data for a memory cache, and threads +- * it into the global linked list. Give the new object two references, one for +- * the table slot and one for the caller's handle. ++ * Utility routine: Creates the back-end data for a memory cache, and adds it ++ * to the global table. Give the new object two references, one for the table ++ * slot and one for the caller's handle. + * +- * Call with the global list lock held. ++ * Call with the global table lock held. + */ + static krb5_error_code + new_mcc_data (const char *name, krb5_mcc_data **dataptr) + { + krb5_error_code err; + krb5_mcc_data *d; +- krb5_mcc_list_node *n; + + d = malloc(sizeof(krb5_mcc_data)); + if (d == NULL) +@@ -476,18 +476,13 @@ new_mcc_data (const char *name, krb5_mcc_data **dataptr) + d->generation = 0; + update_mcc_change_time(d); + +- n = malloc(sizeof(krb5_mcc_list_node)); +- if (n == NULL) { ++ if (k5_hashtab_add(mcc_hashtab, d->name, strlen(d->name), d) != 0) { + free(d->name); + k5_cc_mutex_destroy(&d->lock); + free(d); + return KRB5_CC_NOMEM; + } + +- n->cache = d; +- n->next = mcc_head; +- mcc_head = n; +- + *dataptr = d; + return 0; + } +@@ -522,11 +517,10 @@ krb5_mcc_generate_new (krb5_context context, krb5_ccache *id) + lid->ops = &krb5_mcc_ops; + + k5_cc_mutex_lock(context, &krb5int_mcc_mutex); ++ init_table(context); + + /* Check for uniqueness with mutex locked to avoid race conditions */ + while (1) { +- krb5_mcc_list_node *ptr; +- + err = krb5int_random_string (context, uniquename, sizeof (uniquename)); + if (err) { + k5_cc_mutex_unlock(context, &krb5int_mcc_mutex); +@@ -534,12 +528,9 @@ krb5_mcc_generate_new (krb5_context context, krb5_ccache *id) + return err; + } + +- for (ptr = mcc_head; ptr; ptr=ptr->next) { +- if (!strcmp(ptr->cache->name, uniquename)) { +- break; /* got a match, loop again */ +- } +- } +- if (!ptr) break; /* got to the end without finding a match */ ++ if (k5_hashtab_get(mcc_hashtab, uniquename, ++ strlen(uniquename)) == NULL) ++ break; + } + + err = new_mcc_data(uniquename, &d); diff --git a/SOURCES/Use-krb5_timestamp-where-appropriate.patch b/SOURCES/Use-krb5_timestamp-where-appropriate.patch new file mode 100644 index 0000000..96705ed --- /dev/null +++ b/SOURCES/Use-krb5_timestamp-where-appropriate.patch @@ -0,0 +1,327 @@ +From 6eda4c6a2cd301418b2efbfd737a86079abb02e9 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Wed, 17 May 2017 15:14:15 -0400 +Subject: [PATCH] Use krb5_timestamp where appropriate + +Where krb5_int32 is used to hold the number of seconds since the +epoch, use krb5_timestamp instead. + +(cherry picked from commit ae25f6ec5558140a546db34fea389412d81c0631) +--- + src/clients/klist/klist.c | 2 +- + src/include/k5-int.h | 2 +- + src/kadmin/server/misc.c | 2 +- + src/kdc/dispatch.c | 4 ++-- + src/lib/kadm5/srv/server_acl.c | 2 +- + src/lib/kadm5/srv/server_kdb.c | 2 +- + src/lib/kadm5/srv/svr_principal.c | 10 +++++----- + src/lib/krb5/krb/gen_save_subkey.c | 3 ++- + src/lib/krb5/krb/get_in_tkt.c | 2 +- + src/lib/krb5/krb/init_ctx.c | 3 ++- + src/lib/krb5/os/c_ustime.c | 7 +++++-- + src/lib/krb5/os/toffset.c | 3 ++- + src/lib/krb5/os/trace.c | 3 ++- + src/lib/krb5/os/ustime.c | 3 ++- + src/lib/krb5/rcache/rc_dfl.c | 10 +++++----- + src/tests/create/kdb5_mkdums.c | 2 +- + 16 files changed, 34 insertions(+), 26 deletions(-) + +diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c +index ffeecc394..4334415be 100644 +--- a/src/clients/klist/klist.c ++++ b/src/clients/klist/klist.c +@@ -56,7 +56,7 @@ int show_adtype = 0, show_all = 0, list_all = 0, use_client_keytab = 0; + int show_config = 0; + char *defname; + char *progname; +-krb5_int32 now; ++krb5_timestamp now; + unsigned int timestamp_width; + + krb5_context kcontext; +diff --git a/src/include/k5-int.h b/src/include/k5-int.h +index 82ee20760..ed9c7bf75 100644 +--- a/src/include/k5-int.h ++++ b/src/include/k5-int.h +@@ -721,7 +721,7 @@ krb5_error_code krb5int_c_copy_keyblock_contents(krb5_context context, + const krb5_keyblock *from, + krb5_keyblock *to); + +-krb5_error_code krb5_crypto_us_timeofday(krb5_int32 *, krb5_int32 *); ++krb5_error_code krb5_crypto_us_timeofday(krb5_timestamp *, krb5_int32 *); + + /* + * End "los-proto.h" +diff --git a/src/kadmin/server/misc.c b/src/kadmin/server/misc.c +index a75b65a26..ba672d714 100644 +--- a/src/kadmin/server/misc.c ++++ b/src/kadmin/server/misc.c +@@ -159,7 +159,7 @@ kadm5_ret_t + check_min_life(void *server_handle, krb5_principal principal, + char *msg_ret, unsigned int msg_len) + { +- krb5_int32 now; ++ krb5_timestamp now; + kadm5_ret_t ret; + kadm5_policy_ent_rec pol; + kadm5_principal_ent_rec princ; +diff --git a/src/kdc/dispatch.c b/src/kdc/dispatch.c +index 16a35d2be..4ecc23481 100644 +--- a/src/kdc/dispatch.c ++++ b/src/kdc/dispatch.c +@@ -94,8 +94,8 @@ static void + reseed_random(krb5_context kdc_err_context) + { + krb5_error_code retval; +- krb5_int32 now, now_usec; +- krb5_int32 usec_difference; ++ krb5_timestamp now; ++ krb5_int32 now_usec, usec_difference; + krb5_data data; + + retval = krb5_crypto_us_timeofday(&now, &now_usec); +diff --git a/src/lib/kadm5/srv/server_acl.c b/src/lib/kadm5/srv/server_acl.c +index 656dddff5..c2cf69169 100644 +--- a/src/lib/kadm5/srv/server_acl.c ++++ b/src/lib/kadm5/srv/server_acl.c +@@ -375,7 +375,7 @@ kadm5int_acl_impose_restrictions(kcontext, recp, maskp, rp) + restriction_t *rp; + { + krb5_error_code code; +- krb5_int32 now; ++ krb5_timestamp now; + + DPRINT(DEBUG_CALLS, acl_debug_level, + ("* kadm5int_acl_impose_restrictions(..., *maskp=0x%08x, rp=0x%08x)\n", +diff --git a/src/lib/kadm5/srv/server_kdb.c b/src/lib/kadm5/srv/server_kdb.c +index 612553ba3..f4b8aef2b 100644 +--- a/src/lib/kadm5/srv/server_kdb.c ++++ b/src/lib/kadm5/srv/server_kdb.c +@@ -365,7 +365,7 @@ kdb_put_entry(kadm5_server_handle_t handle, + krb5_db_entry *kdb, osa_princ_ent_rec *adb) + { + krb5_error_code ret; +- krb5_int32 now; ++ krb5_timestamp now; + XDR xdrs; + krb5_tl_data tl_data; + +diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c +index f4a9a2ad2..0d4f0a632 100644 +--- a/src/lib/kadm5/srv/svr_principal.c ++++ b/src/lib/kadm5/srv/svr_principal.c +@@ -296,7 +296,7 @@ kadm5_create_principal_3(void *server_handle, + osa_princ_ent_rec adb; + kadm5_policy_ent_rec polent; + krb5_boolean have_polent = FALSE; +- krb5_int32 now; ++ krb5_timestamp now; + krb5_tl_data *tl_data_tail; + unsigned int ret; + kadm5_server_handle_t handle = server_handle; +@@ -1322,7 +1322,7 @@ kadm5_chpass_principal_3(void *server_handle, + int n_ks_tuple, krb5_key_salt_tuple *ks_tuple, + char *password) + { +- krb5_int32 now; ++ krb5_timestamp now; + kadm5_policy_ent_rec pol; + osa_princ_ent_rec adb; + krb5_db_entry *kdb; +@@ -1544,7 +1544,7 @@ kadm5_randkey_principal_3(void *server_handle, + { + krb5_db_entry *kdb; + osa_princ_ent_rec adb; +- krb5_int32 now; ++ krb5_timestamp now; + kadm5_policy_ent_rec pol; + int ret, last_pwd, n_new_keys; + krb5_boolean have_pol = FALSE; +@@ -1686,7 +1686,7 @@ kadm5_setv4key_principal(void *server_handle, + { + krb5_db_entry *kdb; + osa_princ_ent_rec adb; +- krb5_int32 now; ++ krb5_timestamp now; + kadm5_policy_ent_rec pol; + krb5_keysalt keysalt; + int i, kvno, ret; +@@ -1888,7 +1888,7 @@ kadm5_setkey_principal_4(void *server_handle, krb5_principal principal, + { + krb5_db_entry *kdb; + osa_princ_ent_rec adb; +- krb5_int32 now; ++ krb5_timestamp now; + kadm5_policy_ent_rec pol; + krb5_key_data *new_key_data = NULL; + int i, j, ret, n_new_key_data = 0; +diff --git a/src/lib/krb5/krb/gen_save_subkey.c b/src/lib/krb5/krb/gen_save_subkey.c +index 61f36aa36..bc2c46d30 100644 +--- a/src/lib/krb5/krb/gen_save_subkey.c ++++ b/src/lib/krb5/krb/gen_save_subkey.c +@@ -38,7 +38,8 @@ k5_generate_and_save_subkey(krb5_context context, + to guarantee randomness, but to make it less likely that multiple + sessions could pick the same subkey. */ + struct { +- krb5_int32 sec, usec; ++ krb5_timestamp sec; ++ krb5_int32 usec; + } rnd_data; + krb5_data d; + krb5_error_code retval; +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index 40aba1905..7178bd87b 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -1788,7 +1788,7 @@ k5_populate_gic_opt(krb5_context context, krb5_get_init_creds_opt **out, + krb5_creds *creds) + { + int i; +- krb5_int32 starttime; ++ krb5_timestamp starttime; + krb5_deltat lifetime; + krb5_get_init_creds_opt *opt; + krb5_error_code retval; +diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c +index cf226fdba..4246c5dd2 100644 +--- a/src/lib/krb5/krb/init_ctx.c ++++ b/src/lib/krb5/krb/init_ctx.c +@@ -139,7 +139,8 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags, + krb5_context ctx = 0; + krb5_error_code retval; + struct { +- krb5_int32 now, now_usec; ++ krb5_timestamp now; ++ krb5_int32 now_usec; + long pid; + } seed_data; + krb5_data seed; +diff --git a/src/lib/krb5/os/c_ustime.c b/src/lib/krb5/os/c_ustime.c +index 68fb381f4..f69f2ea4c 100644 +--- a/src/lib/krb5/os/c_ustime.c ++++ b/src/lib/krb5/os/c_ustime.c +@@ -29,7 +29,10 @@ + + k5_mutex_t krb5int_us_time_mutex = K5_MUTEX_PARTIAL_INITIALIZER; + +-struct time_now { krb5_int32 sec, usec; }; ++struct time_now { ++ krb5_timestamp sec; ++ krb5_int32 usec; ++}; + + #if defined(_WIN32) + +@@ -73,7 +76,7 @@ get_time_now(struct time_now *n) + static struct time_now last_time; + + krb5_error_code +-krb5_crypto_us_timeofday(krb5_int32 *seconds, krb5_int32 *microseconds) ++krb5_crypto_us_timeofday(krb5_timestamp *seconds, krb5_int32 *microseconds) + { + struct time_now now; + krb5_error_code err; +diff --git a/src/lib/krb5/os/toffset.c b/src/lib/krb5/os/toffset.c +index 37bc69f49..4bbcdde52 100644 +--- a/src/lib/krb5/os/toffset.c ++++ b/src/lib/krb5/os/toffset.c +@@ -40,7 +40,8 @@ krb5_error_code KRB5_CALLCONV + krb5_set_real_time(krb5_context context, krb5_timestamp seconds, krb5_int32 microseconds) + { + krb5_os_context os_ctx = &context->os_context; +- krb5_int32 sec, usec; ++ krb5_timestamp sec; ++ krb5_int32 usec; + krb5_error_code retval; + + retval = krb5_crypto_us_timeofday(&sec, &usec); +diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c +index 74c315c90..8750b7650 100644 +--- a/src/lib/krb5/os/trace.c ++++ b/src/lib/krb5/os/trace.c +@@ -340,7 +340,8 @@ krb5int_trace(krb5_context context, const char *fmt, ...) + va_list ap; + krb5_trace_info info; + char *str = NULL, *msg = NULL; +- krb5_int32 sec, usec; ++ krb5_timestamp sec; ++ krb5_int32 usec; + + if (context == NULL || context->trace_callback == NULL) + return; +diff --git a/src/lib/krb5/os/ustime.c b/src/lib/krb5/os/ustime.c +index 1c1b571eb..a80fdf68c 100644 +--- a/src/lib/krb5/os/ustime.c ++++ b/src/lib/krb5/os/ustime.c +@@ -40,7 +40,8 @@ krb5_error_code + k5_time_with_offset(krb5_timestamp offset, krb5_int32 offset_usec, + krb5_timestamp *time_out, krb5_int32 *usec_out) + { +- krb5_int32 sec, usec; ++ krb5_timestamp sec; ++ krb5_int32 usec; + krb5_error_code retval; + + retval = krb5_crypto_us_timeofday(&sec, &usec); +diff --git a/src/lib/krb5/rcache/rc_dfl.c b/src/lib/krb5/rcache/rc_dfl.c +index 6b043844d..41ebf94da 100644 +--- a/src/lib/krb5/rcache/rc_dfl.c ++++ b/src/lib/krb5/rcache/rc_dfl.c +@@ -93,7 +93,7 @@ cmp(krb5_donot_replay *old, krb5_donot_replay *new1, krb5_deltat t) + } + + static int +-alive(krb5_int32 mytime, krb5_donot_replay *new1, krb5_deltat t) ++alive(krb5_timestamp mytime, krb5_donot_replay *new1, krb5_deltat t) + { + if (mytime == 0) + return CMP_HOHUM; /* who cares? */ +@@ -129,7 +129,7 @@ struct authlist + + static int + rc_store(krb5_context context, krb5_rcache id, krb5_donot_replay *rep, +- krb5_int32 now, krb5_boolean fromfile) ++ krb5_timestamp now, krb5_boolean fromfile) + { + struct dfl_data *t = (struct dfl_data *)id->data; + unsigned int rephash; +@@ -536,7 +536,7 @@ krb5_rc_dfl_recover_locked(krb5_context context, krb5_rcache id) + krb5_error_code retval; + long max_size; + int expired_entries = 0; +- krb5_int32 now; ++ krb5_timestamp now; + + if ((retval = krb5_rc_io_open(context, &t->d, t->name))) { + return retval; +@@ -706,7 +706,7 @@ krb5_rc_dfl_store(krb5_context context, krb5_rcache id, krb5_donot_replay *rep) + { + krb5_error_code ret; + struct dfl_data *t; +- krb5_int32 now; ++ krb5_timestamp now; + + ret = krb5_timeofday(context, &now); + if (ret) +@@ -762,7 +762,7 @@ krb5_rc_dfl_expunge_locked(krb5_context context, krb5_rcache id) + struct authlist **qt; + struct authlist *r; + struct authlist *rt; +- krb5_int32 now; ++ krb5_timestamp now; + + if (krb5_timestamp(context, &now)) + now = 0; +diff --git a/src/tests/create/kdb5_mkdums.c b/src/tests/create/kdb5_mkdums.c +index 622f549f9..7c0666601 100644 +--- a/src/tests/create/kdb5_mkdums.c ++++ b/src/tests/create/kdb5_mkdums.c +@@ -247,7 +247,7 @@ add_princ(context, str_newprinc) + + { + /* Add mod princ to db entry */ +- krb5_int32 now; ++ krb5_timestamp now; + + retval = krb5_timeofday(context, &now); + if (retval) { diff --git a/SOURCES/Use-the-canonical-client-principal-name-for-OTP.patch b/SOURCES/Use-the-canonical-client-principal-name-for-OTP.patch new file mode 100644 index 0000000..ceedcda --- /dev/null +++ b/SOURCES/Use-the-canonical-client-principal-name-for-OTP.patch @@ -0,0 +1,29 @@ +From a23d45875c03d6284f6b5b2851d3ecb8d3ec88ce Mon Sep 17 00:00:00 2001 +From: Matt Rogers +Date: Wed, 5 Apr 2017 16:48:55 -0400 +Subject: [PATCH] Use the canonical client principal name for OTP + +In the OTP module, when constructing the RADIUS request, use the +canonicalized client principal (using the new client_name kdcpreauth +callback) instead of the request client principal. + +ticket: 8571 (new) +(cherry picked from commit 6411398e35e343cdc4d2d103b079c4d3b9031f7e) +--- + src/plugins/preauth/otp/main.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/plugins/preauth/otp/main.c b/src/plugins/preauth/otp/main.c +index 2649e9a90..a1b681682 100644 +--- a/src/plugins/preauth/otp/main.c ++++ b/src/plugins/preauth/otp/main.c +@@ -331,7 +331,8 @@ otp_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request, + + /* Send the request. */ + otp_state_verify((otp_state *)moddata, cb->event_context(context, rock), +- request->client, config, req, on_response, rs); ++ cb->client_name(context, rock), config, req, on_response, ++ rs); + cb->free_string(context, rock, config); + + k5_free_pa_otp_req(context, req); diff --git a/SOURCES/_kadmind b/SOURCES/_kadmind new file mode 100644 index 0000000..b073cfb --- /dev/null +++ b/SOURCES/_kadmind @@ -0,0 +1,14 @@ +#!/bin/sh +# +# Check for error conditions which the init system expects us to check and +# for other common errors, and exit with the expected status codes. +# +kadmind=/usr/sbin/kadmind +if test -f /var/kerberos/krb5kdc/kpropd.acl ; then + echo $"Error. This appears to be a slave server, found kpropd.acl" + exit 6 +fi +if ! test -x "$kadmind" ; then + exit 5 +fi +exec "$kadmind" "$@" diff --git a/SOURCES/_kpropd b/SOURCES/_kpropd new file mode 100644 index 0000000..1808368 --- /dev/null +++ b/SOURCES/_kpropd @@ -0,0 +1,14 @@ +#!/bin/sh +# +# Check for error conditions which the init system expects us to check and +# for other common errors, and exit with the expected status codes. +# +kpropd=/usr/sbin/kpropd +if ! test -f /var/kerberos/krb5kdc/kpropd.acl ; then + echo $"Error. This does not appear to be a slave server, kpropd.acl not found" + exit 6 +fi +if ! test -x "$kpropd" ; then + exit 5 +fi +exec "$kpropd" "$@" diff --git a/SOURCES/kadm5.acl b/SOURCES/kadm5.acl new file mode 100644 index 0000000..dc93eb0 --- /dev/null +++ b/SOURCES/kadm5.acl @@ -0,0 +1 @@ +*/admin@EXAMPLE.COM * diff --git a/SOURCES/kadmin.service b/SOURCES/kadmin.service new file mode 100644 index 0000000..018a14e --- /dev/null +++ b/SOURCES/kadmin.service @@ -0,0 +1,14 @@ +[Unit] +Description=Kerberos 5 Password-changing and Administration +Wants=network-online.target +After=syslog.target network.target network-online.target + +[Service] +Type=forking +PIDFile=/var/run/kadmind.pid +EnvironmentFile=-/etc/sysconfig/kadmin +ExecStart=/usr/sbin/_kadmind -P /var/run/kadmind.pid $KADMIND_ARGS +ExecReload=/bin/kill -HUP $MAINPID + +[Install] +WantedBy=multi-user.target diff --git a/SOURCES/kadmin.sysconfig b/SOURCES/kadmin.sysconfig new file mode 100644 index 0000000..fa72039 --- /dev/null +++ b/SOURCES/kadmin.sysconfig @@ -0,0 +1 @@ +KADMIND_ARGS= diff --git a/SOURCES/kadmind.init b/SOURCES/kadmind.init new file mode 100755 index 0000000..8915e2b --- /dev/null +++ b/SOURCES/kadmind.init @@ -0,0 +1,108 @@ +#!/bin/bash +# +# kadmind Start and stop the Kerberos 5 administrative server. +# +# chkconfig: - 35 65 +# description: Kerberos 5 is a trusted third-party authentication system. \ +# This script starts and stops the Kerberos 5 administrative \ +# server, which should only be run on the master server for a \ +# realm. +# processname: kadmind +# config: /etc/sysconfig/kadmin +# pidfile: /var/run/kadmind.pid +# + +### BEGIN INIT INFO +# Provides: kadmin +# Required-Start: $local_fs $network +# Required-Stop: $local_fs $network +# Should-Start: portreserve +# Default-Start: +# Default-Stop: 0 1 2 3 4 5 6 +# Short-Description: start and stop the Kerberos 5 admin server +# Description: The kadmind service allows administrators to remotely manage \ +# the Kerberos 5 realm database. It should only be run on a \ +# master KDC. +### END INIT INFO + +# Get config. +. /etc/sysconfig/network + +# Get config. +[ -r /etc/sysconfig/kadmin ] && . /etc/sysconfig/kadmin + +# Source function library. +. /etc/init.d/functions +prog="Kerberos 5 Admin Server" +kadmind=/usr/sbin/kadmind +pidfile=/var/run/kadmind.pid + +RETVAL=0 + +# Shell functions to cut down on useless shell instances. +start() { + if [ -f /var/kerberos/krb5kdc/kpropd.acl ] ; then + echo $"Error. This appears to be a slave server, found kpropd.acl" + exit 6 + else + [ -x $kadmind ] || exit 5 + fi + echo -n $"Starting $prog: " + # tell portreserve to release the kerberos-adm port + [ -x /sbin/portrelease ] && /sbin/portrelease kerberos-adm &>/dev/null || : + daemon ${kadmind} ${KRB5REALM:+-r ${KRB5REALM}} -P $pidfile $KADMIND_ARGS + RETVAL=$? + echo + if test $RETVAL -ne 0 ; then + if status -l kadmin ${kadmind} > /dev/null ; then + RETVAL=0 + fi + fi + [ $RETVAL = 0 ] && touch /var/lock/subsys/kadmin +} +stop() { + echo -n $"Stopping $prog: " + killproc ${kadmind} + RETVAL=$? + echo + [ $RETVAL = 0 ] && rm -f /var/lock/subsys/kadmin +} +reload() { + echo -n $"Reopening $prog log file: " + killproc ${kadmind} -HUP + RETVAL=$? + echo +} + +# See how we were called. +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + stop + start + ;; + status) + status -l kadmin ${kadmind} + RETVAL=$? + ;; + reload) + reload + ;; + condrestart) + if [ -f /var/lock/subsys/kadmin ] ; then + stop + start + fi + ;; + *) + echo $"Usage: $0 {start|stop|status|condrestart|reload|restart}" + RETVAL=2 + ;; +esac + +exit $RETVAL diff --git a/SOURCES/kadmind.logrotate b/SOURCES/kadmind.logrotate new file mode 100644 index 0000000..52a66c4 --- /dev/null +++ b/SOURCES/kadmind.logrotate @@ -0,0 +1,9 @@ +/var/log/kadmind.log { + missingok + notifempty + monthly + rotate 12 + postrotate + /bin/kill -HUP `cat /var/run/kadmind.pid 2>/dev/null` 2> /dev/null || true + endscript +} diff --git a/SOURCES/kdc.conf b/SOURCES/kdc.conf new file mode 100644 index 0000000..e99219a --- /dev/null +++ b/SOURCES/kdc.conf @@ -0,0 +1,12 @@ +[kdcdefaults] + kdc_ports = 88 + kdc_tcp_ports = 88 + +[realms] + EXAMPLE.COM = { + #master_key_type = aes256-cts + acl_file = /var/kerberos/krb5kdc/kadm5.acl + dict_file = /usr/share/dict/words + admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab + supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal + } diff --git a/SOURCES/kerberos-adm.portreserve b/SOURCES/kerberos-adm.portreserve new file mode 100644 index 0000000..eb6080d --- /dev/null +++ b/SOURCES/kerberos-adm.portreserve @@ -0,0 +1 @@ +kerberos-adm/tcp diff --git a/SOURCES/kprop.service b/SOURCES/kprop.service new file mode 100644 index 0000000..5903bd1 --- /dev/null +++ b/SOURCES/kprop.service @@ -0,0 +1,12 @@ +[Unit] +Description=Kerberos 5 Propagation +Wants=network-online.target +After=syslog.target network.target network-online.target + +[Service] +Type=forking +EnvironmentFile=-/etc/sysconfig/kprop +ExecStart=/usr/sbin/_kpropd $KPROPD_ARGS + +[Install] +WantedBy=multi-user.target diff --git a/SOURCES/kprop.sysconfig b/SOURCES/kprop.sysconfig new file mode 100644 index 0000000..f43e8bb --- /dev/null +++ b/SOURCES/kprop.sysconfig @@ -0,0 +1 @@ +KPROPD_ARGS= diff --git a/SOURCES/kpropd.init b/SOURCES/kpropd.init new file mode 100755 index 0000000..b872ee3 --- /dev/null +++ b/SOURCES/kpropd.init @@ -0,0 +1,92 @@ +#!/bin/bash +# +# kpropd.init Start and stop the Kerberos 5 propagation client. +# +# chkconfig: - 35 65 +# description: Kerberos 5 is a trusted third-party authentication system. \ +# This script starts and stops the service that allows this \ +# KDC to receive updates from your master KDC. +# processname: kpropd +# + +### BEGIN INIT INFO +# Provides: kprop +# Required-Start: $local_fs $network +# Required-Stop: $local_fs $network +# Should-Start: portreserve +# Default-Start: +# Default-Stop: 0 1 2 3 4 5 6 +# Short-Description: start and stop the Kerberos 5 propagation client +# Description: The kpropd service accepts database updates pushed to it from \ +# the master KDC. It will never be needed on a master KDC. +### END INIT INFO + +# Get config. +. /etc/sysconfig/network + +# Source function library. +. /etc/init.d/functions + +RETVAL=0 +prog="Kerberos 5 Propagation Server" +kpropd=/usr/sbin/kpropd + +# Shell functions to cut down on useless shell instances. +start() { + [ -f /var/kerberos/krb5kdc/kpropd.acl ] || exit 6 + [ -x $kpropd ] || exit 5 + echo -n $"Starting $prog: " + # tell portreserve to release the krb5_prop port + [ -x /sbin/portrelease ] && /sbin/portrelease krb5_prop &>/dev/null || : + daemon ${kpropd} -S + RETVAL=$? + echo + if test $RETVAL -ne 0 ; then + if status -l kprop ${kpropd} > /dev/null ; then + RETVAL=0 + fi + fi + [ $RETVAL = 0 ] && touch /var/lock/subsys/kprop +} +stop() { + echo -n $"Stopping $prog: " + killproc ${kpropd} + RETVAL=$? + echo + [ $RETVAL = 0 ] && rm -f /var/lock/subsys/kprop +} + +# See how we were called. +case "$1" in + start) + start + ;; + stop) + stop + ;; + # We don't really "do" reload, so treat it as a restart. + restart|force-reload) + stop + start + ;; + reload) + echo "can't reload configuration, you have to restart it" + RETVAL=3 + ;; + status) + status -l kprop ${kpropd} + RETVAL=$? + ;; + condrestart) + if [ -f /var/lock/subsys/kprop ] ; then + stop + start + fi + ;; + *) + echo $"Usage: $0 {start|stop|restart|condrestart|reload|status|force-reload}" + RETVAL=2 + ;; +esac + +exit $RETVAL diff --git a/SOURCES/krb5-1.11-kpasswdtest.patch b/SOURCES/krb5-1.11-kpasswdtest.patch new file mode 100644 index 0000000..4657926 --- /dev/null +++ b/SOURCES/krb5-1.11-kpasswdtest.patch @@ -0,0 +1,21 @@ +From c21187b3a9f37fd88230e963275d3242344f8f82 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 22 Apr 2016 10:03:40 -0400 +Subject: [PATCH] krb5-1.11-kpasswdtest.patch + +--- + src/kadmin/testing/proto/krb5.conf.proto | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/kadmin/testing/proto/krb5.conf.proto b/src/kadmin/testing/proto/krb5.conf.proto +index 00c442978..9c4bc1de7 100644 +--- a/src/kadmin/testing/proto/krb5.conf.proto ++++ b/src/kadmin/testing/proto/krb5.conf.proto +@@ -9,6 +9,7 @@ + __REALM__ = { + kdc = __KDCHOST__:1750 + admin_server = __KDCHOST__:1751 ++ kpasswd_server = __KDCHOST__:1752 + database_module = foobar_db2_module_blah + } + diff --git a/SOURCES/krb5-1.11-run_user_0.patch b/SOURCES/krb5-1.11-run_user_0.patch new file mode 100644 index 0000000..734341c --- /dev/null +++ b/SOURCES/krb5-1.11-run_user_0.patch @@ -0,0 +1,41 @@ +From b22fe94f6965ebdd2e0cbf2ac002e0e5f9c11789 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 22 Apr 2016 10:03:22 -0400 +Subject: [PATCH] krb5-1.11-run_user_0.patch + +--- + src/lib/krb5/ccache/cc_dir.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/src/lib/krb5/ccache/cc_dir.c b/src/lib/krb5/ccache/cc_dir.c +index 73f0fe62d..4850c0d07 100644 +--- a/src/lib/krb5/ccache/cc_dir.c ++++ b/src/lib/krb5/ccache/cc_dir.c +@@ -61,6 +61,8 @@ + + #include + ++#define ROOT_SPECIAL_DCC_PARENT "/run/user/0" ++ + extern const krb5_cc_ops krb5_dcc_ops; + extern const krb5_cc_ops krb5_fcc_ops; + +@@ -237,6 +239,18 @@ verify_dir(krb5_context context, const char *dirname) + + if (stat(dirname, &st) < 0) { + if (errno == ENOENT) { ++ if (strncmp(dirname, ROOT_SPECIAL_DCC_PARENT "/", ++ sizeof(ROOT_SPECIAL_DCC_PARENT)) == 0 && ++ stat(ROOT_SPECIAL_DCC_PARENT, &st) < 0 && ++ errno == ENOENT) { ++#ifdef USE_SELINUX ++ selabel = krb5int_push_fscreatecon_for(ROOT_SPECIAL_DCC_PARENT); ++#endif ++ status = mkdir(ROOT_SPECIAL_DCC_PARENT, S_IRWXU); ++#ifdef USE_SELINUX ++ krb5int_pop_fscreatecon(selabel); ++#endif ++ } + #ifdef USE_SELINUX + selabel = krb5int_push_fscreatecon_for(dirname); + #endif diff --git a/SOURCES/krb5-1.12-api.patch b/SOURCES/krb5-1.12-api.patch new file mode 100644 index 0000000..ae261d5 --- /dev/null +++ b/SOURCES/krb5-1.12-api.patch @@ -0,0 +1,34 @@ +From a609a605d87b3107de64141cd3d60c2a73c7b38f Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 22 Apr 2016 09:59:22 -0400 +Subject: [PATCH] krb5-1.12-api.patch + +--- + src/lib/krb5/krb/princ_comp.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/lib/krb5/krb/princ_comp.c b/src/lib/krb5/krb/princ_comp.c +index a6936107d..0ed78833b 100644 +--- a/src/lib/krb5/krb/princ_comp.c ++++ b/src/lib/krb5/krb/princ_comp.c +@@ -36,6 +36,10 @@ realm_compare_flags(krb5_context context, + const krb5_data *realm1 = &princ1->realm; + const krb5_data *realm2 = &princ2->realm; + ++ if (princ1 == NULL || princ2 == NULL) ++ return FALSE; ++ if (realm1 == NULL || realm2 == NULL) ++ return FALSE; + if (realm1->length != realm2->length) + return FALSE; + if (realm1->length == 0) +@@ -88,6 +92,9 @@ krb5_principal_compare_flags(krb5_context context, + krb5_principal upn2 = NULL; + krb5_boolean ret = FALSE; + ++ if (princ1 == NULL || princ2 == NULL) ++ return FALSE; ++ + if (flags & KRB5_PRINCIPAL_COMPARE_ENTERPRISE) { + /* Treat UPNs as if they were real principals */ + if (princ1->type == KRB5_NT_ENTERPRISE_PRINCIPAL) { diff --git a/SOURCES/krb5-1.12-ksu-path.patch b/SOURCES/krb5-1.12-ksu-path.patch new file mode 100644 index 0000000..7127916 --- /dev/null +++ b/SOURCES/krb5-1.12-ksu-path.patch @@ -0,0 +1,21 @@ +From fc004dc501c6fc1f1f423a8d87cdc9137d7f6bbf Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 22 Apr 2016 09:57:25 -0400 +Subject: [PATCH] krb5-1.12-ksu-path.patch + +--- + src/clients/ksu/Makefile.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/clients/ksu/Makefile.in b/src/clients/ksu/Makefile.in +index 5755bb58a..9d58f29b5 100644 +--- a/src/clients/ksu/Makefile.in ++++ b/src/clients/ksu/Makefile.in +@@ -1,6 +1,6 @@ + mydir=clients$(S)ksu + BUILDTOP=$(REL)..$(S).. +-DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin /local/bin"' ++DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/usr/local/sbin /usr/local/bin /sbin /bin /usr/sbin /usr/bin"' + + KSU_LIBS=@KSU_LIBS@ + PAM_LIBS=@PAM_LIBS@ diff --git a/SOURCES/krb5-1.12-ktany.patch b/SOURCES/krb5-1.12-ktany.patch new file mode 100644 index 0000000..d7fe63a --- /dev/null +++ b/SOURCES/krb5-1.12-ktany.patch @@ -0,0 +1,363 @@ +From 5c9294c37210d01f59c54ea623a66618ed2e0e6e Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 22 Apr 2016 09:58:00 -0400 +Subject: [PATCH] krb5-1.12-ktany.patch + +--- + src/lib/krb5/keytab/Makefile.in | 3 + + src/lib/krb5/keytab/kt_any.c | 292 ++++++++++++++++++++++++++++++++ + src/lib/krb5/keytab/ktbase.c | 7 +- + 3 files changed, 301 insertions(+), 1 deletion(-) + create mode 100644 src/lib/krb5/keytab/kt_any.c + +diff --git a/src/lib/krb5/keytab/Makefile.in b/src/lib/krb5/keytab/Makefile.in +index 2a8fceb00..ffd179fb2 100644 +--- a/src/lib/krb5/keytab/Makefile.in ++++ b/src/lib/krb5/keytab/Makefile.in +@@ -12,6 +12,7 @@ STLIBOBJS= \ + ktfr_entry.o \ + ktremove.o \ + ktfns.o \ ++ kt_any.o \ + kt_file.o \ + kt_memory.o \ + kt_srvtab.o \ +@@ -24,6 +25,7 @@ OBJS= \ + $(OUTPRE)ktfr_entry.$(OBJEXT) \ + $(OUTPRE)ktremove.$(OBJEXT) \ + $(OUTPRE)ktfns.$(OBJEXT) \ ++ $(OUTPRE)kt_any.$(OBJEXT) \ + $(OUTPRE)kt_file.$(OBJEXT) \ + $(OUTPRE)kt_memory.$(OBJEXT) \ + $(OUTPRE)kt_srvtab.$(OBJEXT) \ +@@ -36,6 +38,7 @@ SRCS= \ + $(srcdir)/ktfr_entry.c \ + $(srcdir)/ktremove.c \ + $(srcdir)/ktfns.c \ ++ $(srcdir)/kt_any.c \ + $(srcdir)/kt_file.c \ + $(srcdir)/kt_memory.c \ + $(srcdir)/kt_srvtab.c \ +diff --git a/src/lib/krb5/keytab/kt_any.c b/src/lib/krb5/keytab/kt_any.c +new file mode 100644 +index 000000000..1b9b7765b +--- /dev/null ++++ b/src/lib/krb5/keytab/kt_any.c +@@ -0,0 +1,292 @@ ++/* ++ * lib/krb5/keytab/kt_any.c ++ * ++ * Copyright 1998, 1999 by the Massachusetts Institute of Technology. ++ * All Rights Reserved. ++ * ++ * Export of this software from the United States of America may ++ * require a specific license from the United States Government. ++ * It is the responsibility of any person or organization contemplating ++ * export to obtain such a license before exporting. ++ * ++ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and ++ * distribute this software and its documentation for any purpose and ++ * without fee is hereby granted, provided that the above copyright ++ * notice appear in all copies and that both that copyright notice and ++ * this permission notice appear in supporting documentation, and that ++ * the name of M.I.T. not be used in advertising or publicity pertaining ++ * to distribution of the software without specific, written prior ++ * permission. M.I.T. makes no representations about the suitability of ++ * this software for any purpose. It is provided "as is" without express ++ * or implied warranty. ++ * ++ * ++ * krb5_kta_ops ++ */ ++ ++#include "k5-int.h" ++ ++typedef struct _krb5_ktany_data { ++ char *name; ++ krb5_keytab *choices; ++ int nchoices; ++} krb5_ktany_data; ++ ++typedef struct _krb5_ktany_cursor_data { ++ int which; ++ krb5_kt_cursor cursor; ++} krb5_ktany_cursor_data; ++ ++static krb5_error_code krb5_ktany_resolve ++ (krb5_context, ++ const char *, ++ krb5_keytab *); ++static krb5_error_code krb5_ktany_get_name ++ (krb5_context context, ++ krb5_keytab id, ++ char *name, ++ unsigned int len); ++static krb5_error_code krb5_ktany_close ++ (krb5_context context, ++ krb5_keytab id); ++static krb5_error_code krb5_ktany_get_entry ++ (krb5_context context, ++ krb5_keytab id, ++ krb5_const_principal principal, ++ krb5_kvno kvno, ++ krb5_enctype enctype, ++ krb5_keytab_entry *entry); ++static krb5_error_code krb5_ktany_start_seq_get ++ (krb5_context context, ++ krb5_keytab id, ++ krb5_kt_cursor *cursorp); ++static krb5_error_code krb5_ktany_next_entry ++ (krb5_context context, ++ krb5_keytab id, ++ krb5_keytab_entry *entry, ++ krb5_kt_cursor *cursor); ++static krb5_error_code krb5_ktany_end_seq_get ++ (krb5_context context, ++ krb5_keytab id, ++ krb5_kt_cursor *cursor); ++static void cleanup ++ (krb5_context context, ++ krb5_ktany_data *data, ++ int nchoices); ++ ++struct _krb5_kt_ops krb5_kta_ops = { ++ 0, ++ "ANY", /* Prefix -- this string should not appear anywhere else! */ ++ krb5_ktany_resolve, ++ krb5_ktany_get_name, ++ krb5_ktany_close, ++ krb5_ktany_get_entry, ++ krb5_ktany_start_seq_get, ++ krb5_ktany_next_entry, ++ krb5_ktany_end_seq_get, ++ NULL, ++ NULL, ++ NULL, ++}; ++ ++static krb5_error_code ++krb5_ktany_resolve(context, name, id) ++ krb5_context context; ++ const char *name; ++ krb5_keytab *id; ++{ ++ const char *p, *q; ++ char *copy; ++ krb5_error_code kerror; ++ krb5_ktany_data *data; ++ int i; ++ ++ /* Allocate space for our data and remember a copy of the name. */ ++ if ((data = (krb5_ktany_data *)malloc(sizeof(krb5_ktany_data))) == NULL) ++ return(ENOMEM); ++ if ((data->name = (char *)malloc(strlen(name) + 1)) == NULL) { ++ free(data); ++ return(ENOMEM); ++ } ++ strcpy(data->name, name); ++ ++ /* Count the number of choices and allocate memory for them. */ ++ data->nchoices = 1; ++ for (p = name; (q = strchr(p, ',')) != NULL; p = q + 1) ++ data->nchoices++; ++ if ((data->choices = (krb5_keytab *) ++ malloc(data->nchoices * sizeof(krb5_keytab))) == NULL) { ++ free(data->name); ++ free(data); ++ return(ENOMEM); ++ } ++ ++ /* Resolve each of the choices. */ ++ i = 0; ++ for (p = name; (q = strchr(p, ',')) != NULL; p = q + 1) { ++ /* Make a copy of the choice name so we can terminate it. */ ++ if ((copy = (char *)malloc(q - p + 1)) == NULL) { ++ cleanup(context, data, i); ++ return(ENOMEM); ++ } ++ memcpy(copy, p, q - p); ++ copy[q - p] = 0; ++ ++ /* Try resolving the choice name. */ ++ kerror = krb5_kt_resolve(context, copy, &data->choices[i]); ++ free(copy); ++ if (kerror) { ++ cleanup(context, data, i); ++ return(kerror); ++ } ++ i++; ++ } ++ if ((kerror = krb5_kt_resolve(context, p, &data->choices[i]))) { ++ cleanup(context, data, i); ++ return(kerror); ++ } ++ ++ /* Allocate and fill in an ID for the caller. */ ++ if ((*id = (krb5_keytab)malloc(sizeof(**id))) == NULL) { ++ cleanup(context, data, i); ++ return(ENOMEM); ++ } ++ (*id)->ops = &krb5_kta_ops; ++ (*id)->data = (krb5_pointer)data; ++ (*id)->magic = KV5M_KEYTAB; ++ ++ return(0); ++} ++ ++static krb5_error_code ++krb5_ktany_get_name(context, id, name, len) ++ krb5_context context; ++ krb5_keytab id; ++ char *name; ++ unsigned int len; ++{ ++ krb5_ktany_data *data = (krb5_ktany_data *)id->data; ++ ++ if (len < strlen(data->name) + 1) ++ return(KRB5_KT_NAME_TOOLONG); ++ strcpy(name, data->name); ++ return(0); ++} ++ ++static krb5_error_code ++krb5_ktany_close(context, id) ++ krb5_context context; ++ krb5_keytab id; ++{ ++ krb5_ktany_data *data = (krb5_ktany_data *)id->data; ++ ++ cleanup(context, data, data->nchoices); ++ id->ops = 0; ++ free(id); ++ return(0); ++} ++ ++static krb5_error_code ++krb5_ktany_get_entry(context, id, principal, kvno, enctype, entry) ++ krb5_context context; ++ krb5_keytab id; ++ krb5_const_principal principal; ++ krb5_kvno kvno; ++ krb5_enctype enctype; ++ krb5_keytab_entry *entry; ++{ ++ krb5_ktany_data *data = (krb5_ktany_data *)id->data; ++ krb5_error_code kerror = KRB5_KT_NOTFOUND; ++ int i; ++ ++ for (i = 0; i < data->nchoices; i++) { ++ if ((kerror = krb5_kt_get_entry(context, data->choices[i], principal, ++ kvno, enctype, entry)) != ENOENT) ++ return kerror; ++ } ++ return kerror; ++} ++ ++static krb5_error_code ++krb5_ktany_start_seq_get(context, id, cursorp) ++ krb5_context context; ++ krb5_keytab id; ++ krb5_kt_cursor *cursorp; ++{ ++ krb5_ktany_data *data = (krb5_ktany_data *)id->data; ++ krb5_ktany_cursor_data *cdata; ++ krb5_error_code kerror = ENOENT; ++ int i; ++ ++ if ((cdata = (krb5_ktany_cursor_data *) ++ malloc(sizeof(krb5_ktany_cursor_data))) == NULL) ++ return(ENOMEM); ++ ++ /* Find a choice which can handle the serialization request. */ ++ for (i = 0; i < data->nchoices; i++) { ++ if ((kerror = krb5_kt_start_seq_get(context, data->choices[i], ++ &cdata->cursor)) == 0) ++ break; ++ else if (kerror != ENOENT) { ++ free(cdata); ++ return(kerror); ++ } ++ } ++ ++ if (i == data->nchoices) { ++ /* Everyone returned ENOENT, so no go. */ ++ free(cdata); ++ return(kerror); ++ } ++ ++ cdata->which = i; ++ *cursorp = (krb5_kt_cursor)cdata; ++ return(0); ++} ++ ++static krb5_error_code ++krb5_ktany_next_entry(context, id, entry, cursor) ++ krb5_context context; ++ krb5_keytab id; ++ krb5_keytab_entry *entry; ++ krb5_kt_cursor *cursor; ++{ ++ krb5_ktany_data *data = (krb5_ktany_data *)id->data; ++ krb5_ktany_cursor_data *cdata = (krb5_ktany_cursor_data *)*cursor; ++ krb5_keytab choice_id; ++ ++ choice_id = data->choices[cdata->which]; ++ return(krb5_kt_next_entry(context, choice_id, entry, &cdata->cursor)); ++} ++ ++static krb5_error_code ++krb5_ktany_end_seq_get(context, id, cursor) ++ krb5_context context; ++ krb5_keytab id; ++ krb5_kt_cursor *cursor; ++{ ++ krb5_ktany_data *data = (krb5_ktany_data *)id->data; ++ krb5_ktany_cursor_data *cdata = (krb5_ktany_cursor_data *)*cursor; ++ krb5_keytab choice_id; ++ krb5_error_code kerror; ++ ++ choice_id = data->choices[cdata->which]; ++ kerror = krb5_kt_end_seq_get(context, choice_id, &cdata->cursor); ++ free(cdata); ++ return(kerror); ++} ++ ++static void ++cleanup(context, data, nchoices) ++ krb5_context context; ++ krb5_ktany_data *data; ++ int nchoices; ++{ ++ int i; ++ ++ free(data->name); ++ for (i = 0; i < nchoices; i++) ++ krb5_kt_close(context, data->choices[i]); ++ free(data->choices); ++ free(data); ++} +diff --git a/src/lib/krb5/keytab/ktbase.c b/src/lib/krb5/keytab/ktbase.c +index 0d39b2940..6534d7c52 100644 +--- a/src/lib/krb5/keytab/ktbase.c ++++ b/src/lib/krb5/keytab/ktbase.c +@@ -57,14 +57,19 @@ extern const krb5_kt_ops krb5_ktf_ops; + extern const krb5_kt_ops krb5_ktf_writable_ops; + extern const krb5_kt_ops krb5_kts_ops; + extern const krb5_kt_ops krb5_mkt_ops; ++extern const krb5_kt_ops krb5_kta_ops; + + struct krb5_kt_typelist { + const krb5_kt_ops *ops; + const struct krb5_kt_typelist *next; + }; ++static struct krb5_kt_typelist krb5_kt_typelist_any = { ++ &krb5_kta_ops, ++ NULL ++}; + const static struct krb5_kt_typelist krb5_kt_typelist_srvtab = { + &krb5_kts_ops, +- NULL ++ &krb5_kt_typelist_any + }; + const static struct krb5_kt_typelist krb5_kt_typelist_memory = { + &krb5_mkt_ops, diff --git a/SOURCES/krb5-1.12.1-pam.patch b/SOURCES/krb5-1.12.1-pam.patch new file mode 100644 index 0000000..9ea8088 --- /dev/null +++ b/SOURCES/krb5-1.12.1-pam.patch @@ -0,0 +1,757 @@ +From 9a6c3d9c1f4286a1a17cd89a1225712606863da8 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Mon, 18 Apr 2016 15:57:38 -0400 +Subject: [PATCH] krb5-1.12.1-pam.patch + +--- + src/aclocal.m4 | 67 +++++++ + src/clients/ksu/Makefile.in | 8 +- + src/clients/ksu/main.c | 88 +++++++- + src/clients/ksu/pam.c | 389 ++++++++++++++++++++++++++++++++++++ + src/clients/ksu/pam.h | 57 ++++++ + src/configure.in | 2 + + 6 files changed, 608 insertions(+), 3 deletions(-) + create mode 100644 src/clients/ksu/pam.c + create mode 100644 src/clients/ksu/pam.h + +diff --git a/src/aclocal.m4 b/src/aclocal.m4 +index 9c46da4b5..508e5fe90 100644 +--- a/src/aclocal.m4 ++++ b/src/aclocal.m4 +@@ -1675,3 +1675,70 @@ AC_DEFUN(KRB5_AC_PERSISTENT_KEYRING,[ + ])) + ])dnl + dnl ++dnl ++dnl Use PAM instead of local crypt() compare for checking local passwords, ++dnl and perform PAM account, session management, and password-changing where ++dnl appropriate. ++dnl ++AC_DEFUN(KRB5_WITH_PAM,[ ++AC_ARG_WITH(pam,[AC_HELP_STRING(--with-pam,[compile with PAM support])], ++ withpam="$withval",withpam=auto) ++AC_ARG_WITH(pam-ksu-service,[AC_HELP_STRING(--with-ksu-service,[PAM service name for ksu ["ksu"]])], ++ withksupamservice="$withval",withksupamservice=ksu) ++old_LIBS="$LIBS" ++if test "$withpam" != no ; then ++ AC_MSG_RESULT([checking for PAM...]) ++ PAM_LIBS= ++ ++ AC_CHECK_HEADERS(security/pam_appl.h) ++ if test "x$ac_cv_header_security_pam_appl_h" != xyes ; then ++ if test "$withpam" = auto ; then ++ AC_MSG_RESULT([Unable to locate security/pam_appl.h.]) ++ withpam=no ++ else ++ AC_MSG_ERROR([Unable to locate security/pam_appl.h.]) ++ fi ++ fi ++ ++ LIBS= ++ unset ac_cv_func_pam_start ++ AC_CHECK_FUNCS(putenv pam_start) ++ if test "x$ac_cv_func_pam_start" = xno ; then ++ unset ac_cv_func_pam_start ++ AC_CHECK_LIB(dl,dlopen) ++ AC_CHECK_FUNCS(pam_start) ++ if test "x$ac_cv_func_pam_start" = xno ; then ++ AC_CHECK_LIB(pam,pam_start) ++ unset ac_cv_func_pam_start ++ unset ac_cv_func_pam_getenvlist ++ AC_CHECK_FUNCS(pam_start pam_getenvlist) ++ if test "x$ac_cv_func_pam_start" = xyes ; then ++ PAM_LIBS="$LIBS" ++ else ++ if test "$withpam" = auto ; then ++ AC_MSG_RESULT([Unable to locate libpam.]) ++ withpam=no ++ else ++ AC_MSG_ERROR([Unable to locate libpam.]) ++ fi ++ fi ++ fi ++ fi ++ if test "$withpam" != no ; then ++ AC_MSG_NOTICE([building with PAM support]) ++ AC_DEFINE(USE_PAM,1,[Define if Kerberos-aware tools should support PAM]) ++ AC_DEFINE_UNQUOTED(KSU_PAM_SERVICE,"$withksupamservice", ++ [Define to the name of the PAM service name to be used by ksu.]) ++ PAM_LIBS="$LIBS" ++ NON_PAM_MAN=".\\\" " ++ PAM_MAN= ++ else ++ PAM_MAN=".\\\" " ++ NON_PAM_MAN= ++ fi ++fi ++LIBS="$old_LIBS" ++AC_SUBST(PAM_LIBS) ++AC_SUBST(PAM_MAN) ++AC_SUBST(NON_PAM_MAN) ++])dnl +diff --git a/src/clients/ksu/Makefile.in b/src/clients/ksu/Makefile.in +index b2fcbf240..5755bb58a 100644 +--- a/src/clients/ksu/Makefile.in ++++ b/src/clients/ksu/Makefile.in +@@ -3,12 +3,14 @@ BUILDTOP=$(REL)..$(S).. + DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin /local/bin"' + + KSU_LIBS=@KSU_LIBS@ ++PAM_LIBS=@PAM_LIBS@ + + SRCS = \ + $(srcdir)/krb_auth_su.c \ + $(srcdir)/ccache.c \ + $(srcdir)/authorization.c \ + $(srcdir)/main.c \ ++ $(srcdir)/pam.c \ + $(srcdir)/heuristic.c \ + $(srcdir)/xmalloc.c \ + $(srcdir)/setenv.c +@@ -17,13 +19,17 @@ OBJS = \ + ccache.o \ + authorization.o \ + main.o \ ++ pam.o \ + heuristic.o \ + xmalloc.o @SETENVOBJ@ + + all: ksu + + ksu: $(OBJS) $(KRB5_BASE_DEPLIBS) +- $(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS) ++ $(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS) $(PAM_LIBS) ++ ++pam.o: pam.c ++ $(CC) $(ALL_CFLAGS) -c $< + + clean: + $(RM) ksu +diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c +index 28342c2d7..cab0c1806 100644 +--- a/src/clients/ksu/main.c ++++ b/src/clients/ksu/main.c +@@ -26,6 +26,7 @@ + * KSU was writen by: Ari Medvinsky, ari@isi.edu + */ + ++#include "autoconf.h" + #include "ksu.h" + #include "adm_proto.h" + #include +@@ -33,6 +34,10 @@ + #include + #include + ++#ifdef USE_PAM ++#include "pam.h" ++#endif ++ + /* globals */ + char * prog_name; + int auth_debug =0; +@@ -40,6 +45,7 @@ char k5login_path[MAXPATHLEN]; + char k5users_path[MAXPATHLEN]; + char * gb_err = NULL; + int quiet = 0; ++int force_fork = 0; + /***********/ + + #define KS_TEMPORARY_CACHE "MEMORY:_ksu" +@@ -515,6 +521,23 @@ main (argc, argv) + prog_name,target_user,client_name, + source_user,ontty()); + ++#ifdef USE_PAM ++ if (appl_pam_enabled(ksu_context, "ksu")) { ++ if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL, ++ NULL, source_user, ++ ttyname(STDERR_FILENO)) != 0) { ++ fprintf(stderr, "Access denied for %s.\n", target_user); ++ exit(1); ++ } ++ if (appl_pam_requires_chauthtok()) { ++ fprintf(stderr, "Password change required for %s.\n", ++ target_user); ++ exit(1); ++ } ++ force_fork++; ++ } ++#endif ++ + /* Run authorization as target.*/ + if (krb5_seteuid(target_uid)) { + com_err(prog_name, errno, _("while switching to target for " +@@ -575,6 +598,24 @@ main (argc, argv) + + exit(1); + } ++#ifdef USE_PAM ++ } else { ++ /* we always do PAM account management, even for root */ ++ if (appl_pam_enabled(ksu_context, "ksu")) { ++ if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL, ++ NULL, source_user, ++ ttyname(STDERR_FILENO)) != 0) { ++ fprintf(stderr, "Access denied for %s.\n", target_user); ++ exit(1); ++ } ++ if (appl_pam_requires_chauthtok()) { ++ fprintf(stderr, "Password change required for %s.\n", ++ target_user); ++ exit(1); ++ } ++ force_fork++; ++ } ++#endif + } + + if( some_rest_copy){ +@@ -632,6 +673,30 @@ main (argc, argv) + exit(1); + } + ++#ifdef USE_PAM ++ if (appl_pam_enabled(ksu_context, "ksu")) { ++ if (appl_pam_session_open() != 0) { ++ fprintf(stderr, "Error opening session for %s.\n", target_user); ++ exit(1); ++ } ++#ifdef DEBUG ++ if (auth_debug){ ++ printf(" Opened PAM session.\n"); ++ } ++#endif ++ if (appl_pam_cred_init()) { ++ fprintf(stderr, "Error initializing credentials for %s.\n", ++ target_user); ++ exit(1); ++ } ++#ifdef DEBUG ++ if (auth_debug){ ++ printf(" Initialized PAM credentials.\n"); ++ } ++#endif ++ } ++#endif ++ + /* set permissions */ + if (setgid(target_pwd->pw_gid) < 0) { + perror("ksu: setgid"); +@@ -729,7 +794,7 @@ main (argc, argv) + fprintf(stderr, "program to be execed %s\n",params[0]); + } + +- if( keep_target_cache ) { ++ if( keep_target_cache && !force_fork ) { + execv(params[0], params); + com_err(prog_name, errno, _("while trying to execv %s"), params[0]); + sweep_up(ksu_context, cc_target); +@@ -759,16 +824,35 @@ main (argc, argv) + if (ret_pid == -1) { + com_err(prog_name, errno, _("while calling waitpid")); + } +- sweep_up(ksu_context, cc_target); ++ if( !keep_target_cache ) { ++ sweep_up(ksu_context, cc_target); ++ } + exit (statusp); + case -1: + com_err(prog_name, errno, _("while trying to fork.")); + sweep_up(ksu_context, cc_target); + exit (1); + case 0: ++#ifdef USE_PAM ++ if (appl_pam_enabled(ksu_context, "ksu")) { ++ if (appl_pam_setenv() != 0) { ++ fprintf(stderr, "Error setting up environment for %s.\n", ++ target_user); ++ exit (1); ++ } ++#ifdef DEBUG ++ if (auth_debug){ ++ printf(" Set up PAM environment.\n"); ++ } ++#endif ++ } ++#endif + execv(params[0], params); + com_err(prog_name, errno, _("while trying to execv %s"), + params[0]); ++ if( keep_target_cache ) { ++ sweep_up(ksu_context, cc_target); ++ } + exit (1); + } + } +diff --git a/src/clients/ksu/pam.c b/src/clients/ksu/pam.c +new file mode 100644 +index 000000000..cbfe48704 +--- /dev/null ++++ b/src/clients/ksu/pam.c +@@ -0,0 +1,389 @@ ++/* ++ * src/clients/ksu/pam.c ++ * ++ * Copyright 2007,2009,2010 Red Hat, Inc. ++ * ++ * All Rights Reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * Redistributions of source code must retain the above copyright notice, this ++ * list of conditions and the following disclaimer. ++ * ++ * Redistributions in binary form must reproduce the above copyright notice, ++ * this list of conditions and the following disclaimer in the documentation ++ * and/or other materials provided with the distribution. ++ * ++ * Neither the name of Red Hat, Inc. nor the names of its contributors may be ++ * used to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ * ++ * Convenience wrappers for using PAM. ++ */ ++ ++#include "autoconf.h" ++#ifdef USE_PAM ++#include ++#include ++#include ++#include ++#include ++#include "k5-int.h" ++#include "pam.h" ++ ++#ifndef MAXPWSIZE ++#define MAXPWSIZE 128 ++#endif ++ ++static int appl_pam_started; ++static pid_t appl_pam_starter = -1; ++static int appl_pam_session_opened; ++static int appl_pam_creds_initialized; ++static int appl_pam_pwchange_required; ++static pam_handle_t *appl_pamh; ++static struct pam_conv appl_pam_conv; ++static char *appl_pam_user; ++struct appl_pam_non_interactive_args { ++ const char *user; ++ const char *password; ++}; ++ ++int ++appl_pam_enabled(krb5_context context, const char *section) ++{ ++ int enabled = 1; ++ if ((context != NULL) && (context->profile != NULL)) { ++ if (profile_get_boolean(context->profile, ++ section, ++ USE_PAM_CONFIGURATION_KEYWORD, ++ NULL, ++ enabled, &enabled) != 0) { ++ enabled = 1; ++ } ++ } ++ return enabled; ++} ++ ++void ++appl_pam_cleanup(void) ++{ ++ if (getpid() != appl_pam_starter) { ++ return; ++ } ++#ifdef DEBUG ++ printf("Called to clean up PAM.\n"); ++#endif ++ if (appl_pam_creds_initialized) { ++#ifdef DEBUG ++ printf("Deleting PAM credentials.\n"); ++#endif ++ pam_setcred(appl_pamh, PAM_DELETE_CRED); ++ appl_pam_creds_initialized = 0; ++ } ++ if (appl_pam_session_opened) { ++#ifdef DEBUG ++ printf("Closing PAM session.\n"); ++#endif ++ pam_close_session(appl_pamh, 0); ++ appl_pam_session_opened = 0; ++ } ++ appl_pam_pwchange_required = 0; ++ if (appl_pam_started) { ++#ifdef DEBUG ++ printf("Shutting down PAM.\n"); ++#endif ++ pam_end(appl_pamh, 0); ++ appl_pam_started = 0; ++ appl_pam_starter = -1; ++ free(appl_pam_user); ++ appl_pam_user = NULL; ++ } ++} ++static int ++appl_pam_interactive_converse(int num_msg, const struct pam_message **msg, ++ struct pam_response **presp, void *appdata_ptr) ++{ ++ const struct pam_message *message; ++ struct pam_response *resp; ++ int i, code; ++ char *pwstring, pwbuf[MAXPWSIZE]; ++ unsigned int pwsize; ++ resp = malloc(sizeof(struct pam_response) * num_msg); ++ if (resp == NULL) { ++ return PAM_BUF_ERR; ++ } ++ memset(resp, 0, sizeof(struct pam_response) * num_msg); ++ code = PAM_SUCCESS; ++ for (i = 0; i < num_msg; i++) { ++ message = &(msg[0][i]); /* XXX */ ++ message = msg[i]; /* XXX */ ++ pwstring = NULL; ++ switch (message->msg_style) { ++ case PAM_TEXT_INFO: ++ case PAM_ERROR_MSG: ++ printf("[%s]\n", message->msg ? message->msg : ""); ++ fflush(stdout); ++ resp[i].resp = NULL; ++ resp[i].resp_retcode = PAM_SUCCESS; ++ break; ++ case PAM_PROMPT_ECHO_ON: ++ case PAM_PROMPT_ECHO_OFF: ++ if (message->msg_style == PAM_PROMPT_ECHO_ON) { ++ if (fgets(pwbuf, sizeof(pwbuf), ++ stdin) != NULL) { ++ pwbuf[strcspn(pwbuf, "\r\n")] = '\0'; ++ pwstring = pwbuf; ++ } ++ } else { ++ pwstring = getpass(message->msg ? ++ message->msg : ++ ""); ++ } ++ if ((pwstring != NULL) && (pwstring[0] != '\0')) { ++ pwsize = strlen(pwstring); ++ resp[i].resp = malloc(pwsize + 1); ++ if (resp[i].resp == NULL) { ++ resp[i].resp_retcode = PAM_BUF_ERR; ++ } else { ++ memcpy(resp[i].resp, pwstring, pwsize); ++ resp[i].resp[pwsize] = '\0'; ++ resp[i].resp_retcode = PAM_SUCCESS; ++ } ++ } else { ++ resp[i].resp_retcode = PAM_CONV_ERR; ++ code = PAM_CONV_ERR; ++ } ++ break; ++ default: ++ break; ++ } ++ } ++ *presp = resp; ++ return code; ++} ++static int ++appl_pam_non_interactive_converse(int num_msg, ++ const struct pam_message **msg, ++ struct pam_response **presp, ++ void *appdata_ptr) ++{ ++ const struct pam_message *message; ++ struct pam_response *resp; ++ int i, code; ++ unsigned int pwsize; ++ struct appl_pam_non_interactive_args *args; ++ const char *pwstring; ++ resp = malloc(sizeof(struct pam_response) * num_msg); ++ if (resp == NULL) { ++ return PAM_BUF_ERR; ++ } ++ args = appdata_ptr; ++ memset(resp, 0, sizeof(struct pam_response) * num_msg); ++ code = PAM_SUCCESS; ++ for (i = 0; i < num_msg; i++) { ++ message = &((*msg)[i]); ++ message = msg[i]; ++ pwstring = NULL; ++ switch (message->msg_style) { ++ case PAM_TEXT_INFO: ++ case PAM_ERROR_MSG: ++ break; ++ case PAM_PROMPT_ECHO_ON: ++ case PAM_PROMPT_ECHO_OFF: ++ if (message->msg_style == PAM_PROMPT_ECHO_ON) { ++ /* assume "user" */ ++ pwstring = args->user; ++ } else { ++ /* assume "password" */ ++ pwstring = args->password; ++ } ++ if ((pwstring != NULL) && (pwstring[0] != '\0')) { ++ pwsize = strlen(pwstring); ++ resp[i].resp = malloc(pwsize + 1); ++ if (resp[i].resp == NULL) { ++ resp[i].resp_retcode = PAM_BUF_ERR; ++ } else { ++ memcpy(resp[i].resp, pwstring, pwsize); ++ resp[i].resp[pwsize] = '\0'; ++ resp[i].resp_retcode = PAM_SUCCESS; ++ } ++ } else { ++ resp[i].resp_retcode = PAM_CONV_ERR; ++ code = PAM_CONV_ERR; ++ } ++ break; ++ default: ++ break; ++ } ++ } ++ *presp = resp; ++ return code; ++} ++static int ++appl_pam_start(const char *service, int interactive, ++ const char *login_username, ++ const char *non_interactive_password, ++ const char *hostname, ++ const char *ruser, ++ const char *tty) ++{ ++ static int exit_handler_registered; ++ static struct appl_pam_non_interactive_args args; ++ int ret = 0; ++ if (appl_pam_started && ++ (strcmp(login_username, appl_pam_user) != 0)) { ++ appl_pam_cleanup(); ++ appl_pam_user = NULL; ++ } ++ if (!appl_pam_started) { ++#ifdef DEBUG ++ printf("Starting PAM up (service=\"%s\",user=\"%s\").\n", ++ service, login_username); ++#endif ++ memset(&appl_pam_conv, 0, sizeof(appl_pam_conv)); ++ appl_pam_conv.conv = interactive ? ++ &appl_pam_interactive_converse : ++ &appl_pam_non_interactive_converse; ++ memset(&args, 0, sizeof(args)); ++ args.user = strdup(login_username); ++ args.password = non_interactive_password ? ++ strdup(non_interactive_password) : ++ NULL; ++ appl_pam_conv.appdata_ptr = &args; ++ ret = pam_start(service, login_username, ++ &appl_pam_conv, &appl_pamh); ++ if (ret == 0) { ++ if (hostname != NULL) { ++#ifdef DEBUG ++ printf("Setting PAM_RHOST to \"%s\".\n", hostname); ++#endif ++ pam_set_item(appl_pamh, PAM_RHOST, hostname); ++ } ++ if (ruser != NULL) { ++#ifdef DEBUG ++ printf("Setting PAM_RUSER to \"%s\".\n", ruser); ++#endif ++ pam_set_item(appl_pamh, PAM_RUSER, ruser); ++ } ++ if (tty != NULL) { ++#ifdef DEBUG ++ printf("Setting PAM_TTY to \"%s\".\n", tty); ++#endif ++ pam_set_item(appl_pamh, PAM_TTY, tty); ++ } ++ if (!exit_handler_registered && ++ (atexit(appl_pam_cleanup) != 0)) { ++ pam_end(appl_pamh, 0); ++ appl_pamh = NULL; ++ ret = -1; ++ } else { ++ appl_pam_started = 1; ++ appl_pam_starter = getpid(); ++ appl_pam_user = strdup(login_username); ++ exit_handler_registered = 1; ++ } ++ } ++ } ++ return ret; ++} ++int ++appl_pam_acct_mgmt(const char *service, int interactive, ++ const char *login_username, ++ const char *non_interactive_password, ++ const char *hostname, ++ const char *ruser, ++ const char *tty) ++{ ++ int ret; ++ appl_pam_pwchange_required = 0; ++ ret = appl_pam_start(service, interactive, login_username, ++ non_interactive_password, hostname, ruser, tty); ++ if (ret == 0) { ++#ifdef DEBUG ++ printf("Calling pam_acct_mgmt().\n"); ++#endif ++ ret = pam_acct_mgmt(appl_pamh, 0); ++ switch (ret) { ++ case PAM_IGNORE: ++ ret = 0; ++ break; ++ case PAM_NEW_AUTHTOK_REQD: ++ appl_pam_pwchange_required = 1; ++ ret = 0; ++ break; ++ default: ++ break; ++ } ++ } ++ return ret; ++} ++int ++appl_pam_requires_chauthtok(void) ++{ ++ return appl_pam_pwchange_required; ++} ++int ++appl_pam_session_open(void) ++{ ++ int ret = 0; ++ if (appl_pam_started) { ++#ifdef DEBUG ++ printf("Opening PAM session.\n"); ++#endif ++ ret = pam_open_session(appl_pamh, 0); ++ if (ret == 0) { ++ appl_pam_session_opened = 1; ++ } ++ } ++ return ret; ++} ++int ++appl_pam_setenv(void) ++{ ++ int ret = 0; ++#ifdef HAVE_PAM_GETENVLIST ++#ifdef HAVE_PUTENV ++ int i; ++ char **list; ++ if (appl_pam_started) { ++ list = pam_getenvlist(appl_pamh); ++ for (i = 0; ((list != NULL) && (list[i] != NULL)); i++) { ++#ifdef DEBUG ++ printf("Setting \"%s\" in environment.\n", list[i]); ++#endif ++ putenv(list[i]); ++ } ++ } ++#endif ++#endif ++ return ret; ++} ++int ++appl_pam_cred_init(void) ++{ ++ int ret = 0; ++ if (appl_pam_started) { ++#ifdef DEBUG ++ printf("Initializing PAM credentials.\n"); ++#endif ++ ret = pam_setcred(appl_pamh, PAM_ESTABLISH_CRED); ++ if (ret == 0) { ++ appl_pam_creds_initialized = 1; ++ } ++ } ++ return ret; ++} ++#endif +diff --git a/src/clients/ksu/pam.h b/src/clients/ksu/pam.h +new file mode 100644 +index 000000000..0ab76569c +--- /dev/null ++++ b/src/clients/ksu/pam.h +@@ -0,0 +1,57 @@ ++/* ++ * src/clients/ksu/pam.h ++ * ++ * Copyright 2007,2009,2010 Red Hat, Inc. ++ * ++ * All Rights Reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * Redistributions of source code must retain the above copyright notice, this ++ * list of conditions and the following disclaimer. ++ * ++ * Redistributions in binary form must reproduce the above copyright notice, ++ * this list of conditions and the following disclaimer in the documentation ++ * and/or other materials provided with the distribution. ++ * ++ * Neither the name of Red Hat, Inc. nor the names of its contributors may be ++ * used to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ * ++ * Convenience wrappers for using PAM. ++ */ ++ ++#include ++#ifdef HAVE_SECURITY_PAM_APPL_H ++#include ++#endif ++ ++#define USE_PAM_CONFIGURATION_KEYWORD "use_pam" ++ ++#ifdef USE_PAM ++int appl_pam_enabled(krb5_context context, const char *section); ++int appl_pam_acct_mgmt(const char *service, int interactive, ++ const char *local_username, ++ const char *non_interactive_password, ++ const char *hostname, ++ const char *ruser, ++ const char *tty); ++int appl_pam_requires_chauthtok(void); ++int appl_pam_session_open(void); ++int appl_pam_setenv(void); ++int appl_pam_cred_init(void); ++void appl_pam_cleanup(void); ++#endif +diff --git a/src/configure.in b/src/configure.in +index 037c9f316..daabd12c8 100644 +--- a/src/configure.in ++++ b/src/configure.in +@@ -1336,6 +1336,8 @@ AC_SUBST([VERTO_VERSION]) + + AC_PATH_PROG(GROFF, groff) + ++KRB5_WITH_PAM ++ + # Make localedir work in autoconf 2.5x. + if test "${localedir+set}" != set; then + localedir='$(datadir)/locale' diff --git a/SOURCES/krb5-1.13-dirsrv-accountlock.patch b/SOURCES/krb5-1.13-dirsrv-accountlock.patch new file mode 100644 index 0000000..4ef1afa --- /dev/null +++ b/SOURCES/krb5-1.13-dirsrv-accountlock.patch @@ -0,0 +1,73 @@ +From f8404b502015b4a9806894d212462c63c3307fa8 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 22 Apr 2016 10:01:15 -0400 +Subject: [PATCH] krb5-1.13-dirsrv-accountlock.patch + +--- + src/aclocal.m4 | 9 +++++++++ + src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c | 17 +++++++++++++++++ + .../kdb/ldap/libkdb_ldap/ldap_principal.c | 3 +++ + 3 files changed, 29 insertions(+) + +diff --git a/src/aclocal.m4 b/src/aclocal.m4 +index f5667c35f..2bfb99496 100644 +--- a/src/aclocal.m4 ++++ b/src/aclocal.m4 +@@ -1656,6 +1656,15 @@ if test "$with_ldap" = yes; then + AC_MSG_NOTICE(enabling OpenLDAP database backend module support) + OPENLDAP_PLUGIN=yes + fi ++AC_ARG_WITH([dirsrv-account-locking], ++[ --with-dirsrv-account-locking compile 389/Red Hat/Fedora/Netscape Directory Server database backend module], ++[case "$withval" in ++ yes | no) ;; ++ *) AC_MSG_ERROR(Invalid option value --with-dirsrv-account-locking="$withval") ;; ++esac], with_dirsrv_account_locking=no) ++if test $with_dirsrv_account_locking = yes; then ++ AC_DEFINE(HAVE_DIRSRV_ACCOUNT_LOCKING,1,[Define if LDAP KDB interface should heed 389 DS's nsAccountLock attribute.]) ++fi + ])dnl + dnl + dnl If libkeyutils exists (on Linux) include it and use keyring ccache +diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c +index 32efc4f54..af8b2db7b 100644 +--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c ++++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c +@@ -1674,6 +1674,23 @@ populate_krb5_db_entry(krb5_context context, krb5_ldap_context *ldap_context, + ret = krb5_dbe_update_tl_data(context, entry, &userinfo_tl_data); + if (ret) + goto cleanup; ++#ifdef HAVE_DIRSRV_ACCOUNT_LOCKING ++ { ++ krb5_timestamp expiretime=0; ++ char *is_login_disabled=NULL; ++ ++ /* LOGIN DISABLED */ ++ ret = krb5_ldap_get_string(ld, ent, "nsAccountLock", &is_login_disabled, ++ &attr_present); ++ if (ret) ++ goto cleanup; ++ if (attr_present == TRUE) { ++ if (strcasecmp(is_login_disabled, "TRUE")== 0) ++ entry->attributes |= KRB5_KDB_DISALLOW_ALL_TIX; ++ free (is_login_disabled); ++ } ++ } ++#endif + + ret = krb5_read_tkt_policy(context, ldap_context, entry, tktpolname); + if (ret) +diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c +index d722dbfa6..5e8e9a897 100644 +--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c ++++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c +@@ -54,6 +54,9 @@ char *principal_attributes[] = { "krbprincipalname", + "krbLastFailedAuth", + "krbLoginFailedCount", + "krbLastSuccessfulAuth", ++#ifdef HAVE_DIRSRV_ACCOUNT_LOCKING ++ "nsAccountLock", ++#endif + "krbLastPwdChange", + "krbLastAdminUnlock", + "krbPrincipalAuthInd", diff --git a/SOURCES/krb5-1.15-beta1-buildconf.patch b/SOURCES/krb5-1.15-beta1-buildconf.patch new file mode 100644 index 0000000..958cfdf --- /dev/null +++ b/SOURCES/krb5-1.15-beta1-buildconf.patch @@ -0,0 +1,65 @@ +From eda215b5fdf43de6d5e0ee3641bb4bb42728ab11 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Wed, 4 Jan 2017 13:18:18 -0500 +Subject: [PATCH] krb5-1.15-beta1-buildconf.patch + +--- + src/build-tools/krb5-config.in | 7 +++++++ + src/config/pre.in | 2 +- + src/config/shlib.conf | 5 +++-- + 3 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/src/build-tools/krb5-config.in b/src/build-tools/krb5-config.in +index c17cb5eb5..1891dea99 100755 +--- a/src/build-tools/krb5-config.in ++++ b/src/build-tools/krb5-config.in +@@ -226,6 +226,13 @@ if test -n "$do_libs"; then + -e 's#\$(PTHREAD_CFLAGS)#'"$PTHREAD_CFLAGS"'#' \ + -e 's#\$(CFLAGS)##'` + ++ if test `dirname $libdir` = /usr ; then ++ lib_flags=`echo $lib_flags | sed -e "s#-L$libdir##" -e "s#$RPATH_FLAG$libdir##"` ++ fi ++ lib_flags=`echo $lib_flags | sed -e "s#-fPIE##g" -e "s#-pie##g"` ++ lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,relro##g"` ++ lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,now##g"` ++ + if test $library = 'kdb'; then + lib_flags="$lib_flags -lkdb5 $KDB5_DB_LIB" + library=krb5 +diff --git a/src/config/pre.in b/src/config/pre.in +index fcea229bd..d961b5621 100644 +--- a/src/config/pre.in ++++ b/src/config/pre.in +@@ -185,7 +185,7 @@ INSTALL_PROGRAM=@INSTALL_PROGRAM@ $(INSTALL_STRIP) + INSTALL_SCRIPT=@INSTALL_PROGRAM@ + INSTALL_DATA=@INSTALL_DATA@ + INSTALL_SHLIB=@INSTALL_SHLIB@ +-INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 -o root ++INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 + ## This is needed because autoconf will sometimes define @exec_prefix@ to be + ## ${prefix}. + prefix=@prefix@ +diff --git a/src/config/shlib.conf b/src/config/shlib.conf +index 3e4af6c02..2b20c3fda 100644 +--- a/src/config/shlib.conf ++++ b/src/config/shlib.conf +@@ -423,7 +423,7 @@ mips-*-netbsd*) + # Linux ld doesn't default to stuffing the SONAME field... + # Use objdump -x to examine the fields of the library + # UNDEF_CHECK is suppressed by --enable-asan +- LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) $(UNDEF_CHECK)' ++ LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) $(UNDEF_CHECK) -Wl,-z,relro -Wl,--warn-shared-textrel' + UNDEF_CHECK='-Wl,--no-undefined' + # $(EXPORT_CHECK) runs export-check.pl when in maintainer mode. + LDCOMBINE_TAIL='-Wl,--version-script binutils.versions $(EXPORT_CHECK)' +@@ -435,7 +435,8 @@ mips-*-netbsd*) + SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' + PROFFLAGS=-pg + PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' +- CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' ++ CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) -pie -Wl,-z,relro -Wl,-z,now $(LDFLAGS)' ++ INSTALL_SHLIB='${INSTALL} -m755' + CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' + CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' + CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' diff --git a/SOURCES/krb5-1.15-beta1-selinux-label.patch b/SOURCES/krb5-1.15-beta1-selinux-label.patch new file mode 100644 index 0000000..2a11b20 --- /dev/null +++ b/SOURCES/krb5-1.15-beta1-selinux-label.patch @@ -0,0 +1,1033 @@ +From 71fe21b5aeac1834df824ff5c6475e653ceb8b6b Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Wed, 4 Jan 2017 13:17:28 -0500 +Subject: [PATCH] krb5-1.15-beta1-selinux-label.patch + +--- + src/aclocal.m4 | 49 +++ + src/build-tools/krb5-config.in | 3 +- + src/config/pre.in | 3 +- + src/configure.in | 2 + + src/include/k5-int.h | 1 + + src/include/k5-label.h | 32 ++ + src/include/krb5/krb5.hin | 6 + + src/kadmin/dbutil/dump.c | 11 +- + src/kdc/main.c | 2 +- + src/lib/kadm5/logger.c | 4 +- + src/lib/kdb/kdb_log.c | 2 +- + src/lib/krb5/ccache/cc_dir.c | 26 +- + src/lib/krb5/keytab/kt_file.c | 4 +- + src/lib/krb5/os/trace.c | 2 +- + src/lib/krb5/rcache/rc_dfl.c | 13 + + src/plugins/kdb/db2/adb_openclose.c | 2 +- + src/plugins/kdb/db2/kdb_db2.c | 4 +- + src/plugins/kdb/db2/libdb2/btree/bt_open.c | 3 +- + src/plugins/kdb/db2/libdb2/hash/hash.c | 3 +- + src/plugins/kdb/db2/libdb2/recno/rec_open.c | 4 +- + .../kdb/ldap/ldap_util/kdb5_ldap_services.c | 11 +- + src/slave/kpropd.c | 9 + + src/util/profile/prof_file.c | 3 +- + src/util/support/Makefile.in | 3 +- + src/util/support/selinux.c | 406 ++++++++++++++++++ + 25 files changed, 587 insertions(+), 21 deletions(-) + create mode 100644 src/include/k5-label.h + create mode 100644 src/util/support/selinux.c + +diff --git a/src/aclocal.m4 b/src/aclocal.m4 +index 508e5fe90..607859f17 100644 +--- a/src/aclocal.m4 ++++ b/src/aclocal.m4 +@@ -89,6 +89,7 @@ AC_SUBST_FILE(libnodeps_frag) + dnl + KRB5_AC_PRAGMA_WEAK_REF + WITH_LDAP ++KRB5_WITH_SELINUX + KRB5_LIB_PARAMS + KRB5_AC_INITFINI + KRB5_AC_ENABLE_THREADS +@@ -1742,3 +1743,51 @@ AC_SUBST(PAM_LIBS) + AC_SUBST(PAM_MAN) + AC_SUBST(NON_PAM_MAN) + ])dnl ++dnl ++dnl Use libselinux to set file contexts on newly-created files. ++dnl ++AC_DEFUN(KRB5_WITH_SELINUX,[ ++AC_ARG_WITH(selinux,[AC_HELP_STRING(--with-selinux,[compile with SELinux labeling support])], ++ withselinux="$withval",withselinux=auto) ++old_LIBS="$LIBS" ++if test "$withselinux" != no ; then ++ AC_MSG_RESULT([checking for libselinux...]) ++ SELINUX_LIBS= ++ AC_CHECK_HEADERS(selinux/selinux.h selinux/label.h) ++ if test "x$ac_cv_header_selinux_selinux_h" != xyes ; then ++ if test "$withselinux" = auto ; then ++ AC_MSG_RESULT([Unable to locate selinux/selinux.h.]) ++ withselinux=no ++ else ++ AC_MSG_ERROR([Unable to locate selinux/selinux.h.]) ++ fi ++ fi ++ ++ LIBS= ++ unset ac_cv_func_setfscreatecon ++ AC_CHECK_FUNCS(setfscreatecon selabel_open) ++ if test "x$ac_cv_func_setfscreatecon" = xno ; then ++ AC_CHECK_LIB(selinux,setfscreatecon) ++ unset ac_cv_func_setfscreatecon ++ AC_CHECK_FUNCS(setfscreatecon selabel_open) ++ if test "x$ac_cv_func_setfscreatecon" = xyes ; then ++ SELINUX_LIBS="$LIBS" ++ else ++ if test "$withselinux" = auto ; then ++ AC_MSG_RESULT([Unable to locate libselinux.]) ++ withselinux=no ++ else ++ AC_MSG_ERROR([Unable to locate libselinux.]) ++ fi ++ fi ++ fi ++ if test "$withselinux" != no ; then ++ AC_MSG_NOTICE([building with SELinux labeling support]) ++ AC_DEFINE(USE_SELINUX,1,[Define if Kerberos-aware tools should set SELinux file contexts when creating files.]) ++ SELINUX_LIBS="$LIBS" ++ EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS krb5int_labeled_open krb5int_labeled_fopen krb5int_push_fscreatecon_for krb5int_pop_fscreatecon" ++ fi ++fi ++LIBS="$old_LIBS" ++AC_SUBST(SELINUX_LIBS) ++])dnl +diff --git a/src/build-tools/krb5-config.in b/src/build-tools/krb5-config.in +index f6184da3f..c17cb5eb5 100755 +--- a/src/build-tools/krb5-config.in ++++ b/src/build-tools/krb5-config.in +@@ -41,6 +41,7 @@ DL_LIB='@DL_LIB@' + DEFCCNAME='@DEFCCNAME@' + DEFKTNAME='@DEFKTNAME@' + DEFCKTNAME='@DEFCKTNAME@' ++SELINUX_LIBS='@SELINUX_LIBS@' + + LIBS='@LIBS@' + GEN_LIB=@GEN_LIB@ +@@ -255,7 +256,7 @@ if test -n "$do_libs"; then + fi + + # If we ever support a flag to generate output suitable for static +- # linking, we would output "-lkrb5support $GEN_LIB $LIBS $DL_LIB" ++ # linking, we would output "-lkrb5support $GEN_LIB $LIBS $SELINUX_LIBS $DL_LIB" + # here. + + echo $lib_flags +diff --git a/src/config/pre.in b/src/config/pre.in +index e0626320c..fcea229bd 100644 +--- a/src/config/pre.in ++++ b/src/config/pre.in +@@ -177,6 +177,7 @@ LD = $(PURE) @LD@ + KRB_INCLUDES = -I$(BUILDTOP)/include -I$(top_srcdir)/include + LDFLAGS = @LDFLAGS@ + LIBS = @LIBS@ ++SELINUX_LIBS=@SELINUX_LIBS@ + + INSTALL=@INSTALL@ + INSTALL_STRIP= +@@ -399,7 +400,7 @@ SUPPORT_LIB = -l$(SUPPORT_LIBNAME) + # HESIOD_LIBS is -lhesiod... + HESIOD_LIBS = @HESIOD_LIBS@ + +-KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(DL_LIB) ++KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(SELINUX_LIBS) $(DL_LIB) + KDB5_LIBS = $(KDB5_LIB) $(GSSRPC_LIBS) + GSS_LIBS = $(GSS_KRB5_LIB) + # needs fixing if ever used on Mac OS X! +diff --git a/src/configure.in b/src/configure.in +index daabd12c8..acf3a458b 100644 +--- a/src/configure.in ++++ b/src/configure.in +@@ -1338,6 +1338,8 @@ AC_PATH_PROG(GROFF, groff) + + KRB5_WITH_PAM + ++KRB5_WITH_SELINUX ++ + # Make localedir work in autoconf 2.5x. + if test "${localedir+set}" != set; then + localedir='$(datadir)/locale' +diff --git a/src/include/k5-int.h b/src/include/k5-int.h +index 64991738a..173cb0264 100644 +--- a/src/include/k5-int.h ++++ b/src/include/k5-int.h +@@ -128,6 +128,7 @@ typedef unsigned char u_char; + + + #include "k5-platform.h" ++#include "k5-label.h" + + #define KRB5_KDB_MAX_LIFE (60*60*24) /* one day */ + #define KRB5_KDB_MAX_RLIFE (60*60*24*7) /* one week */ +diff --git a/src/include/k5-label.h b/src/include/k5-label.h +new file mode 100644 +index 000000000..dfaaa847c +--- /dev/null ++++ b/src/include/k5-label.h +@@ -0,0 +1,32 @@ ++#ifndef _KRB5_LABEL_H ++#define _KRB5_LABEL_H ++ ++#ifdef THREEPARAMOPEN ++#undef THREEPARAMOPEN ++#endif ++#ifdef WRITABLEFOPEN ++#undef WRITABLEFOPEN ++#endif ++ ++/* Wrapper functions which help us create files and directories with the right ++ * context labels. */ ++#ifdef USE_SELINUX ++#include ++#include ++#include ++#include ++#include ++FILE *krb5int_labeled_fopen(const char *path, const char *mode); ++int krb5int_labeled_creat(const char *path, mode_t mode); ++int krb5int_labeled_open(const char *path, int flags, ...); ++int krb5int_labeled_mkdir(const char *path, mode_t mode); ++int krb5int_labeled_mknod(const char *path, mode_t mode, dev_t device); ++#define THREEPARAMOPEN(x,y,z) krb5int_labeled_open(x,y,z) ++#define WRITABLEFOPEN(x,y) krb5int_labeled_fopen(x,y) ++void *krb5int_push_fscreatecon_for(const char *pathname); ++void krb5int_pop_fscreatecon(void *previous); ++#else ++#define WRITABLEFOPEN(x,y) fopen(x,y) ++#define THREEPARAMOPEN(x,y,z) open(x,y,z) ++#endif ++#endif +diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin +index ac22f4c55..cf60d6c41 100644 +--- a/src/include/krb5/krb5.hin ++++ b/src/include/krb5/krb5.hin +@@ -87,6 +87,12 @@ + #define THREEPARAMOPEN(x,y,z) open(x,y,z) + #endif + ++#if KRB5_PRIVATE ++#ifndef WRITABLEFOPEN ++#define WRITABLEFOPEN(x,y) fopen(x,y) ++#endif ++#endif ++ + #define KRB5_OLD_CRYPTO + + #include +diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c +index f7889bd23..cad53cfbf 100644 +--- a/src/kadmin/dbutil/dump.c ++++ b/src/kadmin/dbutil/dump.c +@@ -148,12 +148,21 @@ create_ofile(char *ofile, char **tmpname) + { + int fd = -1; + FILE *f; ++#ifdef USE_SELINUX ++ void *selabel; ++#endif + + *tmpname = NULL; + if (asprintf(tmpname, "%s-XXXXXX", ofile) < 0) + goto error; + ++#ifdef USE_SELINUX ++ selabel = krb5int_push_fscreatecon_for(ofile); ++#endif + fd = mkstemp(*tmpname); ++#ifdef USE_SELINUX ++ krb5int_pop_fscreatecon(selabel); ++#endif + if (fd == -1) + goto error; + +@@ -194,7 +203,7 @@ prep_ok_file(krb5_context context, char *file_name, int *fd) + return 0; + } + +- *fd = open(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600); ++ *fd = THREEPARAMOPEN(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (*fd == -1) { + com_err(progname, errno, _("while creating 'ok' file, '%s'"), file_ok); + exit_status++; +diff --git a/src/kdc/main.c b/src/kdc/main.c +index ebc852bba..a4dffb29a 100644 +--- a/src/kdc/main.c ++++ b/src/kdc/main.c +@@ -872,7 +872,7 @@ write_pid_file(const char *path) + FILE *file; + unsigned long pid; + +- file = fopen(path, "w"); ++ file = WRITABLEFOPEN(path, "w"); + if (file == NULL) + return errno; + pid = (unsigned long) getpid(); +diff --git a/src/lib/kadm5/logger.c b/src/lib/kadm5/logger.c +index ce79fabf7..c53a5743f 100644 +--- a/src/lib/kadm5/logger.c ++++ b/src/lib/kadm5/logger.c +@@ -414,7 +414,7 @@ krb5_klog_init(krb5_context kcontext, char *ename, char *whoami, krb5_boolean do + */ + append = (cp[4] == ':') ? O_APPEND : 0; + if (append || cp[4] == '=') { +- fd = open(&cp[5], O_CREAT | O_WRONLY | append, ++ fd = THREEPARAMOPEN(&cp[5], O_CREAT | O_WRONLY | append, + S_IRUSR | S_IWUSR | S_IRGRP); + if (fd != -1) + f = fdopen(fd, append ? "a" : "w"); +@@ -918,7 +918,7 @@ krb5_klog_reopen(krb5_context kcontext) + * In case the old logfile did not get moved out of the + * way, open for append to prevent squashing the old logs. + */ +- f = fopen(log_control.log_entries[lindex].lfu_fname, "a+"); ++ f = WRITABLEFOPEN(log_control.log_entries[lindex].lfu_fname, "a+"); + if (f) { + set_cloexec_file(f); + log_control.log_entries[lindex].lfu_filep = f; +diff --git a/src/lib/kdb/kdb_log.c b/src/lib/kdb/kdb_log.c +index 766d3002a..6466417b7 100644 +--- a/src/lib/kdb/kdb_log.c ++++ b/src/lib/kdb/kdb_log.c +@@ -476,7 +476,7 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries) + int ulogfd = -1; + + if (stat(logname, &st) == -1) { +- ulogfd = open(logname, O_RDWR | O_CREAT, 0600); ++ ulogfd = THREEPARAMOPEN(logname, O_RDWR | O_CREAT, 0600); + if (ulogfd == -1) + return errno; + +diff --git a/src/lib/krb5/ccache/cc_dir.c b/src/lib/krb5/ccache/cc_dir.c +index bba64e516..73f0fe62d 100644 +--- a/src/lib/krb5/ccache/cc_dir.c ++++ b/src/lib/krb5/ccache/cc_dir.c +@@ -183,10 +183,19 @@ write_primary_file(const char *primary_path, const char *contents) + char *newpath = NULL; + FILE *fp = NULL; + int fd = -1, status; ++#ifdef USE_SELINUX ++ void *selabel; ++#endif + + if (asprintf(&newpath, "%s.XXXXXX", primary_path) < 0) + return ENOMEM; ++#ifdef USE_SELINUX ++ selabel = krb5int_push_fscreatecon_for(primary_path); ++#endif + fd = mkstemp(newpath); ++#ifdef USE_SELINUX ++ krb5int_pop_fscreatecon(selabel); ++#endif + if (fd < 0) + goto cleanup; + #ifdef HAVE_CHMOD +@@ -221,10 +230,23 @@ static krb5_error_code + verify_dir(krb5_context context, const char *dirname) + { + struct stat st; ++ int status; ++#ifdef USE_SELINUX ++ void *selabel; ++#endif + + if (stat(dirname, &st) < 0) { +- if (errno == ENOENT && mkdir(dirname, S_IRWXU) == 0) +- return 0; ++ if (errno == ENOENT) { ++#ifdef USE_SELINUX ++ selabel = krb5int_push_fscreatecon_for(dirname); ++#endif ++ status = mkdir(dirname, S_IRWXU); ++#ifdef USE_SELINUX ++ krb5int_pop_fscreatecon(selabel); ++#endif ++ if (status == 0) ++ return 0; ++ } + k5_setmsg(context, KRB5_FCC_NOFILE, + _("Credential cache directory %s does not exist"), + dirname); +diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c +index 6a42f267d..674d88bab 100644 +--- a/src/lib/krb5/keytab/kt_file.c ++++ b/src/lib/krb5/keytab/kt_file.c +@@ -1022,14 +1022,14 @@ krb5_ktfileint_open(krb5_context context, krb5_keytab id, int mode) + + KTCHECKLOCK(id); + errno = 0; +- KTFILEP(id) = fopen(KTFILENAME(id), ++ KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id), + (mode == KRB5_LOCKMODE_EXCLUSIVE) ? "rb+" : "rb"); + if (!KTFILEP(id)) { + if ((mode == KRB5_LOCKMODE_EXCLUSIVE) && (errno == ENOENT)) { + /* try making it first time around */ + k5_create_secure_file(context, KTFILENAME(id)); + errno = 0; +- KTFILEP(id) = fopen(KTFILENAME(id), "rb+"); ++ KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id), "rb+"); + if (!KTFILEP(id)) + goto report_errno; + writevno = 1; +diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c +index 83c8d4db8..a19246128 100644 +--- a/src/lib/krb5/os/trace.c ++++ b/src/lib/krb5/os/trace.c +@@ -397,7 +397,7 @@ krb5_set_trace_filename(krb5_context context, const char *filename) + fd = malloc(sizeof(*fd)); + if (fd == NULL) + return ENOMEM; +- *fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, 0600); ++ *fd = THREEPARAMOPEN(filename, O_WRONLY|O_CREAT|O_APPEND, 0600); + if (*fd == -1) { + free(fd); + return errno; +diff --git a/src/lib/krb5/rcache/rc_dfl.c b/src/lib/krb5/rcache/rc_dfl.c +index c4d2c744d..c0f12ed9d 100644 +--- a/src/lib/krb5/rcache/rc_dfl.c ++++ b/src/lib/krb5/rcache/rc_dfl.c +@@ -794,6 +794,9 @@ krb5_rc_dfl_expunge_locked(krb5_context context, krb5_rcache id) + krb5_error_code retval = 0; + krb5_rcache tmp; + krb5_deltat lifespan = t->lifespan; /* save original lifespan */ ++#ifdef USE_SELINUX ++ void *selabel; ++#endif + + if (! t->recovering) { + name = t->name; +@@ -815,7 +818,17 @@ krb5_rc_dfl_expunge_locked(krb5_context context, krb5_rcache id) + retval = krb5_rc_resolve(context, tmp, 0); + if (retval) + goto cleanup; ++#ifdef USE_SELINUX ++ if (t->d.fn != NULL) ++ selabel = krb5int_push_fscreatecon_for(t->d.fn); ++ else ++ selabel = NULL; ++#endif + retval = krb5_rc_initialize(context, tmp, lifespan); ++#ifdef USE_SELINUX ++ if (selabel != NULL) ++ krb5int_pop_fscreatecon(selabel); ++#endif + if (retval) + goto cleanup; + for (q = t->a; q; q = q->na) { +diff --git a/src/plugins/kdb/db2/adb_openclose.c b/src/plugins/kdb/db2/adb_openclose.c +index 7db30a33b..2b9d01921 100644 +--- a/src/plugins/kdb/db2/adb_openclose.c ++++ b/src/plugins/kdb/db2/adb_openclose.c +@@ -152,7 +152,7 @@ osa_adb_init_db(osa_adb_db_t *dbp, char *filename, char *lockfilename, + * needs be open read/write so that write locking can work with + * POSIX systems + */ +- if ((lockp->lockinfo.lockfile = fopen(lockfilename, "r+")) == NULL) { ++ if ((lockp->lockinfo.lockfile = WRITABLEFOPEN(lockfilename, "r+")) == NULL) { + /* + * maybe someone took away write permission so we could only + * get shared locks? +diff --git a/src/plugins/kdb/db2/kdb_db2.c b/src/plugins/kdb/db2/kdb_db2.c +index 4c4036eb4..d90bdeaba 100644 +--- a/src/plugins/kdb/db2/kdb_db2.c ++++ b/src/plugins/kdb/db2/kdb_db2.c +@@ -694,8 +694,8 @@ ctx_create_db(krb5_context context, krb5_db2_context *dbc) + if (retval) + return retval; + +- dbc->db_lf_file = open(dbc->db_lf_name, O_CREAT | O_RDWR | O_TRUNC, +- 0600); ++ dbc->db_lf_file = THREEPARAMOPEN(dbc->db_lf_name, ++ O_CREAT | O_RDWR | O_TRUNC, 0600); + if (dbc->db_lf_file < 0) { + retval = errno; + goto cleanup; +diff --git a/src/plugins/kdb/db2/libdb2/btree/bt_open.c b/src/plugins/kdb/db2/libdb2/btree/bt_open.c +index 2977b17f3..d5809a5a9 100644 +--- a/src/plugins/kdb/db2/libdb2/btree/bt_open.c ++++ b/src/plugins/kdb/db2/libdb2/btree/bt_open.c +@@ -60,6 +60,7 @@ static char sccsid[] = "@(#)bt_open.c 8.11 (Berkeley) 11/2/95"; + #include + #include + ++#include "k5-int.h" + #include "db-int.h" + #include "btree.h" + +@@ -203,7 +204,7 @@ __bt_open(fname, flags, mode, openinfo, dflags) + goto einval; + } + +- if ((t->bt_fd = open(fname, flags | O_BINARY, mode)) < 0) ++ if ((t->bt_fd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0) + goto err; + + } else { +diff --git a/src/plugins/kdb/db2/libdb2/hash/hash.c b/src/plugins/kdb/db2/libdb2/hash/hash.c +index 76f5d4709..1fa8b8389 100644 +--- a/src/plugins/kdb/db2/libdb2/hash/hash.c ++++ b/src/plugins/kdb/db2/libdb2/hash/hash.c +@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)hash.c 8.12 (Berkeley) 11/7/95"; + #include + #endif + ++#include "k5-int.h" + #include "db-int.h" + #include "hash.h" + #include "page.h" +@@ -140,7 +141,7 @@ __kdb2_hash_open(file, flags, mode, info, dflags) + new_table = 1; + } + if (file) { +- if ((hashp->fp = open(file, flags|O_BINARY, mode)) == -1) ++ if ((hashp->fp = THREEPARAMOPEN(file, flags|O_BINARY, mode)) == -1) + RETURN_ERROR(errno, error0); + (void)fcntl(hashp->fp, F_SETFD, 1); + } +diff --git a/src/plugins/kdb/db2/libdb2/recno/rec_open.c b/src/plugins/kdb/db2/libdb2/recno/rec_open.c +index d8b26e701..b0daa7c02 100644 +--- a/src/plugins/kdb/db2/libdb2/recno/rec_open.c ++++ b/src/plugins/kdb/db2/libdb2/recno/rec_open.c +@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)rec_open.c 8.12 (Berkeley) 11/18/94"; + #include + #include + ++#include "k5-int.h" + #include "db-int.h" + #include "recno.h" + +@@ -68,7 +69,8 @@ __rec_open(fname, flags, mode, openinfo, dflags) + int rfd = -1, sverrno; + + /* Open the user's file -- if this fails, we're done. */ +- if (fname != NULL && (rfd = open(fname, flags | O_BINARY, mode)) < 0) ++ if (fname != NULL && ++ (rfd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0) + return (NULL); + + if (fname != NULL && fcntl(rfd, F_SETFD, 1) == -1) { +diff --git a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c +index 022156a5e..3d6994c67 100644 +--- a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c ++++ b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c +@@ -203,7 +203,7 @@ kdb5_ldap_stash_service_password(int argc, char **argv) + + /* set password in the file */ + old_mode = umask(0177); +- pfile = fopen(file_name, "a+"); ++ pfile = WRITABLEFOPEN(file_name, "a+"); + if (pfile == NULL) { + com_err(me, errno, _("Failed to open file %s: %s"), file_name, + strerror (errno)); +@@ -244,6 +244,9 @@ kdb5_ldap_stash_service_password(int argc, char **argv) + * Delete the existing entry and add the new entry + */ + FILE *newfile; ++#ifdef USE_SELINUX ++ void *selabel; ++#endif + + mode_t omask; + +@@ -255,7 +258,13 @@ kdb5_ldap_stash_service_password(int argc, char **argv) + } + + omask = umask(077); ++#ifdef USE_SELINUX ++ selabel = krb5int_push_fscreatecon_for(file_name); ++#endif + newfile = fopen(tmp_file, "w"); ++#ifdef USE_SELINUX ++ krb5int_pop_fscreatecon(selabel); ++#endif + umask (omask); + if (newfile == NULL) { + com_err(me, errno, _("Error creating file %s"), tmp_file); +diff --git a/src/slave/kpropd.c b/src/slave/kpropd.c +index 056c31a42..b78c3d9e5 100644 +--- a/src/slave/kpropd.c ++++ b/src/slave/kpropd.c +@@ -464,6 +464,9 @@ doit(int fd) + krb5_enctype etype; + int database_fd; + char host[INET6_ADDRSTRLEN + 1]; ++#ifdef USE_SELINUX ++ void *selabel; ++#endif + + signal_wrapper(SIGALRM, alarm_handler); + alarm(params.iprop_resync_timeout); +@@ -520,9 +523,15 @@ doit(int fd) + free(name); + exit(1); + } ++#ifdef USE_SELINUX ++ selabel = krb5int_push_fscreatecon_for(file); ++#endif + omask = umask(077); + lock_fd = open(temp_file_name, O_RDWR | O_CREAT, 0600); + (void)umask(omask); ++#ifdef USE_SELINUX ++ krb5int_pop_fscreatecon(selabel); ++#endif + retval = krb5_lock_file(kpropd_context, lock_fd, + KRB5_LOCKMODE_EXCLUSIVE | KRB5_LOCKMODE_DONTBLOCK); + if (retval) { +diff --git a/src/util/profile/prof_file.c b/src/util/profile/prof_file.c +index 907c119bb..0f5462aea 100644 +--- a/src/util/profile/prof_file.c ++++ b/src/util/profile/prof_file.c +@@ -33,6 +33,7 @@ + #endif + + #include "k5-platform.h" ++#include "k5-label.h" + + struct global_shared_profile_data { + /* This is the head of the global list of shared trees */ +@@ -423,7 +424,7 @@ static errcode_t write_data_to_file(prf_data_t data, const char *outfile, + + errno = 0; + +- f = fopen(new_file, "w"); ++ f = WRITABLEFOPEN(new_file, "w"); + if (!f) { + retval = errno; + if (retval == 0) +diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in +index 6239e4176..17bcd2a67 100644 +--- a/src/util/support/Makefile.in ++++ b/src/util/support/Makefile.in +@@ -69,6 +69,7 @@ IPC_SYMS= \ + + STLIBOBJS= \ + threads.o \ ++ selinux.o \ + init-addrinfo.o \ + plugins.o \ + errors.o \ +@@ -148,7 +149,7 @@ SRCS=\ + + SHLIB_EXPDEPS = + # Add -lm if dumping thread stats, for sqrt. +-SHLIB_EXPLIBS= $(LIBS) $(DL_LIB) ++SHLIB_EXPLIBS= $(LIBS) $(SELINUX_LIBS) $(DL_LIB) + + DEPLIBS= + +diff --git a/src/util/support/selinux.c b/src/util/support/selinux.c +new file mode 100644 +index 000000000..230263421 +--- /dev/null ++++ b/src/util/support/selinux.c +@@ -0,0 +1,406 @@ ++/* ++ * Copyright 2007,2008,2009,2011,2012,2013,2016 Red Hat, Inc. All Rights Reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * Redistributions of source code must retain the above copyright notice, this ++ * list of conditions and the following disclaimer. ++ * ++ * Redistributions in binary form must reproduce the above copyright notice, ++ * this list of conditions and the following disclaimer in the documentation ++ * and/or other materials provided with the distribution. ++ * ++ * Neither the name of Red Hat, Inc. nor the names of its contributors may be ++ * used to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ * ++ * File-opening wrappers for creating correctly-labeled files. So far, we can ++ * assume that this is Linux-specific, so we make many simplifying assumptions. ++ */ ++ ++#include "../../include/autoconf.h" ++ ++#ifdef USE_SELINUX ++ ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++/* #define DEBUG 1 */ ++static void ++debug_log(const char *fmt, ...) ++{ ++#ifdef DEBUG ++ va_list ap; ++ va_start(ap, str); ++ if (isatty(fileno(stderr))) { ++ vfprintf(stderr, fmt, ap); ++ } ++ va_end(ap); ++#endif ++ ++ return; ++} ++ ++/* Mutex used to serialize use of the process-global file creation context. */ ++k5_mutex_t labeled_mutex = K5_MUTEX_PARTIAL_INITIALIZER; ++ ++/* Make sure we finish initializing that mutex before attempting to use it. */ ++k5_once_t labeled_once = K5_ONCE_INIT; ++static void ++label_mutex_init(void) ++{ ++ k5_mutex_finish_init(&labeled_mutex); ++} ++ ++static struct selabel_handle *selabel_ctx; ++static time_t selabel_last_changed; ++ ++MAKE_FINI_FUNCTION(cleanup_fscreatecon); ++ ++static void ++cleanup_fscreatecon(void) ++{ ++ if (selabel_ctx != NULL) { ++ selabel_close(selabel_ctx); ++ selabel_ctx = NULL; ++ } ++} ++ ++static security_context_t ++push_fscreatecon(const char *pathname, mode_t mode) ++{ ++ security_context_t previous, configuredsc, currentsc, derivedsc; ++ context_t current, derived; ++ const char *fullpath, *currentuser; ++ char *genpath; ++ ++ previous = configuredsc = currentsc = derivedsc = NULL; ++ current = derived = NULL; ++ genpath = NULL; ++ ++ fullpath = pathname; ++ ++ if (!is_selinux_enabled()) { ++ goto fail; ++ } ++ ++ if (getfscreatecon(&previous) != 0) { ++ goto fail; ++ } ++ ++ /* Canonicalize pathname */ ++ if (pathname[0] != '/') { ++ char *wd; ++ size_t len; ++ len = 0; ++ ++ wd = getcwd(NULL, len); ++ if (wd == NULL) { ++ goto fail; ++ } ++ ++ len = strlen(wd) + 1 + strlen(pathname) + 1; ++ genpath = malloc(len); ++ if (genpath == NULL) { ++ free(wd); ++ goto fail; ++ } ++ ++ sprintf(genpath, "%s/%s", wd, pathname); ++ free(wd); ++ fullpath = genpath; ++ } ++ ++ debug_log("Looking up context for \"%s\"(%05o).\n", fullpath, mode); ++ ++ /* Check whether context file has changed under us */ ++ if (selabel_ctx != NULL || selabel_last_changed == 0) { ++ const char *cpath; ++ struct stat st; ++ int i = -1; ++ ++ cpath = selinux_file_context_path(); ++ if (cpath == NULL || (i = stat(cpath, &st)) != 0 || ++ st.st_mtime != selabel_last_changed) { ++ cleanup_fscreatecon(); ++ ++ selabel_last_changed = i ? time(NULL) : st.st_mtime; ++ } ++ } ++ ++ if (selabel_ctx == NULL) { ++ selabel_ctx = selabel_open(SELABEL_CTX_FILE, NULL, 0); ++ } ++ ++ if (selabel_ctx != NULL && ++ selabel_lookup(selabel_ctx, &configuredsc, fullpath, mode) != 0) { ++ goto fail; ++ } ++ ++ if (genpath != NULL) { ++ free(genpath); ++ genpath = NULL; ++ } ++ ++ if (configuredsc == NULL) { ++ goto fail; ++ } ++ ++ getcon(¤tsc); ++ ++ /* AAAAAAAA */ ++ if (currentsc != NULL) { ++ derived = context_new(configuredsc); ++ ++ if (derived != NULL) { ++ current = context_new(currentsc); ++ ++ if (current != NULL) { ++ currentuser = context_user_get(current); ++ ++ if (currentuser != NULL) { ++ if (context_user_set(derived, ++ currentuser) == 0) { ++ derivedsc = context_str(derived); ++ ++ if (derivedsc != NULL) { ++ freecon(configuredsc); ++ configuredsc = strdup(derivedsc); ++ } ++ } ++ } ++ ++ context_free(current); ++ } ++ ++ context_free(derived); ++ } ++ ++ freecon(currentsc); ++ } ++ ++ debug_log("Setting file creation context to \"%s\".\n", configuredsc); ++ if (setfscreatecon(configuredsc) != 0) { ++ debug_log("Unable to determine current context.\n"); ++ goto fail; ++ } ++ ++ freecon(configuredsc); ++ return previous; ++ ++fail: ++ if (previous != NULL) { ++ freecon(previous); ++ } ++ if (genpath != NULL) { ++ free(genpath); ++ } ++ if (configuredsc != NULL) { ++ freecon(configuredsc); ++ } ++ ++ cleanup_fscreatecon(); ++ return NULL; ++} ++ ++static void ++pop_fscreatecon(security_context_t previous) ++{ ++ if (!is_selinux_enabled()) { ++ return; ++ } ++ ++ if (previous != NULL) { ++ debug_log("Resetting file creation context to \"%s\".\n", previous); ++ } else { ++ debug_log("Resetting file creation context to default.\n"); ++ } ++ ++ /* NULL resets to default */ ++ setfscreatecon(previous); ++ ++ if (previous != NULL) { ++ freecon(previous); ++ } ++ ++ /* Need to clean this up here otherwise it leaks */ ++ cleanup_fscreatecon(); ++} ++ ++void * ++krb5int_push_fscreatecon_for(const char *pathname) ++{ ++ struct stat st; ++ void *retval; ++ ++ k5_once(&labeled_once, label_mutex_init); ++ k5_mutex_lock(&labeled_mutex); ++ ++ if (stat(pathname, &st) != 0) { ++ st.st_mode = S_IRUSR | S_IWUSR; ++ } ++ ++ retval = push_fscreatecon(pathname, st.st_mode); ++ return retval ? retval : (void *) -1; ++} ++ ++void ++krb5int_pop_fscreatecon(void *con) ++{ ++ if (con != NULL) { ++ pop_fscreatecon((con == (void *) -1) ? NULL : con); ++ k5_mutex_unlock(&labeled_mutex); ++ } ++} ++ ++FILE * ++krb5int_labeled_fopen(const char *path, const char *mode) ++{ ++ FILE *fp; ++ int errno_save; ++ security_context_t ctx; ++ ++ if ((strcmp(mode, "r") == 0) || ++ (strcmp(mode, "rb") == 0)) { ++ return fopen(path, mode); ++ } ++ ++ k5_once(&labeled_once, label_mutex_init); ++ k5_mutex_lock(&labeled_mutex); ++ ctx = push_fscreatecon(path, 0); ++ ++ fp = fopen(path, mode); ++ errno_save = errno; ++ ++ pop_fscreatecon(ctx); ++ k5_mutex_unlock(&labeled_mutex); ++ ++ errno = errno_save; ++ return fp; ++} ++ ++int ++krb5int_labeled_creat(const char *path, mode_t mode) ++{ ++ int fd; ++ int errno_save; ++ security_context_t ctx; ++ ++ k5_once(&labeled_once, label_mutex_init); ++ k5_mutex_lock(&labeled_mutex); ++ ctx = push_fscreatecon(path, 0); ++ ++ fd = creat(path, mode); ++ errno_save = errno; ++ ++ pop_fscreatecon(ctx); ++ k5_mutex_unlock(&labeled_mutex); ++ ++ errno = errno_save; ++ return fd; ++} ++ ++int ++krb5int_labeled_mknod(const char *path, mode_t mode, dev_t dev) ++{ ++ int ret; ++ int errno_save; ++ security_context_t ctx; ++ ++ k5_once(&labeled_once, label_mutex_init); ++ k5_mutex_lock(&labeled_mutex); ++ ctx = push_fscreatecon(path, mode); ++ ++ ret = mknod(path, mode, dev); ++ errno_save = errno; ++ ++ pop_fscreatecon(ctx); ++ k5_mutex_unlock(&labeled_mutex); ++ ++ errno = errno_save; ++ return ret; ++} ++ ++int ++krb5int_labeled_mkdir(const char *path, mode_t mode) ++{ ++ int ret; ++ int errno_save; ++ security_context_t ctx; ++ ++ k5_once(&labeled_once, label_mutex_init); ++ k5_mutex_lock(&labeled_mutex); ++ ctx = push_fscreatecon(path, S_IFDIR); ++ ++ ret = mkdir(path, mode); ++ errno_save = errno; ++ ++ pop_fscreatecon(ctx); ++ k5_mutex_unlock(&labeled_mutex); ++ ++ errno = errno_save; ++ return ret; ++} ++ ++int ++krb5int_labeled_open(const char *path, int flags, ...) ++{ ++ int fd; ++ int errno_save; ++ security_context_t ctx; ++ mode_t mode; ++ va_list ap; ++ ++ if ((flags & O_CREAT) == 0) { ++ return open(path, flags); ++ } ++ ++ k5_once(&labeled_once, label_mutex_init); ++ k5_mutex_lock(&labeled_mutex); ++ ctx = push_fscreatecon(path, 0); ++ ++ va_start(ap, flags); ++ mode = va_arg(ap, mode_t); ++ fd = open(path, flags, mode); ++ va_end(ap); ++ ++ errno_save = errno; ++ ++ pop_fscreatecon(ctx); ++ k5_mutex_unlock(&labeled_mutex); ++ ++ errno = errno_save; ++ return fd; ++} ++ ++#endif /* USE_SELINUX */ diff --git a/SOURCES/krb5-1.15.1.tar.gz.asc b/SOURCES/krb5-1.15.1.tar.gz.asc new file mode 100644 index 0000000..15dad17 --- /dev/null +++ b/SOURCES/krb5-1.15.1.tar.gz.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1 + +iQIVAwUAWLmTPQy6CFdfg3LfAQKWgBAAnahZbh9rFKBor8lz8icPdOAPyF7QP9xM +aDlxANUePQxN7BG68MPNL0A4/kIB1QHVl07t9vEnPBMKuF6RfVS1Sl9LYvxAF5Gf +pp5nbOOYf8bs5V/isMYjAu61D4Hyr/anKYZsbOTcR+c5CI4UXAB1uaznGcTUT+vL +MJie3ebWxJOPhv2HhkMU4BMkBxnGs1ONNsmU7yvCnbf6kgxpLaVITDzKGDrjIdQu +ej6HZQpwidUZDRICFks6pY4ASfSBEzUGswnnhdsq3uvUhxm5F6jn097K+3nIydVT +SgbJX4sBn5iJBBNumRZZ3OAovwBN+6XKM54ELWgyeQCY3Pk2P8qTojIWaqNJtyuf +q0FSR16rWKq7ZRxHwgc93YETmzIkdil5WFnTpAtqVR5RFOL/GNGh5Dwn645mC3XY +WOFBaVhX1libl+GApJjwriIzZ3e+gtaqsYa/A473BGJL+mKCp8xOfeTXeZCTCVgo +x32NhUcXTxr6RRCq/WTEH6reu4oU+VkostCv3yknHOHatYbzh2DDni+mUVnUpGw8 +WEh3XNjHrjPQ5Vr1F7/aIhmG80QXVKWfJgrVVTwUXjk8+v0enTWudsKYVanvPZDN +Yo1Jqrgc7tfRJpirVpJKxS0rNt/ES2I4heLkoz8j/DnDNqNmKV718jWVAms6jjuR +Cunhql8OvtU= +=Tvr2 +-----END PGP SIGNATURE----- diff --git a/SOURCES/krb5-1.3.1-dns.patch b/SOURCES/krb5-1.3.1-dns.patch new file mode 100644 index 0000000..7f2cfdf --- /dev/null +++ b/SOURCES/krb5-1.3.1-dns.patch @@ -0,0 +1,21 @@ +From e48799ea02841461af9a97a8f490bcf4f4ac5666 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 22 Apr 2016 09:59:05 -0400 +Subject: [PATCH] krb5-1.3.1-dns.patch + +--- + src/aclocal.m4 | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/aclocal.m4 b/src/aclocal.m4 +index 607859f17..f5667c35f 100644 +--- a/src/aclocal.m4 ++++ b/src/aclocal.m4 +@@ -703,6 +703,7 @@ AC_HELP_STRING([--with-netlib=LIBS], use user defined resolver library), + LIBS="$LIBS $withval" + AC_MSG_RESULT("netlib will use \'$withval\'") + fi ++ KRB5_AC_ENABLE_DNS + ],dnl + [AC_LIBRARY_NET] + )])dnl diff --git a/SOURCES/krb5-1.9-debuginfo.patch b/SOURCES/krb5-1.9-debuginfo.patch new file mode 100644 index 0000000..c9a6499 --- /dev/null +++ b/SOURCES/krb5-1.9-debuginfo.patch @@ -0,0 +1,36 @@ +From 502177c9256aa52ee3f7812f5127619475b3c7a5 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 22 Apr 2016 10:02:40 -0400 +Subject: [PATCH] krb5-1.9-debuginfo.patch + +--- + src/kadmin/cli/Makefile.in | 5 +++++ + src/plugins/kdb/ldap/ldap_util/Makefile.in | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/kadmin/cli/Makefile.in b/src/kadmin/cli/Makefile.in +index adfea6e2b..d1327e400 100644 +--- a/src/kadmin/cli/Makefile.in ++++ b/src/kadmin/cli/Makefile.in +@@ -37,3 +37,8 @@ clean-unix:: + # CC_LINK is not meant for compilation and this use may break in the future. + datetest: getdate.c + $(CC_LINK) $(ALL_CFLAGS) -DTEST -o datetest getdate.c ++ ++%.c: %.y ++ $(RM) y.tab.c $@ ++ $(YACC.y) $< ++ $(CP) y.tab.c $@ +diff --git a/src/plugins/kdb/ldap/ldap_util/Makefile.in b/src/plugins/kdb/ldap/ldap_util/Makefile.in +index 8669c2436..a22f23c02 100644 +--- a/src/plugins/kdb/ldap/ldap_util/Makefile.in ++++ b/src/plugins/kdb/ldap/ldap_util/Makefile.in +@@ -20,7 +20,7 @@ $(PROG): $(OBJS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIB) $(GETDATE) + getdate.c: $(GETDATE) + $(RM) getdate.c y.tab.c + $(YACC) $(GETDATE) +- $(MV) y.tab.c getdate.c ++ $(CP) y.tab.c getdate.c + + install: + $(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(ADMIN_BINDIR)/$(PROG) diff --git a/SOURCES/krb5-krb5kdc.conf b/SOURCES/krb5-krb5kdc.conf new file mode 100644 index 0000000..eadeb51 --- /dev/null +++ b/SOURCES/krb5-krb5kdc.conf @@ -0,0 +1 @@ +d /var/run/krb5kdc 0755 root root diff --git a/SOURCES/krb5-kvno-230379.patch b/SOURCES/krb5-kvno-230379.patch new file mode 100644 index 0000000..0e7c5d5 --- /dev/null +++ b/SOURCES/krb5-kvno-230379.patch @@ -0,0 +1,53 @@ +From 16c9dd3d2f8d74958495674f4906626a74ef8c12 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 22 Apr 2016 10:03:07 -0400 +Subject: [PATCH] krb5-kvno-230379.patch + +--- + src/kadmin/ktutil/ktutil.c | 5 +++-- + src/lib/krb5/keytab/kt_file.c | 2 +- + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/kadmin/ktutil/ktutil.c b/src/kadmin/ktutil/ktutil.c +index ef16d37a5..64a6d6ab1 100644 +--- a/src/kadmin/ktutil/ktutil.c ++++ b/src/kadmin/ktutil/ktutil.c +@@ -140,7 +140,7 @@ void ktutil_add_entry(argc, argv) + char *princ = NULL; + char *enctype = NULL; + krb5_kvno kvno = 0; +- int use_pass = 0, use_key = 0, i; ++ int use_pass = 0, use_key = 0, use_kvno = 0, i; + + for (i = 1; i < argc; i++) { + if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-p", 2)) { +@@ -149,6 +149,7 @@ void ktutil_add_entry(argc, argv) + } + if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-k", 2)) { + kvno = (krb5_kvno) atoi(argv[++i]); ++ use_kvno++; + continue; + } + if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) { +@@ -165,7 +166,7 @@ void ktutil_add_entry(argc, argv) + } + } + +- if (argc != 8 || !(princ && kvno && enctype) || (use_pass+use_key != 1)) { ++ if (argc != 8 || !(princ && use_kvno && enctype) || (use_pass+use_key != 1)) { + fprintf(stderr, _("usage: %s (-key | -password) -p principal " + "-k kvno -e enctype\n"), argv[0]); + return; +diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c +index 674d88bab..131549ffe 100644 +--- a/src/lib/krb5/keytab/kt_file.c ++++ b/src/lib/krb5/keytab/kt_file.c +@@ -377,7 +377,7 @@ krb5_ktfile_get_entry(krb5_context context, krb5_keytab id, + * Otherwise, remember that we were here so we can return the right + * error, and free the new. + */ +- if (new_entry.vno == kvno) { ++ if (new_entry.vno == kvno || new_entry.vno == IGNORE_VNO) { + krb5_kt_free_entry(context, &cur_entry); + cur_entry = new_entry; + if (new_entry.vno == kvno) diff --git a/SOURCES/krb5.conf b/SOURCES/krb5.conf new file mode 100644 index 0000000..2356a60 --- /dev/null +++ b/SOURCES/krb5.conf @@ -0,0 +1,26 @@ +# Configuration snippets may be placed in this directory as well +includedir /etc/krb5.conf.d/ + +[logging] + default = FILE:/var/log/krb5libs.log + kdc = FILE:/var/log/krb5kdc.log + admin_server = FILE:/var/log/kadmind.log + +[libdefaults] + dns_lookup_realm = false + ticket_lifetime = 24h + renew_lifetime = 7d + forwardable = true + rdns = false + pkinit_anchors = FILE:/etc/pki/tls/certs/ca-bundle.crt +# default_realm = EXAMPLE.COM + +[realms] +# EXAMPLE.COM = { +# kdc = kerberos.example.com +# admin_server = kerberos.example.com +# } + +[domain_realm] +# .example.com = EXAMPLE.COM +# example.com = EXAMPLE.COM diff --git a/SOURCES/krb5_prop.portreserve b/SOURCES/krb5_prop.portreserve new file mode 100644 index 0000000..54eeff2 --- /dev/null +++ b/SOURCES/krb5_prop.portreserve @@ -0,0 +1 @@ +krb5_prop/tcp diff --git a/SOURCES/krb5kdc.init b/SOURCES/krb5kdc.init new file mode 100755 index 0000000..3462ca6 --- /dev/null +++ b/SOURCES/krb5kdc.init @@ -0,0 +1,102 @@ +#!/bin/bash +# +# krb5kdc Start and stop the Kerberos 5 servers. +# +# chkconfig: - 35 65 +# description: Kerberos 5 is a trusted third-party authentication system. \ +# This script starts and stops the server that Kerberos 5 \ +# clients need to connect to in order to obtain credentials. +# processname: krb5kdc +# config: /etc/sysconfig/krb5kdc +# pidfile: /var/run/krb5kdc.pid +# + +### BEGIN INIT INFO +# Provides: krb5kdc +# Required-Start: $local_fs $network +# Required-Stop: $local_fs $network +# Should-Start: portreserve +# Default-Start: +# Default-Stop: 0 1 2 3 4 5 6 +# Short-Description: start and stop the Kerberos 5 KDC +# Description: The krb5kdc is the Kerberos 5 key distribution center, which \ +# issues credentials to Kerberos 5 clients. +### END INIT INFO + +# Get config. +. /etc/sysconfig/network + +# Get config. +[ -r /etc/sysconfig/krb5kdc ] && . /etc/sysconfig/krb5kdc + +# Source function library. +. /etc/rc.d/init.d/functions + +RETVAL=0 +prog="Kerberos 5 KDC" +krb5kdc=/usr/sbin/krb5kdc +pidfile=/var/run/krb5kdc.pid +PATH=/usr/lib64/krb5:/usr/lib/krb5:"$PATH" + +# Shell functions to cut down on useless shell instances. +start() { + [ -x $krb5kdc ] || exit 5 + echo -n $"Starting $prog: " + # tell portreserve to release the kerberos-iv port + [ -x /sbin/portrelease ] && /sbin/portrelease kerberos-iv &>/dev/null || : + daemon ${krb5kdc} ${KRB5REALM:+-r ${KRB5REALM}} -P $pidfile $KRB5KDC_ARGS + RETVAL=$? + echo + if test $RETVAL -ne 0 ; then + if status ${krb5kdc} > /dev/null ; then + RETVAL=0 + fi + fi + [ $RETVAL = 0 ] && touch /var/lock/subsys/krb5kdc +} +stop() { + echo -n $"Stopping $prog: " + killproc ${krb5kdc} + RETVAL=$? + echo + [ $RETVAL = 0 ] && rm -f /var/lock/subsys/krb5kdc +} +reload() { + echo -n $"Reopening $prog log file: " + killproc ${krb5kdc} -HUP + RETVAL=$? + echo +} + +# See how we were called. +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + stop + start + ;; + reload) + reload + ;; + status) + status ${krb5kdc} + RETVAL=$? + ;; + condrestart) + if [ -f /var/lock/subsys/krb5kdc ] ; then + stop + start + fi + ;; + *) + echo $"Usage: $0 {start|stop|status|reload|restart|condrestart}" + RETVAL=2 + ;; +esac + +exit $RETVAL diff --git a/SOURCES/krb5kdc.logrotate b/SOURCES/krb5kdc.logrotate new file mode 100644 index 0000000..1100ed3 --- /dev/null +++ b/SOURCES/krb5kdc.logrotate @@ -0,0 +1,9 @@ +/var/log/krb5kdc.log { + missingok + notifempty + monthly + rotate 12 + postrotate + /bin/kill -HUP `cat /var/run/krb5kdc.pid 2>/dev/null` 2> /dev/null || true + endscript +} diff --git a/SOURCES/krb5kdc.service b/SOURCES/krb5kdc.service new file mode 100644 index 0000000..806b062 --- /dev/null +++ b/SOURCES/krb5kdc.service @@ -0,0 +1,14 @@ +[Unit] +Description=Kerberos 5 KDC +Wants=network-online.target +After=syslog.target network.target network-online.target + +[Service] +Type=forking +PIDFile=/var/run/krb5kdc.pid +EnvironmentFile=-/etc/sysconfig/krb5kdc +ExecStart=/usr/sbin/krb5kdc -P /var/run/krb5kdc.pid $KRB5KDC_ARGS +ExecReload=/bin/kill -HUP $MAINPID + +[Install] +WantedBy=multi-user.target diff --git a/SOURCES/krb5kdc.sysconfig b/SOURCES/krb5kdc.sysconfig new file mode 100644 index 0000000..791216d --- /dev/null +++ b/SOURCES/krb5kdc.sysconfig @@ -0,0 +1 @@ +KRB5KDC_ARGS= diff --git a/SOURCES/ksu.pamd b/SOURCES/ksu.pamd new file mode 100644 index 0000000..66f5b2c --- /dev/null +++ b/SOURCES/ksu.pamd @@ -0,0 +1,4 @@ +#%PAM-1.0 +auth include su +account include su +session include su diff --git a/SOURCES/noport.c b/SOURCES/noport.c new file mode 100644 index 0000000..22088eb --- /dev/null +++ b/SOURCES/noport.c @@ -0,0 +1,111 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +static int +port_is_okay(unsigned short port) +{ + char *p, *q; + long l; + + p = getenv("NOPORT"); + while ((p != NULL) && (*p != '\0')) { + l = strtol(p, &q, 10); + if ((q == NULL) || (q == p)) { + break; + } + if ((*q == '\0') || (*q == ',')) { + if (port == l) { + errno = ECONNREFUSED; + return -1; + } + } + p = q; + p += strspn(p, ","); + } + return 0; +} + +int +connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) +{ + unsigned short port; + static int (*next_connect)(int, const struct sockaddr *, socklen_t); + + if (next_connect == NULL) { + next_connect = dlsym(RTLD_NEXT, "connect"); + if (next_connect == NULL) { + errno = ENOSYS; + return -1; + } + } + + if (getenv("NOPORT") == NULL) { + return next_connect(sockfd, addr, addrlen); + } + + switch (addr->sa_family) { + case AF_INET: + port = ntohs(((struct sockaddr_in *)addr)->sin_port); + if (port_is_okay(port) != 0) { + return -1; + } + break; + case AF_INET6: + port = ntohs(((struct sockaddr_in6 *)addr)->sin6_port); + if (port_is_okay(port) != 0) { + return -1; + } + break; + default: + break; + } + return next_connect(sockfd, addr, addrlen); +} + +ssize_t +sendto(int sockfd, const void *buf, size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen) +{ + unsigned short port; + static int (*next_sendto)(int, const void *, size_t, int, + const struct sockaddr *, socklen_t); + + if (next_sendto == NULL) { + next_sendto = dlsym(RTLD_NEXT, "sendto"); + if (next_sendto == NULL) { + errno = ENOSYS; + return -1; + } + } + + if (getenv("NOPORT") == NULL) { + return next_sendto(sockfd, buf, len, flags, dest_addr, addrlen); + } + + if (dest_addr != NULL) { + switch (dest_addr->sa_family) { + case AF_INET: + port = ((struct sockaddr_in *)dest_addr)->sin_port; + port = ntohs(port); + if (port_is_okay(port) != 0) { + return -1; + } + break; + case AF_INET6: + port = ((struct sockaddr_in6 *)dest_addr)->sin6_port; + port = ntohs(port); + if (port_is_okay(port) != 0) { + return -1; + } + break; + default: + break; + } + } + return next_sendto(sockfd, buf, len, flags, dest_addr, addrlen); +} diff --git a/SPECS/krb5.spec b/SPECS/krb5.spec new file mode 100644 index 0000000..249e0ca --- /dev/null +++ b/SPECS/krb5.spec @@ -0,0 +1,3782 @@ +%global WITH_DIRSRV 1 + +# Set this so that find-lang.sh will recognize the .po files. +%global gettext_domain mit-krb5 + +# Guess where the -libs subpackage's docs are going to go. +%define libsdocdir %{?_pkgdocdir:%(echo %{_pkgdocdir} | sed -e s,krb5,krb5-libs,g)}%{!?_pkgdocdir:%{_docdir}/%{name}-libs-%{version}} + +# Figure out where the default ccache lives and how we set it. +%global configured_default_ccache_name KEYRING:persistent:%%{uid} + +Summary: The Kerberos network authentication system +Name: krb5 +Version: 1.15.1 +Release: 46%{?dist} + +# - Maybe we should explode from the now-available-to-everybody tarball instead? +# http://web.mit.edu/kerberos/dist/krb5/1.13/krb5-1.13.2-signed.tar +# - The sources below are stored in a lookaside cache. Upload with +# $ rhpkg upload krb5-1.13.2.tar.gz krb5-1.13.2.tar.gz.asc # (and don't +# remove, otherwise you can't go back or branch from a previous point) +Source0: krb5-%{version}.tar.gz +Source1: krb5-%{version}.tar.gz.asc +Source3: krb5-%{version}-pdfs.tar +Source2: kprop.service +Source4: kadmin.service +Source5: krb5kdc.service +Source6: krb5.conf +Source7: _kpropd +Source8: _kadmind +Source10: kdc.conf +Source11: kadm5.acl +Source19: krb5kdc.sysconfig +Source20: kadmin.sysconfig +Source21: kprop.sysconfig +Source29: ksu.pamd +Source31: kerberos-adm.portreserve +Source32: krb5_prop.portreserve +Source33: krb5kdc.logrotate +Source34: kadmind.logrotate +Source36: kpropd.init +Source37: kadmind.init +Source38: krb5kdc.init +Source39: krb5-krb5kdc.conf + +BuildRequires: cmake xz +# Carry this locally until it's available in a packaged form. +Source100: nss_wrapper-0.0-20140204195100.git3d58327.tar.xz +Source101: noport.c +Source102: socket_wrapper-0.0-20140204194748.gitf3b2ece.tar.xz + +Patch136: krb5-1.12.1-pam.patch +Patch137: krb5-1.15-beta1-selinux-label.patch +Patch138: krb5-1.12-ksu-path.patch +Patch139: krb5-1.12-ktany.patch +Patch140: krb5-1.15-beta1-buildconf.patch +Patch141: krb5-1.3.1-dns.patch +Patch142: krb5-1.12-api.patch +Patch143: krb5-1.13-dirsrv-accountlock.patch +Patch144: krb5-1.9-debuginfo.patch +Patch145: krb5-kvno-230379.patch +Patch146: krb5-1.11-run_user_0.patch +Patch147: krb5-1.11-kpasswdtest.patch +Patch148: Improve-PKINIT-UPN-SAN-matching.patch +Patch149: Deindent-crypto_retrieve_X509_sans.patch +Patch152: Add-certauth-pluggable-interface.patch +Patch154: Add-the-client_name-kdcpreauth-callback.patch +Patch155: Use-the-canonical-client-principal-name-for-OTP.patch +Patch156: Remove-incomplete-PKINIT-OCSP-support.patch +Patch157: Add-support-to-query-the-SSF-of-a-GSS-context.patch +Patch158: Add-k5test-expected_msg-expected_trace.patch +Patch159: Add-PKINIT-UPN-tests-to-t_pkinit.py.patch +Patch160: Add-test-cert-generation-to-make-certs.sh.patch +Patch161: Fix-make-certs.sh-for-OpenSSL-1.1.patch +Patch162: Allow-clock-skew-in-krb5-gss_context_time.patch +Patch163: Fix-in_clock_skew-and-use-it-in-AS-client-code.patch +Patch164: Add-timestamp-helper-functions.patch +Patch165: Make-timestamp-manipulations-y2038-safe.patch +Patch166: Add-timestamp-tests.patch +Patch167: Add-y2038-documentation.patch +Patch168: Fix-more-time-manipulations-for-y2038.patch +Patch169: Use-krb5_timestamp-where-appropriate.patch +Patch170: Add-KDC-policy-pluggable-interface.patch +Patch171: Fix-bugs-in-kdcpolicy-commit.patch +Patch172: Prevent-KDC-unset-status-assertion-failures.patch +Patch173: Convert-some-pkiDebug-messages-to-TRACE-macros.patch +Patch174: Fix-certauth-built-in-module-returns.patch +Patch175: Add-test-cert-with-no-extensions.patch +Patch176: Expose-context-errors-in-pkinit_server_plugin_init.patch +Patch177: Limit-ticket-lifetime-to-2-31-1-seconds.patch +Patch178: Fix-hex-conversion-of-PKINIT-certid-strings.patch +Patch179: Simplify-PKINIT-cert-iteration-and-selection.patch +Patch180: Fix-PKINIT-cert-matching-data-construction.patch +Patch181: Save-SANs-separately-and-unparse-them-with-NO_REALM.patch +Patch182: Return-UPN-SANs-as-strings.patch +Patch183: Fix-segfault-in-finish_dispatch.patch +Patch184: Fix-flaws-in-LDAP-DN-checking.patch +Patch185: Merge-duplicate-subsections-in-profile-library.patch +Patch186: Continue-after-KRB5_CC_END-in-KCM-cache-iteration.patch +Patch187: Exit-with-status-0-from-kadmind.patch +Patch188: Ignore-dotfiles-in-profile-includedir.patch +Patch189: Add-k5_dir_filenames-to-libkrb5support.patch +Patch190: Process-profile-includedir-in-sorted-order.patch +Patch191: Add-German-translation.patch +Patch192: Remove-nodes-option-from-make-certs-scripts.patch +Patch193: Make-krb5_preauth_context-a-pointer-type.patch +Patch194: Properly-scope-per-request-preauth-data.patch +Patch195: Add-tests-for-per-request-preauth-data-scoping.patch +Patch196: Document-and-check-init_creds-context-requirement.patch +Patch197: Add-test-case-for-PKINIT-DH-renegotiation.patch +Patch198: Echo-KDC-cookies-in-preauth-tryagain.patch +Patch199: Adjust-processing-of-pa_type-ccache-config.patch +Patch200: Simplify-k5_preauth_tryagain.patch +Patch201: Remove-sent_nontrivial_preauth-field.patch +Patch202: Track-preauth-failures-instead-of-tries.patch +Patch203: Preserve-method-data-in-get_in_tkt.c.patch +Patch204: Continue-preauth-after-client-side-failures.patch +Patch205: Continue-after-KDC_ERR_PREAUTH_FAILED.patch +Patch206: Add-test-cases-for-preauth-fallback-behavior.patch +Patch207: Include-preauth-name-in-trace-output-if-possible.patch +Patch208: Add-vector-support-to-k5_sha256.patch +Patch209: Use-SHA-256-instead-of-MD5-for-audit-ticket-IDs.patch +Patch211: In-FIPS-mode-add-plaintext-fallback-for-RC4-usages-a.patch +Patch212: Fix-bugs-with-concurrent-use-of-MEMORY-ccaches.patch +Patch213: Don-t-include-all-MEMORY-ccaches-in-collection.patch +Patch214: Add-libkrb5support-hex-functions-and-tests.patch +Patch215: Add-a-hash-table-implementation-to-libkrb5support.patch +Patch216: Use-a-hash-table-for-MEMORY-ccache-resolution.patch +Patch217: Remove-incorrect-KDC-assertion.patch +Patch218: Prefer-TCP-to-UDP-for-password-changes.patch +Patch219: Bring-back-general-kerberos-man-page.patch +Patch220: Modernize-kerberos-7.patch +Patch221: Update-man-pages-to-reference-kerberos-7.patch +Patch222: Log-when-non-root-ksu-authorization-fails.patch +Patch223: Correct-kpasswd_server-description-in-krb5.conf-5.patch +Patch224: Address-some-optimized-out-memset-calls.patch +Patch225: Add-the-certauth-dbmatch-module.patch +Patch226: Correct-error-handling-bug-in-prior-commit.patch +Patch227: Add-PKINIT-test-case-for-generic-client-cert.patch + +License: MIT +URL: http://web.mit.edu/kerberos/www/ +Group: System Environment/Libraries +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +BuildRequires: autoconf, bison, flex, gawk, gettext, pkgconfig, sed +BuildRequires: libcom_err-devel, libedit-devel, libss-devel +BuildRequires: gzip, ncurses-devel +BuildRequires: python-sphinx, texlive-pdftex + +# Taken from \usepackage directives produced by sphinx: +BuildRequires: tex(babel.sty) +BuildRequires: tex(bookmark.sty) +BuildRequires: tex(fancybox.sty) +BuildRequires: tex(fncychap.sty) +BuildRequires: tex(fontenc.sty) +BuildRequires: tex(framed.sty) +BuildRequires: tex(hyperref.sty) +BuildRequires: tex(ifthen.sty) +BuildRequires: tex(inputenc.sty) +BuildRequires: tex(longtable.sty) +BuildRequires: tex(multirow.sty) +BuildRequires: tex(times.sty) +BuildRequires: tex(titlesec.sty) +BuildRequires: tex(threeparttable.sty) +BuildRequires: tex(wrapfig.sty) +BuildRequires: tex(report.cls) + +# Typical fonts, and the commands which we need to have present. +BuildRequires: texlive, texlive-latex, texlive-texmf-fonts +BuildRequires: /usr/bin/pdflatex /usr/bin/makeindex +BuildRequires: keyutils, keyutils-libs-devel >= 1.5.8 +BuildRequires: libselinux-devel +BuildRequires: pam-devel +BuildRequires: systemd-units +# For the test framework. +BuildRequires: perl, dejagnu, tcl-devel +BuildRequires: net-tools, rpcbind +BuildRequires: hostname +BuildRequires: iproute + +# someday... +%if 0%{?fedora} >= 9 +BuildRequires: python-pyrad +%endif +%if 0%{?fedora} >= 8 +%ifarch %{ix86} x86_64 +BuildRequires: yasm +%endif +%endif + +BuildRequires: openldap-devel +BuildRequires: openssl-devel >= 0.9.8 +BuildRequires: libverto-devel + +%description +Kerberos V5 is a trusted-third-party network authentication system, +which can improve your network's security by eliminating the insecure +practice of sending passwords over the network in unencrypted form. + +%package devel +Summary: Development files needed to compile Kerberos 5 programs +Group: Development/Libraries +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: libkadm5%{?_isa} = %{version}-%{release} +Requires: libcom_err-devel +Requires: keyutils-libs-devel, libselinux-devel +Requires: libverto-devel + +%description devel +Kerberos is a network authentication system. The krb5-devel package +contains the header files and libraries needed for compiling Kerberos +5 programs. If you want to develop Kerberos-aware programs, you need +to install this package. + +%package libs +Summary: The non-admin shared libraries used by Kerberos 5 +Group: System Environment/Libraries +Requires: coreutils, gawk, grep, sed +Requires: keyutils-libs >= 1.5.8 + +%description libs +Kerberos is a network authentication system. The krb5-libs package +contains the shared libraries needed by Kerberos 5. If you are using +Kerberos, you need to install this package. + +%package server +Group: System Environment/Daemons +Summary: The KDC and related programs for Kerberos 5 +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires(post): systemd-units +Requires(preun): systemd-units +Requires(postun): systemd-units +# we drop files in its directory, but we don't want to own that directory +Requires: logrotate +# we specify /usr/share/dict/words as the default dict_file in kdc.conf +Requires: /usr/share/dict/words +# for run-time, and for parts of the test suite +BuildRequires: libverto-module-base +Requires: libverto-module-base +%ifarch x86_64 +Obsoletes: krb5-server-1.11.3-49.el7.i686 +%endif +%ifarch ppc64 +Obsoletes: krb5-server-1.11.3-49.el7.ppc +%endif +%ifarch s390x +Obsoletes: krb5-server-1.11.3-49.el7.s390 +%endif +Requires: libkadm5%{?_isa} = %{version}-%{release} + +%description server +Kerberos is a network authentication system. The krb5-server package +contains the programs that must be installed on a Kerberos 5 key +distribution center (KDC). If you are installing a Kerberos 5 KDC, +you need to install this package (in other words, most people should +NOT install this package). + +%package server-ldap +Group: System Environment/Daemons +Summary: The LDAP storage plugin for the Kerberos 5 KDC +Requires: %{name}-server%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: libkadm5%{?_isa} = %{version}-%{release} +%ifarch x86_64 +Obsoletes: krb5-server-ldap-1.11.3-49.el7.i686 +%endif +%ifarch ppc64 +Obsoletes: krb5-server-ldap-1.11.3-49.el7.ppc +%endif +%ifarch s390x +Obsoletes: krb5-server-ldap-1.11.3-49.el7.s390 +%endif + +%description server-ldap +Kerberos is a network authentication system. The krb5-server package +contains the programs that must be installed on a Kerberos 5 key +distribution center (KDC). If you are installing a Kerberos 5 KDC, +and you wish to use a directory server to store the data for your +realm, you need to install this package. + +%package workstation +Summary: Kerberos 5 programs for use on workstations +Group: System Environment/Base +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: libkadm5%{?_isa} = %{version}-%{release} +# mktemp is used by krb5-send-pr +Requires: coreutils + +%description workstation +Kerberos is a network authentication system. The krb5-workstation +package contains the basic Kerberos programs (kinit, klist, kdestroy, +kpasswd). If your network uses Kerberos, this package should be +installed on every workstation. + +%package pkinit +Summary: The PKINIT module for Kerberos 5 +Group: System Environment/Libraries +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Obsoletes: krb5-pkinit-openssl < %{version}-%{release} +Provides: krb5-pkinit-openssl = %{version}-%{release} + +%description pkinit +Kerberos is a network authentication system. The krb5-pkinit +package contains the PKINIT plugin, which allows clients +to obtain initial credentials from a KDC using a private key and a +certificate. + +%package -n libkadm5 +Summary: Kerberos 5 Administrative libraries +Group: System Environment/Base +Requires: %{name}-libs%{?_isa} = %{version}-%{release} + +%description -n libkadm5 +Kerberos is a network authentication system. The libkadm5 package +contains the libkadm5clnt and libkadm5serv shared objects, for use +ONLY by kerberos itself. Do not depend on this package. + +%prep +# Apply run_user_0 when the hard-wired or configured default location is +# DIR:/run/user/%%{uid}/krb5cc. +%setup -q -a 3 -a 100 -a 102 +%patch136 -p1 -b .krb5-1.12.1-pam +%patch137 -p1 -b .krb5-1.15-beta1-selinux-label +%patch138 -p1 -b .krb5-1.12-ksu-path +%patch139 -p1 -b .krb5-1.12-ktany +%patch140 -p1 -b .krb5-1.15-beta1-buildconf +%patch141 -p1 -b .krb5-1.3.1-dns +%patch142 -p1 -b .krb5-1.12-api +%patch143 -p1 -b .krb5-1.13-dirsrv-accountlock +%patch144 -p1 -b .krb5-1.9-debuginfo +%patch145 -p1 -b .krb5-kvno-230379 +%patch146 -p1 -b .krb5-1.11-run_user_0 +%patch147 -p1 -b .krb5-1.11-kpasswdtest +%patch148 -p1 -b .Improve-PKINIT-UPN-SAN-matching +%patch149 -p1 -b .Deindent-crypto_retrieve_X509_sans +%patch152 -p1 -b .Add-certauth-pluggable-interface +%patch154 -p1 -b .Add-the-client_name-kdcpreauth-callback +%patch155 -p1 -b .Use-the-canonical-client-principal-name-for-OTP +%patch156 -p1 -b .Remove-incomplete-PKINIT-OCSP-support +%patch157 -p1 -b .Add-support-to-query-the-SSF-of-a-GSS-context +%patch158 -p1 -b .Add-k5test-expected_msg-expected_trace +%patch159 -p1 -b .Add-PKINIT-UPN-tests-to-t_pkinit.py +%patch160 -p1 -b .Add-test-cert-generation-to-make-certs.sh +%patch161 -p1 -b .Fix-make-certs.sh-for-OpenSSL-1.1 +%patch162 -p1 -b .Allow-clock-skew-in-krb5-gss_context_time +%patch163 -p1 -b .Fix-in_clock_skew-and-use-it-in-AS-client-code +%patch164 -p1 -b .Add-timestamp-helper-functions +%patch165 -p1 -b .Make-timestamp-manipulations-y2038-safe +%patch166 -p1 -b .Add-timestamp-tests +%patch167 -p1 -b .Add-y2038-documentation +%patch168 -p1 -b .Fix-more-time-manipulations-for-y2038 +%patch169 -p1 -b .Use-krb5_timestamp-where-appropriate +%patch170 -p1 -b .Add-KDC-policy-pluggable-interface +%patch171 -p1 -b .Fix-bugs-in-kdcpolicy-commit +%patch172 -p1 -b .Prevent-KDC-unset-status-assertion-failures +%patch173 -p1 -b .Convert-some-pkiDebug-messages-to-TRACE-macros +%patch174 -p1 -b .Fix-certauth-built-in-module-returns +%patch175 -p1 -b .Add-test-cert-with-no-extensions +%patch176 -p1 -b .Expose-context-errors-in-pkinit_server_plugin_init +%patch177 -p1 -b .Limit-ticket-lifetime-to-2-31-1-seconds +%patch178 -p1 -b .Fix-hex-conversion-of-PKINIT-certid-strings +%patch179 -p1 -b .Simplify-PKINIT-cert-iteration-and-selection +%patch180 -p1 -b .Fix-PKINIT-cert-matching-data-construction +%patch181 -p1 -b .Save-SANs-separately-and-unparse-them-with-NO_REALM +%patch182 -p1 -b .Return-UPN-SANs-as-strings +%patch183 -p1 -b .Fix-segfault-in-finish_dispatch +%patch184 -p1 -b .Fix-flaws-in-LDAP-DN-checking +%patch185 -p1 -b .Merge-duplicate-subsections-in-profile-library +%patch186 -p1 -b .Continue-after-KRB5_CC_END-in-KCM-cache-iteration +%patch187 -p1 -b .Exit-with-status-0-from-kadmind +%patch188 -p1 -b .Ignore-dotfiles-in-profile-includedir +%patch189 -p1 -b .Add-k5_dir_filenames-to-libkrb5support +%patch190 -p1 -b .Process-profile-includedir-in-sorted-order +%patch191 -p1 -b .Add-German-translation +%patch192 -p1 -b .Remove-nodes-option-from-make-certs-scripts +%patch193 -p1 -b .Make-krb5_preauth_context-a-pointer-type +%patch194 -p1 -b .Properly-scope-per-request-preauth-data +%patch195 -p1 -b .Add-tests-for-per-request-preauth-data-scoping +%patch196 -p1 -b .Document-and-check-init_creds-context-requirement +%patch197 -p1 -b .Add-test-case-for-PKINIT-DH-renegotiation +%patch198 -p1 -b .Echo-KDC-cookies-in-preauth-tryagain +%patch199 -p1 -b .Adjust-processing-of-pa_type-ccache-config +%patch200 -p1 -b .Simplify-k5_preauth_tryagain +%patch201 -p1 -b .Remove-sent_nontrivial_preauth-field +%patch202 -p1 -b .Track-preauth-failures-instead-of-tries +%patch203 -p1 -b .Preserve-method-data-in-get_in_tkt.c +%patch204 -p1 -b .Continue-preauth-after-client-side-failures +%patch205 -p1 -b .Continue-after-KDC_ERR_PREAUTH_FAILED +%patch206 -p1 -b .Add-test-cases-for-preauth-fallback-behavior +%patch207 -p1 -b .Include-preauth-name-in-trace-output-if-possible +%patch208 -p1 -b .Add-vector-support-to-k5_sha256 +%patch209 -p1 -b .Use-SHA-256-instead-of-MD5-for-audit-ticket-IDs +%patch211 -p1 -b .In-FIPS-mode-add-plaintext-fallback-for-RC4-usages-a +%patch212 -p1 -b .Fix-bugs-with-concurrent-use-of-MEMORY-ccaches +%patch213 -p1 -b .Don-t-include-all-MEMORY-ccaches-in-collection +%patch214 -p1 -b .Add-libkrb5support-hex-functions-and-tests +%patch215 -p1 -b .Add-a-hash-table-implementation-to-libkrb5support +%patch216 -p1 -b .Use-a-hash-table-for-MEMORY-ccache-resolution +%patch217 -p1 -b .Remove-incorrect-KDC-assertion +%patch218 -p1 -b .Prefer-TCP-to-UDP-for-password-changes +%patch219 -p1 -b .Bring-back-general-kerberos-man-page +%patch220 -p1 -b .Modernize-kerberos-7 +%patch221 -p1 -b .Update-man-pages-to-reference-kerberos-7 +%patch222 -p1 -b .Log-when-non-root-ksu-authorization-fails +%patch223 -p1 -b .Correct-kpasswd_server-description-in-krb5.conf-5 +%patch224 -p1 -b .Address-some-optimized-out-memset-calls +%patch225 -p1 -b .Add-the-certauth-dbmatch-module +%patch226 -p1 -b .Correct-error-handling-bug-in-prior-commit +%patch227 -p1 -b .Add-PKINIT-test-case-for-generic-client-cert + +ln NOTICE LICENSE + +chmod u+x src/util/paste-kdcproxy.py +# Take the execute bit off of documentation. +chmod -x doc/ccapi/*.html + +# Generate an FDS-compatible LDIF file. +inldif=src/plugins/kdb/ldap/libkdb_ldap/kerberos.ldif +cat > '60kerberos.ldif' << EOF +# This is a variation on kerberos.ldif which 389 Directory Server will like. +dn: cn=schema +EOF +egrep -iv '(^$|^dn:|^changetype:|^add:)' $inldif | \ +sed -r 's,^ , ,g' | \ +sed -r 's,^ , ,g' >> 60kerberos.ldif +touch -r $inldif 60kerberos.ldif + +# Rebuild the configure scripts. +pushd src +autoreconf -fiv +popd + +# Create build spaces for the test wrappers. +mkdir -p nss_wrapper/build +mkdir -p socket_wrapper/build + +# Mess with some of the default ports that we use for testing, so that multiple +# builds going on the same host don't step on each other. +cfg="src/kadmin/testing/proto/kdc.conf.proto \ + src/kadmin/testing/proto/krb5.conf.proto \ + src/lib/kadm5/unit-test/api.current/init-v2.exp \ + src/util/k5test.py" +LONG_BIT=`getconf LONG_BIT` +PORT=`expr 61000 + $LONG_BIT - 48` +sed -i -e s,61000,`expr "$PORT" + 0`,g $cfg +PORT=`expr 1750 + $LONG_BIT - 48` +sed -i -e s,1750,`expr "$PORT" + 0`,g $cfg +sed -i -e s,1751,`expr "$PORT" + 1`,g $cfg +sed -i -e s,1752,`expr "$PORT" + 2`,g $cfg +PORT=`expr 8888 + $LONG_BIT - 48` +sed -i -e s,8888,`expr "$PORT" - 0`,g $cfg +sed -i -e s,8887,`expr "$PORT" - 1`,g $cfg +sed -i -e s,8886,`expr "$PORT" - 2`,g $cfg +PORT=`expr 7777 + $LONG_BIT - 48` +sed -i -e s,7777,`expr "$PORT" + 0`,g $cfg +sed -i -e s,7778,`expr "$PORT" + 1`,g $cfg + +%build +# Go ahead and supply tcl info, because configure doesn't know how to find it. +source %{_libdir}/tclConfig.sh +pushd src + +# Set this so that configure will have a value even if the current version of +# autoconf doesn't set one. +runstatedir=%{_localstatedir}/run; export runstatedir +# Work out the CFLAGS and CPPFLAGS which we intend to use. +INCLUDES=-I%{_includedir}/et +CFLAGS="`echo $RPM_OPT_FLAGS $DEFINES $INCLUDES -fPIC -fno-strict-aliasing -fstack-protector-all`" +CPPFLAGS="`echo $DEFINES $INCLUDES`" +%configure \ + CC="%{__cc}" \ + CFLAGS="$CFLAGS" \ + CPPFLAGS="$CPPFLAGS" \ +%if 0%{?fedora} >= 7 || 0%{?rhel} >= 6 + SS_LIB="-lss" \ +%else + SS_LIB="-lss -lncurses" \ +%endif + --enable-shared \ + --localstatedir=%{_var}/kerberos \ + --disable-rpath \ + --without-krb5-config \ + --with-system-et \ + --with-system-ss \ + --with-netlib=-lresolv \ + --with-tcl \ + --enable-dns-for-realm \ + --with-ldap \ +%if %{WITH_DIRSRV} + --with-dirsrv-account-locking \ +%endif + --enable-pkinit \ + --with-crypto-impl=builtin \ + --with-pkinit-crypto-impl=openssl \ + --with-tls-impl=openssl \ + --with-system-verto \ + --with-pam \ + --with-selinux \ + --with-prng-alg=os +# Now build it. +make +popd + +# Sanity check the KDC_RUN_DIR. +configured_kdcrundir=`grep KDC_RUN_DIR src/include/osconf.h | awk '{print $NF}'` +configured_kdcrundir=`eval echo $configured_kdcrundir` +if test "$configured_kdcrundir" != %{_localstatedir}/run/krb5kdc ; then + exit 1 +fi + +# Build the docs. +make -C src/doc paths.py version.py +cp src/doc/paths.py doc/ +mkdir -p build-man build-html build-pdf +sphinx-build -a -b man -t pathsubs doc build-man +sphinx-build -a -b html -t pathsubs doc build-html +rm -fr build-html/_sources +sphinx-build -a -b latex -t pathsubs doc build-pdf +# Build the PDFs if we didn't have pre-built ones. +for pdf in admin appdev basic build plugindev user ; do + test -s build-pdf/$pdf.pdf || make -C build-pdf +done +# new krb5-%{version}-pdf +tar -cf "krb5-%{version}-pdfs.tar.new" build-pdf/*.pdf + +# Build the test wrappers. +pushd nss_wrapper/build +cmake .. +make +popd +pushd socket_wrapper/build +cmake .. +make +popd + +# We need to cut off any access to locally-running nameservers, too. +%{__cc} -fPIC -shared -o noport.so -Wall -Wextra $RPM_SOURCE_DIR/noport.c + +%check +# Alright, this much is still a work in progress. +%if %{?__isa_bits:%{__isa_bits}}%{!?__isa_bits:32} == 64 +if hostname | grep -q build ; then + sleep 600 +fi +%endif + +# Set things up to use the test wrappers. +NSS_WRAPPER_HOSTNAME=test.example.com ; export NSS_WRAPPER_HOSTNAME +NSS_WRAPPER_HOSTS="`pwd`/nss_wrapper/fakehosts" ; export NSS_WRAPPER_HOSTS +echo 127.0.0.1 $NSS_WRAPPER_HOSTNAME $NSS_WRAPPER_HOSTNAME localhost localhost >"$NSS_WRAPPER_HOSTS" +NOPORT=53,111; export NOPORT +SOCKET_WRAPPER_DIR=`pwd`/sockets; mkdir -p $SOCKET_WRAPPER_DIR; export SOCKET_WRAPPER_DIR +LD_PRELOAD=`pwd`/noport.so:`pwd`/nss_wrapper/build/src/libnss_wrapper.so:`pwd`/socket_wrapper/build/src/libsocket_wrapper.so ; export LD_PRELOAD + +# Run the test suite. We can't actually run the whole thing in the build +# system, but we can at least run more than we used to. The build system may +# give us a revoked session keyring, so run affected tests with a new one. +make -C src runenv.py +: make -C src check TMPDIR=%{_tmppath} +keyctl session - make -C src/lib check TMPDIR=%{_tmppath} OFFLINE=yes +make -C src/kdc check TMPDIR=%{_tmppath} +keyctl session - make -C src/appl check TMPDIR=%{_tmppath} +make -C src/clients check TMPDIR=%{_tmppath} +keyctl session - make -C src/util check TMPDIR=%{_tmppath} + +%install +[ "$RPM_BUILD_ROOT" != '/' ] && rm -rf -- $RPM_BUILD_ROOT + +# Sample KDC config files (bundled kdc.conf and kadm5.acl). +mkdir -p $RPM_BUILD_ROOT%{_var}/kerberos/krb5kdc +install -pm 600 %{SOURCE10} $RPM_BUILD_ROOT%{_var}/kerberos/krb5kdc/ +install -pm 600 %{SOURCE11} $RPM_BUILD_ROOT%{_var}/kerberos/krb5kdc/ + +# Where per-user keytabs live by default. +mkdir -p $RPM_BUILD_ROOT%{_var}/kerberos/krb5/user + +# Default configuration file for everything. +mkdir -p $RPM_BUILD_ROOT/etc +install -pm 644 %{SOURCE6} $RPM_BUILD_ROOT/etc/krb5.conf + +# Default include on this directory +mkdir -p $RPM_BUILD_ROOT/etc/krb5.conf.d + +# Parent of configuration file for list of loadable GSS mechs ("mechs"). This +# location is not relative to sysconfdir, but is hard-coded in g_initialize.c. +mkdir -m 755 -p $RPM_BUILD_ROOT/etc/gss +# Parent of groups of configuration files for a list of loadable GSS mechs +# ("mechs"). This location is not relative to sysconfdir, and is also +# hard-coded in g_initialize.c. +mkdir -m 755 -p $RPM_BUILD_ROOT/etc/gss/mech.d + +# If the default configuration needs to start specifying a default cache +# location, add it now, then fixup the timestamp so that it looks the same. +DEFCCNAME="%{configured_default_ccache_name}"; export DEFCCNAME +awk '{print} + /^# default_realm/{print " default_ccache_name =", ENVIRON["DEFCCNAME"]}' \ + %{SOURCE6} > $RPM_BUILD_ROOT/etc/krb5.conf +touch -r %{SOURCE6} $RPM_BUILD_ROOT/etc/krb5.conf +grep default_ccache_name $RPM_BUILD_ROOT/etc/krb5.conf + +# Server init scripts (krb5kdc,kadmind,kpropd) and their sysconfig files. +mkdir -p $RPM_BUILD_ROOT%{_unitdir} +for unit in \ + %{SOURCE5}\ + %{SOURCE4} \ + %{SOURCE2} ; do + # In the past, the init script was supposed to be named after the + # service that the started daemon provided. Changing their names + # is an upgrade-time problem I'm in no hurry to deal with. + install -pm 644 ${unit} $RPM_BUILD_ROOT%{_unitdir} +done +mkdir -p $RPM_BUILD_ROOT%{_sbindir} +for wrapper in \ + %{SOURCE7} \ + %{SOURCE8} ; do + install -pm 755 ${wrapper} $RPM_BUILD_ROOT%{_sbindir}/ +done +mkdir -p $RPM_BUILD_ROOT/%{_tmpfilesdir} +install -pm 644 %{SOURCE39} $RPM_BUILD_ROOT/%{_tmpfilesdir}/ +mkdir -p $RPM_BUILD_ROOT/%{_localstatedir}/run/krb5kdc + +mkdir -p $RPM_BUILD_ROOT/etc/sysconfig +for sysconfig in \ + %{SOURCE19}\ + %{SOURCE20}\ + %{SOURCE21} ; do + install -pm 644 ${sysconfig} \ + $RPM_BUILD_ROOT/etc/sysconfig/`basename ${sysconfig} .sysconfig` +done + +# logrotate configuration files +mkdir -p $RPM_BUILD_ROOT/etc/logrotate.d/ +for logrotate in \ + %{SOURCE33} \ + %{SOURCE34} ; do + install -pm 644 ${logrotate} \ + $RPM_BUILD_ROOT/etc/logrotate.d/`basename ${logrotate} .logrotate` +done + +# PAM configuration files. +mkdir -p $RPM_BUILD_ROOT/etc/pam.d/ +for pam in \ + %{SOURCE29} ; do + install -pm 644 ${pam} \ + $RPM_BUILD_ROOT/etc/pam.d/`basename ${pam} .pamd` +done + +# Plug-in directories. +install -pdm 755 $RPM_BUILD_ROOT/%{_libdir}/krb5/plugins/preauth +install -pdm 755 $RPM_BUILD_ROOT/%{_libdir}/krb5/plugins/kdb +install -pdm 755 $RPM_BUILD_ROOT/%{_libdir}/krb5/plugins/authdata + +# The rest of the binaries, headers, libraries, and docs. +make -C src DESTDIR=$RPM_BUILD_ROOT EXAMPLEDIR=%{libsdocdir}/examples install + +# Munge krb5-config yet again. This is totally wrong for 64-bit, but chunks +# of the buildconf patch already conspire to strip out /usr/ from the +# list of link flags, and it helps prevent file conflicts on multilib systems. +sed -r -i -e 's|^libdir=/usr/lib(64)?$|libdir=/usr/lib|g' $RPM_BUILD_ROOT%{_bindir}/krb5-config + +# FIXME: Temporay workaround for RH bug #1204646 ("krb5-config +# returns wrong -specs path") so that development of krb5 +# dependicies gets unstuck. +sed -r -i -e "s/-specs=\/.+?\/redhat-hardened-ld//g" $RPM_BUILD_ROOT%{_bindir}/krb5-config + +if [[ "$(< $RPM_BUILD_ROOT%{_bindir}/krb5-config )" == *redhat-hardened-ld* ]] ; then + printf '# redhat-hardened-ld for krb5-config failed' 1>&2 + exit 1 +fi + +# Install processed man pages. +for section in 1 5 8 ; do + install -m 644 build-man/*.${section} \ + $RPM_BUILD_ROOT/%{_mandir}/man${section}/ +done + +# This script just tells you to send bug reports to krb5-bugs@mit.edu, but +# since we don't have a man page for it, just drop it. +rm -- $RPM_BUILD_ROOT/%{_sbindir}/krb5-send-pr + +# These files are already packaged elsewhere +rm -f -- "$RPM_BUILD_ROOT/%{_docdir}/krb5-libs/examples/kdc.conf" +rm -f -- "$RPM_BUILD_ROOT/%{_docdir}/krb5-libs/examples/krb5.conf" +rm -f -- "$RPM_BUILD_ROOT/%{_docdir}/krb5-libs/examples/services.append" + +# This is only needed for tests +rm -- "$RPM_BUILD_ROOT/%{_libdir}/krb5/plugins/preauth/test.so" + +%find_lang %{gettext_domain} + +%clean +[ "$RPM_BUILD_ROOT" != '/' ] && rm -rf -- $RPM_BUILD_ROOT + +%post libs -p /sbin/ldconfig + +%triggerun libs -- krb5-libs < 1.15.1-13 +if ! grep -q 'includedir /etc/krb5.conf.d' /etc/krb5.conf ; then + sed -i '1i # Other applications require this directory to perform krb5 configuration.\nincludedir /etc/krb5.conf.d/\n' /etc/krb5.conf +fi + +%postun libs -p /sbin/ldconfig + +%post server-ldap -p /sbin/ldconfig + +%postun server-ldap -p /sbin/ldconfig + +%post server +# assert sanity. A cleaner solution probably exists but it is opaque. +/bin/systemctl daemon-reload +exit 0 + +%preun server +if [ "$1" -eq "0" ] ; then + /bin/systemctl --no-reload disable krb5kdc.service > /dev/null 2>&1 || : + /bin/systemctl --no-reload disable kadmin.service > /dev/null 2>&1 || : + /bin/systemctl --no-reload disable kprop.service > /dev/null 2>&1 || : + /bin/systemctl stop krb5kdc.service > /dev/null 2>&1 || : + /bin/systemctl stop kadmin.service > /dev/null 2>&1 || : + /bin/systemctl stop kprop.service > /dev/null 2>&1 || : +fi +exit 0 + +%postun server +/bin/systemctl daemon-reload >/dev/null 2>&1 || : +if [ "$1" -ge 1 ] ; then + /bin/systemctl try-restart krb5kdc.service >/dev/null 2>&1 || : + /bin/systemctl try-restart kadmin.service >/dev/null 2>&1 || : + /bin/systemctl try-restart kprop.service >/dev/null 2>&1 || : +fi +exit 0 + +%post -n libkadm5 -p /sbin/ldconfig + +%postun -n libkadm5 -p /sbin/ldconfig + +%files workstation +%defattr(-,root,root,-) +%doc src/config-files/services.append +%doc build-html/* +%doc build-pdf/user.pdf build-pdf/basic.pdf +%attr(0755,root,root) %doc src/config-files/convert-config-files + +# Clients of the KDC, including tools you're likely to need if you're running +# app servers other than those built from this source package. +%{_bindir}/kdestroy +%{_mandir}/man1/kdestroy.1* +%{_bindir}/kinit +%{_mandir}/man1/kinit.1* +%{_bindir}/klist +%{_mandir}/man1/klist.1* +%{_bindir}/kpasswd +%{_mandir}/man1/kpasswd.1* +%{_bindir}/kswitch +%{_mandir}/man1/kswitch.1* + +%{_bindir}/kvno +%{_mandir}/man1/kvno.1* +%{_bindir}/kadmin +%{_mandir}/man1/kadmin.1* +%{_bindir}/k5srvutil +%{_mandir}/man1/k5srvutil.1* +%{_bindir}/ktutil +%{_mandir}/man1/ktutil.1* + +# Doesn't really fit anywhere else. +%attr(4755,root,root) %{_bindir}/ksu +%{_mandir}/man1/ksu.1* +%config(noreplace) /etc/pam.d/ksu + +%files server +%defattr(-,root,root,-) +%docdir %{_mandir} +%doc build-pdf/admin.pdf build-pdf/build.pdf +%{_unitdir}/krb5kdc.service +%{_unitdir}/kadmin.service +%{_unitdir}/kprop.service +%{_tmpfilesdir}/krb5-krb5kdc.conf +%dir %{_localstatedir}/run/krb5kdc +%config(noreplace) /etc/sysconfig/krb5kdc +%config(noreplace) /etc/sysconfig/kadmin +%config(noreplace) /etc/sysconfig/kprop +%config(noreplace) /etc/logrotate.d/krb5kdc +%config(noreplace) /etc/logrotate.d/kadmind + +%dir %{_var}/kerberos +%dir %{_var}/kerberos/krb5kdc +%config(noreplace) %{_var}/kerberos/krb5kdc/kdc.conf +%config(noreplace) %{_var}/kerberos/krb5kdc/kadm5.acl + +%dir %{_libdir}/krb5 +%dir %{_libdir}/krb5/plugins +%dir %{_libdir}/krb5/plugins/kdb +%dir %{_libdir}/krb5/plugins/preauth +%dir %{_libdir}/krb5/plugins/authdata +%{_libdir}/krb5/plugins/preauth/otp.so +%{_libdir}/krb5/plugins/kdb/db2.so + +# KDC binaries and configuration. +%{_mandir}/man5/kadm5.acl.5* +%{_mandir}/man5/kdc.conf.5* +%{_sbindir}/kadmin.local +%{_mandir}/man8/kadmin.local.8* +%{_sbindir}/kadmind +%{_sbindir}/_kadmind +%{_mandir}/man8/kadmind.8* +%{_sbindir}/kdb5_util +%{_mandir}/man8/kdb5_util.8* +%{_sbindir}/kprop +%{_mandir}/man8/kprop.8* +%{_sbindir}/kpropd +%{_sbindir}/_kpropd +%{_mandir}/man8/kpropd.8* +%{_sbindir}/kproplog +%{_mandir}/man8/kproplog.8* +%{_sbindir}/krb5kdc +%{_mandir}/man8/krb5kdc.8* + +# This is here for people who want to test their server. It was formerly also +# in -devel. +%{_bindir}/sclient +%{_mandir}/man1/sclient.1* +%{_sbindir}/sserver +%{_mandir}/man8/sserver.8* + +%files server-ldap +%defattr(-,root,root,-) +%docdir %{_mandir} +%doc src/plugins/kdb/ldap/libkdb_ldap/kerberos.ldif +%doc src/plugins/kdb/ldap/libkdb_ldap/kerberos.schema +%doc 60kerberos.ldif +%dir %{_libdir}/krb5 +%dir %{_libdir}/krb5/plugins +%dir %{_libdir}/krb5/plugins/kdb +%{_libdir}/krb5/plugins/kdb/kldap.so +%{_libdir}/libkdb_ldap.so +%{_libdir}/libkdb_ldap.so.* +%{_mandir}/man8/kdb5_ldap_util.8.gz +%{_sbindir}/kdb5_ldap_util + +%files libs -f %{gettext_domain}.lang +%defattr(-,root,root,-) +%doc README NOTICE +%{!?_licensedir:%global license %%doc} +%license LICENSE +%docdir %{_mandir} +# These are hard-coded, not-dependent-on-the-configure-script paths. +%dir /etc/gss +%dir /etc/gss/mech.d +%dir /etc/krb5.conf.d +%config(noreplace) /etc/krb5.conf +/%{_mandir}/man5/.k5identity.5* +/%{_mandir}/man5/.k5login.5* +/%{_mandir}/man5/k5identity.5* +/%{_mandir}/man5/k5login.5* +/%{_mandir}/man5/krb5.conf.5* +/%{_mandir}/man7/kerberos.7* +%{_libdir}/libgssapi_krb5.so.* +%{_libdir}/libgssrpc.so.* +%{_libdir}/libk5crypto.so.* +%{_libdir}/libkdb5.so.* +%{_libdir}/libkrad.so.* +%{_libdir}/libkrb5.so.* +%{_libdir}/libkrb5support.so.* +%dir %{_libdir}/krb5 +%dir %{_libdir}/krb5/plugins +%dir %{_libdir}/krb5/plugins/* +%{_libdir}/krb5/plugins/tls/k5tls.so +%dir %{_var}/kerberos +%dir %{_var}/kerberos/krb5 +%dir %{_var}/kerberos/krb5/user + +%files pkinit +%defattr(-,root,root,-) +%dir %{_libdir}/krb5 +%dir %{_libdir}/krb5/plugins +%dir %{_libdir}/krb5/plugins/preauth +%{_libdir}/krb5/plugins/preauth/pkinit.so + +%files devel +%defattr(-,root,root,-) +%docdir %{_mandir} + +%{_includedir}/* +%{_libdir}/libgssapi_krb5.so +%{_libdir}/libgssrpc.so +%{_libdir}/libk5crypto.so +%{_libdir}/libkdb5.so +%{_libdir}/libkrad.so +%{_libdir}/libkrb5.so +%{_libdir}/libkrb5support.so +%{_libdir}/pkgconfig/* + +%{_bindir}/krb5-config +%{_mandir}/man1/krb5-config.1* + +# Protocol test clients. +%{_bindir}/sim_client +%{_bindir}/gss-client +%{_bindir}/uuclient + +# Protocol test servers. +%{_sbindir}/sim_server +%{_sbindir}/gss-server +%{_sbindir}/uuserver + +%files -n libkadm5 +%defattr(-,root,root,-) +%{_libdir}/libkadm5clnt.so +%{_libdir}/libkadm5clnt_mit.so +%{_libdir}/libkadm5srv.so +%{_libdir}/libkadm5srv_mit.so +%{_libdir}/libkadm5clnt_mit.so.* +%{_libdir}/libkadm5srv_mit.so.* + +%changelog +* Mon Jul 29 2019 Robbie Harwood - 1.15.1-46 +- Add pkinit_cert_match support +- Resolves: #1656126 + +* Mon Jul 29 2019 Robbie Harwood - 1.15.1-45 +- Install kerberos(7) +- Resolves: #1704726 + +* Mon Jul 29 2019 Robbie Harwood - 1.15.1-44 +- Address some optimized-out memset() calls +- Resolves: #1663506 + +* Mon Jul 29 2019 Robbie Harwood - 1.15.1-43 +- Correct kpasswd_server description in krb5.conf(5) +- Resolves: #1498347 + +* Mon Jul 29 2019 Robbie Harwood - 1.15.1-42 +- Log when non-root ksu authorization fails +- Resolves: #1270927 + +* Mon Jul 29 2019 Robbie Harwood - 1.15.1-41 +- Update man pages to reference kerberos(7) +- Resolves: #1704726 + +* Wed Jul 24 2019 Robbie Harwood - 1.15.1-40 +- Prefer TCP to UDP for password changes +- Resolves: #1637349 + +* Mon Jul 22 2019 Robbie Harwood - 1.15.1-39 +- Remove incorrect KDC assertion +- Resolves: #1673017 + +* Mon Jul 22 2019 Robbie Harwood - 1.15.1-38 +- Add FILE prefix to pkinit_anchors field +- Resolves: #1661338 + +* Tue Dec 18 2018 Robbie Harwood - 1.15.1-37 +- Bring back builtin crypto (openssl broke too many FIPS setups) +- Resolves: #1645711 + +* Mon Dec 17 2018 Robbie Harwood - 1.15.1-36 +- Clean up MEMORY ccache behavior to match upstream more closely +- Resolves: #1605756 + +* Tue Dec 11 2018 Robbie Harwood - 1.15.1-35 +- Fix bugs with concurrent use of MEMORY ccaches +- Resolves: #1605756 + +* Wed Aug 01 2018 Robbie Harwood - 1.15.1-34 +- In FIPS mode, add plaintext fallback for RC4 usages and taint +- Resolves: #1570600 + +* Tue Jul 10 2018 Robbie Harwood - 1.15.1-33 +- Use SHA-256 instead of MD5 for audit ticket IDs +- Resolves: #1570600 + +* Mon Jun 11 2018 Robbie Harwood - 1.15.1-32 +- Include preauth name in trace output if possible +- Update cert generation scripts to work on modern openssl +- Fix per-request preauth scoping +- Add test case for PKINIT DH renegotiation +- Echo KDC cookies in preauth tryagain +- Fall back to other preauth mechanisms after failures +- Resolves: #1540130 + +* Fri Jun 08 2018 Robbie Harwood - 1.15.1-31 +- Add German translation +- Resolves: #1497301 + +* Fri Jun 08 2018 Robbie Harwood - 1.15.1-30 +- Add default pkinit_anchors value to krb5.conf +- Resolves: #1508081 + +* Thu Jun 07 2018 Robbie Harwood - 1.15.1-29 +- Process profile includedir in sorted order +- Also, ignore dotfiles in included directories +- Resolves: #1539824 + +* Thu Jun 07 2018 Robbie Harwood - 1.15.1-28 +- Exit with status 0 from kadmind +- Resolves: #1373909 + +* Thu Jun 07 2018 Robbie Harwood - 1.15.1-27 +- Continue after KRB5_CC_END in KCM cache iteration +- Resolves: #1563166 + +* Thu Jun 07 2018 Robbie Harwood - 1.15.1-26 +- Merge duplicate subsections in profile library +- Resolves: #1519625 + +* Thu Jun 07 2018 Robbie Harwood - 1.15.1-25 +- Fix service dependencies on network state +- Resolves: #1525232 + +* Thu Jun 07 2018 Robbie Harwood - 1.15.1-24 +- Explicitly use openssl rather than builtin crypto +- Resolves: #1570600 + +* Mon Apr 30 2018 Robbie Harwood - 1.15.1-23 +- Fix flaws in LDAP DN checking (CVE-2018-5729, CVE-2018-5730) +- Resolves: #1562684 +- Resolves: #1562679 + +* Wed Apr 18 2018 Robbie Harwood - 1.15.1-22 +- Fix segfault in finish_dispatch() +- Resolves: #1568970 + +* Thu Apr 05 2018 Robbie Harwood - 1.15.1-21 +- Unparse SANs with NO_REALM +- Resolves: #1482457 + +* Thu Mar 22 2018 Robbie Harwood - 1.15.1-20 +- Fix hex conversion of PKINIT certid strings +- Resolves: #1538491 + +* Fri Mar 02 2018 Robbie Harwood - 1.15.1-19 +- Limit ticket lifetime to 2^31-1 seconds +- Resolves: #1554723 + +* Tue Nov 28 2017 Robbie Harwood - 1.15.1-18 +- Expose context errors in pkinit_server_plugin_init +- Resolves: #1460089 + +* Thu Nov 02 2017 Robbie Harwood - 1.15.1-17 +- Drop certauth test changes that prevented runnig it +- Resolves: #1498767 + +* Thu Nov 02 2017 Robbie Harwood - 1.15.1-16 +- Drop irrelevant DIR trigger logic +- Resolves: #1431198 + +* Thu Oct 05 2017 Robbie Harwood - 1.15.1-15 +- Fix CVE-2017-7562 (certauth eku bypass) +- Resolves: #1498767 + +* Thu Oct 05 2017 Robbie Harwood - 1.15.1-14 +- Fix CVE-2017-11368 (s4u2 request assertion failures) +- Resolves: #1498768 + +* Tue Oct 03 2017 Robbie Harwood - 1.15.1-13 +- Force-add /etc/krb5.conf.d so we can guarantee it exists +- Resolves: #1431198 + +* Tue Sep 26 2017 Robbie Harwood - 1.15.1-12 +- Add krb5 policy plugin interface +- Remove soname downgrade +- Resolves: #1462982 + +* Wed Sep 06 2017 Robbie Harwood - 1.15.1-11 +- Make t_certauth.py runnable +- Resolves: #1443388 + +* Tue Sep 05 2017 Robbie Harwood - 1.15.1-10 +- Add context SSF query support +- Resolves: #1472956 + +* Thu Aug 17 2017 Robbie Harwood - 1.15.1-9 +- Remove incomplete PKINIT OCSP support +- Resolves: #1460089 + +* Fri Apr 28 2017 Robbie Harwood - 1.15.1-8 +- Add kprop.service argument file +- Resolves: #1389073 + +* Fri Apr 07 2017 Robbie Harwood - 1.15.1-7 +- Fix enterprise principal forwarding +- Resolves: #1378440 + +* Thu Apr 06 2017 Robbie Harwood - 1.15.1-6 +- Fix bug in certauth backport +- Resolves: #1428484 + +* Wed Mar 22 2017 Robbie Harwood - 1.15.1-5 +- rubygem-rkerberos still needs us to lie about soname +- Resolves: #1389073 + +* Wed Mar 22 2017 Robbie Harwood - 1.15.1-4 +- Backport certauth plugin and related pkinit changes +- Note: related changes cannot be tested because RHEL does not allow + binary git diffs +- Resolves: #1428484 + +* Tue Mar 07 2017 Robbie Harwood - 1.15.1-3 +- Remove duplication between subpackages +- Resolves: #1254640 + +* Mon Mar 06 2017 Robbie Harwood - 1.15.1-2 +- Add back deleted sources +- Resolves: #1389073 + +* Mon Mar 06 2017 Robbie Harwood - 1.15.1-1 +- Bump to krb5-1.15.1 (very small change) +- Apply some sanity to our patches and ordering +- Resolves: #1389073 + +* Mon Jan 23 2017 Robbie Harwood - 1.15-2 +- Reinstate e_data free method; bumps KDB to 6.1 +- Resolves: #1389073 + +* Wed Jan 04 2017 Robbie Harwood - 1.15-1 +- Rebase to 1.15-final +- Resolves: #1389073 +- Resolves: #1367169 +- Resolves: #1389072 +- Resolves: #1366863 + +* Wed Nov 02 2016 Robbie Harwood - 1.14.1-27 +- Properly handle EOF on libkrad sockets +- Resolves: #1382449 + +* Wed Aug 17 2016 Robbie Harwood - 1.14.1-26 +- Use responder in non-preauth AS reqs +- Resolves: #1363690 + +* Wed Aug 17 2016 Robbie Harwood - 1.14.1-25 +- Fix bad debug_log() call in selinux handling +- Resolves: #1292153 + +* Wed Aug 10 2016 Robbie Harwood - 1.14.1-24 +- Fix KKDCPP with TLS SNI by always presenting "Host:" header +- Resolves: #1364993 + +* Fri Aug 05 2016 Robbie Harwood - 1.14.1-23 +- Add dependency on libkadm5 to krb5-devel +- Resolves: #1347403 + +* Fri Jul 29 2016 Robbie Harwood - 1.14.1-22 +- Builders have new version of mock; adapt. +- Resolves: #1290239 + +* Fri Jul 29 2016 Robbie Harwood - 1.14.1-21 +- Fix CVE-2016-3120 +- Resolves: #1361504 + +* Wed Jul 20 2016 Robbie Harwood - 1.14.1-20 +- Make version dependencies on libkadm5 more explicit to appease rpmdiff +- Resolves: #1347403 + +* Wed Jul 20 2016 Robbie Harwood - 1.14.1-19 +- Add in upstream version of kprop port and tests +- Resolves: #1292795 + +* Wed Jun 29 2016 Robbie Harwood - 1.14.1-18 +- Fix incorrect recv() size calculation in libkrad +- Resolves: #1349042 + +* Wed Jun 15 2016 Robbie Harwood - 1.14.1-17 +- Separate out the kadm5 libs +- Resolves: #1347403 + +* Mon Jun 13 2016 Robbie Harwood - 1.14.1-16 +- Fix kprop/iprop handling of default realm +- Fix t_kprop.py +- Resolves: #1290561 +- Resolves: #1302967 +- Resolves: #1292795 + +* Thu Jun 02 2016 Robbie Harwood - 1.14.1-15 +- Fix SPNEGO with NTLM to conform to MS-SPNG section 3.3.5.1 +- Resolves: #1341726 + +* Sat May 28 2016 Robbie Harwood - 1.14.1-14 +- Do not indicate depricated mechanisms when requested +- Resolves: #1293908 + +* Fri May 27 2016 Robbie Harwood - 1.14.1-13 +- Fix OTP module incorrectly overwriting as_key +- Resolves: #1340304 + +* Wed May 25 2016 Robbie Harwood - 1.14.1-12 +- Fix CVE-2016-3119 (LDAP NULL dereference) +- Resolves: #1339562 + +* Thu Apr 28 2016 Robbie Harwood - 1.14.1-11 +- Make ksu not ask for password without -n +- Resolves: #1247261 + +* Wed Apr 20 2016 Robbie Harwood - 1.14.1-10 +- Frob kadm5 soname version so that the rebase does not break things +- Resolves: #1292153 + +* Tue Apr 19 2016 Robbie Harwood - 1.14.1-9 +- Revamp selinux patch to not leak memory +- Resolves: #1313457 + +* Mon Apr 11 2016 Robbie Harwood - 1.14.1-8 +- Add snippet support in /etc/krb5.conf.d +- Resolves: #1146945 + +* Fri Apr 08 2016 Robbie Harwood - 1.14.1-7 +- Skip unnecessary mech calls in gss_inquire_cred +- Resolves: #1314493 + +* Thu Apr 07 2016 Robbie Harwood - 1.14.1-6 +- Fix impersonate_name to work with interposers +- Resolves: #1284987 + +* Thu Apr 07 2016 Robbie Harwood - 1.14.1-5 +- Fix change tracking of krb5.conf +- Resolves: #1208243 + +* Tue Apr 05 2016 Robbie Harwood - 1.14.1-4 +- Ensure log files are not world-readable +- Resolves: #1256735 + +* Wed Mar 30 2016 Robbie Harwood - 1.14.1-3 +- Clean up initscript handling in spec file +- Resolves: #1283902 +- Resolves: #1183058 + +* Wed Mar 30 2016 Robbie Harwood - 1.14.1-2 +- Backport spec file changes from Fedora +- Resolves: #1290239 + +* Thu Mar 10 2016 Robbie Harwood - 1.14.1-1 +- Rebase to new upstream version 1.14.1 +- Remove pax logic +- Resolves: #1292153 +- Resolves: #1135427 +- Resolves: #1265509 +- Resolves: #1265510 +- Resolves: #1296241 + +* Fri Feb 12 2016 Robbie Harwood - 1.13.2-12 +- Remove obsolete trigger to enable building of package +- Resolves: #1306970 + +* Fri Feb 12 2016 Robbie Harwood - 1.13.2-11 +- Fix CVE-2015-8631, CVE-2015-8630, and CVE-2015-8629 +- Resolves: #1306970 + +* Fri Sep 04 2015 Robbie Harwood 1.13.2-9 +- Add patch and test case for "KDC does not return proper + client principal for client referrals" +- Resolves: #1259846 + +* Mon Aug 31 2015 Roland Mainz - 1.13.2-9 +- Ammend patch for RedHat bug #1252454 ('testsuite complains + "Lifetime has increased by 32436 sec while 0 sec passed!", + while rhel5-libkrb5 passes') to handle the newly introduced + valgrind hits. + +* Wed Aug 19 2015 Roland Mainz - 1.13.2-8 +- Add a patch to fix RH Bug #1250154 ("[s390x, ppc64, ppc64le]: + kadmind does not accept ACL if kadm5.acl does not end with EOL") + The code "accidently" works on x86/AMD64 because declaring a + variable |char| results in an |unsigned char| by default while + most other platforms (e.g. { s390x, ppc64, ppc64le, ...}) + default to |signed char| (still have to use lint(1) to clean + up 38 more instances of this kind of bug). + +* Wed Aug 19 2015 Roland Mainz - 1.13.2-7 +- Obsolete multilib versions of server packages to fix RH + bug #1251913 ("krb5 should obsolete the multilib versions + of krb5-server and krb5-server-ldap"). + The following packages are declared obsolete: + - krb5-server-1.11.3-49.el7.i686 + - krb5-server-1.11.3-49.el7.ppc + - krb5-server-1.11.3-49.el7.s390 + - krb5-server-ldap-1.11.3-49.el7.i686 + - krb5-server-ldap-1.11.3-49.el7.ppc + - krb5-server-ldap-1.11.3-49.el7.s390 + +* Wed Aug 19 2015 Roland Mainz - 1.13.2-6 +- Add a patch to fix RedHat bug #1252454 ('testsuite complains + "Lifetime has increased by 32436 sec while 0 sec passed!", + while rhel5-libkrb5 passes') so that krb5 resolves GSS creds + if |time_rec| is requested. + +* Fri Aug 7 2015 Roland Mainz - 1.13.2-5 +- Add a patch to fix RedHat bug #1251586 ("KDC sends multiple + requests to ipa-otpd for the same authentication") which causes + the KDC to send multiple retries to ipa-otpd for TCP transports + while it should only be done for UDP. + +* Tue Jul 28 2015 Roland Mainz - 1.13.2-4 +- the rebase to krb5 1.13.2 in vers 1.13.2-0 also fixed: + - Redhat Bug #1247761 ("RFE: Minor krb5 spec file cleanup and sync + with recent Fedora 22/23 changes") + - Redhat Bug #1247751 ("krb5-config returns wrong -specs path") + - Redhat Bug #1247608 ('Add support for multi-hop preauth mechs + via |KDC_ERR_MORE_PREAUTH_DATA_REQUIRED| for RFC 6113 ("A + Generalized Framework for Kerberos Pre-Authentication")') +- Removed "krb5-1.10-kprop-mktemp.patch" and + "krb5-1.3.4-send-pr-tempfile.patch", both are no longer used since + the rebase to krb5 1.13.1 + +* Fri May 29 2015 Roland Mainz - 1.13.2-3 +- Add patch to fix Redhat Bug #1222903 ("[SELinux] AVC denials may appear + when kadmind starts"). The issue was caused by an unneeded |htons()| + which triggered SELinux AVC denials due to the "random" port usage. + +* Thu May 21 2015 Roland Mainz - 1.13.2-2 +- Add fix for RedHat Bug #1164304 ("Upstream unit tests loads + the installed shared libraries instead the ones from the build") + +* Fri May 15 2015 Roland Mainz - 1.13.2-1 +- the rebase to krb5 1.13.1 in vers 1.13.1-0 also fixed: + - Bug 1144498 ("Fix the race condition in the libkrb5 replay cache") + - Bug 1163402 ("kdb5_ldap_util view_policy does not shows ticket flags on s390x and ppc64") + - Bug 1185770 ("Missing upstream test in krb5-1.12.2: src/tests/gssapi/t_invalid.c") + - Bug 1204211 ("CVE-2014-5355 krb5: unauthenticated denial of service in recvauth_common() and other") + +* Fri May 15 2015 Roland Mainz - 1.13.2-0 +- Update to krb5-1.13.2 + - drop patch for krb5-1.13.2-CVE_2015_2694_requires_preauth_bypass_in_PKINIT_enabled_KDC, fixed in krb5-1.13.2 + - drop patch for krb5-1.12.1-CVE_2014_5355_fix_krb5_read_message_handling, fixed in krb5-1.13.2 + +* Thu May 14 2015 Roland Mainz - 1.13.1-2 +- the rebase to krb5 1.13.1 in vers 1.13.1-0 also fixed RH + bug #1156144 ("krb5 upstream test t_kdb.py failure") + +* Mon May 4 2015 Roland Mainz - 1.13.1-1 +- fix for CVE-2015-2694 (#1218020) "requires_preauth bypass + in PKINIT-enabled KDC". + In MIT krb5 1.12 and later, when the KDC is configured with + PKINIT support, an unauthenticated remote attacker can + bypass the requires_preauth flag on a client principal and + obtain a ciphertext encrypted in the principal's long-term + key. This ciphertext could be used to conduct an off-line + dictionary attack against the user's password. + +* Fri Apr 24 2015 Roland Mainz - 1.13.1-0 +- Update to krb5-1.13.1 + - patch krb5-1.12-selinux-label was updated and renamed to krb5-1.13-selinux-label + - patch krb5-1.11-dirsrv-accountlock was updated and renamed to krb5-1.13-dirsrv-accountlock + - drop patch for krb5-1.12-pwdch-fast, fixed in krb5-1.13 + - drop patch for krb5-1.12ish-kpasswd_tcp, fixed in krb5-1.13 + - drop patch for krb5-master-rcache-internal-const, no longer needed + - drop patch for krb5-master-rcache-acquirecred-cleanup, no longer needed + - drop patch for krb5-master-rcache-acquirecred-source, no longer needed + - drop patch for krb5-master-rcache-acquirecred-test, no longer needed + - drop patch for krb5-master-move-otp-sockets, no longer needed + - drop patch for krb5-master-mechd, no longer needed + - drop patch for krb5-master-strdupcheck, no longer needed + - drop patch for krb5-master-compatible-keys, no longer needed + - drop patch for krb5-1.12-system-exts, fixed in krb5-1.13 + - drop patch for 0001-In-ksu-merge-krb5_ccache_copy-and-_restricted, no longer needed + - drop patch for 0002-In-ksu-don-t-stat-not-on-disk-ccache-residuals, no longer needed + - drop patch for 0003-Use-an-intermediate-memory-cache-in-ksu, no longer needed + - drop patch for 0004-Make-ksu-respect-the-default_ccache_name-setting, no longer needed + - drop patch for 0005-Copy-config-entries-to-the-ksu-target-ccache, no longer needed + - drop patch for 0006-Use-more-randomness-for-ksu-secondary-cache-names, no longer needed + - drop patch for 0007-Make-krb5_cc_new_unique-create-DIR-directories, no longer needed + - drop patch for krb5-1.12-kpasswd-skip-address-check, fixed in krb5-1.13 + - drop patch for 0000-Refactor-cm-functions-in-sendto_kdc.c, no longer needed + - drop patch for 0001-Simplify-sendto_kdc.c, no longer needed + - drop patch for 0002-Add-helper-to-determine-if-a-KDC-is-the-master, no longer needed + - drop patch for 0003-Use-k5_transport-_strategy-enums-for-k5_sendto, no longer needed + - drop patch for 0004-Build-support-for-TLS-used-by-HTTPS-proxy-support, no longer needed + - drop patch for 0005-Add-ASN.1-codec-for-KKDCP-s-KDC-PROXY-MESSAGE, no longer needed + - drop patch for 0006-Dispatch-style-protocol-switching-for-transport, no longer needed + - drop patch for 0007-HTTPS-transport-Microsoft-KKDCPP-implementation, no longer needed + - drop patch for 0008-Load-custom-anchors-when-using-KKDCP, no longer needed + - drop patch for 0009-Check-names-in-the-server-s-cert-when-using-KKDCP, no longer needed + - drop patch for 0010-Add-some-longer-form-docs-for-HTTPS, no longer needed + - drop patch for 0011-Have-k5test.py-provide-runenv-to-python-tests, no longer needed + - drop patch for 0012-Add-a-simple-KDC-proxy-test-server, no longer needed + - drop patch for 0013-Add-tests-for-MS-KKDCP-client-support, no longer needed + - drop patch for krb5-1.12ish-tls-plugins, fixed in krb5-1.13.1 + - drop patch for krb5-1.12-nodelete-plugins, fixed in krb5-1.13.1 + - drop patch for krb5-1.12-ksu-untyped-default-ccache-name, fixed in krb5-1.13.1 + - drop patch for krb5-1.12-ksu-no-ccache, fixed in krb5-1.13.1 + - drop patch for krb5-ksu_not_working_with_default_principal, fixed in krb5-1.13.1 + - drop patch for CVE_2014_5353_fix_LDAP_misused_policy_name_crash, fixed in krb5-1.13.1 + - drop patch for CVE_2014_5354_support_keyless_principals_in_ldap, fixed in krb5-1.13.1 + - drop patch for kinit -C loops (MIT/krb5 bug #243), fixed in krb5-1.13.1 + - drop patch for CVEs { 2014-9421, 2014-9422, 2014-9423, 2014-5352 }, fixed in krb5-1.13.1 + - added patch krb5-1.14-Support-KDC_ERR_MORE_PREAUTH_DATA_REQUIRED + - added patch krb5-1.12.1-CVE_2014_5355_fix_krb5_read_message_handling +- Minor spec cleanup + +* Mon Jan 26 2015 Roland Mainz - 1.12.2-14 +- fix for kinit -C loops (#1184629, MIT/krb5 issue 243, "Do not + loop on principal unknown errors"). + +* Mon Jan 12 2015 Roland Mainz - 1.12.2-13 +- fix for CVE-2014-5352 (#1179856) "gss_process_context_token() + incorrectly frees context (MITKRB5-SA-2015-001)" +- fix for CVE-2014-9421 (#1179857) "kadmind doubly frees partial + deserialization results (MITKRB5-SA-2015-001)" +- fix for CVE-2014-9422 (#1179861) "kadmind incorrectly + validates server principal name (MITKRB5-SA-2015-001)" +- fix for CVE-2014-9423 (#1179863) "libgssrpc server applications + leak uninitialized bytes (MITKRB5-SA-2015-001)" + +* Mon Dec 22 2014 Roland Mainz - 1.12.2-12 +- fix for CVE-2014-5354 (#1174546) "krb5: NULL pointer + dereference when using keyless entries" + +* Mon Dec 22 2014 Roland Mainz - 1.12.2-11 +- fix for CVE-2014-5353 (#1174543) "Fix LDAP misused policy + name crash" + +* Sun Dec 7 2014 Roland Mainz - 1.12.2-10 +- In ksu, without the -e flag, also check .k5users (#1105489) + When ksu was explicitly told to spawn a shell, a line in .k5users which + listed "*" as the allowed command would cause the principal named on the + line to be considered as a candidate for authentication. + When ksu was not passed a command to run, which implicitly meant that + the invoking user wanted to run the target user's login shell, knowledge + that the principal was a valid candidate was ignored, which could cause + a less optimal choice of the default target principal. + This doesn't impact the authorization checks which we perform later. + Patch by Nalin Dahyabhai + +* Wed Dec 3 2014 Roland Mainz - 1.12.2-9 +- Undo libkadmclnt SONAME change (from 8 to 9) which originally + happened in the krb5 1.12 rebase (#1166012) but broke + rubygem-rkerberos (sort of ruby language bindings for + libkadmclnt&co.) dependicies, as side effect of + rubygem-rkerberos using private interfaces in libkadmclnt. + +* Mon Sep 8 2014 Nalin Dahyabhai - 1.12.2-8 +- fix the problem where the %%license file has been a dangling symlink +- ksu: pull in fix from pull #206 to avoid breakage when the + default_ccache_name doesn't include a cache type as a prefix +- ksu: pull in a proposed fix for pull #207 to avoid breakage when the + invoking user doesn't already have a ccache + +* Sat Sep 6 2014 Nalin Dahyabhai - 1.12.2-7 +- pull in patch from master to load plugins with RTLD_NODELETE, when + defined (RT#7947) + +* Fri Sep 5 2014 Nalin Dahyabhai - 1.12.2-6 +- backport patch to make the client skip checking the server's reply + address when processing responses to password-change requests, which + between NAT and upcoming HTTPS support, can cause us to erroneously + report an error to the user when the server actually reported success + (RT#7886) +- backport support for accessing KDCs and kpasswd services via HTTPS + proxies (marked by being specified as https URIs instead as hostnames + or hostname-and-port), such as the one implemented in python-kdcproxy + (RT#7929, #109919), and pick up a subsequent patch to build HTTPS + as a plugin + +* Thu Aug 28 2014 Nalin Dahyabhai - 1.12.2-5 +- backport fix for trying all compatible keys when not being strict about + acceptor names while reading AP-REQs (RT#7883, #1078888) +- define _GNU_SOURCE in files where we use EAI_NODATA, to make sure that + it's declared (#1059730,#1084068,#1109102) + +* Tue Aug 26 2014 Nalin Dahyabhai - 1.12.2-4 +- kpropd hasn't bothered with -S since 1.11; stop trying to use that flag + in the systemd unit file + +* Wed Aug 20 2014 Nalin Dahyabhai - 1.12.2-3 +- pull in upstream fix for an incorrect check on the value returned by a + strdup() call (#1132062) + +* Sun Aug 17 2014 Fedora Release Engineering - 1.12.1-15 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Sun Aug 17 2014 Fedora Release Engineering - 1.12.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Fri Aug 15 2014 Nalin Dahyabhai - 1.12.2-1 +- update to 1.12.2 + - drop patch for RT#7820, fixed in 1.12.2 + - drop patch for #231147, fixed as RT#3277 in 1.12.2 + - drop patch for RT#7818, fixed in 1.12.2 + - drop patch for RT#7836, fixed in 1.12.2 + - drop patch for RT#7858, fixed in 1.12.2 + - drop patch for RT#7924, fixed in 1.12.2 + - drop patch for RT#7926, fixed in 1.12.2 + - drop patches for CVE-2014-4341/CVE-2014-4342, included in 1.12.2 + - drop patch for CVE-2014-4343, included in 1.12.2 + - drop patch for CVE-2014-4344, included in 1.12.2 + - drop patch for CVE-2014-4345, included in 1.12.2 +- replace older proposed changes for ksu with backports of the changes + after review and merging upstream (#1015559, #1026099, #1118347) + +* Thu Aug 7 2014 Nalin Dahyabhai - 1.12.1-14 +- incorporate fix for MITKRB5-SA-2014-001 (CVE-2014-4345) + +* Mon Jul 21 2014 Nalin Dahyabhai - 1.12.1-13 +- gssapi: pull in upstream fix for a possible NULL dereference + in spnego (CVE-2014-4344) + +* Wed Jul 16 2014 Nalin Dahyabhai - 1.12.1-12 +- gssapi: pull in proposed fix for a double free in initiators (David + Woodhouse, CVE-2014-4343, #1117963) + +* Sat Jul 12 2014 Tom Callaway - 1.12.1-11 +- fix license handling + +* Mon Jul 7 2014 Nalin Dahyabhai - 1.12.1-10 +- pull in fix for denial of service by injection of malformed GSSAPI tokens + (CVE-2014-4341, CVE-2014-4342, #1116181) + +* Tue Jun 24 2014 Nalin Dahyabhai - 1.12.1-9 +- pull in changes from upstream which add processing of the contents of + /etc/gss/mech.d/*.conf when loading GSS modules (#1102839) + +* Thu Jun 12 2014 Nalin Dahyabhai - 1.12.1-8 +- pull in fix for building against tcl 8.6 (#1107061) + +* Sun Jun 08 2014 Fedora Release Engineering - 1.12.1-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Tue Mar 04 2014 Nathaniel McCallum - 1.12.1-6 +- Backport fix for change password requests when using FAST (RT#7868) + +* Mon Feb 17 2014 Nalin Dahyabhai - 1.12.1-5 +- spnego: pull in patch from master to restore preserving the OID of the + mechanism the initiator requested when we have multiple OIDs for the same + mechanism, so that we reply using the same mechanism OID and the initiator + doesn't get confused (#1066000, RT#7858) + +* Fri Feb 7 2014 Nalin Dahyabhai - 1.12.1-4 +- pull in patch from master to move the default directory which the KDC uses + when computing the socket path for a local OTP daemon from the database + directory (/var/kerberos/krb5kdc) to the newly-added run directory + (/run/krb5kdc), in line with what we're expecting in 1.13 (RT#7859, more + of #1040056 as #1063905) +- add a tmpfiles.d configuration file to have /run/krb5kdc created at + boot-time +- own /var/run/krb5kdc + +* Fri Jan 31 2014 Nalin Dahyabhai - 1.12.1-3 +- refresh nss_wrapper and add socket_wrapper to the %%check environment + +* Fri Jan 31 2014 Nalin Dahyabhai +- add currently-proposed changes to teach ksu about credential cache + collections and the default_ccache_name setting (#1015559,#1026099) + +* Tue Jan 21 2014 Nalin Dahyabhai - 1.12.1-2 +- pull in multiple changes to allow replay caches to be added to a GSS + credential store as "rcache"-type credentials (RT#7818/#7819/#7836, + #1056078/#1056080) + +* Fri Jan 17 2014 Nalin Dahyabhai - 1.12.1-1 +- update to 1.12.1 + - drop patch for RT#7794, included now + - drop patch for RT#7797, included now + - drop patch for RT#7803, included now + - drop patch for RT#7805, included now + - drop patch for RT#7807, included now + - drop patch for RT#7045, included now + - drop patches for RT#7813 and RT#7815, included now + - add patch to always retrieve the KDC time offsets from keyring caches, + so that we don't mistakenly interpret creds as expired before their + time when our clock is ahead of the KDC's (RT#7820, #1030607) + +* Mon Jan 13 2014 Nalin Dahyabhai - 1.12-11 +- update the PIC patch for iaesx86.s to not use ELF relocations to the version + that landed upstream (RT#7815, #1045699) + +* Thu Jan 9 2014 Nalin Dahyabhai +- pass -Wl,--warn-shared-textrel to the compiler when we're creating shared + libraries + +* Thu Jan 9 2014 Nalin Dahyabhai - 1.12-10 +- amend the PIC patch for iaesx86.s to also save/restore ebx in the + functions where we modify it, because the ELF spec says we need to + +* Mon Jan 6 2014 Nalin Dahyabhai - 1.12-9 +- grab a more-commented version of the most recent patch from upstream + master +- make a guess at making the 32-bit AES-NI implementation sufficiently + position-independent to not require execmod permissions for libk5crypto + (more of #1045699) + +* Thu Jan 2 2014 Nalin Dahyabhai - 1.12-8 +- add patch from Dhiru Kholia for the AES-NI implementations to allow + libk5crypto to be properly marked as not needing an executable stack + on arches where they're used (#1045699, and so many others) + +* Thu Jan 2 2014 Nalin Dahyabhai - 1.12-7 +- revert that last change for a bit while sorting out execstack when we + use AES-NI (#1045699) + +* Thu Dec 19 2013 Nalin Dahyabhai - 1.12-6 +- add yasm as a build requirement for AES-NI support, on arches that have + yasm and AES-NI + +* Thu Dec 19 2013 Nalin Dahyabhai - 1.12-5 +- pull in fix from master to make reporting of errors encountered by + the SPNEGO mechanism work better (RT#7045, part of #1043962) + +* Thu Dec 19 2013 Nalin Dahyabhai +- update a test wrapper to properly handle things that the new libkrad does, + and add python-pyrad as a build requirement so that we can run its tests + +* Wed Dec 18 2013 Nalin Dahyabhai - 1.12-4 +- revise previous patch to initialize one more element + +* Wed Dec 18 2013 Nalin Dahyabhai - 1.12-3 +- backport fixes to krb5_copy_context (RT#7807, #1044735/#1044739) + +* Wed Dec 18 2013 Nalin Dahyabhai - 1.12-2 +- pull in fix from master to return a NULL pointer rather than allocating + zero bytes of memory if we read a zero-length input token (RT#7794, part of + #1043962) +- pull in fix from master to ignore an empty token from an acceptor if + we've already finished authenticating (RT#7797, part of #1043962) +- pull in fix from master to avoid a memory leak when a mechanism's + init_sec_context function fails (RT#7803, part of #1043962) +- pull in fix from master to avoid a memory leak in a couple of error + cases which could occur while obtaining acceptor credentials (RT#7805, part + of #1043962) + +* Wed Dec 11 2013 Nalin Dahyabhai - 1.12-1 +- update to 1.12 final + +* Mon Dec 2 2013 Nalin Dahyabhai - 1.12-beta2.0 +- update to beta2 + - drop obsolete backports for storing KDC time offsets and expiration times + in keyring credential caches + +* Tue Nov 19 2013 Nalin Dahyabhai - 1.12-beta1.0 +- rebase to master +- update to beta1 + - drop obsolete backport of fix for RT#7706 + +* Mon Nov 18 2013 Nalin Dahyabhai - 1.11.4-2 +- pull in fix to store KDC time offsets in keyring credential caches (RT#7768, + #1030607) +- pull in fix to set expiration times on credentials stored in keyring + credential caches (RT#7769, #1031724) + +* Tue Nov 12 2013 Nalin Dahyabhai - 1.11.4-1 +- update to 1.11.4 + - drop patch for RT#7650, obsoleted + - drop patch for RT#7706, obsoleted as RT#7723 + - drop patch for CVE-2013-1418/CVE-2013-6800, included in 1.11.4 + +* Tue Nov 12 2013 Nalin Dahyabhai - 1.11.3-31 +- switch to the simplified version of the patch for #1029110 (RT#7764) + +* Mon Nov 11 2013 Nalin Dahyabhai - 1.11.3-30 +- check more thoroughly for errors when resolving KEYRING ccache names of type + "persistent", which should only have a numeric UID as the next part of the + name (#1029110) + +* Tue Nov 5 2013 Nalin Dahyabhai - 1.11.3-29 +- incorporate upstream patch for remote crash of KDCs which serve multiple + realms simultaneously (RT#7756, CVE-2013-1418/CVE-2013-6800, + #1026997/#1031501) + +* Mon Nov 4 2013 Nalin Dahyabhai - 1.11.3-28 +- drop patch to add additional access() checks to ksu - they add to breakage + when non-FILE: caches are in use (#1026099), shouldn't be resulting in any + benefit, and clash with proposed changes to fix its cache handling + +* Tue Oct 22 2013 Nalin Dahyabhai - 1.11.3-27 +- add some minimal description to the top of the wrapper scripts we use + when starting krb5kdc and kadmind to describe why they exist (tooling) + +* Thu Oct 17 2013 Nalin Dahyabhai - 1.12-alpha1.0 +- initial update to alpha1 + - drop backport of persistent keyring support + - drop backport for RT#7689 + - drop obsolete patch for fixing a use-before-init in a test program + - drop obsolete patch teaching config.guess/config.sub about aarch64-linux + - drop backport for RT#7598 + - drop backport for RT#7172 + - drop backport for RT#7642 + - drop backport for RT#7643 + - drop patches from master to not test GSSRPC-over-UDP and to not + depend on the portmapper, which are areas where our build systems + often give us trouble, too; obsolete + - drop backports for RT#7682 + - drop backport for RT#7709 + - drop backport for RT#7590 and partial backport for RT#7680 + - drop OTP backport + - drop backports for RT#7656 and RT#7657 +- BuildRequires: libedit-devel to prefer it +- BuildRequires: pkgconfig, since configure uses it + +* Wed Oct 16 2013 Nalin Dahyabhai - 1.11.3-26 +- create and own /etc/gss (#1019937) + +* Tue Oct 15 2013 Nalin Dahyabhai - 1.11.3-25 +- pull up fix for importing previously-exported credential caches in the + gssapi library (RT# 7706, #1019420) + +* Mon Oct 14 2013 Nalin Dahyabhai - 1.11.3-24 +- backport the callback to use the libkrb5 prompter when we can't load PEM + files for PKINIT (RT#7590, includes part of #965721/#1016690) +- extract the rest of the fix #965721/#1016690 from the changes for RT#7680 + +* Mon Oct 14 2013 Nalin Dahyabhai - 1.11.3-23 +- fix trigger scriptlet's invocation of sed (#1016945) + +* Fri Oct 4 2013 Nalin Dahyabhai - 1.11.3-22 +- rebuild with keyutils 1.5.8 (part of #1012043) + +* Wed Oct 2 2013 Nalin Dahyabhai - 1.11.3-21 +- switch to the version of persistent-keyring that was just merged to + master (RT#7711), along with related changes to kinit (RT#7689) +- go back to setting default_ccache_name to a KEYRING type + +* Mon Sep 30 2013 Nalin Dahyabhai - 1.11.3-20 +- pull up fix for not calling a kdb plugin's check-transited-path + method before calling the library's default version, which only knows + how to read what's in the configuration file (RT#7709, #1013664) + +* Thu Sep 26 2013 Nalin Dahyabhai - 1.11.3-19 +- configure --without-krb5-config so that we don't pull in the old default + ccache name when we want to stop setting a default ccache name at configure- + time + +* Wed Sep 25 2013 Nalin Dahyabhai - 1.11.3-18 +- fix broken dependency on awk (should be gawk, rdieter) + +* Wed Sep 25 2013 Nalin Dahyabhai - 1.11.3-17 +- add missing dependency on newer keyutils-libs (#1012034) + +* Tue Sep 24 2013 Nalin Dahyabhai - 1.11.3-16 +- back out setting default_ccache_name to the new default for now, resetting + it to the old default while the kernel/keyutils bits get sorted (sgallagh) + +* Mon Sep 23 2013 Nalin Dahyabhai - 1.11.3-15 +- add explicit build-time dependency on a version of keyutils that's new + enough to include keyctl_get_persistent() (more of #991148) + +* Thu Sep 19 2013 Nalin Dahyabhai - 1.11.3-14 +- incorporate Simo's updated backport of his updated persistent-keyring changes + (more of #991148) + +* Fri Sep 13 2013 Nalin Dahyabhai - 1.11.3-13 +- don't break during %%check when the session keyring is revoked + +* Fri Sep 13 2013 Nalin Dahyabhai - 1.11.3-12 +- pull the newer F21 defaults back to F20 (sgallagh) + +* Mon Sep 9 2013 Nalin Dahyabhai +- only apply the patch to autocreate /run/user/0 when we're hard-wiring the + default ccache location to be under it; otherwise it's unnecessary + +* Mon Sep 9 2013 Nalin Dahyabhai 1.11.3-11 +- don't let comments intended for one scriptlet become part of the "script" + that gets passed to ldconfig as part of another one (Mattias Ellert, #1005675) + +* Fri Sep 6 2013 Nalin Dahyabhai 1.11.3-10 +- incorporate Simo's backport of his persistent-keyring changes (#991148) +- restore build-time default DEFCCNAME on Fedora 21 and later and EL, and + instead set default_ccache_name in the default krb5.conf's [libdefaults] + section (#991148) +- on releases where we expect krb5.conf to be configured with a + default_ccache_name, add it whenever we upgrade from an older version of + the package that wouldn't have included it in its default configuration + file (#991148) + +* Fri Aug 23 2013 Nalin Dahyabhai 1.11.3-9 +- take another stab at accounting for UnversionedDocdirs for the -libs + subpackage (spotted by ssorce) +- switch to just the snapshot of nss_wrapper we were using, since we + no longer need to carry anything that isn't in the cwrap.org repository + (ssorce) + +* Thu Aug 15 2013 Nalin Dahyabhai 1.11.3-8 +- drop a patch we weren't not applying (build tooling) +- wrap kadmind and kpropd in scripts which check for the presence/absence + of files which dictate particular exit codes before exec'ing the actual + binaries, instead of trying to use ConditionPathExists in the unit files + to accomplish that, so that we exit with failure properly when what we + expect isn't actually in effect on the system (#800343) + +* Mon Jul 29 2013 Nalin Dahyabhai 1.11.3-7 +- attempt to account for UnversionedDocdirs for the -libs subpackage + +* Fri Jul 26 2013 Nalin Dahyabhai 1.11.3-6 +- tweak configuration files used during tests to try to reduce the number + of conflicts encountered when builds for multiple arches land on the same + builder + +* Mon Jul 22 2013 Nalin Dahyabhai 1.11.3-5 +- pull up changes to allow GSSAPI modules to provide more functions + (RT#7682, #986564/#986565) + +* Fri Jul 19 2013 Nalin Dahyabhai 1.11.3-4 +- use (a bundled, for now, copy of) nss_wrapper to let us run some of the + self-tests at build-time in more places than we could previously (#978756) +- cover inconsistencies in whether or not there's a local caching nameserver + that's willing to answer when the build environment doesn't have a + resolver configuration, so that nss_wrapper's faking of the local + hostname can be complete + +* Mon Jul 1 2013 Nalin Dahyabhai 1.11.3-3 +- specify dependencies on the same arch of krb5-libs by using the %%{?_isa} + suffix, to avoid dragging 32-bit libraries onto 64-bit systems (#980155) + +* Thu Jun 13 2013 Nalin Dahyabhai 1.11.3-2 +- special-case /run/user/0, attempting to create it when resolving a + directory cache below it fails due to ENOENT and we find that it doesn't + already exist, either, before attempting to create the directory cache + (maybe helping, maybe just making things more confusing for #961235) + +* Tue Jun 4 2013 Nalin Dahyabhai 1.11.3-1 +- update to 1.11.3 + - drop patch for RT#7605, fixed in this release + - drop patch for CVE-2002-2443, fixed in this release + - drop patch for RT#7369, fixed in this release +- pull upstream fix for breaking t_skew.py by adding the patch for #961221 + +* Fri May 31 2013 Nalin Dahyabhai 1.11.2-10 +- respin with updated version of patch for RT#7650 (#969331) + +* Thu May 30 2013 Nalin Dahyabhai 1.11.2-9 +- don't forget to set the SELinux label when creating the directory for + a DIR: ccache +- pull in proposed fix for attempts to get initial creds, which end up + following referrals, incorrectly trying to always use master KDCs if + they talked to a master at any point (should fix RT#7650) + +* Thu May 30 2013 Nalin Dahyabhai 1.11.2-8 +- pull in patches from master to not test GSSRPC-over-UDP and to not + depend on the portmapper, which are areas where our build systems + often give us trouble, too + +* Tue May 28 2013 Nalin Dahyabhai 1.11.2-7 +- backport fix for not being able to verify the list of transited realms + in GSS acceptors (RT#7639, #959685) +- backport fix for not being able to pass an empty password to the + get-init-creds APIs and have them actually use it (RT#7642, #960001) +- add backported proposed fix to use the unauthenticated server time + as the basis for computing the requested credential expiration times, + rather than the client's idea of the current time, which could be + significantly incorrect (#961221) + +* Tue May 21 2013 Nalin Dahyabhai 1.11.2-6 +- pull in upstream fix to start treating a KRB5CCNAME value that begins + with DIR:: the same as it would a DIR: value with just one ccache file + in it (RT#7172, #965574) + +* Mon May 13 2013 Nalin Dahyabhai 1.11.2-5 +- pull up fix for UDP ping-pong flaw in kpasswd service (CVE-2002-2443, + #962531,#962534) + +* Mon Apr 29 2013 Nathaniel McCallum 1.11.2-4 +- Update otp patches +- Merge otp patches into a single patch +- Add keycheck patch + +* Tue Apr 23 2013 Nalin Dahyabhai 1.11.2-3 +- pull the changing of the compiled-in default ccache location to + DIR:/run/user/%%{uid}/krb5cc back into F19, in line with SSSD and + the most recent pam_krb5 build + +* Wed Apr 17 2013 Nalin Dahyabhai 1.11.2-2 +- correct some configuration file paths which the KDC_DIR patch missed + +* Mon Apr 15 2013 Nalin Dahyabhai 1.11.2-1 +- update to 1.11.2 + - drop pulled in patch for RT#7586, included in this release + - drop pulled in patch for RT#7592, included in this release +- pull in fix for keeping track of the message type when parsing FAST requests + in the KDC (RT#7605, #951843) (also #951965) + +* Fri Apr 12 2013 Nalin Dahyabhai 1.11.1-9 +- move the compiled-in default ccache location from the previous default of + FILE:/tmp/krb5cc_%%{uid} to DIR:/run/user/%%{uid}/krb5cc (part of #949588) + +* Tue Apr 09 2013 Nathaniel McCallum - 1.11.1-8 +- Update otp backport patches (libk5radius => libkrad) + +* Wed Apr 3 2013 Nalin Dahyabhai 1.11.1-7 +- when testing the RPC library, treat denials from the local portmapper the + same as a portmapper-not-running situation, to allow other library tests + to be run while building the package + +* Thu Mar 28 2013 Nalin Dahyabhai 1.11.1-6 +- create and own /var/kerberos/krb5/user instead of /var/kerberos/kdc/user, + since that's what the libraries actually look for +- add buildrequires on nss-myhostname, in an attempt to get more of the tests + to run properly during builds +- pull in Simo's patch to recognize "client_keytab" as a key type which can + be passed in to gss_acquire_cred_from() (RT#7598) + +* Tue Mar 26 2013 Nalin Dahyabhai 1.11.1-5 +- pull up Simo's patch to mark the correct mechanism on imported GSSAPI + contexts (RT#7592) +- go back to using reconf to run autoconf and autoheader (part of #925640) +- add temporary patch to use newer config.guess/config.sub (more of #925640) + +* Mon Mar 18 2013 Nalin Dahyabhai +- fix a version comparison to expect newer texlive build requirements when + %%{_rhel} > 6 rather than when it's > 7 + +* Mon Mar 11 2013 Nathaniel McCallum 1.11.1-4 +- Add libverto-devel requires for krb5-devel +- Add otp support + +* Thu Feb 28 2013 Nalin Dahyabhai 1.11.1-3 +- fix a memory leak when acquiring credentials using a keytab (RT#7586, #911110) + +* Wed Feb 27 2013 Nalin Dahyabhai 1.11.1-2 +- prebuild PDF docs to reduce multilib differences (internal tooling, #884065) +- drop the kerberos-iv portreserve file, and drop the rest on systemd systems +- escape uses of macros in comments (more of #884065) + +* Mon Feb 25 2013 Nalin Dahyabhai 1.11.1-1 +- update to 1.11.1 + - drop patch for noticing negative timeouts being passed to the poll() + wrapper in the client transmit functions + +* Fri Feb 8 2013 Nalin Dahyabhai 1.11-2 +- set "rdns = false" in the default krb5.conf (#908323,#908324) + +* Tue Dec 18 2012 Nalin Dahyabhai 1.11-1 +- update to 1.11 release + +* Thu Dec 13 2012 Nalin Dahyabhai 1.11-0.beta2.0 +- update to 1.11 beta 2 + +* Thu Dec 13 2012 Nalin Dahyabhai +- when building with our bundled copy of libverto, package it in with -libs + rather than with -server (#886049) + +* Wed Nov 21 2012 Nalin Dahyabhai 1.11-0.beta1.0 +- update to 1.11 beta 1 + +* Fri Nov 16 2012 Nalin Dahyabhai 1.11-0.alpha1.1 +- handle releases where texlive packaging wasn't yet as complicated as it + is in Fedora 18 +- fix an uninitialized-variable error building one of the test programs + +* Fri Nov 16 2012 Nalin Dahyabhai 1.11-0.alpha1.0 +- move the rather large pile of html and pdf docs to -workstation, so + that just having something that links to the libraries won't drag + them onto a system, and we avoid having to sort out hard-coded paths + that include %%{_libdir} showing up in docs in multilib packages +- actually create %%{_var}/kerberos/kdc/user, so that it can be packaged +- correct the list of packaged man pages +- don't dummy up required tex stylesheets, require them +- require pdflatex and makeindex + +* Thu Nov 15 2012 Nalin Dahyabhai +- update to 1.11 alpha 1 + - drop backported patch for RT #7406 + - drop backported patch for RT #7407 + - drop backported patch for RT #7408 + - the new docs system generates PDFs, so stop including them as sources + - drop backported patch to allow deltat.y to build with the usual + warning flags and the current gcc + - drop backported fix for disabling use of a replay cache when verifying + initial credentials + - drop backported fix for teaching PKINIT clients which trust the KDC's + certificate directly to verify signed-data messages that are signed with + the KDC's certificate, when the blobs don't include a copy of the KDC's + certificate + - drop backported patches to make keytab-based authentication attempts + work better when the client tells the KDC that it supports a particular + cipher, but doesn't have a key for it in the keytab + - drop backported fix for avoiding spurious clock skew when a TGT is + decrypted long after the KDC sent it to the client which decrypts it + - move the cross-referenced HTML docs into the -libs package to avoid + broken internal links + - drop patches to fixup paths in man pages, shouldn't be needed any more + +* Wed Oct 17 2012 Nalin Dahyabhai 1.10.3-7 +- tag a couple of other patches which we still need to be applied during + %%{?_rawbuild} builds (zmraz) + +* Tue Sep 25 2012 Nalin Dahyabhai 1.10.3-6 +- actually pull up the patch for RT#7063, and not some other ticket (#773496) + +* Mon Sep 10 2012 Nalin Dahyabhai 1.10.3-5 +- add patch based on one from Filip Krska to not call poll() with a negative + timeout when the caller's intent is for us to just stop calling it (#838548) + +* Fri Sep 7 2012 Nalin Dahyabhai +- on EL6, conflict with libsmbclient before 3.5.10-124, which is when it + stopped linking with a symbol which we no longer export (#771687) +- pull up patch for RT#7063, in which not noticing a prompt for a long + time throws the client library's idea of the time difference between it + and the KDC really far out of whack (#773496) +- add a backport of more patches to set the client's list of supported enctypes + when using a keytab to be the list of types of keys in the keytab, plus the + list of other types the client supports but for which it doesn't have keys, + in that order, so that KDCs have a better chance of being able to issue + tickets with session keys of types that the client can use (#837855) + +* Thu Sep 6 2012 Nalin Dahyabhai 1.10.3-4 +- cut down the number of times we load SELinux labeling configuration from + a minimum of two times to actually one (more of #845125) + +* Thu Aug 30 2012 Nalin Dahyabhai 1.10.3-3 +- backport patch to disable replay detection in krb5_verify_init_creds() + while reading the AP-REQ that's generated in the same function (RT#7229) + +* Thu Aug 30 2012 Nalin Dahyabhai 1.10.3-2 +- undo rename from krb5-pkinit-openssl to krb5-pkinit on EL6 +- version the Obsoletes: on the krb5-pkinit-openssl to krb5-pkinit rename +- reintroduce the init scripts for non-systemd releases +- forward-port %%{?_rawbuild} annotations from EL6 packaging + +* Thu Aug 9 2012 Nalin Dahyabhai 1.10.3-1 +- update to 1.10.3, rolling in the fixes from MITKRB5-SA-2012-001 + +* Thu Aug 2 2012 Nalin Dahyabhai 1.10.2-7 +- selinux: hang on to the list of selinux contexts, freeing and reloading + it only when the file we read it from is modified, freeing it when the + shared library is being unloaded (#845125) + +* Thu Aug 2 2012 Nalin Dahyabhai 1.10.2-6 +- go back to not messing with library file paths on Fedora 17: it breaks + file path dependencies in other packages, and since Fedora 17 is already + released, breaking that is our fault + +* Tue Jul 31 2012 Nalin Dahyabhai 1.10.2-5 +- add upstream patch to fix freeing an uninitialized pointer and dereferencing + another uninitialized pointer in the KDC (MITKRB5-SA-2012-001, CVE-2012-1014 + and CVE-2012-1015, #844779 and #844777) +- fix a thinko in whether or not we mess around with devel .so symlinks on + systems without a separate /usr (sbose) + +* Fri Jul 27 2012 Fedora Release Engineering - 1.10.2-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Fri Jun 22 2012 Nalin Dahyabhai 1.10.2-3 +- backport a fix to allow a PKINIT client to handle SignedData from a KDC + that's signed with a certificate that isn't in the SignedData, but which + is available as an anchor or intermediate on the client (RT#7183) + +* Tue Jun 5 2012 Nalin Dahyabhai 1.10.2-2 +- back out this labeling change (dwalsh): + - when building the new label for a file we're about to create, also mix + in the current range, in addition to the current user + +* Fri Jun 1 2012 Nalin Dahyabhai 1.10.2-1 +- update to 1.10.2 + - when building the new label for a file we're about to create, also mix + in the current range, in addition to the current user + - also package the PDF format admin, user, and install guides + - drop some PDFs that no longer get built right +- add a backport of Stef's patch to set the client's list of supported + enctypes to match the types of keys that we have when we are using a + keytab to try to get initial credentials, so that a KDC won't send us + an AS reply that we can't encrypt (RT#2131, #748528) +- don't shuffle around any shared libraries on releases with no-separate-/usr, + since /usr/lib is the same place as /lib +- add explicit buildrequires: on 'hostname', for the tests, on systems where + it's in its own package, and require net-tools, which used to provide the + command, everywhere + +* Mon May 7 2012 Nalin Dahyabhai +- skip the setfscreatecon() if fopen() is passed "rb" as the open mode (part + of #819115) + +* Tue May 1 2012 Nalin Dahyabhai 1.10.1-3 +- have -server require /usr/share/dict/words, which we set as the default + dict_file in kdc.conf (#817089) + +* Tue Mar 20 2012 Nalin Dahyabhai 1.10.1-2 +- change back dns_lookup_kdc to the default setting (Stef Walter, #805318) +- comment out example.com examples in default krb5.conf (Stef Walter, #805320) + +* Fri Mar 9 2012 Nalin Dahyabhai 1.10.1-1 +- update to 1.10.1 + - drop the KDC crash fix + - drop the KDC lookaside cache fix + - drop the fix for kadmind RPC ACLs (CVE-2012-1012) + +* Wed Mar 7 2012 Nalin Dahyabhai 1.10-5 +- when removing -workstation, remove our files from the info index while + the file is still there, in %%preun, rather than %%postun, and use the + compressed file's name (#801035) + +* Tue Feb 21 2012 Nathaniel McCallum - 1.10-4 +- Fix string RPC ACLs (RT#7093); CVE-2012-1012 + +* Tue Jan 31 2012 Nathaniel McCallum - 1.10-3 +- Add upstream lookaside cache behavior fix (RT#7082) + +* Mon Jan 30 2012 Nalin Dahyabhai 1.10-2 +- add patch to accept keytab entries with vno==0 as matches when we're + searching for an entry with a specific name/kvno (#230382/#782211,RT#3349) + +* Mon Jan 30 2012 Nalin Dahyabhai 1.10-1 +- update to 1.10 final + +* Thu Jan 26 2012 Nathaniel McCallum - 1.10-0.beta1.2 +- Add upstream crashfix patch (RT#7081) + +* Thu Jan 12 2012 Nalin Dahyabhai 1.10-0.beta1.1 +- update to beta 1 + +* Wed Jan 11 2012 Peter Robinson +- mktemp was long obsoleted by coreutils + +* Wed Jan 4 2012 Nalin Dahyabhai 1.10-0.alpha2.2 +- modify the deltat grammar to also tell gcc (4.7) to suppress + "maybe-uninitialized" warnings in addition to the "uninitialized" warnings + it's already being told to suppress (RT#7080) + +* Tue Dec 20 2011 Nalin Dahyabhai 1.10-0.alpha2.1 +- update to alpha 2 +- drop a couple of patches which were integrated for alpha 2 + +* Tue Dec 13 2011 Nalin Dahyabhai 1.10-0.alpha1.3 +- pull in patch for RT#7046: tag a ccache containing credentials obtained via + S4U2Proxy with the principal name of the proxying principal (part of #761317) + so that the default principal name can be set to that of the client for which + it is proxying, which results in the ccache looking more normal to consumers + of the ccache that don't care that there's proxying going on +- pull in patch for RT#7047: allow tickets obtained via S4U2Proxy to be cached + (more of #761317) +- pull in patch for RT#7048: allow PAC verification to only bother trying to + verify the signature with keys that it's given (still more of #761317) + +* Tue Dec 6 2011 Nalin Dahyabhai 1.10-0.alpha1.2 +- apply upstream patch to fix a null pointer dereference when processing + TGS requests (CVE-2011-1530, #753748) + +* Wed Nov 30 2011 Nalin Dahyabhai 1.10-0.alpha1.1 +- correct a bug in the fix for #754001 so that the file creation context is + consistently reset + +* Tue Nov 15 2011 Nalin Dahyabhai 1.10-0.alpha1.0 +- update to 1.10 alpha 1 +- on newer releases where we can assume NSS >= 3.13, configure PKINIT to build + using NSS +- on newer releases where we build PKINIT using NSS, configure libk5crypto to + build using NSS +- rename krb5-pkinit-openssl to krb5-pkinit on newer releases where we're + expecting to build PKINIT using NSS instead +- during %%check, run check in the library and kdc subdirectories, which + should be able to run inside of the build system without issue + +* Wed Oct 26 2011 Fedora Release Engineering - 1.9.1-19 +- Rebuilt for glibc bug#747377 + +* Tue Oct 18 2011 Nalin Dahyabhai 1.9.1-18 +- apply upstream patch to fix a null pointer dereference with the LDAP kdb + backend (CVE-2011-1527, #744125), an assertion failure with multiple kdb + backends (CVE-2011-1528), and a null pointer dereference with multiple kdb + backends (CVE-2011-1529) (#737711) + +* Thu Oct 13 2011 Nalin Dahyabhai 1.9.1-17 +- pull in patch from trunk to rename krb5int_pac_sign() to krb5_pac_sign() and + make it public (#745533) + +* Fri Oct 7 2011 Nalin Dahyabhai 1.9.1-16 +- kadmin.service: fix #723723 again +- kadmin.service,krb5kdc.service: remove optional use of $KRB5REALM in command + lines, because systemd parsing doesn't handle alternate value shell variable + syntax +- kprop.service: add missing Type=forking so that systemd doesn't assume simple +- kprop.service: expect the ACL configuration to be there, not absent +- handle a harder-to-trigger assertion failure that starts cropping up when we + exit the transmit loop on time (#739853) + +* Sun Oct 2 2011 Tom Callaway 1.9.1-15 +- hardcode pid file as option in krb5kdc.service + +* Fri Sep 30 2011 Tom Callaway 1.9.1-14 +- fix pid path in krb5kdc.service + +* Mon Sep 19 2011 Tom Callaway 1.9.1-13 +- convert to systemd + +* Tue Sep 6 2011 Nalin Dahyabhai 1.9.1-12 +- pull in upstream patch for RT#6952, confusion following referrals for + cross-realm auth (#734341) +- pull in build-time deps for the tests + +* Thu Sep 1 2011 Nalin Dahyabhai 1.9.1-11 +- switch to the upstream patch for #727829 + +* Wed Aug 31 2011 Nalin Dahyabhai 1.9.1-10 +- handle an assertion failure that starts cropping up when the patch for + using poll (#701446) meets servers that aren't running KDCs or against + which the connection fails for other reasons (#727829, #734172) + +* Mon Aug 8 2011 Nalin Dahyabhai 1.9.1-9 +- override the default build rules to not delete temporary y.tab.c files, + so that they can be packaged, allowing debuginfo files which point to them + do so usefully (#729044) + +* Fri Jul 22 2011 Nalin Dahyabhai 1.9.1-8 +- build shared libraries with partial RELRO support (#723995) +- filter out potentially multiple instances of -Wl,-z,relro from krb5-config + output, now that it's in the buildroot's default LDFLAGS +- pull in a patch to fix losing track of the replay cache FD, from SVN by + way of Kevin Coffman + +* Wed Jul 20 2011 Nalin Dahyabhai 1.9.1-7 +- kadmind.init: drop the attempt to detect no-database-present errors (#723723), + which is too fragile in cases where the database has been manually moved or + is accessed through another kdb plugin + +* Tue Jul 19 2011 Nalin Dahyabhai 1.9.1-6 +- backport fixes to teach libkrb5 to use descriptors higher than FD_SETSIZE + to talk to a KDC by using poll() if it's detected at compile-time (#701446, + RT#6905) + +* Thu Jun 23 2011 Nalin Dahyabhai 1.9.1-5 +- pull a fix from SVN to try to avoid triggering a PTR lookup in getaddrinfo() + during krb5_sname_to_principal(), and to let getaddrinfo() decide whether or + not to ask for an IPv6 address based on the set of configured interfaces + (#717378, RT#6922) +- pull a fix from SVN to use AI_ADDRCONFIG more often (RT#6923) + +* Mon Jun 20 2011 Nalin Dahyabhai 1.9.1-4 +- apply upstream patch by way of Burt Holzman to fall back to a non-referral + method in cases where we might be derailed by a KDC that rejects the + canonicalize option (for example, those from the RHEL 2.1 or 3 era) (#715074) + +* Tue Jun 14 2011 Nalin Dahyabhai 1.9.1-3 +- pull a fix from SVN to get libgssrpc clients (e.g. kadmin) authenticating + using the old protocol over IPv4 again (RT#6920) + +* Tue Jun 14 2011 Nalin Dahyabhai +- incorporate a fix to teach the file labeling bits about when replay caches + are expunged (#576093) + +* Thu May 26 2011 Nalin Dahyabhai +- switch to the upstream patch for #707145 + +* Wed May 25 2011 Nalin Dahyabhai 1.9.1-2 +- klist: don't trip over referral entries when invoked with -s (#707145, + RT#6915) + +* Fri May 6 2011 Nalin Dahyabhai +- fixup URL in a comment +- when built with NSS, require 3.12.10 rather than 3.12.9 + +* Thu May 5 2011 Nalin Dahyabhai 1.9.1-1 +- update to 1.9.1: + - drop no-longer-needed patches for CVE-2010-4022, CVE-2011-0281, + CVE-2011-0282, CVE-2011-0283, CVE-2011-0284, CVE-2011-0285 + +* Wed Apr 13 2011 Nalin Dahyabhai 1.9-9 +- kadmind: add upstream patch to fix free() on an invalid pointer (#696343, + MITKRB5-SA-2011-004, CVE-2011-0285) + +* Mon Apr 4 2011 Nalin Dahyabhai +- don't discard the error code from an error message received in response + to a change-password request (#658871, RT#6893) + +* Fri Apr 1 2011 Nalin Dahyabhai +- override INSTALL_SETUID at build-time so that ksu is installed into + the buildroot with the right permissions (part of #225974) + +* Fri Mar 18 2011 Nalin Dahyabhai 1.9-8 +- backport change from SVN to fix a computed-value-not-used warning in + kpropd (#684065) + +* Tue Mar 15 2011 Nalin Dahyabhai 1.9-7 +- turn off NSS as the backend for libk5crypto for now to work around its + DES string2key not working (#679012) +- add revised upstream patch to fix double-free in KDC while returning + typed-data with errors (MITKRB5-SA-2011-003, CVE-2011-0284, #674325) + +* Thu Feb 17 2011 Nalin Dahyabhai +- throw in a not-applied-by-default patch to try to make pkinit debugging + into a run-time boolean option named "pkinit_debug" + +* Wed Feb 16 2011 Nalin Dahyabhai 1.9-6 +- turn on NSS as the backend for libk5crypto, adding nss-devel as a build + dependency when that switch is flipped + +* Wed Feb 9 2011 Nalin Dahyabhai 1.9-5 +- krb5kdc init script: prototype some changes to do a quick spot-check + of the TGS and kadmind keys and warn if there aren't any non-weak keys + on file for them (to flush out parts of #651466) + +* Tue Feb 8 2011 Nalin Dahyabhai 1.9-4 +- add upstream patches to fix standalone kpropd exiting if the per-client + child process exits with an error (MITKRB5-SA-2011-001), a hang or crash + in the KDC when using the LDAP kdb backend, and an uninitialized pointer + use in the KDC (MITKRB5-SA-2011-002) (CVE-2010-4022, #664009, + CVE-2011-0281, #668719, CVE-2011-0282, #668726, CVE-2011-0283, #676126) + +* Mon Feb 07 2011 Fedora Release Engineering - 1.9-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Mon Feb 7 2011 Nalin Dahyabhai +- fix a compile error in the SELinux labeling patch when -DDEBUG is used (Sumit + Bose) + +* Tue Feb 1 2011 Nalin Dahyabhai +- properly advertise that the kpropd init script now supports force-reload + (Zbysek Mraz, #630587) + +* Wed Jan 26 2011 Nalin Dahyabhai 1.9-2 +- pkinit: when verifying signed data, use the CMS APIs for better + interoperability (#636985, RT#6851) + +* Wed Dec 22 2010 Nalin Dahyabhai 1.9-1 +- update to 1.9 final + +* Mon Dec 20 2010 Nalin Dahyabhai 1.9-0.beta3.1 +- fix link flags and permissions on shared libraries (ausil) + +* Thu Dec 16 2010 Nalin Dahyabhai 1.9-0.beta3.0 +- update to 1.9 beta 3 + +* Mon Dec 6 2010 Nalin Dahyabhai 1.9-0.beta2.0 +- update to 1.9 beta 2 + +* Tue Nov 9 2010 Nalin Dahyabhai 1.9-0.beta1.1 +- drop not-needed-since-1.8 build dependency on rsh (ssorce) + +* Fri Nov 5 2010 Nalin Dahyabhai 1.9-0.beta1.0 +- start moving to 1.9 with beta 1 + - drop patches for RT#5755, RT#6762, RT#6774, RT#6775 + - drop no-longer-needed backport patch for #539423 + - drop no-longer-needed patch for CVE-2010-1322 +- if WITH_NSS is set, built with --with-crypto-impl=nss (requires NSS 3.12.9) + +* Tue Oct 5 2010 Nalin Dahyabhai 1.8.3-8 +- incorporate upstream patch to fix uninitialized pointer crash in the KDC's + authorization data handling (CVE-2010-1322, #636335) + +* Mon Oct 4 2010 Nalin Dahyabhai 1.8.3-7 +- rebuild + +* Mon Oct 4 2010 Nalin Dahyabhai 1.8.3-6 +- pull down patches from trunk to implement k5login_authoritative and + k5login_directory settings for krb5.conf (#539423) + +* Wed Sep 29 2010 jkeating - 1.8.3-5 +- Rebuilt for gcc bug 634757 + +* Wed Sep 15 2010 Nalin Dahyabhai 1.8.3-4 +- fix reading of keyUsage extensions when attempting to select pkinit client + certs (part of #629022, RT#6775) +- fix selection of pkinit client certs when one or more don't include a + subjectAltName extension (part of #629022, RT#6774) + +* Fri Sep 3 2010 Nalin Dahyabhai 1.8.3-3 +- build with -fstack-protector-all instead of the default -fstack-protector, + so that we add checking to more functions (i.e., all of them) (#629950) +- also link binaries with -Wl,-z,relro,-z,now (part of #629950) + +* Tue Aug 24 2010 Nalin Dahyabhai 1.8.3-2 +- fix a logic bug in computing key expiration times (RT#6762, #627022) + +* Wed Aug 4 2010 Nalin Dahyabhai 1.8.3-1 +- update to 1.8.3 + - drop backports of fixes for gss context expiration and error table + registration/deregistration mismatch + - drop patch for upstream #6750 + +* Wed Jul 7 2010 Nalin Dahyabhai 1.8.2-3 +- tell krb5kdc and kadmind to create pid files, since they can +- add logrotate configuration files for krb5kdc and kadmind (#462658) +- fix parsing of the pidfile option in the KDC (upstream #6750) + +* Mon Jun 21 2010 Nalin Dahyabhai 1.8.2-2 +- libgssapi: pull in patch from svn to stop returning context-expired errors + when the ticket which was used to set up the context expires (#605366, + upstream #6739) + +* Mon Jun 21 2010 Nalin Dahyabhai +- pull up fix for upstream #6745, in which the gssapi library would add the + wrong error table but subsequently attempt to unload the right one + +* Thu Jun 10 2010 Nalin Dahyabhai 1.8.2-1 +- update to 1.8.2 + - drop patches for CVE-2010-1320, CVE-2010-1321 + +* Tue Jun 1 2010 Nalin Dahyabhai 1.8.1-7 +- rebuild + +* Thu May 27 2010 Nalin Dahyabhai +- ksu: move session management calls to before we drop privileges, like + su does (#596887), and don't skip the PAM account check for root or the + same user (more of #540769) + +* Mon May 24 2010 Nalin Dahyabhai 1.8.1-6 +- make krb5-server-ldap also depend on the same version-release of krb5-libs, + as the other subpackages do, if only to make it clearer than it is when we + just do it through krb5-server +- drop explicit linking with libtinfo for applications that use libss, now + that readline itself links with libtinfo (as of readline-5.2-3, since + fedora 7 or so) +- go back to building without strict aliasing (compiler warnings in gssrpc) + +* Tue May 18 2010 Nalin Dahyabhai 1.8.1-5 +- add patch to correct GSSAPI library null pointer dereference which could be + triggered by malformed client requests (CVE-2010-1321, #582466) + +* Tue May 4 2010 Nalin Dahyabhai 1.8.1-4 +- fix output of kprop's init script's "status" and "reload" commands (#588222) + +* Tue Apr 20 2010 Nalin Dahyabhai 1.8.1-3 +- incorporate patch to fix double-free in the KDC (CVE-2010-1320, #581922) + +* Wed Apr 14 2010 Nalin Dahyabhai 1.8.1-2 +- fix a typo in kerberos.ldif + +* Fri Apr 9 2010 Nalin Dahyabhai 1.8.1-1 +- update to 1.8.1 + - no longer need patches for #555875, #561174, #563431, RT#6661, CVE-2010-0628 +- replace buildrequires on tetex-latex with one on texlive-latex, which is + the package that provides it now + +* Thu Apr 8 2010 Nalin Dahyabhai +- kdc.conf: no more need to suggest a v4 mode, or listening on the v4 port + +* Thu Apr 8 2010 Nalin Dahyabhai +- drop patch to suppress key expiration warnings sent from the KDC in + the last-req field, as the KDC is expected to just be configured to either + send them or not as a particular key approaches expiration (#556495) + +* Tue Mar 23 2010 Nalin Dahyabhai - 1.8-5 +- add upstream fix for denial-of-service in SPNEGO (CVE-2010-0628, #576325) +- kdc.conf: no more need to suggest keeping keys with v4-compatible salting + +* Fri Mar 19 2010 Nalin Dahyabhai - 1.8-4 +- remove the krb5-appl bits (the -workstation-clients and -workstation-servers + subpackages) now that krb5-appl is its own package +- replace our patch for #563431 (kpasswd doesn't fall back to guessing your + principal name using your user name if you don't have a ccache) with the + one upstream uses + +* Fri Mar 12 2010 Nalin Dahyabhai - 1.8-3 +- add documentation for the ticket_lifetime option (#561174) + +* Mon Mar 8 2010 Nalin Dahyabhai - 1.8-2 +- pull up patch to get the client libraries to correctly perform password + changes over IPv6 (Sumit Bose, RT#6661) + +* Fri Mar 5 2010 Nalin Dahyabhai - 1.8-1 +- update to 1.8 + - temporarily bundling the krb5-appl package (split upstream as of 1.8) + until its package review is complete + - profile.d scriptlets are now only needed by -workstation-clients + - adjust paths in init scripts + - drop upstreamed fix for KDC denial of service (CVE-2010-0283) + - drop patch to check the user's password correctly using crypt(), which + isn't a code path we hit when we're using PAM + +* Wed Mar 3 2010 Nalin Dahyabhai - 1.7.1-6 +- fix a null pointer dereference and crash introduced in our PAM patch that + would happen if ftpd was given the name of a user who wasn't known to the + local system, limited to being triggerable by gssapi-authenticated clients by + the default xinetd config (Olivier Fourdan, #569472) + +* Tue Mar 2 2010 Nalin Dahyabhai - 1.7.1-5 +- fix a regression (not labeling a kdb database lock file correctly, #569902) + +* Thu Feb 25 2010 Nalin Dahyabhai - 1.7.1-4 +- move the package changelog to the end to match the usual style (jdennis) +- scrub out references to $RPM_SOURCE_DIR (jdennis) +- include a symlink to the readme with the name LICENSE so that people can + find it more easily (jdennis) + +* Wed Feb 17 2010 Nalin Dahyabhai - 1.7.1-3 +- pull up the change to make kpasswd's behavior better match the docs + when there's no ccache (#563431) + +* Tue Feb 16 2010 Nalin Dahyabhai - 1.7.1-2 +- apply patch from upstream to fix KDC denial of service (CVE-2010-0283, + #566002) + +* Wed Feb 3 2010 Nalin Dahyabhai - 1.7.1-1 +- update to 1.7.1 + - don't trip AD lockout on wrong password (#542687, #554351) + - incorporates fixes for CVE-2009-4212 and CVE-2009-3295 + - fixes gss_krb5_copy_ccache() when SPNEGO is used +- move sim_client/sim_server, gss-client/gss-server, uuclient/uuserver to + the devel subpackage, better lining up with the expected krb5/krb5-appl + split in 1.8 +- drop kvno,kadmin,k5srvutil,ktutil from -workstation-servers, as it already + depends on -workstation which also includes them + +* Mon Jan 25 2010 Nalin Dahyabhai - 1.7-23 +- tighten up default permissions on kdc.conf and kadm5.acl (#558343) + +* Fri Jan 22 2010 Nalin Dahyabhai - 1.7-22 +- use portreserve correctly -- portrelease takes the basename of the file + whose entries should be released, so we need three files, not one + +* Mon Jan 18 2010 Nalin Dahyabhai - 1.7-21 +- suppress warnings of impending password expiration if expiration is more than + seven days away when the KDC reports it via the last-req field, just as we + already do when it reports expiration via the key-expiration field (#556495) +- link with libtinfo rather than libncurses, when we can, in future RHEL + +* Fri Jan 15 2010 Nalin Dahyabhai - 1.7-20 +- krb5_get_init_creds_password: check opte->flags instead of options->flags + when checking whether or not we get to use the prompter callback (#555875) + +* Thu Jan 14 2010 Nalin Dahyabhai - 1.7-19 +- use portreserve to make sure the KDC can always bind to the kerberos-iv + port, kpropd can always bind to the krb5_prop port, and that kadmind can + always bind to the kerberos-adm port (#555279) +- correct inadvertent use of macros in the changelog (rpmlint) + +* Tue Jan 12 2010 Nalin Dahyabhai - 1.7-18 +- add upstream patch for integer underflow during AES and RC4 decryption + (CVE-2009-4212), via Tom Yu (#545015) + +* Wed Jan 6 2010 Nalin Dahyabhai - 1.7-17 +- put the conditional back for the -devel subpackage +- back down to the earlier version of the patch for #551764; the backported + alternate version was incomplete + +* Tue Jan 5 2010 Nalin Dahyabhai - 1.7-16 +- use %%global instead of %%define +- pull up proposed patch for creating previously-not-there lock files for + kdb databases when 'kdb5_util' is called to 'load' (#551764) + +* Mon Jan 4 2010 Dennis Gregorovic +- fix conditional for future RHEL + +* Mon Jan 4 2010 Nalin Dahyabhai - 1.7-15 +- add upstream patch for KDC crash during referral processing (CVE-2009-3295), + via Tom Yu (#545002) + +* Mon Dec 21 2009 Nalin Dahyabhai - 1.7-14 +- refresh patch for #542868 from trunk + +* Thu Dec 10 2009 Nalin Dahyabhai +- move man pages that live in the -libs subpackage into the regular + %%{_mandir} tree where they'll still be found if that package is the + only one installed (#529319) + +* Wed Dec 9 2009 Nalin Dahyabhai - 1.7-13 +- and put it back in + +* Tue Dec 8 2009 Nalin Dahyabhai +- back that last change out + +* Tue Dec 8 2009 Nalin Dahyabhai - 1.7-12 +- try to make gss_krb5_copy_ccache() work correctly for spnego (#542868) + +* Fri Dec 4 2009 Nalin Dahyabhai +- make krb5-config suppress CFLAGS output when called with --libs (#544391) + +* Thu Dec 3 2009 Nalin Dahyabhai - 1.7-11 +- ksu: move account management checks to before we drop privileges, like + su does (#540769) +- selinux: set the user part of file creation contexts to match the current + context instead of what we looked up +- configure with --enable-dns-for-realm instead of --enable-dns, which isn't + recognized any more + +* Fri Nov 20 2009 Nalin Dahyabhai - 1.7-10 +- move /etc/pam.d/ksu from krb5-workstation-servers to krb5-workstation, + where it's actually needed (#538703) + +* Fri Oct 23 2009 Nalin Dahyabhai - 1.7-9 +- add some conditional logic to simplify building on older Fedora releases + +* Tue Oct 13 2009 Nalin Dahyabhai +- don't forget the README + +* Mon Sep 14 2009 Nalin Dahyabhai - 1.7-8 +- specify the location of the subsystem lock when using the status() function + in the kadmind and kpropd init scripts, so that we get the right error when + we're dead but have a lock file - requires initscripts 8.99 (#521772) + +* Tue Sep 8 2009 Nalin Dahyabhai +- if the init script fails to start krb5kdc/kadmind/kpropd because it's already + running (according to status()), return 0 (part of #521772) + +* Mon Aug 24 2009 Nalin Dahyabhai - 1.7-7 +- work around a compile problem with new openssl + +* Fri Aug 21 2009 Tomas Mraz - 1.7-6 +- rebuilt with new openssl + +* Fri Jul 24 2009 Fedora Release Engineering - 1.7-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Tue Jul 7 2009 Nalin Dahyabhai 1.7-5 +- rebuild to pick up the current forms of various patches + +* Mon Jul 6 2009 Nalin Dahyabhai +- simplify the man pages patch by only preprocessing the files we care about + and moving shared configure.in logic into a shared function +- catch the case of ftpd printing file sizes using %%i, when they might be + bigger than an int now + +* Tue Jun 30 2009 Nalin Dahyabhai 1.7-4 +- try to merge and clean up all the large file support for ftp and rcp + - ftpd no longer prints a negative length when sending a large file + from a 32-bit host + +* Tue Jun 30 2009 Nalin Dahyabhai +- pam_rhosts_auth.so's been gone, use pam_rhosts.so instead + +* Mon Jun 29 2009 Nalin Dahyabhai 1.7-3 +- switch buildrequires: and requires: on e2fsprogs-devel into + buildrequires: and requires: on libss-devel, libcom_err-devel, per + sandeen on fedora-devel-list + +* Fri Jun 26 2009 Nalin Dahyabhai +- fix a type mismatch in krb5_copy_error_message() +- ftp: fix some odd use of strlen() +- selinux labeling: use selabel_open() family of functions rather than + matchpathcon(), bail on it if attempting to get the mutex lock fails + +* Tue Jun 16 2009 Nalin Dahyabhai +- compile with %%{?_smp_mflags} (Steve Grubb) +- drop the bit where we munge part of the error table header, as it's not + needed any more + +* Fri Jun 5 2009 Nalin Dahyabhai 1.7-2 +- add and own %%{_libdir}/krb5/plugins/authdata + +* Thu Jun 4 2009 Nalin Dahyabhai 1.7-1 +- update to 1.7 + - no need to work around build issues with ASN1BUF_OMIT_INLINE_FUNCS + - configure recognizes --enable/--disable-pkinit now + - configure can take --disable-rpath now + - no more libdes425, krb524d, krb425.info + - kadmin/k5srvutil/ktutil are user commands now + - new kproplog + - FAST encrypted-challenge plugin is new +- drop static build logic +- drop pam_krb5-specific configuration from the default krb5.conf +- drop only-use-v5 flags being passed to various things started by xinetd +- put %%{krb5prefix}/sbin in everyone's path, too (#504525) + +* Tue May 19 2009 Nalin Dahyabhai 1.6.3-106 +- add an auth stack to ksu's PAM configuration so that pam_setcred() calls + won't just fail + +* Mon May 11 2009 Nalin Dahyabhai 1.6.3-105 +- make PAM support for ksu also set PAM_RUSER + +* Thu Apr 23 2009 Nalin Dahyabhai 1.6.3-104 +- extend PAM support to ksu: perform account and session management for the + target user +- pull up and merge James Leddy's changes to also set PAM_RHOST in PAM-aware + network-facing services + +* Tue Apr 21 2009 Nalin Dahyabhai 1.6.3-103 +- fix a typo in a ksu error message (Marek Mahut) +- "rev" works the way the test suite expects now, so don't disable tests + that use it + +* Mon Apr 20 2009 Nalin Dahyabhai 1.6.3-102 +- add LSB-style init script info + +* Fri Apr 17 2009 Nalin Dahyabhai +- explicitly run the pdf generation script using sh (part of #225974) + +* Tue Apr 7 2009 Nalin Dahyabhai 1.6.3-101 +- add patches for read overflow and null pointer dereference in the + implementation of the SPNEGO mechanism (CVE-2009-0844, CVE-2009-0845) +- add patch for attempt to free uninitialized pointer in libkrb5 + (CVE-2009-0846) +- add patch to fix length validation bug in libkrb5 (CVE-2009-0847) +- put the krb5-user .info file into just -workstation and not also + -workstation-clients + +* Mon Apr 6 2009 Nalin Dahyabhai 1.6.3-100 +- turn off krb4 support (it won't be part of the 1.7 release, but do it now) +- use triggeruns to properly shut down and disable krb524d when -server and + -workstation-servers gets upgraded, because it's gone now +- move the libraries to /%%{_lib}, but leave --libdir alone so that plugins + get installed and are searched for in the same locations (#473333) +- clean up buildprereq/prereqs, explicit mktemp requires, and add the + ldconfig for the -server-ldap subpackage (part of #225974) +- escape possible macros in the changelog (part of #225974) +- fixup summary texts (part of #225974) +- take the execute bit off of the protocol docs (part of #225974) +- unflag init scripts as configuration files (part of #225974) +- make the kpropd init script treat 'reload' as 'restart' (part of #225974) + +* Tue Mar 17 2009 Nalin Dahyabhai 1.6.3-19 +- libgssapi_krb5: backport fix for some errors which can occur when + we fail to set up the server half of a context (CVE-2009-0845) + +* Wed Feb 25 2009 Fedora Release Engineering - 1.6.3-18 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Fri Jan 16 2009 Nalin Dahyabhai 1.6.3-17 +- rebuild + +* Thu Sep 4 2008 Nalin Dahyabhai +- if we successfully change the user's password during an attempt to get + initial credentials, but then fail to get initial creds from a non-master + using the new password, retry against the master (#432334) + +* Tue Aug 5 2008 Tom "spot" Callaway 1.6.3-16 +- fix license tag + +* Wed Jul 16 2008 Nalin Dahyabhai +- clear fuzz out of patches, dropping a man page patch which is no longer + necessary +- quote %%{__cc} where needed because it includes whitespace now +- define ASN1BUF_OMIT_INLINE_FUNCS at compile-time (for now) to keep building + +* Fri Jul 11 2008 Nalin Dahyabhai 1.6.3-15 +- build with -fno-strict-aliasing, which is needed because the library + triggers these warnings +- don't forget to label principal database lock files +- fix the labeling patch so that it doesn't break bootstrapping + +* Sat Jun 14 2008 Tom "spot" Callaway 1.6.3-14 +- generate src/include/krb5/krb5.h before building +- fix conditional for sparcv9 + +* Wed Apr 16 2008 Nalin Dahyabhai 1.6.3-13 +- ftp: use the correct local filename during mget when the 'case' option is + enabled (#442713) + +* Fri Apr 4 2008 Nalin Dahyabhai 1.6.3-12 +- stop exporting kadmin keys to a keytab file when kadmind starts -- the + daemon's been able to use the database directly for a long long time now +- belatedly add aes128,aes256 to the default set of supported key types + +* Tue Apr 1 2008 Nalin Dahyabhai 1.6.3-11 +- libgssapi_krb5: properly export the acceptor subkey when creating a lucid + context (Kevin Coffman, via the nfs4 mailing list) + +* Tue Mar 18 2008 Nalin Dahyabhai 1.6.3-10 +- add fixes from MITKRB5-SA-2008-001 for use of null or dangling pointer + when v4 compatibility is enabled on the KDC (CVE-2008-0062, CVE-2008-0063, + #432620, #432621) +- add fixes from MITKRB5-SA-2008-002 for array out-of-bounds accesses when + high-numbered descriptors are used (CVE-2008-0947, #433596) +- add backport bug fix for an attempt to free non-heap memory in + libgssapi_krb5 (CVE-2007-5901, #415321) +- add backport bug fix for a double-free in out-of-memory situations in + libgssapi_krb5 (CVE-2007-5971, #415351) + +* Tue Mar 18 2008 Nalin Dahyabhai 1.6.3-9 +- rework file labeling patch to not depend on fragile preprocessor trickery, + in another attempt at fixing #428355 and friends + +* Tue Feb 26 2008 Nalin Dahyabhai 1.6.3-8 +- ftp: add patch to fix "runique on" case when globbing fixes applied +- stop adding a redundant but harmless call to initialize the gssapi internals + +* Mon Feb 25 2008 Nalin Dahyabhai +- add patch to suppress double-processing of /etc/krb5.conf when we build + with --sysconfdir=/etc, thereby suppressing double-logging (#231147) + +* Mon Feb 25 2008 Nalin Dahyabhai +- remove a patch, to fix problems with interfaces which are "up" but which + have no address assigned, which conflicted with a different fix for the same + problem in 1.5 (#200979) + +* Mon Feb 25 2008 Nalin Dahyabhai +- ftp: don't lose track of a descriptor on passive get when the server fails to + open a file + +* Mon Feb 25 2008 Nalin Dahyabhai +- in login, allow PAM to interact with the user when they've been strongly + authenticated +- in login, signal PAM when we're changing an expired password that it's an + expired password, so that when cracklib flags a password as being weak it's + treated as an error even if we're running as root + +* Mon Feb 18 2008 Nalin Dahyabhai 1.6.3-7 +- drop netdb patch +- kdb_ldap: add patch to treat 'nsAccountLock: true' as an indication that + the DISALLOW_ALL_TIX flag is set on an entry, for better interop with Fedora, + Netscape, Red Hat Directory Server (Simo Sorce) + +* Wed Feb 13 2008 Nalin Dahyabhai 1.6.3-6 +- patch to avoid depending on to define NI_MAXHOST and NI_MAXSERV + +* Tue Feb 12 2008 Nalin Dahyabhai 1.6.3-5 +- enable patch for key-expiration reporting +- enable patch to make kpasswd fall back to TCP if UDP fails (#251206) +- enable patch to make kpasswd use the right sequence number on retransmit +- enable patch to allow mech-specific creds delegated under spnego to be found + when searching for creds + +* Wed Jan 2 2008 Nalin Dahyabhai 1.6.3-4 +- some init script cleanups + - drop unquoted check and silent exit for "$NETWORKING" (#426852, #242502) + - krb524: don't barf on missing database if it looks like we're using kldap, + same as for kadmin + - return non-zero status for missing files which cause startup to + fail (#242502) + +* Tue Dec 18 2007 Nalin Dahyabhai 1.6.3-3 +- allocate space for the nul-terminator in the local pathname when looking up + a file context, and properly free a previous context (Jose Plans, #426085) + +* Wed Dec 5 2007 Nalin Dahyabhai 1.6.3-2 +- rebuild + +* Tue Oct 23 2007 Nalin Dahyabhai 1.6.3-1 +- update to 1.6.3, dropping now-integrated patches for CVE-2007-3999 + and CVE-2007-4000 (the new pkinit module is built conditionally and goes + into the -pkinit-openssl package, at least for now, to make a buildreq + loop with openssl avoidable) + +* Wed Oct 17 2007 Nalin Dahyabhai 1.6.2-10 +- make proper use of pam_loginuid and pam_selinux in rshd and ftpd + +* Fri Oct 12 2007 Nalin Dahyabhai +- make krb5.conf %%verify(not md5 size mtime) in addition to + %%config(noreplace), like /etc/nsswitch.conf (#329811) + +* Mon Oct 1 2007 Nalin Dahyabhai 1.6.2-9 +- apply the fix for CVE-2007-4000 instead of the experimental patch for + setting ok-as-delegate flags + +* Tue Sep 11 2007 Nalin Dahyabhai 1.6.2-8 +- move the db2 kdb plugin from -server to -libs, because a multilib libkdb + might need it + +* Tue Sep 11 2007 Nalin Dahyabhai 1.6.2-7 +- also perform PAM session and credential management when ftpd accepts a + client using strong authentication, missed earlier +- also label kadmind log files and files created by the db2 plugin + +* Thu Sep 6 2007 Nalin Dahyabhai 1.6.2-6 +- incorporate updated fix for CVE-2007-3999 (CVE-2007-4743) +- fix incorrect call to "test" in the kadmin init script (#252322,#287291) + +* Tue Sep 4 2007 Nalin Dahyabhai 1.6.2-5 +- incorporate fixes for MITKRB5-SA-2007-006 (CVE-2007-3999, CVE-2007-4000) + +* Sat Aug 25 2007 Nalin Dahyabhai 1.6.2-4 +- cover more cases in labeling files on creation +- add missing gawk build dependency + +* Thu Aug 23 2007 Nalin Dahyabhai 1.6.2-3 +- rebuild + +* Thu Jul 26 2007 Nalin Dahyabhai 1.6.2-2 +- kdc.conf: default to listening for TCP clients, too (#248415) + +* Thu Jul 19 2007 Nalin Dahyabhai 1.6.2-1 +- update to 1.6.2 +- add "buildrequires: texinfo-tex" to get texi2pdf + +* Wed Jun 27 2007 Nalin Dahyabhai 1.6.1-8 +- incorporate fixes for MITKRB5-SA-2007-004 (CVE-2007-2442,CVE-2007-2443) + and MITKRB5-SA-2007-005 (CVE-2007-2798) + +* Mon Jun 25 2007 Nalin Dahyabhai 1.6.1-7 +- reintroduce missing %%postun for the non-split_workstation case + +* Mon Jun 25 2007 Nalin Dahyabhai 1.6.1-6 +- rebuild + +* Mon Jun 25 2007 Nalin Dahyabhai 1.6.1-5.1 +- rebuild + +* Sun Jun 24 2007 Nalin Dahyabhai 1.6.1-5 +- add missing pam-devel build requirement, force selinux-or-fail build + +* Sun Jun 24 2007 Nalin Dahyabhai 1.6.1-4 +- rebuild + +* Sun Jun 24 2007 Nalin Dahyabhai 1.6.1-3 +- label all files at creation-time according to the SELinux policy (#228157) + +* Fri Jun 22 2007 Nalin Dahyabhai +- perform PAM account / session management in krshd (#182195,#195922) +- perform PAM authentication and account / session management in ftpd +- perform PAM authentication, account / session management, and password- + changing in login.krb5 (#182195,#195922) + +* Fri Jun 22 2007 Nalin Dahyabhai +- preprocess kerberos.ldif into a format FDS will like better, and include + that as a doc file as well + +* Fri Jun 22 2007 Nalin Dahyabhai +- switch man pages to being generated with the right paths in them +- drop old, incomplete SELinux patch +- add patch from Greg Hudson to make srvtab routines report missing-file errors + at same point that keytab routines do (#241805) + +* Thu May 24 2007 Nalin Dahyabhai 1.6.1-2 +- pull patch from svn to undo unintentional chattiness in ftp +- pull patch from svn to handle NULL krb5_get_init_creds_opt structures + better in a couple of places where they're expected + +* Wed May 23 2007 Nalin Dahyabhai 1.6.1-1 +- update to 1.6.1 + - drop no-longer-needed patches for CVE-2007-0956,CVE-2007-0957,CVE-2007-1216 + - drop patch for sendto bug in 1.6, fixed in 1.6.1 + +* Fri May 18 2007 Nalin Dahyabhai +- kadmind.init: don't fail outright if the default principal database + isn't there if it looks like we might be using the kldap plugin +- kadmind.init: attempt to extract the key for the host-specific kadmin + service when we try to create the keytab + +* Wed May 16 2007 Nalin Dahyabhai 1.6-6 +- omit dependent libraries from the krb5-config --libs output, as using + shared libraries (no more static libraries) makes them unnecessary and + they're not part of the libkrb5 interface (patch by Rex Dieter, #240220) + (strips out libkeyutils, libresolv, libdl) + +* Fri May 4 2007 Nalin Dahyabhai 1.6-5 +- pull in keyutils as a build requirement to get the "KEYRING:" ccache type, + because we've merged + +* Fri May 4 2007 Nalin Dahyabhai 1.6-4 +- fix an uninitialized length value which could cause a crash when parsing + key data coming from a directory server +- correct a typo in the krb5.conf man page ("ldap_server"->"ldap_servers") + +* Fri Apr 13 2007 Nalin Dahyabhai +- move the default acl_file, dict_file, and admin_keytab settings to + the part of the default/example kdc.conf where they'll actually have + an effect (#236417) + +* Thu Apr 5 2007 Nalin Dahyabhai 1.5-24 +- merge security fixes from RHSA-2007:0095 + +* Tue Apr 3 2007 Nalin Dahyabhai 1.6-3 +- add patch to correct unauthorized access via krb5-aware telnet + daemon (#229782, CVE-2007-0956) +- add patch to fix buffer overflow in krb5kdc and kadmind + (#231528, CVE-2007-0957) +- add patch to fix double-free in kadmind (#231537, CVE-2007-1216) + +* Thu Mar 22 2007 Nalin Dahyabhai +- back out buildrequires: keyutils-libs-devel for now + +* Thu Mar 22 2007 Nalin Dahyabhai 1.6-2 +- add buildrequires: on keyutils-libs-devel to enable use of keyring ccaches, + dragging keyutils-libs in as a dependency + +* Mon Mar 19 2007 Nalin Dahyabhai 1.5-23 +- fix bug ID in changelog + +* Thu Mar 15 2007 Nalin Dahyabhai 1.5-22 + +* Thu Mar 15 2007 Nalin Dahyabhai 1.5-21 +- add preliminary patch to fix buffer overflow in krb5kdc and kadmind + (#231528, CVE-2007-0957) +- add preliminary patch to fix double-free in kadmind (#231537, CVE-2007-1216) + +* Wed Feb 28 2007 Nalin Dahyabhai +- add patch to build semi-useful static libraries, but don't apply it unless + we need them + +* Tue Feb 27 2007 Nalin Dahyabhai - 1.5-20 +- temporarily back out %%post changes, fix for #143289 for security update +- add preliminary patch to correct unauthorized access via krb5-aware telnet + +* Mon Feb 19 2007 Nalin Dahyabhai +- make profile.d scriptlets mode 644 instead of 755 (part of #225974) + +* Tue Jan 30 2007 Nalin Dahyabhai 1.6-1 +- clean up quoting of command-line arguments passed to the krsh/krlogin + wrapper scripts + +* Mon Jan 22 2007 Nalin Dahyabhai +- initial update to 1.6, pre-package-reorg +- move workstation daemons to a new subpackage (#81836, #216356, #217301), and + make the new subpackage require xinetd (#211885) + +* Mon Jan 22 2007 Nalin Dahyabhai - 1.5-18 +- make use of install-info more failsafe (Ville Skyttä, #223704) +- preserve timestamps on shell scriptlets at %%install-time + +* Tue Jan 16 2007 Nalin Dahyabhai - 1.5-17 +- move to using pregenerated PDF docs to cure multilib conflicts (#222721) + +* Fri Jan 12 2007 Nalin Dahyabhai - 1.5-16 +- update backport of the preauth module interface (part of #194654) + +* Tue Jan 9 2007 Nalin Dahyabhai - 1.5-14 +- apply fixes from Tom Yu for MITKRB5-SA-2006-002 (CVE-2006-6143) (#218456) +- apply fixes from Tom Yu for MITKRB5-SA-2006-003 (CVE-2006-6144) (#218456) + +* Wed Dec 20 2006 Nalin Dahyabhai - 1.5-12 +- update backport of the preauth module interface + +* Mon Oct 30 2006 Nalin Dahyabhai +- update backport of the preauth module interface +- add proposed patches 4566, 4567 +- add proposed edata reporting interface for KDC +- add temporary placeholder for module global context fixes + +* Mon Oct 23 2006 Nalin Dahyabhai - 1.5-11 +- don't bail from the KDC init script if there's no database, it may be in + a different location than the default (fenlason) +- remove the [kdc] section from the default krb5.conf -- doesn't seem to have + been applicable for a while + +* Wed Oct 18 2006 Nalin Dahyabhai - 1.5-10 +- rename krb5.sh and krb5.csh so that they don't overlap (#210623) +- way-late application of added error info in kadmind.init (#65853) + +* Wed Oct 18 2006 Nalin Dahyabhai - 1.5-9.pal_18695 +- add backport of in-development preauth module interface (#208643) + +* Mon Oct 9 2006 Nalin Dahyabhai - 1.5-9 +- provide docs in PDF format instead of as tex source (Enrico Scholz, #209943) + +* Wed Oct 4 2006 Nalin Dahyabhai - 1.5-8 +- add missing shebang headers to krsh and krlogin wrapper scripts (#209238) + +* Wed Sep 6 2006 Nalin Dahyabhai - 1.5-7 +- set SS_LIB at configure-time so that libss-using apps get working readline + support (#197044) + +* Fri Aug 18 2006 Nalin Dahyabhai - 1.5-6 +- switch to the updated patch for MITKRB-SA-2006-001 + +* Tue Aug 8 2006 Nalin Dahyabhai - 1.5-5 +- apply patch to address MITKRB-SA-2006-001 (CVE-2006-3084) + +* Mon Aug 7 2006 Nalin Dahyabhai - 1.5-4 +- ensure that the gssapi library's been initialized before walking the + internal mechanism list in gss_release_oid(), needed if called from + gss_release_name() right after a gss_import_name() (#198092) + +* Tue Jul 25 2006 Nalin Dahyabhai - 1.5-3 +- rebuild + +* Tue Jul 25 2006 Nalin Dahyabhai - 1.5-2 +- pull up latest revision of patch to reduce lockups in rsh/rshd + +* Mon Jul 17 2006 Nalin Dahyabhai - 1.5-1.2 +- rebuild + +* Wed Jul 12 2006 Jesse Keating - 1.5-1.1 +- rebuild + +* Thu Jul 6 2006 Nalin Dahyabhai 1.5-1 +- build + +* Wed Jul 5 2006 Nalin Dahyabhai 1.5-0 +- update to 1.5 + +* Fri Jun 23 2006 Nalin Dahyabhai 1.4.3-9 +- mark profile.d config files noreplace (Laurent Rineau, #196447) + +* Thu Jun 8 2006 Nalin Dahyabhai 1.4.3-8 +- add buildprereq for autoconf + +* Mon May 22 2006 Nalin Dahyabhai 1.4.3-7 +- further munge krb5-config so that 'libdir=/usr/lib' is given even on 64-bit + architectures, to avoid multilib conflicts; other changes will conspire to + strip out the -L flag which uses this, so it should be harmless (#192692) + +* Fri Apr 28 2006 Nalin Dahyabhai 1.4.3-6 +- adjust the patch which removes the use of rpath to also produce a + krb5-config which is okay in multilib environments (#190118) +- make the name-of-the-tempfile comment which compile_et adds to error code + headers always list the same file to avoid conflicts on multilib installations +- strip SIZEOF_LONG out of krb5.h so that it doesn't conflict on multilib boxes +- strip GSS_SIZEOF_LONG out of gssapi.h so that it doesn't conflict on mulitlib + boxes + +* Fri Apr 14 2006 Stepan Kasal 1.4.3-5 +- Fix formatting typo in kinit.1 (krb5-kinit-man-typo.patch) + +* Fri Feb 10 2006 Jesse Keating 1.4.3-4.1 +- bump again for double-long bug on ppc(64) + +* Mon Feb 6 2006 Nalin Dahyabhai 1.4.3-4 +- give a little bit more information to the user when kinit gets the catch-all + I/O error (#180175) + +* Thu Jan 19 2006 Nalin Dahyabhai 1.4.3-3 +- rebuild properly when pthread_mutexattr_setrobust_np() is defined but not + declared, such as with recent glibc when _GNU_SOURCE isn't being used + +* Thu Jan 19 2006 Matthias Clasen 1.4.3-2 +- Use full paths in krb5.sh to avoid path lookups + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Thu Dec 1 2005 Nalin Dahyabhai +- login: don't truncate passwords before passing them into crypt(), in + case they're significant (#149476) + +* Thu Nov 17 2005 Nalin Dahyabhai 1.4.3-1 +- update to 1.4.3 +- make ksu setuid again (#137934, others) + +* Tue Sep 13 2005 Nalin Dahyabhai 1.4.2-4 +- mark %%{krb5prefix}/man so that files which are packaged within it are + flagged as %%doc (#168163) + +* Tue Sep 6 2005 Nalin Dahyabhai 1.4.2-3 +- add an xinetd configuration file for encryption-only telnetd, parallelling + the kshell/ekshell pair (#167535) + +* Wed Aug 31 2005 Nalin Dahyabhai 1.4.2-2 +- change the default configured encryption type for KDC databases to the + compiled-in default of des3-hmac-sha1 (#57847) + +* Thu Aug 11 2005 Nalin Dahyabhai 1.4.2-1 +- update to 1.4.2, incorporating the fixes for MIT-KRB5-SA-2005-002 and + MIT-KRB5-SA-2005-003 + +* Wed Jun 29 2005 Nalin Dahyabhai 1.4.1-6 +- rebuild + +* Wed Jun 29 2005 Nalin Dahyabhai 1.4.1-5 +- fix telnet client environment variable disclosure the same way NetKit's + telnet client did (CAN-2005-0488) (#159305) +- keep apps which call krb5_principal_compare() or krb5_realm_compare() with + malformed or NULL principal structures from crashing outright (Thomas Biege) + (#161475) + +* Tue Jun 28 2005 Nalin Dahyabhai +- apply fixes from draft of MIT-KRB5-SA-2005-002 (CAN-2005-1174,CAN-2005-1175) + (#157104) +- apply fixes from draft of MIT-KRB5-SA-2005-003 (CAN-2005-1689) (#159755) + +* Fri Jun 24 2005 Nalin Dahyabhai 1.4.1-4 +- fix double-close in keytab handling +- add port of fixes for CAN-2004-0175 to krb5-aware rcp (#151612) + +* Fri May 13 2005 Nalin Dahyabhai 1.4.1-3 +- prevent spurious EBADF in krshd when stdin is closed by the client while + the command is running (#151111) + +* Fri May 13 2005 Martin Stransky 1.4.1-2 +- add deadlock patch, removed old patch + +* Fri May 6 2005 Nalin Dahyabhai 1.4.1-1 +- update to 1.4.1, incorporating fixes for CAN-2005-0468 and CAN-2005-0469 +- when starting the KDC or kadmind, if KRB5REALM is set via the /etc/sysconfig + file for the service, pass it as an argument for the -r flag + +* Wed Mar 23 2005 Nalin Dahyabhai 1.4-3 +- drop krshd patch for now + +* Thu Mar 17 2005 Nalin Dahyabhai +- add draft fix from Tom Yu for slc_add_reply() buffer overflow (CAN-2005-0469) +- add draft fix from Tom Yu for env_opt_add() buffer overflow (CAN-2005-0468) + +* Wed Mar 16 2005 Nalin Dahyabhai 1.4-2 +- don't include into the telnet client when we're not using curses + +* Thu Feb 24 2005 Nalin Dahyabhai 1.4-1 +- update to 1.4 + - v1.4 kadmin client requires a v1.4 kadmind on the server, or use the "-O" + flag to specify that it should communicate with the server using the older + protocol + - new libkrb5support library + - v5passwdd and kadmind4 are gone + - versioned symbols +- pick up $KRB5KDC_ARGS from /etc/sysconfig/krb5kdc, if it exists, and pass + it on to krb5kdc +- pick up $KADMIND_ARGS from /etc/sysconfig/kadmin, if it exists, and pass + it on to kadmind +- pick up $KRB524D_ARGS from /etc/sysconfig/krb524, if it exists, and pass + it on to krb524d *instead of* "-m" +- set "forwardable" in [libdefaults] in the default krb5.conf to match the + default setting which we supply for pam_krb5 +- set a default of 24h for "ticket_lifetime" in [libdefaults], reflecting the + compiled-in default + +* Mon Dec 20 2004 Nalin Dahyabhai 1.3.6-3 +- rebuild + +* Mon Dec 20 2004 Nalin Dahyabhai 1.3.6-2 +- rebuild + +* Mon Dec 20 2004 Nalin Dahyabhai 1.3.6-1 +- update to 1.3.6, which includes the previous fix + +* Mon Dec 20 2004 Nalin Dahyabhai 1.3.5-8 +- apply fix from Tom Yu for MITKRB5-SA-2004-004 (CAN-2004-1189) + +* Fri Dec 17 2004 Martin Stransky 1.3.5-7 +- fix deadlock during file transfer via rsync/krsh +- thanks goes to James Antill for hint + +* Fri Nov 26 2004 Nalin Dahyabhai 1.3.5-6 +- rebuild + +* Mon Nov 22 2004 Nalin Dahyabhai 1.3.5-3 +- fix predictable-tempfile-name bug in krb5-send-pr (CAN-2004-0971, #140036) + +* Tue Nov 16 2004 Nalin Dahyabhai +- silence compiler warning in kprop by using an in-memory ccache with a fixed + name instead of an on-disk ccache with a name generated by tmpnam() + +* Tue Nov 16 2004 Nalin Dahyabhai 1.3.5-2 +- fix globbing patch port mode (#139075) + +* Mon Nov 1 2004 Nalin Dahyabhai 1.3.5-1 +- fix segfault in telnet due to incorrect checking of gethostbyname_r result + codes (#129059) + +* Fri Oct 15 2004 Nalin Dahyabhai +- remove rc4-hmac:norealm and rc4-hmac:onlyrealm from the default list of + supported keytypes in kdc.conf -- they produce exactly the same keys as + rc4-hmac:normal because rc4 string-to-key ignores salts +- nuke kdcrotate -- there are better ways to balance the load on KDCs, and + the SELinux policy for it would have been scary-looking +- update to 1.3.5, mainly to include MITKRB5SA 2004-002 and 2004-003 + +* Tue Aug 31 2004 Nalin Dahyabhai 1.3.4-7 +- rebuild + +* Tue Aug 24 2004 Nalin Dahyabhai 1.3.4-6 +- rebuild + +* Tue Aug 24 2004 Nalin Dahyabhai 1.3.4-5 +- incorporate revised fixes from Tom Yu for CAN-2004-0642, CAN-2004-0644, + CAN-2004-0772 + +* Mon Aug 23 2004 Nalin Dahyabhai 1.3.4-4 +- rebuild + +* Mon Aug 23 2004 Nalin Dahyabhai 1.3.4-3 +- incorporate fixes from Tom Yu for CAN-2004-0642, CAN-2004-0772 + (MITKRB5-SA-2004-002, #130732) +- incorporate fixes from Tom Yu for CAN-2004-0644 (MITKRB5-SA-2004-003, #130732) + +* Tue Jul 27 2004 Nalin Dahyabhai 1.3.4-2 +- fix indexing error in server sorting patch (#127336) + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Mon Jun 14 2004 Nalin Dahyabhai 1.3.4-0.1 +- update to 1.3.4 final + +* Mon Jun 7 2004 Nalin Dahyabhai 1.3.4-0 +- update to 1.3.4 beta1 +- remove MITKRB5-SA-2004-001, included in 1.3.4 + +* Mon Jun 7 2004 Nalin Dahyabhai 1.3.3-8 +- rebuild + +* Fri Jun 4 2004 Nalin Dahyabhai 1.3.3-7 +- rebuild + +* Fri Jun 4 2004 Nalin Dahyabhai 1.3.3-6 +- apply updated patch from MITKRB5-SA-2004-001 (revision 2004-06-02) + +* Tue Jun 1 2004 Nalin Dahyabhai 1.3.3-5 +- rebuild + +* Tue Jun 1 2004 Nalin Dahyabhai 1.3.3-4 +- apply patch from MITKRB5-SA-2004-001 (#125001) + +* Wed May 12 2004 Thomas Woerner 1.3.3-3 +- removed rpath + +* Thu Apr 15 2004 Nalin Dahyabhai 1.3.3-2 +- re-enable large file support, fell out in 1.3-1 +- patch rcp to use long long and %%lld format specifiers when reporting file + sizes on large files + +* Tue Apr 13 2004 Nalin Dahyabhai 1.3.3-1 +- update to 1.3.3 + +* Wed Mar 10 2004 Nalin Dahyabhai 1.3.2-1 +- update to 1.3.2 + +* Mon Mar 8 2004 Nalin Dahyabhai 1.3.1-12 +- rebuild + +* Tue Mar 02 2004 Elliot Lee 1.3.1-11.1 +- rebuilt + +* Fri Feb 13 2004 Elliot Lee 1.3.1-11 +- rebuilt + +* Mon Feb 9 2004 Nalin Dahyabhai 1.3.1-10 +- catch krb4 send_to_kdc cases in kdc preference patch + +* Mon Feb 2 2004 Nalin Dahyabhai 1.3.1-9 +- remove patch to set TERM in klogind which, combined with the upstream fix in + 1.3.1, actually produces the bug now (#114762) + +* Mon Jan 19 2004 Nalin Dahyabhai 1.3.1-8 +- when iterating over lists of interfaces which are "up" from getifaddrs(), + skip over those which have no address (#113347) + +* Mon Jan 12 2004 Nalin Dahyabhai +- prefer the kdc which last replied to a request when sending requests to kdcs + +* Mon Nov 24 2003 Nalin Dahyabhai 1.3.1-7 +- fix combination of --with-netlib and --enable-dns (#82176) + +* Tue Nov 18 2003 Nalin Dahyabhai +- remove libdefault ticket_lifetime option from the default krb5.conf, it is + ignored by libkrb5 + +* Thu Sep 25 2003 Nalin Dahyabhai 1.3.1-6 +- fix bug in patch to make rlogind start login with a clean environment a la + netkit rlogin, spotted and fixed by Scott McClung + +* Tue Sep 23 2003 Nalin Dahyabhai 1.3.1-5 +- include profile.d scriptlets in krb5-devel so that krb5-config will be in + the path if krb5-workstation isn't installed, reported by Kir Kolyshkin + +* Mon Sep 8 2003 Nalin Dahyabhai +- add more etypes (arcfour) to the default enctype list in kdc.conf +- don't apply previous patch, refused upstream + +* Fri Sep 5 2003 Nalin Dahyabhai 1.3.1-4 +- fix 32/64-bit bug storing and retrieving the issue_date in v4 credentials + +* Wed Sep 3 2003 Dan Walsh 1.3.1-3 +- Don't check for write access on /etc/krb5.conf if SELinux + +* Tue Aug 26 2003 Nalin Dahyabhai 1.3.1-2 +- fixup some int/pointer varargs wackiness + +* Tue Aug 5 2003 Nalin Dahyabhai 1.3.1-1 +- rebuild + +* Mon Aug 4 2003 Nalin Dahyabhai 1.3.1-0 +- update to 1.3.1 + +* Thu Jul 24 2003 Nalin Dahyabhai 1.3-2 +- pull fix for non-compliant encoding of salt field in etype-info2 preauth + data from 1.3.1 beta 1, until 1.3.1 is released. + +* Mon Jul 21 2003 Nalin Dahyabhai 1.3-1 +- update to 1.3 + +* Mon Jul 7 2003 Nalin Dahyabhai 1.2.8-4 +- correctly use stdargs + +* Wed Jun 18 2003 Nalin Dahyabhai 1.3-0.beta.4 +- test update to 1.3 beta 4 +- ditch statglue build option +- krb5-devel requires e2fsprogs-devel, which now provides libss and libcom_err + +* Wed Jun 04 2003 Elliot Lee +- rebuilt + +* Wed May 21 2003 Jeremy Katz 1.2.8-2 +- gcc 3.3 doesn't implement varargs.h, include stdarg.h instead + +* Wed Apr 9 2003 Nalin Dahyabhai 1.2.8-1 +- update to 1.2.8 + +* Mon Mar 31 2003 Nalin Dahyabhai 1.2.7-14 +- fix double-free of enc_part2 in krb524d + +* Fri Mar 21 2003 Nalin Dahyabhai 1.2.7-13 +- update to latest patch kit for MITKRB5-SA-2003-004 + +* Wed Mar 19 2003 Nalin Dahyabhai 1.2.7-12 +- add patch included in MITKRB5-SA-2003-003 (CAN-2003-0028) + +* Mon Mar 17 2003 Nalin Dahyabhai 1.2.7-11 +- add patches from patchkit from MITKRB5-SA-2003-004 (CAN-2003-0138 and + CAN-2003-0139) + +* Thu Mar 6 2003 Nalin Dahyabhai 1.2.7-10 +- rebuild + +* Thu Mar 6 2003 Nalin Dahyabhai 1.2.7-9 +- fix buffer underrun in unparsing certain principals (CAN-2003-0082) + +* Tue Feb 4 2003 Nalin Dahyabhai 1.2.7-8 +- add patch to document the reject-bad-transited option in kdc.conf + +* Mon Feb 3 2003 Nalin Dahyabhai +- add patch to fix server-side crashes when principals have no + components (CAN-2003-0072) + +* Thu Jan 23 2003 Nalin Dahyabhai 1.2.7-7 +- add patch from Mark Cox for exploitable bugs in ftp client + +* Wed Jan 22 2003 Tim Powers +- rebuilt + +* Wed Jan 15 2003 Nalin Dahyabhai 1.2.7-5 +- use PICFLAGS when building code from the ktany patch + +* Thu Jan 9 2003 Bill Nottingham 1.2.7-4 +- debloat + +* Tue Jan 7 2003 Jeremy Katz 1.2.7-3 +- include .so.* symlinks as well as .so.*.* + +* Mon Dec 9 2002 Jakub Jelinek 1.2.7-2 +- always #include to access errno, never do it directly +- enable LFS on a bunch of other 32-bit arches + +* Wed Dec 4 2002 Nalin Dahyabhai +- increase the maximum name length allowed by kuserok() to the higher value + used in development versions + +* Mon Dec 2 2002 Nalin Dahyabhai +- install src/krb524/README as README.krb524 in the -servers package, + includes information about converting for AFS principals + +* Fri Nov 15 2002 Nalin Dahyabhai 1.2.7-1 +- update to 1.2.7 +- disable use of tcl + +* Mon Nov 11 2002 Nalin Dahyabhai +- update to 1.2.7-beta2 (internal only, not for release), dropping dnsparse + and kadmind4 fixes + +* Wed Oct 23 2002 Nalin Dahyabhai 1.2.6-5 +- add patch for buffer overflow in kadmind4 (not used by default) + +* Fri Oct 11 2002 Nalin Dahyabhai 1.2.6-4 +- drop a hunk from the dnsparse patch which is actually redundant (thanks to + Tom Yu) + +* Wed Oct 9 2002 Nalin Dahyabhai 1.2.6-3 +- patch to handle truncated dns responses + +* Mon Oct 7 2002 Nalin Dahyabhai 1.2.6-2 +- remove hashless key types from the default kdc.conf, they're not supposed to + be there, noted by Sam Hartman on krbdev + +* Fri Sep 27 2002 Nalin Dahyabhai 1.2.6-1 +- update to 1.2.6 + +* Fri Sep 13 2002 Nalin Dahyabhai 1.2.5-7 +- use %%{_lib} for the sake of multilib systems + +* Fri Aug 2 2002 Nalin Dahyabhai 1.2.5-6 +- add patch from Tom Yu for exploitable bugs in rpc code used in kadmind + +* Tue Jul 23 2002 Nalin Dahyabhai 1.2.5-5 +- fix bug in krb5.csh which would cause the path check to always succeed + +* Fri Jul 19 2002 Jakub Jelinek 1.2.5-4 +- build even libdb.a with -fPIC and $RPM_OPT_FLAGS. + +* Fri Jun 21 2002 Tim Powers +- automated rebuild + +* Sun May 26 2002 Tim Powers +- automated rebuild + +* Wed May 1 2002 Nalin Dahyabhai 1.2.5-1 +- update to 1.2.5 +- disable statglue + +* Fri Mar 1 2002 Nalin Dahyabhai 1.2.4-1 +- update to 1.2.4 + +* Wed Feb 20 2002 Nalin Dahyabhai 1.2.3-5 +- rebuild in new environment +- reenable statglue + +* Sat Jan 26 2002 Florian La Roche +- prereq chkconfig for the server subpackage + +* Wed Jan 16 2002 Nalin Dahyabhai 1.2.3-3 +- build without -g3, which gives us large static libraries in -devel + +* Tue Jan 15 2002 Nalin Dahyabhai 1.2.3-2 +- reintroduce ld.so.conf munging in the -libs %%post + +* Thu Jan 10 2002 Nalin Dahyabhai 1.2.3-1 +- rename the krb5 package back to krb5-libs; the previous rename caused + something of an uproar +- update to 1.2.3, which includes the FTP and telnetd fixes +- configure without --enable-dns-for-kdc --enable-dns-for-realm, which now set + the default behavior instead of enabling the feature (the feature is enabled + by --enable-dns, which we still use) +- reenable optimizations on Alpha +- support more encryption types in the default kdc.conf (heads-up from post + to comp.protocols.kerberos by Jason Heiss) + +* Fri Aug 3 2001 Nalin Dahyabhai 1.2.2-14 +- rename the krb5-libs package to krb5 (naming a subpackage -libs when there + is no main package is silly) +- move defaults for PAM to the appdefaults section of krb5.conf -- this is + the area where the krb5_appdefault_* functions look for settings) +- disable statglue (warning: breaks binary compatibility with previous + packages, but has to be broken at some point to work correctly with + unpatched versions built with newer versions of glibc) + +* Fri Aug 3 2001 Nalin Dahyabhai 1.2.2-13 +- bump release number and rebuild + +* Wed Aug 1 2001 Nalin Dahyabhai +- add patch to fix telnetd vulnerability + +* Fri Jul 20 2001 Nalin Dahyabhai +- tweak statglue.c to fix stat/stat64 aliasing problems +- be cleaner in use of gcc to build shlibs + +* Wed Jul 11 2001 Nalin Dahyabhai +- use gcc to build shared libraries + +* Wed Jun 27 2001 Nalin Dahyabhai +- add patch to support "ANY" keytab type (i.e., + "default_keytab_name = ANY:FILE:/etc/krb5.keytab,SRVTAB:/etc/srvtab" + patch from Gerald Britton, #42551) +- build with -D_FILE_OFFSET_BITS=64 to get large file I/O in ftpd (#30697) +- patch ftpd to use long long and %%lld format specifiers to support the SIZE + command on large files (also #30697) +- don't use LOG_AUTH as an option value when calling openlog() in ksu (#45965) +- implement reload in krb5kdc and kadmind init scripts (#41911) +- lose the krb5server init script (not using it any more) + +* Sun Jun 24 2001 Elliot Lee +- Bump release + rebuild. + +* Tue May 29 2001 Nalin Dahyabhai +- pass some structures by address instead of on the stack in krb5kdc + +* Tue May 22 2001 Nalin Dahyabhai +- rebuild in new environment + +* Thu Apr 26 2001 Nalin Dahyabhai +- add patch from Tom Yu to fix ftpd overflows (#37731) + +* Wed Apr 18 2001 Than Ngo +- disable optimizations on the alpha again + +* Fri Mar 30 2001 Nalin Dahyabhai +- add in glue code to make sure that libkrb5 continues to provide a + weak copy of stat() + +* Thu Mar 15 2001 Nalin Dahyabhai +- build alpha with -O0 for now + +* Thu Mar 8 2001 Nalin Dahyabhai +- fix the kpropd init script + +* Mon Mar 5 2001 Nalin Dahyabhai +- update to 1.2.2, which fixes some bugs relating to empty ETYPE-INFO +- re-enable optimization on Alpha + +* Thu Feb 8 2001 Nalin Dahyabhai +- build alpha with -O0 for now +- own %%{_var}/kerberos + +* Tue Feb 6 2001 Nalin Dahyabhai +- own the directories which are created for each package (#26342) + +* Tue Jan 23 2001 Nalin Dahyabhai +- gettextize init scripts + +* Fri Jan 19 2001 Nalin Dahyabhai +- add some comments to the ksu patches for the curious +- re-enable optimization on alphas + +* Mon Jan 15 2001 Nalin Dahyabhai +- fix krb5-send-pr (#18932) and move it from -server to -workstation +- buildprereq libtermcap-devel +- temporariliy disable optimization on alphas +- gettextize init scripts + +* Tue Dec 5 2000 Nalin Dahyabhai +- force -fPIC + +* Fri Dec 1 2000 Nalin Dahyabhai +- rebuild in new environment + +* Tue Oct 31 2000 Nalin Dahyabhai +- add bison as a BuildPrereq (#20091) + +* Mon Oct 30 2000 Nalin Dahyabhai +- change /usr/dict/words to /usr/share/dict/words in default kdc.conf (#20000) + +* Thu Oct 5 2000 Nalin Dahyabhai +- apply kpasswd bug fixes from David Wragg + +* Wed Oct 4 2000 Nalin Dahyabhai +- make krb5-libs obsolete the old krb5-configs package (#18351) +- don't quit from the kpropd init script if there's no principal database so + that you can propagate the first time without running kpropd manually +- don't complain if /etc/ld.so.conf doesn't exist in the -libs %%post + +* Tue Sep 12 2000 Nalin Dahyabhai +- fix credential forwarding problem in klogind (goof in KRB5CCNAME handling) + (#11588) +- fix heap corruption bug in FTP client (#14301) + +* Wed Aug 16 2000 Nalin Dahyabhai +- fix summaries and descriptions +- switched the default transfer protocol from PORT to PASV as proposed on + bugzilla (#16134), and to match the regular ftp package's behavior + +* Wed Jul 19 2000 Jeff Johnson +- rebuild to compress man pages. + +* Sat Jul 15 2000 Bill Nottingham +- move initscript back + +* Fri Jul 14 2000 Nalin Dahyabhai +- disable servers by default to keep linuxconf from thinking they need to be + started when they don't + +* Thu Jul 13 2000 Prospector +- automatic rebuild + +* Mon Jul 10 2000 Nalin Dahyabhai +- change cleanup code in post to not tickle chkconfig +- add grep as a Prereq: for -libs + +* Thu Jul 6 2000 Nalin Dahyabhai +- move condrestarts to postun +- make xinetd configs noreplace +- add descriptions to xinetd configs +- add /etc/init.d as a prereq for the -server package +- patch to properly truncate $TERM in krlogind + +* Fri Jun 30 2000 Nalin Dahyabhai +- update to 1.2.1 +- back out Tom Yu's patch, which is a big chunk of the 1.2 -> 1.2.1 update +- start using the official source tarball instead of its contents + +* Thu Jun 29 2000 Nalin Dahyabhai +- Tom Yu's patch to fix compatibility between 1.2 kadmin and 1.1.1 kadmind +- pull out 6.2 options in the spec file (sonames changing in 1.2 means it's not + compatible with other stuff in 6.2, so no need) + +* Wed Jun 28 2000 Nalin Dahyabhai +- tweak graceful start/stop logic in post and preun + +* Mon Jun 26 2000 Nalin Dahyabhai +- update to the 1.2 release +- ditch a lot of our patches which went upstream +- enable use of DNS to look up things at build-time +- disable use of DNS to look up things at run-time in default krb5.conf +- change ownership of the convert-config-files script to root.root +- compress PS docs +- fix some typos in the kinit man page +- run condrestart in server post, and shut down in preun + +* Mon Jun 19 2000 Nalin Dahyabhai +- only remove old krb5server init script links if the init script is there + +* Sat Jun 17 2000 Nalin Dahyabhai +- disable kshell and eklogin by default + +* Thu Jun 15 2000 Nalin Dahyabhai +- patch mkdir/rmdir problem in ftpcmd.y +- add condrestart option to init script +- split the server init script into three pieces and add one for kpropd + +* Wed Jun 14 2000 Nalin Dahyabhai +- make sure workstation servers are all disabled by default +- clean up krb5server init script + +* Fri Jun 9 2000 Nalin Dahyabhai +- apply second set of buffer overflow fixes from Tom Yu +- fix from Dirk Husung for a bug in buffer cleanups in the test suite +- work around possibly broken rev binary in running test suite +- move default realm configs from /var/kerberos to %%{_var}/kerberos + +* Tue Jun 6 2000 Nalin Dahyabhai +- make ksu and v4rcp owned by root + +* Sat Jun 3 2000 Nalin Dahyabhai +- use %%{_infodir} to better comply with FHS +- move .so files to -devel subpackage +- tweak xinetd config files (bugs #11833, #11835, #11836, #11840) +- fix package descriptions again + +* Wed May 24 2000 Nalin Dahyabhai +- change a LINE_MAX to 1024, fix from Ken Raeburn +- add fix for login vulnerability in case anyone rebuilds without krb4 compat +- add tweaks for byte-swapping macros in krb.h, also from Ken +- add xinetd config files +- make rsh and rlogin quieter +- build with debug to fix credential forwarding +- add rsh as a build-time req because the configure scripts look for it to + determine paths + +* Wed May 17 2000 Nalin Dahyabhai +- fix config_subpackage logic + +* Tue May 16 2000 Nalin Dahyabhai +- remove setuid bit on v4rcp and ksu in case the checks previously added + don't close all of the problems in ksu +- apply patches from Jeffrey Schiller to fix overruns Chris Evans found +- reintroduce configs subpackage for use in the errata +- add PreReq: sh-utils + +* Mon May 15 2000 Nalin Dahyabhai +- fix double-free in the kdc (patch merged into MIT tree) +- include convert-config-files script as a documentation file + +* Wed May 03 2000 Nalin Dahyabhai +- patch ksu man page because the -C option never works +- add access() checks and disable debug mode in ksu +- modify default ksu build arguments to specify more directories in CMD_PATH + and to use getusershell() + +* Wed May 03 2000 Bill Nottingham +- fix configure stuff for ia64 + +* Mon Apr 10 2000 Nalin Dahyabhai +- add LDCOMBINE=-lc to configure invocation to use libc versioning (bug #10653) +- change Requires: for/in subpackages to include %%{version} + +* Wed Apr 05 2000 Nalin Dahyabhai +- add man pages for kerberos(1), kvno(1), .k5login(5) +- add kvno to -workstation + +* Mon Apr 03 2000 Nalin Dahyabhai +- Merge krb5-configs back into krb5-libs. The krb5.conf file is marked as + a %%config file anyway. +- Make krb5.conf a noreplace config file. + +* Thu Mar 30 2000 Nalin Dahyabhai +- Make klogind pass a clean environment to children, like NetKit's rlogind does. + +* Wed Mar 08 2000 Nalin Dahyabhai +- Don't enable the server by default. +- Compress info pages. +- Add defaults for the PAM module to krb5.conf + +* Mon Mar 06 2000 Nalin Dahyabhai +- Correct copyright: it's exportable now, provided the proper paperwork is + filed with the government. + +* Fri Mar 03 2000 Nalin Dahyabhai +- apply Mike Friedman's patch to fix format string problems +- don't strip off argv[0] when invoking regular rsh/rlogin + +* Thu Mar 02 2000 Nalin Dahyabhai +- run kadmin.local correctly at startup + +* Mon Feb 28 2000 Nalin Dahyabhai +- pass absolute path to kadm5.keytab if/when extracting keys at startup + +* Sat Feb 19 2000 Nalin Dahyabhai +- fix info page insertions + +* Wed Feb 9 2000 Nalin Dahyabhai +- tweak server init script to automatically extract kadm5 keys if + /var/kerberos/krb5kdc/kadm5.keytab doesn't exist yet +- adjust package descriptions + +* Thu Feb 3 2000 Nalin Dahyabhai +- fix for potentially gzipped man pages + +* Fri Jan 21 2000 Nalin Dahyabhai +- fix comments in krb5-configs + +* Fri Jan 7 2000 Nalin Dahyabhai +- move /usr/kerberos/bin to end of PATH + +* Tue Dec 28 1999 Nalin Dahyabhai +- install kadmin header files + +* Tue Dec 21 1999 Nalin Dahyabhai +- patch around TIOCGTLC defined on alpha and remove warnings from libpty.h +- add installation of info docs +- remove krb4 compat patch because it doesn't fix workstation-side servers + +* Mon Dec 20 1999 Nalin Dahyabhai +- remove hesiod dependency at build-time + +* Sun Dec 19 1999 Nalin Dahyabhai +- rebuild on 1.1.1 + +* Thu Oct 7 1999 Nalin Dahyabhai +- clean up init script for server, verify that it works [jlkatz] +- clean up rotation script so that rc likes it better +- add clean stanza + +* Mon Oct 4 1999 Nalin Dahyabhai +- backed out ncurses and makeshlib patches +- update for krb5-1.1 +- add KDC rotation to rc.boot, based on ideas from Michael's C version + +* Mon Sep 27 1999 Nalin Dahyabhai +- added -lncurses to telnet and telnetd makefiles + +* Mon Jul 5 1999 Nalin Dahyabhai +- added krb5.csh and krb5.sh to /etc/profile.d + +* Tue Jun 22 1999 Nalin Dahyabhai +- broke out configuration files + +* Mon Jun 14 1999 Nalin Dahyabhai +- fixed server package so that it works now + +* Sat May 15 1999 Nalin Dahyabhai +- started changelog (previous package from zedz.net) +- updated existing 1.0.5 RPM from Eos Linux to krb5 1.0.6 +- added --force to makeinfo commands to skip errors during build