]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Map CANTLOCK_DB to SVC_UNAVAILABLE in krb5kdc
authorNicolas Williams <nico@cryptonector.com>
Wed, 12 Sep 2012 02:32:28 +0000 (21:32 -0500)
committerGreg Hudson <ghudson@mit.edu>
Wed, 12 Sep 2012 18:48:41 +0000 (14:48 -0400)
The KDC should not return KRB5KRB_ERR_GENERIC (KRB_ERR_GENERIC) when the
KDB plugin returns KRB5_KDB_CANTLOCK_DB: it should return
KRB5KDC_ERR_SVC_UNAVAILABLE (KDC_ERR_SVC_UNAVAILABLE) instead.  This
allows clients to immediately fallback onto other KDCs.

When we switch to using blocking locks in the db2 KDB backend we'll very
rarely hit this code path, perhaps only when racing against a kdb5_util load.
Other KDB backends might still return KRB5_KDB_CANTLOCK_DB often enough that
this change is desirable.

ticket: 7358 (new)

src/kdc/do_as_req.c
src/kdc/do_tgs_req.c

index 363d3ab95f9211406dc654d853217fd1256fb9fd..81db7675662e9a942542c049b1cc5a46ccbf5ca2 100644 (file)
@@ -539,6 +539,8 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
     }
     errcode = krb5_db_get_principal(kdc_context, state->request->client,
                                     state->c_flags, &state->client);
+    if (errcode == KRB5_KDB_CANTLOCK_DB)
+        errcode = KRB5KDC_ERR_SVC_UNAVAILABLE;
     if (errcode == KRB5_KDB_NOENTRY) {
         state->status = "CLIENT_NOT_FOUND";
         if (vague_errors)
@@ -570,6 +572,8 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
     }
     errcode = krb5_db_get_principal(kdc_context, state->request->server,
                                     s_flags, &state->server);
+    if (errcode == KRB5_KDB_CANTLOCK_DB)
+        errcode = KRB5KDC_ERR_SVC_UNAVAILABLE;
     if (errcode == KRB5_KDB_NOENTRY) {
         state->status = "SERVER_NOT_FOUND";
         errcode = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
index 56d9869c160d9608497640855b86b3a886c0be50..e9cb4212a7647492b1c05e9af711215b69d8359b 100644 (file)
@@ -215,6 +215,8 @@ ref_tgt_again:
 
     errcode = krb5_db_get_principal(kdc_context, request->server,
                                     s_flags, &server);
+    if (errcode == KRB5_KDB_CANTLOCK_DB)
+        errcode = KRB5KDC_ERR_SVC_UNAVAILABLE;
     if (errcode && errcode != KRB5_KDB_NOENTRY) {
         status = "LOOKING_UP_SERVER";
         goto cleanup;
@@ -1078,6 +1080,8 @@ find_alternate_tgs(krb5_kdc_req *request, krb5_db_entry **server_ptr)
         krb5_princ_set_realm(kdc_context, *pl2,
                              krb5_princ_realm(kdc_context, tgs_server));
         retval = krb5_db_get_principal(kdc_context, *pl2, 0, &server);
+        if (retval == KRB5_KDB_CANTLOCK_DB)
+            retval = KRB5KDC_ERR_SVC_UNAVAILABLE;
         krb5_princ_set_realm(kdc_context, *pl2, &tmp);
         if (retval == KRB5_KDB_NOENTRY)
             continue;