diff options
author | Andrew Bartlett <abartlet@samba.org> | 2010-10-19 15:12:20 +1100 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2010-10-19 18:57:06 +1100 |
commit | 15a3077885227cc5e81e331979713c27192a01ef (patch) | |
tree | 10801a75509b666d20b369b99b09fd308abb349c /source4/auth/gensec/cyrus_sasl.c | |
parent | f9c7365e535727b1d6d6ef55ed8c196368c625b9 (diff) | |
download | samba-15a3077885227cc5e81e331979713c27192a01ef.tar.gz samba-15a3077885227cc5e81e331979713c27192a01ef.tar.bz2 samba-15a3077885227cc5e81e331979713c27192a01ef.zip |
s4-gensec Don't upgrade all DIGEST-MD5 connections to seal
The issue here is that when props.max_ssf = UINT_MAX was always set,
as was the maxbufsize, and the connection would always be upgraded,
regardless of the callers wishes.
Andrew Bartlett
Diffstat (limited to 'source4/auth/gensec/cyrus_sasl.c')
-rw-r--r-- | source4/auth/gensec/cyrus_sasl.c | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/source4/auth/gensec/cyrus_sasl.c b/source4/auth/gensec/cyrus_sasl.c index c4f954442c..c95bae91fe 100644 --- a/source4/auth/gensec/cyrus_sasl.c +++ b/source4/auth/gensec/cyrus_sasl.c @@ -29,6 +29,7 @@ struct gensec_sasl_state { sasl_conn_t *conn; int step; + bool wrap; }; static NTSTATUS sasl_nt_status(int sasl_ret) @@ -125,7 +126,7 @@ static NTSTATUS gensec_sasl_client_start(struct gensec_security *gensec_security sasl_callback_t *callbacks; - gensec_sasl_state = talloc(gensec_security, struct gensec_sasl_state); + gensec_sasl_state = talloc_zero(gensec_security, struct gensec_sasl_state); if (!gensec_sasl_state) { return NT_STATUS_NO_MEMORY; } @@ -173,26 +174,27 @@ static NTSTATUS gensec_sasl_client_start(struct gensec_security *gensec_security local_addr, remote_addr, callbacks, 0, &gensec_sasl_state->conn); - if (sasl_ret == SASL_OK || sasl_ret == SASL_CONTINUE) { + if (sasl_ret == SASL_OK) { sasl_security_properties_t props; talloc_set_destructor(gensec_sasl_state, gensec_sasl_dispose); - + ZERO_STRUCT(props); if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { props.min_ssf = 1; + props.max_ssf = 1; + props.maxbufsize = 65536; + gensec_sasl_state->wrap = true; } if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { props.min_ssf = 40; - } - - props.max_ssf = UINT_MAX; - props.maxbufsize = 65536; - sasl_ret = sasl_setprop(gensec_sasl_state->conn, SASL_SEC_PROPS, &props); - if (sasl_ret != SASL_OK) { - return sasl_nt_status(sasl_ret); + props.max_ssf = UINT_MAX; + props.maxbufsize = 65536; + gensec_sasl_state->wrap = true; } - } else { + sasl_ret = sasl_setprop(gensec_sasl_state->conn, SASL_SEC_PROPS, &props); + } + if (sasl_ret != SASL_OK) { DEBUG(1, ("GENSEC SASL: client_new failed: %s\n", sasl_errdetail(gensec_sasl_state->conn))); } return sasl_nt_status(sasl_ret); @@ -281,7 +283,14 @@ static bool gensec_sasl_have_feature(struct gensec_security *gensec_security, struct gensec_sasl_state *gensec_sasl_state = talloc_get_type(gensec_security->private_data, struct gensec_sasl_state); sasl_ssf_t ssf; - int sasl_ret = sasl_getprop(gensec_sasl_state->conn, SASL_SSF, + int sasl_ret; + + /* If we did not elect to wrap, then we have neither sign nor seal, no matter what the SSF claims */ + if (!gensec_sasl_state->wrap) { + return false; + } + + sasl_ret = sasl_getprop(gensec_sasl_state->conn, SASL_SSF, (const void**)&ssf); if (sasl_ret != SASL_OK) { return false; |