Univention Bugzilla – Attachment 4786 Details for
Bug 29083
Reinstall eines Samba 4 Servers
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
kerberos-retry.patch
kerberos-retry.patch (text/plain), 26.02 KB, created by
Arvid Requate
on 2012-11-13 12:33 CET
(
hide
)
Description:
kerberos-retry.patch
Filename:
MIME Type:
Creator:
Arvid Requate
Created:
2012-11-13 12:33 CET
Size:
26.02 KB
patch
obsolete
>From ef289fd3858813c0fdaf0913aa2d578e63707cf0 Mon Sep 17 00:00:00 2001 >From: Andrew Tridgell <tridge@samba.org> >Date: Wed, 31 Oct 2012 17:58:20 +1100 >Subject: [PATCH 01/10] auth: added cli_credentials_failed_kerberos_login() > >this is used to support retrying kerberos connections after removing a >ccache entry, to cope with a server being re-built while our client >still has a valid service ticket > >Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org> >--- > auth/credentials/credentials.h | 3 ++ > auth/credentials/credentials_krb5.c | 61 +++++++++++++++++++++++++++++++++++++ > 2 files changed, 64 insertions(+) > >diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h >index 0bcfd61..dbc014f 100644 >--- a/auth/credentials/credentials.h >+++ b/auth/credentials/credentials.h >@@ -182,6 +182,9 @@ int cli_credentials_get_named_ccache(struct cli_credentials *cred, > struct loadparm_context *lp_ctx, > char *ccache_name, > struct ccache_container **ccc, const char **error_string); >+bool cli_credentials_failed_kerberos_login(struct cli_credentials *cred, >+ const char *principal, >+ unsigned int *count); > int cli_credentials_get_keytab(struct cli_credentials *cred, > struct loadparm_context *lp_ctx, > struct keytab_container **_ktc); >diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c >index 459e948..cc51f56 100644 >--- a/auth/credentials/credentials_krb5.c >+++ b/auth/credentials/credentials_krb5.c >@@ -212,6 +212,67 @@ _PUBLIC_ int cli_credentials_set_ccache(struct cli_credentials *cred, > return 0; > } > >+/* >+ * Indicate the we failed to log in to this service/host with these >+ * credentials. The caller passes an unsigned int which they >+ * initialise to the number of times they would like to retry. >+ * >+ * This method is used to support re-trying with freshly fetched >+ * credentials in case a server is rebuilt while clients have >+ * non-expired tickets. When the client code gets a logon failure they >+ * throw away the existing credentials for the server and retry. >+ */ >+_PUBLIC_ bool cli_credentials_failed_kerberos_login(struct cli_credentials *cred, >+ const char *principal, >+ unsigned int *count) >+{ >+ struct ccache_container *ccc; >+ krb5_creds creds, creds2; >+ int ret; >+ >+ if (principal == NULL) { >+ /* no way to delete if we don't know the principal */ >+ return false; >+ } >+ >+ ccc = cred->ccache; >+ if (ccc == NULL) { >+ /* not a kerberos connection */ >+ return false; >+ } >+ >+ if (*count > 0) { >+ /* We have already tried discarding the credentials */ >+ return false; >+ } >+ (*count)++; >+ >+ ZERO_STRUCT(creds); >+ ret = krb5_parse_name(ccc->smb_krb5_context->krb5_context, principal, &creds.server); >+ if (ret != 0) { >+ return false; >+ } >+ >+ ret = krb5_cc_retrieve_cred(ccc->smb_krb5_context->krb5_context, ccc->ccache, KRB5_TC_MATCH_SRV_NAMEONLY, &creds, &creds2); >+ if (ret != 0) { >+ /* don't retry - we didn't find these credentials to remove */ >+ return false; >+ } >+ >+ ret = krb5_cc_remove_cred(ccc->smb_krb5_context->krb5_context, ccc->ccache, KRB5_TC_MATCH_SRV_NAMEONLY, &creds); >+ krb5_free_cred_contents(ccc->smb_krb5_context->krb5_context, &creds2); >+ if (ret != 0) { >+ /* don't retry - we didn't find these credentials to >+ * remove. Note that with the current backend this >+ * never happens, as it always returns 0 even if the >+ * creds don't exist, which is why we do a separate >+ * krb5_cc_retrieve_cred() above. >+ */ >+ return false; >+ } >+ return true; >+} >+ > > static int cli_credentials_new_ccache(struct cli_credentials *cred, > struct loadparm_context *lp_ctx, >-- >1.7.11.7 > > >From 16500bf020e726789476ec54a8fd0d22d796b5f2 Mon Sep 17 00:00:00 2001 >From: Andrew Tridgell <tridge@samba.org> >Date: Wed, 31 Oct 2012 17:59:54 +1100 >Subject: [PATCH 02/10] libcli: use cli_credentials_failed_kerberos_login() to > cope with server changes > >if a server changes while we have a valid ticket we want to retry >after removing the ccache entry. > >Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org> >--- > source4/libcli/smb_composite/sesssetup.c | 17 +++++++++++++++-- > 1 file changed, 15 insertions(+), 2 deletions(-) > >diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c >index 0023013..4be1ea0 100644 >--- a/source4/libcli/smb_composite/sesssetup.c >+++ b/source4/libcli/smb_composite/sesssetup.c >@@ -39,6 +39,7 @@ struct sesssetup_state { > NTSTATUS gensec_status; > struct smb_composite_sesssetup *io; > struct smbcli_request *req; >+ unsigned int logon_retries; > }; > > static int sesssetup_state_destructor(struct sesssetup_state *state) >@@ -123,7 +124,7 @@ static void request_handler(struct smbcli_request *req) > case RAW_SESSSETUP_NT1: > state->io->out.vuid = state->setup.nt1.out.vuid; > if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { >- /* we neet to reset the vuid for a new try */ >+ /* we need to reset the vuid for a new try */ > session->vuid = 0; > if (cli_credentials_wrong_password(state->io->in.credentials)) { > nt_status = session_setup_nt1(c, session, >@@ -144,9 +145,21 @@ static void request_handler(struct smbcli_request *req) > case RAW_SESSSETUP_SPNEGO: > state->io->out.vuid = state->setup.spnego.out.vuid; > if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { >+ const char *principal; >+ > /* we need to reset the vuid for a new try */ > session->vuid = 0; >- if (cli_credentials_wrong_password(state->io->in.credentials)) { >+ >+ principal = gensec_get_target_principal(session->gensec); >+ if (principal == NULL) { >+ const char *hostname = gensec_get_target_hostname(session->gensec); >+ const char *service = gensec_get_target_service(session->gensec); >+ if (hostname != NULL && service != NULL) { >+ principal = talloc_asprintf(state, "%s/%s", service, hostname); >+ } >+ } >+ if (cli_credentials_failed_kerberos_login(state->io->in.credentials, principal, &state->logon_retries) || >+ cli_credentials_wrong_password(state->io->in.credentials)) { > nt_status = session_setup_spnego(c, session, > state->io, > &state->req); >-- >1.7.11.7 > > >From c45eb123a1150acc27c5b2a983afb5329780857e Mon Sep 17 00:00:00 2001 >From: Andrew Tridgell <tridge@samba.org> >Date: Wed, 31 Oct 2012 18:00:43 +1100 >Subject: [PATCH 03/10] test_chgdpass: added test for kerberos retry > >this tests that we correctly retry with a new ccache entry when a >server changes its password while we have a valid ticket > >Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org> >--- > testprogs/blackbox/test_chgdcpass.sh | 5 +++++ > 1 file changed, 5 insertions(+) > >diff --git a/testprogs/blackbox/test_chgdcpass.sh b/testprogs/blackbox/test_chgdcpass.sh >index 37f9049..ba3d851 100755 >--- a/testprogs/blackbox/test_chgdcpass.sh >+++ b/testprogs/blackbox/test_chgdcpass.sh >@@ -59,6 +59,11 @@ testit "change dc password" $samba4srcdir/scripting/devel/chgtdcpass -s $PROVDIR > #This is important because it shows that the old ticket remains valid (as it must) for incoming connections after the DC password is changed > test_smbclient "Test login with kerberos ccache after password change" 'ls' -k yes || failed=`expr $failed + 1` > >+testit "change dc password (2nd time)" $samba4srcdir/scripting/devel/chgtdcpass -s $PROVDIR/etc/smb.conf || failed=`expr $failed + 1` >+ >+#This is important because it shows that the old ticket remains valid (as it must) for incoming connections after the DC pass >+test_smbclient "Test login with kerberos ccache after 2nd password change" 'ls' -k yes || failed=`expr $failed + 1` >+ > #This confirms that the DC password is valid for a kinit too > testit "kinit with keytab" $samba4kinit $enctype -t $PROVDIR/private/secrets.keytab --use-keytab $USERNAME || failed=`expr $failed + 1` > test_smbclient "Test login with kerberos ccache with fresh kinit" 'ls' -k yes || failed=`expr $failed + 1` >-- >1.7.11.7 > > >From ca344aad013eebd82f1d82e4ee093dc799911e5c Mon Sep 17 00:00:00 2001 >From: Andrew Tridgell <tridge@samba.org> >Date: Wed, 31 Oct 2012 18:44:23 +1100 >Subject: [PATCH 04/10] s4-librpc: use cli_credentials_failed_kerberos_login > to cope with stale tickets > >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 | 16 +++++++++++++++- > 1 file changed, 15 insertions(+), 1 deletion(-) > >diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c >index 1217e34..15847ef 100644 >--- a/source4/librpc/rpc/dcerpc_util.c >+++ b/source4/librpc/rpc/dcerpc_util.c >@@ -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 >-- >1.7.11.7 > > >From acdf884388bd5ca99b42cda151c7a02f7b43bb3f Mon Sep 17 00:00:00 2001 >From: Andrew Tridgell <tridge@samba.org> >Date: Wed, 31 Oct 2012 18:45:25 +1100 >Subject: [PATCH 05/10] test_chgdpass: use drs bind to test password change on > RPC > >Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org> >--- > testprogs/blackbox/test_chgdcpass.sh | 25 +++++++++++++++++++++++++ > 1 file changed, 25 insertions(+) > >diff --git a/testprogs/blackbox/test_chgdcpass.sh b/testprogs/blackbox/test_chgdcpass.sh >index ba3d851..d588394 100755 >--- a/testprogs/blackbox/test_chgdcpass.sh >+++ b/testprogs/blackbox/test_chgdcpass.sh >@@ -45,6 +45,21 @@ test_smbclient() { > return $status > } > >+test_drsbind() { >+ name="$1" >+ shift >+ echo "test: $name" >+ echo $VALGRIND $samba4bindir/samba-tool drs bind $SERVER -k yes $@ >+ $VALGRIND $samba4bindir/samba-tool drs bind $SERVER -k yes $@ >+ status=$? >+ if [ x$status = x0 ]; then >+ echo "success: $name" >+ else >+ echo "failure: $name" >+ fi >+ return $status >+} >+ > enctype="-e $ENCTYPE" > > KRB5CCNAME="$PREFIX/tmpccache" >@@ -54,16 +69,26 @@ testit "kinit with keytab" $samba4kinit $enctype -t $PROVDIR/private/secrets.key > > #This is important because it puts the ticket for the old KVNO and password into a local ccache > test_smbclient "Test login with kerberos ccache before password change" 'ls' -k yes || failed=`expr $failed + 1` >+ >+#check that drs options works before we change the password (prime the ccache) >+test_drsbind "Test drs options with with kerberos ccache" || failed=`expr $failed + 1` >+ > testit "change dc password" $samba4srcdir/scripting/devel/chgtdcpass -s $PROVDIR/etc/smb.conf || failed=`expr $failed + 1` > > #This is important because it shows that the old ticket remains valid (as it must) for incoming connections after the DC password is changed > test_smbclient "Test login with kerberos ccache after password change" 'ls' -k yes || failed=`expr $failed + 1` > >+#check that drs options works after we change the password >+test_drsbind "Test drs options with new password" || failed=`expr $failed + 1` >+ > testit "change dc password (2nd time)" $samba4srcdir/scripting/devel/chgtdcpass -s $PROVDIR/etc/smb.conf || failed=`expr $failed + 1` > > #This is important because it shows that the old ticket remains valid (as it must) for incoming connections after the DC pass > test_smbclient "Test login with kerberos ccache after 2nd password change" 'ls' -k yes || failed=`expr $failed + 1` > >+#check that drs options works after we change the password a 2nd time >+test_drsbind "Test drs options after 2nd password change" || failed=`expr $failed + 1` >+ > #This confirms that the DC password is valid for a kinit too > testit "kinit with keytab" $samba4kinit $enctype -t $PROVDIR/private/secrets.keytab --use-keytab $USERNAME || failed=`expr $failed + 1` > test_smbclient "Test login with kerberos ccache with fresh kinit" 'ls' -k yes || failed=`expr $failed + 1` >-- >1.7.11.7 > > >From d2536bfc4ad5957421297cf583526d940eaf6de6 Mon Sep 17 00:00:00 2001 >From: Andrew Tridgell <tridge@samba.org> >Date: Thu, 1 Nov 2012 13:30:47 +1100 >Subject: [PATCH 06/10] s4-librpc: try a 2nd logon for more error cases > >not all servers give LOGON_FAILURE on authentication failures, so we >need to do the retry with a new ticket on a wider range of error types > >Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org> >--- > source4/librpc/rpc/dcerpc_util.c | 13 ++++++++++--- > 1 file changed, 10 insertions(+), 3 deletions(-) > >diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c >index 15847ef..2a0c405 100644 >--- a/source4/librpc/rpc/dcerpc_util.c >+++ b/source4/librpc/rpc/dcerpc_util.c >@@ -396,7 +396,13 @@ static void continue_auth_auto(struct composite_context *ctx) > s->binding); > composite_continue(c, sec_conn_req, continue_ntlmssp_connection, c); > return; >- } else if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { >+ } else if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE) || >+ NT_STATUS_EQUAL(c->status, NT_STATUS_UNSUCCESSFUL)) { >+ /* >+ try a second time on any error. We don't just do it >+ on LOGON_FAILURE as some servers will give a >+ NT_STATUS_UNSUCCESSFUL on a authentication error on RPC >+ */ > const char *principal; > > principal = gensec_get_target_principal(s->pipe->conn->security_state.generic_state); >@@ -408,8 +414,9 @@ static void continue_auth_auto(struct composite_context *ctx) > } > } > >- if (cli_credentials_failed_kerberos_login(s->credentials, principal, &s->logon_retries) || >- cli_credentials_wrong_password(s->credentials)) { >+ if ((cli_credentials_failed_kerberos_login(s->credentials, principal, &s->logon_retries) || >+ cli_credentials_wrong_password(s->credentials)) && >+ s->binding->endpoint != NULL) { > /* > * Retry SPNEGO with a better password > * send a request for secondary rpc connection >-- >1.7.11.7 > > >From 4689488595348bca43b73d426ebf485bb96ca3b6 Mon Sep 17 00:00:00 2001 >From: Andrew Tridgell <tridge@samba.org> >Date: Thu, 1 Nov 2012 13:31:47 +1100 >Subject: [PATCH 07/10] samba-tool: "drs options" does not need a samdb > connection > >this gives us a handy pure RPC client test for use in blackbox testing > >Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org> >--- > source4/scripting/python/samba/netcmd/drs.py | 1 - > 1 file changed, 1 deletion(-) > >diff --git a/source4/scripting/python/samba/netcmd/drs.py b/source4/scripting/python/samba/netcmd/drs.py >index 074b7af..ff8d830 100644 >--- a/source4/scripting/python/samba/netcmd/drs.py >+++ b/source4/scripting/python/samba/netcmd/drs.py >@@ -361,7 +361,6 @@ class cmd_drs_bind(Command): > self.creds = credopts.get_credentials(self.lp, fallback_machine=True) > > drsuapi_connect(self) >- samdb_connect(self) > > bind_info = drsuapi.DsBindInfoCtr() > bind_info.length = 28 >-- >1.7.11.7 > > >From 3ee7d7153d66a035c2a95daeb444dc398b3080ef Mon Sep 17 00:00:00 2001 >From: Andrew Tridgell <tridge@samba.org> >Date: Thu, 1 Nov 2012 13:42:52 +1100 >Subject: [PATCH 08/10] s4-librpc: set error code to LOGON_FAILURE on RPC > fault with access denied > >this allows the client code to trigger a retry with a new password >callback for NTLM connections > >Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org> >--- > source4/librpc/rpc/dcerpc.c | 9 +++++++-- > 1 file changed, 7 insertions(+), 2 deletions(-) > >diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c >index 4440395..e653cba 100644 >--- a/source4/librpc/rpc/dcerpc.c >+++ b/source4/librpc/rpc/dcerpc.c >@@ -2148,8 +2148,13 @@ static void dcerpc_alter_context_recv_handler(struct rpc_request *subreq, > if (pkt->ptype == DCERPC_PKT_FAULT) { > DEBUG(5,("dcerpc: alter_resp - rpc fault: %s\n", > dcerpc_errstr(state, pkt->u.fault.status))); >- state->p->last_fault_code = pkt->u.fault.status; >- tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT); >+ if (pkt->u.fault.status == DCERPC_FAULT_ACCESS_DENIED) { >+ state->p->last_fault_code = pkt->u.fault.status; >+ tevent_req_nterror(req, NT_STATUS_LOGON_FAILURE); >+ } else { >+ state->p->last_fault_code = pkt->u.fault.status; >+ tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT); >+ } > return; > } > >-- >1.7.11.7 > > >From 351732e95725675eee34d37e95f2a68a9fb25622 Mon Sep 17 00:00:00 2001 >From: Andrew Tridgell <tridge@samba.org> >Date: Thu, 1 Nov 2012 14:10:14 +1100 >Subject: [PATCH 09/10] s4-ldapclient: cope with logon failure retry in LDAP > >similar to what was done for rpc and cifs, we now retry once on logon >failure for ldap, allowing for a new ticket to be fetched when a >server password changes while we have a valid ticket for the old >password > >Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org> >--- > source4/libcli/ldap/ldap_bind.c | 116 +++++++++++++++++++++++++++------------- > 1 file changed, 79 insertions(+), 37 deletions(-) > >diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c >index f167f17..b355e18 100644 >--- a/source4/libcli/ldap/ldap_bind.c >+++ b/source4/libcli/ldap/ldap_bind.c >@@ -221,9 +221,54 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, > "supportedSASLMechanisms", > NULL > }; >+ unsigned int logon_retries = 0; >+ >+ status = ildap_search(conn, "", LDAP_SEARCH_SCOPE_BASE, "", supported_sasl_mech_attrs, >+ false, NULL, NULL, &sasl_mechs_msgs); >+ if (!NT_STATUS_IS_OK(status)) { >+ DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: %s\n", >+ nt_errstr(status))); >+ goto failed; >+ } >+ >+ count = ildap_count_entries(conn, sasl_mechs_msgs); >+ if (count != 1) { >+ DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of replies: %d\n", >+ count)); >+ goto failed; >+ } >+ >+ tmp_ctx = talloc_new(conn); >+ if (tmp_ctx == NULL) goto failed; >+ >+ search = &sasl_mechs_msgs[0]->r.SearchResultEntry; >+ if (search->num_attributes != 1) { >+ DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of attributes: %d != 1\n", >+ search->num_attributes)); >+ goto failed; >+ } >+ >+ sasl_names = talloc_array(tmp_ctx, const char *, search->attributes[0].num_values + 1); >+ if (!sasl_names) { >+ DEBUG(1, ("talloc_arry(char *, %d) failed\n", >+ count)); >+ goto failed; >+ } >+ >+ for (i=0; i<search->attributes[0].num_values; i++) { >+ sasl_names[i] = (const char *)search->attributes[0].values[i].data; >+ } >+ sasl_names[i] = NULL; > > gensec_init(); > >+try_logon_again: >+ /* >+ we loop back here on a logon failure, and re-create the >+ gensec session. The logon_retries counter ensures we don't >+ loop forever. >+ */ >+ > status = gensec_client_start(conn, &conn->gensec, > lpcfg_gensec_settings(conn, lp_ctx)); > if (!NT_STATUS_IS_OK(status)) { >@@ -266,43 +311,6 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, > goto failed; > } > >- status = ildap_search(conn, "", LDAP_SEARCH_SCOPE_BASE, "", supported_sasl_mech_attrs, >- false, NULL, NULL, &sasl_mechs_msgs); >- if (!NT_STATUS_IS_OK(status)) { >- DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: %s\n", >- nt_errstr(status))); >- goto failed; >- } >- >- count = ildap_count_entries(conn, sasl_mechs_msgs); >- if (count != 1) { >- DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of replies: %d\n", >- count)); >- goto failed; >- } >- >- tmp_ctx = talloc_new(conn); >- if (tmp_ctx == NULL) goto failed; >- >- search = &sasl_mechs_msgs[0]->r.SearchResultEntry; >- if (search->num_attributes != 1) { >- DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of attributes: %d != 1\n", >- search->num_attributes)); >- goto failed; >- } >- >- sasl_names = talloc_array(tmp_ctx, const char *, search->attributes[0].num_values + 1); >- if (!sasl_names) { >- DEBUG(1, ("talloc_arry(char *, %d) failed\n", >- count)); >- goto failed; >- } >- >- for (i=0; i<search->attributes[0].num_values; i++) { >- sasl_names[i] = (const char *)search->attributes[0].values[i].data; >- } >- sasl_names[i] = NULL; >- > status = gensec_start_mech_by_sasl_list(conn->gensec, sasl_names); > if (!NT_STATUS_IS_OK(status)) { > DEBUG(1, ("None of the %d proposed SASL mechs were acceptable: %s\n", >@@ -367,6 +375,40 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, > > result = response->r.BindResponse.response.resultcode; > >+ if (result == LDAP_INVALID_CREDENTIALS) { >+ /* >+ try a second time on invalid credentials, to >+ give the user a chance to re-enter the >+ password and to handle the case where our >+ kerberos ticket is invalid as the server >+ password has changed >+ */ >+ const char *principal; >+ >+ principal = gensec_get_target_principal(conn->gensec); >+ if (principal == NULL) { >+ const char *hostname = gensec_get_target_hostname(conn->gensec); >+ const char *service = gensec_get_target_service(conn->gensec); >+ if (hostname != NULL && service != NULL) { >+ principal = talloc_asprintf(tmp_ctx, "%s/%s", service, hostname); >+ } >+ } >+ >+ if (cli_credentials_failed_kerberos_login(creds, principal, &logon_retries) || >+ cli_credentials_wrong_password(creds)) { >+ /* >+ destroy our gensec session and loop >+ back up to the top to retry, >+ offering the user a chance to enter >+ new credentials, or get a new ticket >+ if using kerberos >+ */ >+ talloc_free(conn->gensec); >+ conn->gensec = NULL; >+ goto try_logon_again; >+ } >+ } >+ > if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { > status = ldap_check_response(conn, > &response->r.BindResponse.response); >-- >1.7.11.7 > > >From a191b5606a69d7816d99d69f23d3f032f796fae6 Mon Sep 17 00:00:00 2001 >From: Andrew Tridgell <tridge@samba.org> >Date: Thu, 1 Nov 2012 14:11:02 +1100 >Subject: [PATCH 10/10] test-chgdcpass: test the ldap case for server password > change > >use samba-tool drs options which does both RPC and LDAP connections > >Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org> > >Autobuild-User(master): Andrew Tridgell <tridge@samba.org> >Autobuild-Date(master): Thu Nov 1 07:21:17 CET 2012 on sn-devel-104 >--- > testprogs/blackbox/test_chgdcpass.sh | 25 ++++++++++++++++++------- > 1 file changed, 18 insertions(+), 7 deletions(-) > >diff --git a/testprogs/blackbox/test_chgdcpass.sh b/testprogs/blackbox/test_chgdcpass.sh >index d588394..d4734ea 100755 >--- a/testprogs/blackbox/test_chgdcpass.sh >+++ b/testprogs/blackbox/test_chgdcpass.sh >@@ -45,12 +45,14 @@ test_smbclient() { > return $status > } > >-test_drsbind() { >- name="$1" >+test_drs() { >+ function="$1" >+ name="$2" >+ shift > shift > echo "test: $name" >- echo $VALGRIND $samba4bindir/samba-tool drs bind $SERVER -k yes $@ >- $VALGRIND $samba4bindir/samba-tool drs bind $SERVER -k yes $@ >+ echo $VALGRIND $samba4bindir/samba-tool drs $function $SERVER -k yes $@ >+ $VALGRIND $samba4bindir/samba-tool drs $function $SERVER -k yes $@ > status=$? > if [ x$status = x0 ]; then > echo "success: $name" >@@ -70,24 +72,33 @@ testit "kinit with keytab" $samba4kinit $enctype -t $PROVDIR/private/secrets.key > #This is important because it puts the ticket for the old KVNO and password into a local ccache > test_smbclient "Test login with kerberos ccache before password change" 'ls' -k yes || failed=`expr $failed + 1` > >+#check that drs bind works before we change the password (prime the ccache) >+test_drs bind "Test drs bind with with kerberos ccache" || failed=`expr $failed + 1` >+ > #check that drs options works before we change the password (prime the ccache) >-test_drsbind "Test drs options with with kerberos ccache" || failed=`expr $failed + 1` >+test_drs options "Test drs options with with kerberos ccache" || failed=`expr $failed + 1` > > testit "change dc password" $samba4srcdir/scripting/devel/chgtdcpass -s $PROVDIR/etc/smb.conf || failed=`expr $failed + 1` > > #This is important because it shows that the old ticket remains valid (as it must) for incoming connections after the DC password is changed > test_smbclient "Test login with kerberos ccache after password change" 'ls' -k yes || failed=`expr $failed + 1` > >+#check that drs bind works after we change the password >+test_drs bind "Test drs bind with new password" || failed=`expr $failed + 1` >+ > #check that drs options works after we change the password >-test_drsbind "Test drs options with new password" || failed=`expr $failed + 1` >+test_drs options "Test drs options with new password" || failed=`expr $failed + 1` > > testit "change dc password (2nd time)" $samba4srcdir/scripting/devel/chgtdcpass -s $PROVDIR/etc/smb.conf || failed=`expr $failed + 1` > > #This is important because it shows that the old ticket remains valid (as it must) for incoming connections after the DC pass > test_smbclient "Test login with kerberos ccache after 2nd password change" 'ls' -k yes || failed=`expr $failed + 1` > >+#check that drs bind works after we change the password a 2nd time >+test_drs bind "Test drs bind after 2nd password change" || failed=`expr $failed + 1` >+ > #check that drs options works after we change the password a 2nd time >-test_drsbind "Test drs options after 2nd password change" || failed=`expr $failed + 1` >+test_drs options "Test drs options after 2nd password change" || failed=`expr $failed + 1` > > #This confirms that the DC password is valid for a kinit too > testit "kinit with keytab" $samba4kinit $enctype -t $PROVDIR/private/secrets.keytab --use-keytab $USERNAME || failed=`expr $failed + 1` >-- >1.7.11.7 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Actions:
View
|
Diff
Attachments on
bug 29083
: 4786