Check in Nalin's patch, and a test case for changing passwords via kinit
authorKen Raeburn <raeburn@mit.edu>
Tue, 4 Nov 2008 01:50:02 +0000 (01:50 +0000)
committerKen Raeburn <raeburn@mit.edu>
Tue, 4 Nov 2008 01:50:02 +0000 (01:50 +0000)
when +needchange is set.  Update dependencies.

ticket: 5867

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

src/lib/krb5/os/Makefile.in
src/lib/krb5/os/changepw.c
src/tests/dejagnu/krb-standalone/pwchange.exp [new file with mode: 0644]

index 01f60836f50c64de07b99e8bd6497b8d32643ed4..dc7aeaead26aeef4750a97069de4d6d042065a03 100644 (file)
@@ -306,7 +306,8 @@ changepw.so changepw.po $(OUTPRE)changepw.$(OBJEXT): \
   $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \
   $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \
   $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \
-  $(SRCTOP)/include/socket-utils.h changepw.c os-proto.h
+  $(SRCTOP)/include/socket-utils.h $(srcdir)/../krb/auth_con.h \
+  changepw.c os-proto.h
 dnsglue.so dnsglue.po $(OUTPRE)dnsglue.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
   $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
   $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \
index d0a8dce75e7086b6f70a5c8e0a976b60b3e72278..5bd5b8678193ea2da6a49879e731d2eb9c09a214 100644 (file)
@@ -34,6 +34,7 @@
 #include "k5-int.h"
 #include "os-proto.h"
 #include "cm.h"
+#include "../krb/auth_con.h"
 
 #include <stdio.h>
 #include <errno.h>
@@ -48,6 +49,7 @@ struct sendto_callback_context {
     krb5_principal     set_password_for;
     char               *newpw;
     krb5_data          ap_req;
+    krb5_ui_4           remote_seq_num, local_seq_num;
 };
 
 /*
@@ -159,6 +161,9 @@ static int kpasswd_sendto_msg_callback(struct conn_state *conn, void *callback_c
                                       &local_kaddr, NULL))) 
        goto cleanup;
 
+    ctx->auth_context->remote_seq_number = ctx->remote_seq_num;
+    ctx->auth_context->local_seq_number = ctx->local_seq_num;
+
     if (ctx->set_password_for)
        code = krb5int_mk_setpw_req(ctx->context, 
                                    ctx->auth_context, 
@@ -226,6 +231,9 @@ krb5_change_set_password(krb5_context context, krb5_creds *creds, char *newpw,
                                     &callback_ctx.ap_req)))
        goto cleanup;
 
+    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 {
        if ((code = krb5_locate_kpasswd(callback_ctx.context,
                                        krb5_princ_realm(callback_ctx.context,
diff --git a/src/tests/dejagnu/krb-standalone/pwchange.exp b/src/tests/dejagnu/krb-standalone/pwchange.exp
new file mode 100644 (file)
index 0000000..486ec05
--- /dev/null
@@ -0,0 +1,141 @@
+# Password-changing Kerberos test.
+# This is a DejaGnu test script.
+
+# Set up the Kerberos files and environment.
+if {![get_hostname] || ![setup_kerberos_files] || ![setup_kerberos_env]} {
+    return
+}
+
+# Initialize the Kerberos database.  The argument tells
+# setup_kerberos_db that it is being called from here.
+if ![setup_kerberos_db 0] {
+    return
+}
+
+# We are about to start up a couple of daemon processes.  We do all
+# the rest of the tests inside a proc, so that we can easily kill the
+# processes when the procedure ends.
+
+proc kinit_expecting_pwchange { name pass newpass } {
+    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"
+           return 0
+       }
+       eof {
+           fail "kinit"
+           return 0
+       }
+    }
+    send "$pass\r"
+    expect {
+       "Enter new password: " { }
+       timeout {
+           fail "kinit (new password prompt)"
+           return 0
+       }
+       eof {
+           fail "kinit (new password prompt)"
+           return 0
+       }
+    }
+    send "$newpass\r"
+    expect {
+       " again: " { }
+       timeout {
+           fail "kinit (new password prompt2)"
+           return 0
+       }
+       eof {
+           fail "kinit (new password prompt2)"
+           return 0
+       }
+    }
+    send "$newpass\r"
+    expect eof
+    if ![check_exit_status kinit] {
+       return 0
+    }
+
+    return 1
+}
+
+proc doit { } {
+    global REALMNAME
+    global KLIST
+    global KDESTROY
+    global KEY
+    global KADMIN_LOCAL
+    global KTUTIL
+    global hostname
+    global tmppwd
+    global spawn_id
+    global supported_enctypes
+    global KRBIV
+    global portbase
+    global mode
+
+    # Start up the kerberos and kadmind daemons.
+    if ![start_kerberos_daemons 0] {
+       return
+    }
+
+    # Use kadmin to add a key.
+    if ![add_kerberos_key pwchanger 0] {
+       return
+    }
+
+    spawn $KADMIN_LOCAL -q "modprinc +needchange pwchanger"
+    catch expect_after
+    expect {
+       timeout {
+           fail "kadmin.local modprinc +needchange"
+       }
+       eof {
+           pass "kadmin.local modprinc +needchange"
+       }
+    }
+    set k_stat [wait -i $spawn_id]
+    verbose "wait -i $spawn_id returned $k_stat (kadmin modprinc +needchange)"
+    catch "close -i $spawn_id"
+
+    if ![kinit_expecting_pwchange pwchanger pwchanger$KEY floople] {
+       return
+    }
+    pass "kinit (password change)"
+    if ![kinit pwchanger floople 0] {
+       return
+    }
+    pass "kinit (new password)"
+
+    # Destroy the ticket.
+    spawn $KDESTROY -5
+    if ![check_exit_status "kdestroy"] {
+       return
+    }
+    pass "kdestroy"
+}
+
+set status [catch doit msg]
+
+stop_kerberos_daemons
+
+if { $status != 0 } {
+    send_error "ERROR: error in pwchange.exp\n"
+    send_error "$msg\n"
+    exit 1
+}