r22529@squish: raeburn | 2009-08-12 13:49:45 -0400
authorKen Raeburn <raeburn@mit.edu>
Wed, 12 Aug 2009 17:58:24 +0000 (17:58 +0000)
committerKen Raeburn <raeburn@mit.edu>
Wed, 12 Aug 2009 17:58:24 +0000 (17:58 +0000)
 .
 r22530@squish:  raeburn | 2009-08-12 13:55:57 -0400
 Change KRBCONF_KDC_MODIFIES_KDB to a mostly run-time option.

 Change all code conditionals to test a new global variable, the
 initial value of which is based on KRBCONF_KDC_MODIFIES_KDB.  There is
 currently no way to alter the value from the command line; that will
 presumably be desired later.

 Change initialize_realms to store db_args in a global variable.  In
 process_as_req, call db_open instead of the old set_name + init.
 Don't reopen if an error is reported by krb5_db_fini.

 Add a test of running kinit with an incorrect password, to trigger a
 kdb update if enabled.
 r22531@squish:  raeburn | 2009-08-12 13:58:13 -0400
 Fix trailing whitespace.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@22518 dc483132-0cff-0310-8789-dd5450dbe970

src/kdc/do_as_req.c
src/kdc/extern.c
src/kdc/extern.h
src/kdc/main.c
src/tests/dejagnu/krb-standalone/standalone.exp

index 0c4c923597f55f57deaa34bda09f12dbb05fafea..52fbda5d606798ebb0c0e0b9f3ade88b7dbd1008 100644 (file)
@@ -393,20 +393,20 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
            if (errcode == KRB5KDC_ERR_PREAUTH_FAILED)
                get_preauth_hint_list(request, &client, &server, &e_data);
            
