s4-librpc: use cli_credentials_failed_kerberos_login to cope with stale tickets
authorAndrew Tridgell <tridge@samba.org>
Wed, 31 Oct 2012 07:44:23 +0000 (18:44 +1100)
committerAndrew Tridgell <tridge@samba.org>
Thu, 1 Nov 2012 04:40:40 +0000 (15:40 +1100)
This allows our RPC client code to cope with a kerberos server
changing password while we have a valid service ticket

Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>

source4/librpc/rpc/dcerpc_util.c

index 1217e3460773cc4df7f1c2ef8d34cebe7b83b344..15847efa9df0a3ac3674da275c14acfc298217a9 100644 (file)
@@ -30,6 +30,7 @@
 #include "librpc/gen_ndr/ndr_misc.h"
 #include "librpc/rpc/dcerpc_proto.h"
 #include "auth/credentials/credentials.h"
+#include "auth/gensec/gensec.h"
 #include "param/param.h"
 #include "librpc/rpc/rpc_common.h"
 
@@ -335,6 +336,7 @@ struct pipe_auth_state {
        const struct ndr_interface_table *table;
        struct loadparm_context *lp_ctx;
        struct cli_credentials *credentials;
+       unsigned int logon_retries;
 };
 
 
@@ -395,7 +397,19 @@ static void continue_auth_auto(struct composite_context *ctx)
                composite_continue(c, sec_conn_req, continue_ntlmssp_connection, c);
                return;
        } else if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) {
-               if (cli_credentials_wrong_password(s->credentials)) {
+               const char *principal;
+
+               principal = gensec_get_target_principal(s->pipe->conn->security_state.generic_state);
+               if (principal == NULL) {
+                       const char *hostname = gensec_get_target_hostname(s->pipe->conn->security_state.generic_state);
+                       const char *service  = gensec_get_target_service(s->pipe->conn->security_state.generic_state);
+                       if (hostname != NULL && service != NULL) {
+                               principal = talloc_asprintf(c, "%s/%s", service, hostname);
+                       }
+               }
+
+               if (cli_credentials_failed_kerberos_login(s->credentials, principal, &s->logon_retries) ||
+                   cli_credentials_wrong_password(s->credentials)) {
                        /*
                         * Retry SPNEGO with a better password
                         * send a request for secondary rpc connection