-#ifdef KRBCONF_KDC_MODIFIES_KDB
-           /*
-            * Note: this doesn't work if you're using slave servers!!!
-            * It also causes the database to be modified (and thus
-            * need to be locked) frequently.
-            */
-           if (client.fail_auth_count < KRB5_MAX_FAIL_COUNT) {
-               client.fail_auth_count = client.fail_auth_count + 1;
-               if (client.fail_auth_count == KRB5_MAX_FAIL_COUNT) { 
-                   client.attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
+           if (kdc_modifies_kdb) {
+               /*
+                * Note: this doesn't work if you're using slave servers!!!
+                * It also causes the database to be modified (and thus
+                * need to be locked) frequently.
+                */
+               if (client.fail_auth_count < KRB5_MAX_FAIL_COUNT) {
+                   client.fail_auth_count = client.fail_auth_count + 1;
+                   if (client.fail_auth_count == KRB5_MAX_FAIL_COUNT) {
+                       client.attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
+                   }
                }
+               client.last_failed = kdc_time;
            }
-           client.last_failed = kdc_time;
-#endif
            update_client = 1;
            status = "PREAUTH_FAILED";
 #ifdef KRBCONF_VAGUE_ERRORS
@@ -622,13 +622,13 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
     memset(reply.enc_part.ciphertext.data, 0, reply.enc_part.ciphertext.length);
     free(reply.enc_part.ciphertext.data);
 
-#ifdef KRBCONF_KDC_MODIFIES_KDB
-    /*
-     * If we get this far, we successfully did the AS_REQ.
-     */
-    client.last_success = kdc_time;
-    client.fail_auth_count = 0;
-#endif /* KRBCONF_KDC_MODIFIES_KDB */
+    if (kdc_modifies_kdb) {
+       /*
+        * If we get this far, we successfully did the AS_REQ.
+        */
+       client.last_success = kdc_time;
+       client.fail_auth_count = 0;
+    }
     update_client = 1;
 
     log_as_req(from, request, &reply, &client, cname, &server, sname,
@@ -684,21 +684,22 @@ egress:
     if (sname != NULL)
            free(sname);
     if (c_nprincs) {
-#ifdef KRBCONF_KDC_MODIFIES_KDB
-       if (update_client) {
-           krb5_db_put_principal(kdc_context, &client, &c_nprincs);
-           /*
-            * ptooey.  We want krb5_db_sync() or something like that.
-            */
-           krb5_db_fini(kdc_context);
-           if (kdc_active_realm->realm_dbname)
-               krb5_db_set_name(kdc_active_realm->realm_context,
-                                kdc_active_realm->realm_dbname);
-           krb5_db_init(kdc_context);
-           /* Reset master key */
-           krb5_db_set_mkey(kdc_context, &kdc_active_realm->realm_mkey);
+       if (kdc_modifies_kdb) {
+           if (update_client) {
+               krb5_error_code errcode2;
+
+               krb5_db_put_principal(kdc_context, &client, &c_nprincs);
+               /*
+                * ptooey.  We want krb5_db_sync() or something like that.
+                */
+               errcode2 = krb5_db_fini(kdc_context);
+               if (errcode2 == 0)
+                   errcode2 = krb5_db_open(kdc_context, db_args,
+                                           KRB5_KDB_OPEN_RW|KRB5_KDB_SRV_TYPE_KDC);
+               /* Reset master key */
+               krb5_db_set_mkey(kdc_context, &kdc_active_realm->realm_mkey);
+           }
        }
-#endif /* KRBCONF_KDC_MODIFIES_KDB */
        krb5_db_free_principal(kdc_context, &client, c_nprincs);
     }
     if (s_nprincs)
index 7ebc7bb3a64e5f70c1297a1fab63877176eeaef4..3427bcfff7c8ddb688d760e355e839675bb28654 100644 (file)
@@ -38,6 +38,11 @@ krb5_data empty_string = {0, 0, ""};
 krb5_timestamp kdc_infinity = KRB5_INT32_MAX; /* XXX */
 krb5_rcache    kdc_rcache = (krb5_rcache) NULL;
 krb5_keyblock  psr_key;
+#ifdef KRBCONF_KDC_MODIFIES_KDB
+const int      kdc_modifies_kdb = 1;
+#else
+const int      kdc_modifies_kdb = 0;
+#endif
 krb5_int32     max_dgram_reply_size = MAX_DGRAM_SIZE;
 
 volatile int signal_requests_exit = 0; /* gets set when signal hits */
index 88e8b0ddef956ab18361def47f617a26793b8056..87cc1bfa0cd944cc8971faf6f5f8146900966409 100644 (file)
@@ -101,6 +101,8 @@ extern krb5_data    empty_string;   /* an empty string */
 extern krb5_timestamp  kdc_infinity;   /* greater than all other timestamps */
 extern krb5_rcache     kdc_rcache;     /* replay cache */
 extern krb5_keyblock   psr_key;        /* key for predicted sam response */
+extern const int       kdc_modifies_kdb;
+extern char            **db_args;
 extern krb5_int32      max_dgram_reply_size; /* maximum datagram size */
 
 extern volatile int signal_requests_exit;
index b54aba5302a8162bf11ebd3dcad4d6eba2fc1bcc..83c7de61ee8a1b7caf6ea05a65a5030847972708 100644 (file)
@@ -381,11 +381,10 @@ init_realm(kdc_realm_t *rdp, char *realm, char *def_mpname,
     }
 
     /* first open the database  before doing anything */
-#ifdef KRBCONF_KDC_MODIFIES_KDB
-    kdb_open_flags = KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_KDC;
-#else
-    kdb_open_flags = KRB5_KDB_OPEN_RO | KRB5_KDB_SRV_TYPE_KDC;
-#endif
+    if (kdc_modifies_kdb)
+       kdb_open_flags = KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_KDC;
+    else
+       kdb_open_flags = KRB5_KDB_OPEN_RO | KRB5_KDB_SRV_TYPE_KDC;
     if ((kret = krb5_db_open(rdp->realm_context, db_args, kdb_open_flags))) {
        kdc_err(rdp->realm_context, kret,
                "while initializing database for realm %s", realm);
@@ -558,6 +557,7 @@ usage(char *name)
     return;
 }
 
+char               **db_args      = NULL;
 void
 initialize_realms(krb5_context kcontext, int argc, char **argv)
 {
@@ -574,7 +574,6 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
     char               *default_tcp_ports = 0;
     krb5_pointer       aprof;
     const char         *hierarchy[3];
-    char               **db_args      = NULL;
     char                *no_refrls = NULL;
     char                *host_based_srvcs = NULL;
     int                  db_args_size = 0;
index ad14bcc7d0ccd25b63406adaff4c454ac273fda9..ca1c34d2ff04314c4aa8e3cd589f06f6bafcca9d 100644 (file)
@@ -74,6 +74,56 @@ proc dump_and_reload {} {
     }
 }
 
+proc kinit_wrong_pw { name badpass } {
+    global REALMNAME
+    global KINIT
+    global spawn_id
+
+    # Use kinit to get a ticket.
+       #
+       # For now always get forwardable tickets. Later when we need to make
+       # tests that distiguish between forwardable tickets and otherwise
+       # we should but another option to this proc. --proven
+       #
+    spawn $KINIT -5 -f $name@$REALMNAME
+    expect {
+       "Password for $name@$REALMNAME:" {
+           verbose "kinit started"
+       }
+       timeout {
+           fail "kinit bad pw"
+           return 0
+       }
+       eof {
+           fail "kinit bad pw"
+           return 0
+       }
+    }
+    send "$badpass\r"
+    expect {
+       "Password incorrect while getting initial credentials" {
+       }
+       timeout {
+           fail "kinit bad pw"
+           # kill it?
+       }
+       eof {
+           fail "kinit bad pw"
+           return
+       }
+    }
+    expect eof
+
+    set status_list [wait -i $spawn_id]
+    catch "close -i $spawn_id"
+    verbose -log "exit status: $status_list"
+    if { [lindex $status_list 2] != 0 || [lindex $status_list 3] != 0 } {
+       pass "kinit bad pw"
+    } else {
+       fail "kinit bad pw"
+    }
+}
+
 proc doit { } {
     global REALMNAME
     global KLIST
@@ -140,6 +190,9 @@ proc doit { } {
     verbose "wait -i $spawn_id returned $k_stat (kadmin addpol)"
     catch "close -i $spawn_id"
 
+    # Test use of wrong password.
+    kinit_wrong_pw krbtest/admin wrongpassword
+
     setup_kerberos_env client
     # Use kinit to get a ticket.
     if ![kinit krbtest/admin adminpass$KEY 1] {