Quantcast

[PATCH] libads: abstract out SASL wrapping code

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH] libads: abstract out SASL wrapping code

Samba - samba-technical mailing list
Hi,

this is a preparatory patch to allow libads to user LDAP management via
smbldap instead of doing that directly. The patch has no functional
changes yet but untangles SASL code from direct use of ADS structure
(apart from initialization).

It compiles but I haven't tested yet. Please review.


--
/ Alexander Bokovoy

samba-libads-abstract-sasl-wrapping.patch (33K) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] libads: abstract out SASL wrapping code

Samba - samba-technical mailing list
On Fri, May 05, 2017 at 08:24:43PM +0300, Alexander Bokovoy via samba-technical wrote:
> Hi,
>
> this is a preparatory patch to allow libads to user LDAP management via
> smbldap instead of doing that directly. The patch has no functional
> changes yet but untangles SASL code from direct use of ADS structure
> (apart from initialization).
>
> It compiles but I haven't tested yet. Please review.

LGTM Alexander, simple wrap replace. Let's see if it goes
through autobuild :-).

Cheers,

        Jeremy.

> / Alexander Bokovoy

> From e1ab7f09646a8504f5ad263defc3ab537735b77b Mon Sep 17 00:00:00 2001
> From: Alexander Bokovoy <[hidden email]>
> Date: Fri, 5 May 2017 15:37:20 +0300
> Subject: [PATCH] libads: abstract out SASL wrapping code
>
> Prepare for rebasing libads on top of libsmbldap.
>
> To make libads using 'struct smbldap_state' instead of direct LDAP
> structure, we need to abstract out libads logic from connection
> handling. SASL wrapping does not really depend on availability of LDAP
> handle and does not need direct access to ADS_STRUCT. As result, we'll
> be able to move SASL wrapping code under smbldap once the latter is able
> to pass settings that libads passes to the SASL wrapping.
>
> Signed-off-by: Alexander Bokovoy <[hidden email]>
> ---
>  source3/include/ads.h          |  68 ++++++-------
>  source3/libads/ads_proto.h     |   8 +-
>  source3/libads/ldap.c          |  17 ++--
>  source3/libads/ndr.c           |  26 +----
>  source3/libads/sasl.c          | 126 +++++++++++++------------
>  source3/libads/sasl_wrapping.c | 210 ++++++++++++++++++++++++-----------------
>  6 files changed, 243 insertions(+), 212 deletions(-)
>
> diff --git a/source3/include/ads.h b/source3/include/ads.h
> index cacb25c..2b25c1c 100644
> --- a/source3/include/ads.h
> +++ b/source3/include/ads.h
> @@ -9,13 +9,13 @@
>  #include "libads/ads_status.h"
>  #include "smb_ldap.h"
>  
> -struct ads_struct;
> +struct ads_saslwrap;
>  
>  struct ads_saslwrap_ops {
>   const char *name;
> - ADS_STATUS (*wrap)(struct ads_struct *, uint8_t *buf, uint32_t len);
> - ADS_STATUS (*unwrap)(struct ads_struct *);
> - void (*disconnect)(struct ads_struct *);
> + ADS_STATUS (*wrap)(struct ads_saslwrap *, uint8_t *buf, uint32_t len);
> + ADS_STATUS (*unwrap)(struct ads_saslwrap *);
> + void (*disconnect)(struct ads_saslwrap *);
>  };
>  
>  enum ads_saslwrap_type {
> @@ -24,6 +24,37 @@ enum ads_saslwrap_type {
>   ADS_SASLWRAP_TYPE_SEAL = 4
>  };
>  
> +struct ads_saslwrap {
> + /* expected SASL wrapping type */
> + enum ads_saslwrap_type wrap_type;
> + /* SASL wrapping operations */
> + const struct ads_saslwrap_ops *wrap_ops;
> +#ifdef HAVE_LDAP_SASL_WRAPPING
> + Sockbuf_IO_Desc *sbiod; /* lowlevel state for LDAP wrapping */
> +#endif /* HAVE_LDAP_SASL_WRAPPING */
> + TALLOC_CTX *mem_ctx;
> + void *wrap_private_data;
> + struct {
> + uint32_t ofs;
> + uint32_t needed;
> + uint32_t left;
> +#define        ADS_SASL_WRAPPING_IN_MAX_WRAPPED        0x0FFFFFFF
> + uint32_t max_wrapped;
> + uint32_t min_wrapped;
> + uint32_t size;
> + uint8_t *buf;
> + } in;
> + struct {
> + uint32_t ofs;
> + uint32_t left;
> +#define        ADS_SASL_WRAPPING_OUT_MAX_WRAPPED       0x00A00000
> + uint32_t max_unwrapped;
> + uint32_t sig_size;
> + uint32_t size;
> + uint8_t *buf;
> + } out;
> +};
> +
>  typedef struct ads_struct {
>   int is_mine; /* do I own this structure's memory? */
>  
> @@ -65,39 +96,12 @@ typedef struct ads_struct {
>  
>   /* info about the current LDAP connection */
>  #ifdef HAVE_LDAP
> + struct ads_saslwrap ldap_wrap_data;
>   struct {
>   LDAP *ld;
>   struct sockaddr_storage ss; /* the ip of the active connection, if any */
>   time_t last_attempt; /* last attempt to reconnect, monotonic clock */
>   int port;
> -
> - enum ads_saslwrap_type wrap_type;
> -
> -#ifdef HAVE_LDAP_SASL_WRAPPING
> - Sockbuf_IO_Desc *sbiod; /* lowlevel state for LDAP wrapping */
> -#endif /* HAVE_LDAP_SASL_WRAPPING */
> - TALLOC_CTX *mem_ctx;
> - const struct ads_saslwrap_ops *wrap_ops;
> - void *wrap_private_data;
> - struct {
> - uint32_t ofs;
> - uint32_t needed;
> - uint32_t left;
> -#define        ADS_SASL_WRAPPING_IN_MAX_WRAPPED        0x0FFFFFFF
> - uint32_t max_wrapped;
> - uint32_t min_wrapped;
> - uint32_t size;
> - uint8_t *buf;
> - } in;
> - struct {
> - uint32_t ofs;
> - uint32_t left;
> -#define        ADS_SASL_WRAPPING_OUT_MAX_WRAPPED       0x00A00000
> - uint32_t max_unwrapped;
> - uint32_t sig_size;
> - uint32_t size;
> - uint8_t *buf;
> - } out;
>   } ldap;
>  #endif /* HAVE_LDAP */
>  } ADS_STRUCT;
> diff --git a/source3/libads/ads_proto.h b/source3/libads/ads_proto.h
> index 425c352..b6d9d9b 100644
> --- a/source3/libads/ads_proto.h
> +++ b/source3/libads/ads_proto.h
> @@ -182,12 +182,12 @@ ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads);
>  
>  /* The following definitions come from libads/sasl_wrapping.c  */
>  
> -ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads,
> -   const struct ads_saslwrap_ops *ops,
> -   void *private_data);
> -ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads,
> +ADS_STATUS ads_setup_sasl_wrapping(struct ads_saslwrap *wrap, LDAP *ld,
>     const struct ads_saslwrap_ops *ops,
>     void *private_data);
> +void ndr_print_ads_saslwrap_struct(struct ndr_print *ndr,
> +   const char *name,
> +   const struct ads_saslwrap *r);
>  
>  /* The following definitions come from libads/util.c  */
>  
> diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
> index c70cdeb..fdb729e 100644
> --- a/source3/libads/ldap.c
> +++ b/source3/libads/ldap.c
> @@ -566,8 +566,9 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
>   char addr[INET6_ADDRSTRLEN];
>  
>   ZERO_STRUCT(ads->ldap);
> + ZERO_STRUCT(ads->ldap_wrap_data);
>   ads->ldap.last_attempt = time_mono(NULL);
> - ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_PLAIN;
> + ads->ldap_wrap_data.wrap_type = ADS_SASLWRAP_TYPE_PLAIN;
>  
>   /* try with a user specified server */
>  
> @@ -643,8 +644,8 @@ got_connection:
>   goto out;
>   }
>  
> - ads->ldap.mem_ctx = talloc_init("ads LDAP connection memory");
> - if (!ads->ldap.mem_ctx) {
> + ads->ldap_wrap_data.mem_ctx = talloc_init("ads LDAP connection memory");
> + if (!ads->ldap_wrap_data.mem_ctx) {
>   status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
>   goto out;
>   }
> @@ -730,13 +731,15 @@ void ads_disconnect(ADS_STRUCT *ads)
>   ldap_unbind(ads->ldap.ld);
>   ads->ldap.ld = NULL;
>   }
> - if (ads->ldap.wrap_ops && ads->ldap.wrap_ops->disconnect) {
> - ads->ldap.wrap_ops->disconnect(ads);
> + if (ads->ldap_wrap_data.wrap_ops &&
> + ads->ldap_wrap_data.wrap_ops->disconnect) {
> + ads->ldap_wrap_data.wrap_ops->disconnect(&ads->ldap_wrap_data);
>   }
> - if (ads->ldap.mem_ctx) {
> - talloc_free(ads->ldap.mem_ctx);
> + if (ads->ldap_wrap_data.mem_ctx) {
> + talloc_free(ads->ldap_wrap_data.mem_ctx);
>   }
>   ZERO_STRUCT(ads->ldap);
> + ZERO_STRUCT(ads->ldap_wrap_data);
>  }
>  
>  /*
> diff --git a/source3/libads/ndr.c b/source3/libads/ndr.c
> index 6cecbb0..1b586c3 100644
> --- a/source3/libads/ndr.c
> +++ b/source3/libads/ndr.c
> @@ -87,31 +87,7 @@ void ndr_print_ads_struct(struct ndr_print *ndr, const char *name, const struct
>   ndr_print_sockaddr_storage(ndr, "ss", &r->ldap.ss);
>   ndr_print_time_t(ndr, "last_attempt", r->ldap.last_attempt);
>   ndr_print_uint32(ndr, "port", r->ldap.port);
> - ndr_print_uint16(ndr, "wrap_type", r->ldap.wrap_type);
> -#ifdef HAVE_LDAP_SASL_WRAPPING
> - ndr_print_ptr(ndr, "sbiod", r->ldap.sbiod);
> -#endif /* HAVE_LDAP_SASL_WRAPPING */
> - ndr_print_ptr(ndr, "mem_ctx", r->ldap.mem_ctx);
> - ndr_print_ptr(ndr, "wrap_ops", r->ldap.wrap_ops);
> - ndr_print_ptr(ndr, "wrap_private_data", r->ldap.wrap_private_data);
> - ndr_print_struct(ndr, name, "in");
> - ndr->depth++;
> - ndr_print_uint32(ndr, "ofs", r->ldap.in.ofs);
> - ndr_print_uint32(ndr, "needed", r->ldap.in.needed);
> - ndr_print_uint32(ndr, "left", r->ldap.in.left);
> - ndr_print_uint32(ndr, "max_wrapped", r->ldap.in.max_wrapped);
> - ndr_print_uint32(ndr, "min_wrapped", r->ldap.in.min_wrapped);
> - ndr_print_uint32(ndr, "size", r->ldap.in.size);
> - ndr_print_array_uint8(ndr, "buf", r->ldap.in.buf, r->ldap.in.size);
> - ndr->depth--;
> - ndr_print_struct(ndr, name, "out");
> - ndr->depth++;
> - ndr_print_uint32(ndr, "ofs", r->ldap.out.ofs);
> - ndr_print_uint32(ndr, "left", r->ldap.out.left);
> - ndr_print_uint32(ndr, "max_unwrapped", r->ldap.out.max_unwrapped);
> - ndr_print_uint32(ndr, "sig_size", r->ldap.out.sig_size);
> - ndr_print_uint32(ndr, "size", r->ldap.out.size);
> - ndr_print_array_uint8(ndr, "buf", r->ldap.out.buf, r->ldap.out.size);
> + ndr_print_ads_saslwrap_struct(ndr, "saslwrap", &(r->ldap_wrap_data));
>   ndr->depth--;
>   ndr->depth--;
>  #endif /* HAVE_LDAP */
> diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c
> index ab79f70..580a6d7 100644
> --- a/source3/libads/sasl.c
> +++ b/source3/libads/sasl.c
> @@ -30,10 +30,11 @@
>  
>  #ifdef HAVE_LDAP
>  
> -static ADS_STATUS ads_sasl_gensec_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t len)
> +static ADS_STATUS ads_sasl_gensec_wrap(struct ads_saslwrap *wrap,
> +       uint8_t *buf, uint32_t len)
>  {
>   struct gensec_security *gensec_security =
> - talloc_get_type_abort(ads->ldap.wrap_private_data,
> + talloc_get_type_abort(wrap->wrap_private_data,
>   struct gensec_security);
>   NTSTATUS nt_status;
>   DATA_BLOB unwrapped, wrapped;
> @@ -47,32 +48,32 @@ static ADS_STATUS ads_sasl_gensec_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t l
>   return ADS_ERROR_NT(nt_status);
>   }
>  
> - if ((ads->ldap.out.size - 4) < wrapped.length) {
> + if ((wrap->out.size - 4) < wrapped.length) {
>   TALLOC_FREE(frame);
>   return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR);
>   }
>  
>   /* copy the wrapped blob to the right location */
> - memcpy(ads->ldap.out.buf + 4, wrapped.data, wrapped.length);
> + memcpy(wrap->out.buf + 4, wrapped.data, wrapped.length);
>  
>   /* set how many bytes must be written to the underlying socket */
> - ads->ldap.out.left = 4 + wrapped.length;
> + wrap->out.left = 4 + wrapped.length;
>  
>   TALLOC_FREE(frame);
>  
>   return ADS_SUCCESS;
>  }
>  
> -static ADS_STATUS ads_sasl_gensec_unwrap(ADS_STRUCT *ads)
> +static ADS_STATUS ads_sasl_gensec_unwrap(struct ads_saslwrap *wrap)
>  {
>   struct gensec_security *gensec_security =
> - talloc_get_type_abort(ads->ldap.wrap_private_data,
> + talloc_get_type_abort(wrap->wrap_private_data,
>   struct gensec_security);
>   NTSTATUS nt_status;
>   DATA_BLOB unwrapped, wrapped;
>   TALLOC_CTX *frame = talloc_stackframe();
>  
> - wrapped = data_blob_const(ads->ldap.in.buf + 4, ads->ldap.in.ofs - 4);
> + wrapped = data_blob_const(wrap->in.buf + 4, wrap->in.ofs - 4);
>  
>   nt_status = gensec_unwrap(gensec_security, frame, &wrapped, &unwrapped);
>   if (!NT_STATUS_IS_OK(nt_status)) {
> @@ -86,27 +87,27 @@ static ADS_STATUS ads_sasl_gensec_unwrap(ADS_STRUCT *ads)
>   }
>  
>   /* copy the wrapped blob to the right location */
> - memcpy(ads->ldap.in.buf + 4, unwrapped.data, unwrapped.length);
> + memcpy(wrap->in.buf + 4, unwrapped.data, unwrapped.length);
>  
>   /* set how many bytes must be written to the underlying socket */
> - ads->ldap.in.left = unwrapped.length;
> - ads->ldap.in.ofs = 4;
> + wrap->in.left = unwrapped.length;
> + wrap->in.ofs = 4;
>  
>   TALLOC_FREE(frame);
>  
>   return ADS_SUCCESS;
>  }
>  
> -static void ads_sasl_gensec_disconnect(ADS_STRUCT *ads)
> +static void ads_sasl_gensec_disconnect(struct ads_saslwrap *wrap)
>  {
>   struct gensec_security *gensec_security =
> - talloc_get_type_abort(ads->ldap.wrap_private_data,
> + talloc_get_type_abort(wrap->wrap_private_data,
>   struct gensec_security);
>  
>   TALLOC_FREE(gensec_security);
>  
> - ads->ldap.wrap_ops = NULL;
> - ads->ldap.wrap_private_data = NULL;
> + wrap->wrap_ops = NULL;
> + wrap->wrap_private_data = NULL;
>  }
>  
>  static const struct ads_saslwrap_ops ads_sasl_gensec_ops = {
> @@ -136,6 +137,7 @@ static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads,
>   bool use_spnego_principal = lp_client_use_spnego_principal();
>   const char *sasl_list[] = { sasl, NULL };
>   NTTIME end_nt_time;
> + struct ads_saslwrap *wrap = &ads->ldap_wrap_data;
>  
>   nt_status = auth_generic_client_prepare(NULL, &auth_generic_state);
>   if (!NT_STATUS_IS_OK(nt_status)) {
> @@ -185,7 +187,7 @@ static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads,
>   use_spnego_principal = false;
>   }
>  
> - switch (ads->ldap.wrap_type) {
> + switch (wrap->wrap_type) {
>   case ADS_SASLWRAP_TYPE_SEAL:
>   gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SIGN);
>   gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SEAL);
> @@ -278,7 +280,7 @@ static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads,
>   data_blob_free(&blob_in);
>   data_blob_free(&blob_out);
>  
> - if (ads->ldap.wrap_type >= ADS_SASLWRAP_TYPE_SEAL) {
> + if (wrap->wrap_type >= ADS_SASLWRAP_TYPE_SEAL) {
>   bool ok;
>  
>   ok = gensec_have_feature(auth_generic_state->gensec_security,
> @@ -297,7 +299,7 @@ static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads,
>   return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE);
>   }
>  
> - } else if (ads->ldap.wrap_type >= ADS_SASLWRAP_TYPE_SIGN) {
> + } else if (wrap->wrap_type >= ADS_SASLWRAP_TYPE_SIGN) {
>   bool ok;
>  
>   ok = gensec_have_feature(auth_generic_state->gensec_security,
> @@ -317,20 +319,24 @@ static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads,
>   ads->auth.tgs_expire = tv.tv_sec;
>   }
>  
> - if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) {
> - size_t max_wrapped = gensec_max_wrapped_size(auth_generic_state->gensec_security);
> - ads->ldap.out.max_unwrapped = gensec_max_input_size(auth_generic_state->gensec_security);
> + if (wrap->wrap_type > ADS_SASLWRAP_TYPE_PLAIN) {
> + size_t max_wrapped =
> + gensec_max_wrapped_size(auth_generic_state->gensec_security);
> + wrap->out.max_unwrapped =
> + gensec_max_input_size(auth_generic_state->gensec_security);
>  
> - ads->ldap.out.sig_size = max_wrapped - ads->ldap.out.max_unwrapped;
> + wrap->out.sig_size = max_wrapped - wrap->out.max_unwrapped;
>   /*
>   * Note that we have to truncate this to 0x2C
>   * (taken from a capture with LDAP unbind), as the
>   * signature size is not constant for Kerberos with
>   * arcfour-hmac-md5.
>   */
> - ads->ldap.in.min_wrapped = MIN(ads->ldap.out.sig_size, 0x2C);
> - ads->ldap.in.max_wrapped = ADS_SASL_WRAPPING_IN_MAX_WRAPPED;
> - status = ads_setup_sasl_wrapping(ads, &ads_sasl_gensec_ops, auth_generic_state->gensec_security);
> + wrap->in.min_wrapped = MIN(wrap->out.sig_size, 0x2C);
> + wrap->in.max_wrapped = ADS_SASL_WRAPPING_IN_MAX_WRAPPED;
> + status = ads_setup_sasl_wrapping(wrap->wrap_private_data, ads->ldap.ld,
> + &ads_sasl_gensec_ops,
> + auth_generic_state->gensec_security);
>   if (!ADS_ERR_OK(status)) {
>   DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n",
>   ads_errstr(status)));
> @@ -387,9 +393,9 @@ done:
>   return status;
>  }
>  
> -static ADS_STATUS ads_sasl_gssapi_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t len)
> +static ADS_STATUS ads_sasl_gssapi_wrap(struct ads_saslwrap *wrap, uint8_t *buf, uint32_t len)
>  {
> - gss_ctx_id_t context_handle = (gss_ctx_id_t)ads->ldap.wrap_private_data;
> + gss_ctx_id_t context_handle = (gss_ctx_id_t)wrap->wrap_private_data;
>   ADS_STATUS status;
>   int gss_rc;
>   uint32_t minor_status;
> @@ -400,7 +406,7 @@ static ADS_STATUS ads_sasl_gssapi_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t l
>   unwrapped.length = len;
>  
>   /* for now request sign and seal */
> - conf_req_flag = (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL);
> + conf_req_flag = (wrap->wrap_type == ADS_SASLWRAP_TYPE_SEAL);
>  
>   gss_rc = gss_wrap(&minor_status, context_handle,
>    conf_req_flag, GSS_C_QOP_DEFAULT,
> @@ -413,32 +419,32 @@ static ADS_STATUS ads_sasl_gssapi_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t l
>   return ADS_ERROR_NT(NT_STATUS_ACCESS_DENIED);
>   }
>  
> - if ((ads->ldap.out.size - 4) < wrapped.length) {
> + if ((wrap->out.size - 4) < wrapped.length) {
>   return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR);
>   }
>  
>   /* copy the wrapped blob to the right location */
> - memcpy(ads->ldap.out.buf + 4, wrapped.value, wrapped.length);
> + memcpy(wrap->out.buf + 4, wrapped.value, wrapped.length);
>  
>   /* set how many bytes must be written to the underlying socket */
> - ads->ldap.out.left = 4 + wrapped.length;
> + wrap->out.left = 4 + wrapped.length;
>  
>   gss_release_buffer(&minor_status, &wrapped);
>  
>   return ADS_SUCCESS;
>  }
>  
> -static ADS_STATUS ads_sasl_gssapi_unwrap(ADS_STRUCT *ads)
> +static ADS_STATUS ads_sasl_gssapi_unwrap(struct ads_saslwrap *wrap)
>  {
> - gss_ctx_id_t context_handle = (gss_ctx_id_t)ads->ldap.wrap_private_data;
> + gss_ctx_id_t context_handle = (gss_ctx_id_t)wrap->wrap_private_data;
>   ADS_STATUS status;
>   int gss_rc;
>   uint32_t minor_status;
>   gss_buffer_desc unwrapped, wrapped;
>   int conf_state;
>  
> - wrapped.value = ads->ldap.in.buf + 4;
> - wrapped.length = ads->ldap.in.ofs - 4;
> + wrapped.value = wrap->in.buf + 4;
> + wrapped.length = wrap->in.ofs - 4;
>  
>   gss_rc = gss_unwrap(&minor_status, context_handle,
>      &wrapped, &unwrapped,
> @@ -446,7 +452,7 @@ static ADS_STATUS ads_sasl_gssapi_unwrap(ADS_STRUCT *ads)
>   status = ADS_ERROR_GSS(gss_rc, minor_status);
>   if (!ADS_ERR_OK(status)) return status;
>  
> - if (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL && conf_state == 0) {
> + if (wrap->wrap_type == ADS_SASLWRAP_TYPE_SEAL && conf_state == 0) {
>   return ADS_ERROR_NT(NT_STATUS_ACCESS_DENIED);
>   }
>  
> @@ -455,26 +461,26 @@ static ADS_STATUS ads_sasl_gssapi_unwrap(ADS_STRUCT *ads)
>   }
>  
>   /* copy the wrapped blob to the right location */
> - memcpy(ads->ldap.in.buf + 4, unwrapped.value, unwrapped.length);
> + memcpy(wrap->in.buf + 4, unwrapped.value, unwrapped.length);
>  
>   /* set how many bytes must be written to the underlying socket */
> - ads->ldap.in.left = unwrapped.length;
> - ads->ldap.in.ofs = 4;
> + wrap->in.left = unwrapped.length;
> + wrap->in.ofs = 4;
>  
>   gss_release_buffer(&minor_status, &unwrapped);
>  
>   return ADS_SUCCESS;
>  }
>  
> -static void ads_sasl_gssapi_disconnect(ADS_STRUCT *ads)
> +static void ads_sasl_gssapi_disconnect(struct ads_saslwrap *wrap)
>  {
> - gss_ctx_id_t context_handle = (gss_ctx_id_t)ads->ldap.wrap_private_data;
> + gss_ctx_id_t context_handle = (gss_ctx_id_t)wrap->wrap_private_data;
>   uint32_t minor_status;
>  
>   gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER);
>  
> - ads->ldap.wrap_ops = NULL;
> - ads->ldap.wrap_private_data = NULL;
> + wrap->wrap_ops = NULL;
> + wrap->wrap_private_data = NULL;
>  }
>  
>  static const struct ads_saslwrap_ops ads_sasl_gssapi_ops = {
> @@ -827,6 +833,7 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv
>   uint32_t max_msg_size = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED;
>   uint8_t wrap_type = ADS_SASLWRAP_TYPE_PLAIN;
>   ADS_STATUS status;
> + struct ads_saslwrap *wrap = &ads->ldap_wrap_data;
>  
>   input_token.value = NULL;
>   input_token.length = 0;
> @@ -916,13 +923,13 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv
>  
>   gss_release_buffer(&minor_status, &output_token);
>  
> - if (!(wrap_type & ads->ldap.wrap_type)) {
> + if (!(wrap_type & wrap->wrap_type)) {
>   /*
>   * the server doesn't supports the wrap
>   * type we want :-(
>   */
>   DEBUG(0,("The ldap sasl wrap type doesn't match wanted[%d] server[%d]\n",
> - ads->ldap.wrap_type, wrap_type));
> + wrap->wrap_type, wrap_type));
>   DEBUGADD(0,("You may want to set the 'client ldap sasl wrapping' option\n"));
>   status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED);
>   goto failed;
> @@ -943,7 +950,7 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv
>   p = (uint8_t *)output_token.value;
>  
>   RSIVAL(p,0,max_msg_size);
> - SCVAL(p,0,ads->ldap.wrap_type);
> + SCVAL(p,0,wrap->wrap_type);
>  
>   /*
>   * we used to add sprintf("dn:%s", ads->config.bind_path) here.
> @@ -980,20 +987,22 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv
>   goto failed;
>   }
>  
> - if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) {
> + if (wrap->wrap_type > ADS_SASLWRAP_TYPE_PLAIN) {
>   gss_rc = gss_wrap_size_limit(&minor_status, context_handle,
> -     (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL),
> +     (wrap->wrap_type == ADS_SASLWRAP_TYPE_SEAL),
>       GSS_C_QOP_DEFAULT,
> -     max_msg_size, &ads->ldap.out.max_unwrapped);
> +     max_msg_size, &wrap->out.max_unwrapped);
>   if (gss_rc) {
>   status = ADS_ERROR_GSS(gss_rc, minor_status);
>   goto failed;
>   }
>  
> - ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max_unwrapped;
> - ads->ldap.in.min_wrapped = 0x2C; /* taken from a capture with LDAP unbind */
> - ads->ldap.in.max_wrapped = ADS_SASL_WRAPPING_IN_MAX_WRAPPED;
> - status = ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle);
> + wrap->out.sig_size = max_msg_size - wrap->out.max_unwrapped;
> + wrap->in.min_wrapped = 0x2C; /* taken from a capture with LDAP unbind */
> + wrap->in.max_wrapped = ADS_SASL_WRAPPING_IN_MAX_WRAPPED;
> + status = ads_setup_sasl_wrapping(wrap->wrap_private_data, ads->ldap.ld,
> + &ads_sasl_gssapi_ops,
> + context_handle);
>   if (!ADS_ERR_OK(status)) {
>   DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n",
>   ads_errstr(status)));
> @@ -1068,6 +1077,7 @@ ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads)
>   ADS_STATUS status;
>   int i, j;
>   LDAPMessage *res;
> + struct ads_saslwrap *wrap = &ads->ldap_wrap_data;
>  
>   /* get a list of supported SASL mechanisms */
>   status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
> @@ -1076,11 +1086,11 @@ ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads)
>   values = ldap_get_values(ads->ldap.ld, res, "supportedSASLMechanisms");
>  
>   if (ads->auth.flags & ADS_AUTH_SASL_SEAL) {
> - ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SEAL;
> + wrap->wrap_type = ADS_SASLWRAP_TYPE_SEAL;
>   } else if (ads->auth.flags & ADS_AUTH_SASL_SIGN) {
> - ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SIGN;
> + wrap->wrap_type = ADS_SASLWRAP_TYPE_SIGN;
>   } else {
> - ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_PLAIN;
> + wrap->wrap_type = ADS_SASLWRAP_TYPE_PLAIN;
>   }
>  
>   /* try our supported mechanisms in order */
> @@ -1093,11 +1103,11 @@ retry:
>   status = sasl_mechanisms[i].fn(ads);
>   if (status.error_type == ENUM_ADS_ERROR_LDAP &&
>      status.err.rc == LDAP_STRONG_AUTH_REQUIRED &&
> -    ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_PLAIN)
> +    wrap->wrap_type == ADS_SASLWRAP_TYPE_PLAIN)
>   {
>   DEBUG(3,("SASL bin got LDAP_STRONG_AUTH_REQUIRED "
>   "retrying with signing enabled\n"));
> - ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SIGN;
> + wrap->wrap_type = ADS_SASLWRAP_TYPE_SIGN;
>   goto retry;
>   }
>   ldap_value_free(values);
> diff --git a/source3/libads/sasl_wrapping.c b/source3/libads/sasl_wrapping.c
> index c7a58ab..1dbd357 100644
> --- a/source3/libads/sasl_wrapping.c
> +++ b/source3/libads/sasl_wrapping.c
> @@ -20,15 +20,47 @@
>  #include "includes.h"
>  #include "ads.h"
>  
> +void ndr_print_ads_saslwrap_struct(struct ndr_print *ndr, const char *name, const struct ads_saslwrap *r)
> +{
> + ndr_print_struct(ndr, name, "saslwrap");
> + ndr->depth++;
> + ndr_print_uint16(ndr, "wrap_type", r->wrap_type);
> +#ifdef HAVE_LDAP_SASL_WRAPPING
> + ndr_print_ptr(ndr, "sbiod", r->sbiod);
> +#endif /* HAVE_LDAP_SASL_WRAPPING */
> + ndr_print_ptr(ndr, "mem_ctx", r->mem_ctx);
> + ndr_print_ptr(ndr, "wrap_ops", r->wrap_ops);
> + ndr_print_ptr(ndr, "wrap_private_data", r->wrap_private_data);
> + ndr_print_struct(ndr, name, "in");
> + ndr->depth++;
> + ndr_print_uint32(ndr, "ofs", r->in.ofs);
> + ndr_print_uint32(ndr, "needed", r->in.needed);
> + ndr_print_uint32(ndr, "left", r->in.left);
> + ndr_print_uint32(ndr, "max_wrapped", r->in.max_wrapped);
> + ndr_print_uint32(ndr, "min_wrapped", r->in.min_wrapped);
> + ndr_print_uint32(ndr, "size", r->in.size);
> + ndr_print_array_uint8(ndr, "buf", r->in.buf, r->in.size);
> + ndr->depth--;
> + ndr_print_struct(ndr, name, "out");
> + ndr->depth++;
> + ndr_print_uint32(ndr, "ofs", r->out.ofs);
> + ndr_print_uint32(ndr, "left", r->out.left);
> + ndr_print_uint32(ndr, "max_unwrapped", r->out.max_unwrapped);
> + ndr_print_uint32(ndr, "sig_size", r->out.sig_size);
> + ndr_print_uint32(ndr, "size", r->out.size);
> + ndr_print_array_uint8(ndr, "buf", r->out.buf, r->out.size);
> + ndr->depth--;
> +}
> +
>  #ifdef HAVE_LDAP_SASL_WRAPPING
>  
>  static int ads_saslwrap_setup(Sockbuf_IO_Desc *sbiod, void *arg)
>  {
> - ADS_STRUCT *ads = (ADS_STRUCT *)arg;
> + struct ads_saslwrap *wrap = (struct ads_saslwrap *)arg;
>  
> - ads->ldap.sbiod = sbiod;
> + wrap->sbiod = sbiod;
>  
> - sbiod->sbiod_pvt = ads;
> + sbiod->sbiod_pvt = wrap;
>  
>   return 0;
>  }
> @@ -38,78 +70,80 @@ static int ads_saslwrap_remove(Sockbuf_IO_Desc *sbiod)
>   return 0;
>  }
>  
> -static ber_slen_t ads_saslwrap_prepare_inbuf(ADS_STRUCT *ads)
> +static ber_slen_t ads_saslwrap_prepare_inbuf(struct ads_saslwrap *wrap)
>  {
> - ads->ldap.in.ofs = 0;
> - ads->ldap.in.needed = 0;
> - ads->ldap.in.left = 0;
> - ads->ldap.in.size = 4 + ads->ldap.in.min_wrapped;
> - ads->ldap.in.buf = talloc_array(ads->ldap.mem_ctx,
> -       uint8_t, ads->ldap.in.size);
> - if (!ads->ldap.in.buf) {
> + wrap->in.ofs = 0;
> + wrap->in.needed = 0;
> + wrap->in.left = 0;
> + wrap->in.size = 4 + wrap->in.min_wrapped;
> + wrap->in.buf = talloc_array(wrap->mem_ctx,
> +       uint8_t, wrap->in.size);
> + if (!wrap->in.buf) {
>   return -1;
>   }
>  
>   return 0;
>  }
>  
> -static ber_slen_t ads_saslwrap_grow_inbuf(ADS_STRUCT *ads)
> +static ber_slen_t ads_saslwrap_grow_inbuf(struct ads_saslwrap *wrap)
>  {
> - if (ads->ldap.in.size == (4 + ads->ldap.in.needed)) {
> + if (wrap->in.size == (4 + wrap->in.needed)) {
>   return 0;
>   }
>  
> - ads->ldap.in.size = 4 + ads->ldap.in.needed;
> - ads->ldap.in.buf = talloc_realloc(ads->ldap.mem_ctx,
> - ads->ldap.in.buf,
> - uint8_t, ads->ldap.in.size);
> - if (!ads->ldap.in.buf) {
> + wrap->in.size = 4 + wrap->in.needed;
> + wrap->in.buf = talloc_realloc(wrap->mem_ctx,
> + wrap->in.buf,
> + uint8_t, wrap->in.size);
> + if (!wrap->in.buf) {
>   return -1;
>   }
>  
>   return 0;
>  }
>  
> -static void ads_saslwrap_shrink_inbuf(ADS_STRUCT *ads)
> +static void ads_saslwrap_shrink_inbuf(struct ads_saslwrap *wrap)
>  {
> - talloc_free(ads->ldap.in.buf);
> + talloc_free(wrap->in.buf);
>  
> - ads->ldap.in.buf = NULL;
> - ads->ldap.in.size = 0;
> - ads->ldap.in.ofs = 0;
> - ads->ldap.in.needed = 0;
> - ads->ldap.in.left = 0;
> + wrap->in.buf = NULL;
> + wrap->in.size = 0;
> + wrap->in.ofs = 0;
> + wrap->in.needed = 0;
> + wrap->in.left = 0;
>  }
>  
> -static ber_slen_t ads_saslwrap_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
> +static ber_slen_t ads_saslwrap_read(Sockbuf_IO_Desc *sbiod,
> +    void *buf, ber_len_t len)
>  {
> - ADS_STRUCT *ads = (ADS_STRUCT *)sbiod->sbiod_pvt;
> + struct ads_saslwrap *wrap =
> + (struct ads_saslwrap *)sbiod->sbiod_pvt;
>   ber_slen_t ret;
>  
>   /* If ofs < 4 it means we don't have read the length header yet */
> - if (ads->ldap.in.ofs < 4) {
> - ret = ads_saslwrap_prepare_inbuf(ads);
> + if (wrap->in.ofs < 4) {
> + ret = ads_saslwrap_prepare_inbuf(wrap);
>   if (ret < 0) return ret;
>  
>   ret = LBER_SBIOD_READ_NEXT(sbiod,
> -   ads->ldap.in.buf + ads->ldap.in.ofs,
> -   4 - ads->ldap.in.ofs);
> +   wrap->in.buf + wrap->in.ofs,
> +   4 - wrap->in.ofs);
>   if (ret <= 0) return ret;
> - ads->ldap.in.ofs += ret;
> + wrap->in.ofs += ret;
>  
> - if (ads->ldap.in.ofs < 4) goto eagain;
> + if (wrap->in.ofs < 4) goto eagain;
>  
> - ads->ldap.in.needed = RIVAL(ads->ldap.in.buf, 0);
> - if (ads->ldap.in.needed > ads->ldap.in.max_wrapped) {
> + wrap->in.needed = RIVAL(wrap->in.buf, 0);
> + if (wrap->in.needed > wrap->in.max_wrapped) {
>   errno = EINVAL;
>   return -1;
>   }
> - if (ads->ldap.in.needed < ads->ldap.in.min_wrapped) {
> + if (wrap->in.needed < wrap->in.min_wrapped) {
>   errno = EINVAL;
>   return -1;
>   }
>  
> - ret = ads_saslwrap_grow_inbuf(ads);
> + ret = ads_saslwrap_grow_inbuf(wrap);
>   if (ret < 0) return ret;
>   }
>  
> @@ -117,24 +151,24 @@ static ber_slen_t ads_saslwrap_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t
>   * if there's more data needed from the remote end,
>   * we need to read more
>   */
> - if (ads->ldap.in.needed > 0) {
> + if (wrap->in.needed > 0) {
>   ret = LBER_SBIOD_READ_NEXT(sbiod,
> -   ads->ldap.in.buf + ads->ldap.in.ofs,
> -   ads->ldap.in.needed);
> +   wrap->in.buf + wrap->in.ofs,
> +   wrap->in.needed);
>   if (ret <= 0) return ret;
> - ads->ldap.in.ofs += ret;
> - ads->ldap.in.needed -= ret;
> + wrap->in.ofs += ret;
> + wrap->in.needed -= ret;
>  
> - if (ads->ldap.in.needed > 0) goto eagain;
> + if (wrap->in.needed > 0) goto eagain;
>   }
>  
>   /*
>   * if we have a complete packet and have not yet unwrapped it
>   * we need to call the mech specific unwrap() hook
>   */
> - if (ads->ldap.in.needed == 0 && ads->ldap.in.left == 0) {
> + if (wrap->in.needed == 0 && wrap->in.left == 0) {
>   ADS_STATUS status;
> - status = ads->ldap.wrap_ops->unwrap(ads);
> + status = wrap->wrap_ops->unwrap(wrap);
>   if (!ADS_ERR_OK(status)) {
>   errno = EACCES;
>   return -1;
> @@ -144,19 +178,19 @@ static ber_slen_t ads_saslwrap_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t
>   /*
>   * if we have unwrapped data give it to the caller
>   */
> - if (ads->ldap.in.left > 0) {
> - ret = MIN(ads->ldap.in.left, len);
> - memcpy(buf, ads->ldap.in.buf + ads->ldap.in.ofs, ret);
> - ads->ldap.in.ofs += ret;
> - ads->ldap.in.left -= ret;
> + if (wrap->in.left > 0) {
> + ret = MIN(wrap->in.left, len);
> + memcpy(buf, wrap->in.buf + wrap->in.ofs, ret);
> + wrap->in.ofs += ret;
> + wrap->in.left -= ret;
>  
>   /*
>   * if no more is left shrink the inbuf,
>   * this will trigger reading a new SASL packet
>   * from the remote stream in the next call
>   */
> - if (ads->ldap.in.left == 0) {
> - ads_saslwrap_shrink_inbuf(ads);
> + if (wrap->in.left == 0) {
> + ads_saslwrap_shrink_inbuf(wrap);
>   }
>  
>   return ret;
> @@ -171,37 +205,40 @@ eagain:
>   return -1;
>  }
>  
> -static ber_slen_t ads_saslwrap_prepare_outbuf(ADS_STRUCT *ads, uint32_t len)
> +static ber_slen_t ads_saslwrap_prepare_outbuf(struct ads_saslwrap *wrap,
> +      uint32_t len)
>  {
> - ads->ldap.out.ofs = 0;
> - ads->ldap.out.left = 0;
> - ads->ldap.out.size = 4 + ads->ldap.out.sig_size + len;
> - ads->ldap.out.buf = talloc_array(ads->ldap.mem_ctx,
> -       uint8_t, ads->ldap.out.size);
> - if (!ads->ldap.out.buf) {
> + wrap->out.ofs = 0;
> + wrap->out.left = 0;
> + wrap->out.size = 4 + wrap->out.sig_size + len;
> + wrap->out.buf = talloc_array(wrap->mem_ctx,
> +       uint8_t, wrap->out.size);
> + if (!wrap->out.buf) {
>   return -1;
>   }
>  
>   return 0;
>  }
>  
> -static void ads_saslwrap_shrink_outbuf(ADS_STRUCT *ads)
> +static void ads_saslwrap_shrink_outbuf(struct ads_saslwrap *wrap)
>  {
> - talloc_free(ads->ldap.out.buf);
> + talloc_free(wrap->out.buf);
>  
> - ads->ldap.out.buf = NULL;
> - ads->ldap.out.size = 0;
> - ads->ldap.out.ofs = 0;
> - ads->ldap.out.left = 0;
> + wrap->out.buf = NULL;
> + wrap->out.size = 0;
> + wrap->out.ofs = 0;
> + wrap->out.left = 0;
>  }
>  
> -static ber_slen_t ads_saslwrap_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
> +static ber_slen_t ads_saslwrap_write(Sockbuf_IO_Desc *sbiod,
> +     void *buf, ber_len_t len)
>  {
> - ADS_STRUCT *ads = (ADS_STRUCT *)sbiod->sbiod_pvt;
> + struct ads_saslwrap *wrap =
> + (struct ads_saslwrap *)sbiod->sbiod_pvt;
>   ber_slen_t ret, rlen;
>  
>   /* if the buffer is empty, we need to wrap in incoming buffer */
> - if (ads->ldap.out.left == 0) {
> + if (wrap->out.left == 0) {
>   ADS_STATUS status;
>  
>   if (len == 0) {
> @@ -209,31 +246,31 @@ static ber_slen_t ads_saslwrap_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_
>   return -1;
>   }
>  
> - rlen = MIN(len, ads->ldap.out.max_unwrapped);
> + rlen = MIN(len, wrap->out.max_unwrapped);
>  
> - ret = ads_saslwrap_prepare_outbuf(ads, rlen);
> + ret = ads_saslwrap_prepare_outbuf(wrap, rlen);
>   if (ret < 0) return ret;
>  
> - status = ads->ldap.wrap_ops->wrap(ads, (uint8_t *)buf, rlen);
> + status = wrap->wrap_ops->wrap(wrap, (uint8_t *)buf, rlen);
>   if (!ADS_ERR_OK(status)) {
>   errno = EACCES;
>   return -1;
>   }
>  
> - RSIVAL(ads->ldap.out.buf, 0, ads->ldap.out.left - 4);
> + RSIVAL(wrap->out.buf, 0, wrap->out.left - 4);
>   } else {
>   rlen = -1;
>   }
>  
>   ret = LBER_SBIOD_WRITE_NEXT(sbiod,
> -    ads->ldap.out.buf + ads->ldap.out.ofs,
> -    ads->ldap.out.left);
> +    wrap->out.buf + wrap->out.ofs,
> +    wrap->out.left);
>   if (ret <= 0) return ret;
> - ads->ldap.out.ofs += ret;
> - ads->ldap.out.left -= ret;
> + wrap->out.ofs += ret;
> + wrap->out.left -= ret;
>  
> - if (ads->ldap.out.left == 0) {
> - ads_saslwrap_shrink_outbuf(ads);
> + if (wrap->out.left == 0) {
> + ads_saslwrap_shrink_outbuf(wrap);
>   }
>  
>   if (rlen > 0) return rlen;
> @@ -244,12 +281,13 @@ static ber_slen_t ads_saslwrap_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_
>  
>  static int ads_saslwrap_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg)
>  {
> - ADS_STRUCT *ads = (ADS_STRUCT *)sbiod->sbiod_pvt;
> + struct ads_saslwrap *wrap =
> + (struct ads_saslwrap *)sbiod->sbiod_pvt;
>   int ret;
>  
>   switch (opt) {
>   case LBER_SB_OPT_DATA_READY:
> - if (ads->ldap.in.left > 0) {
> + if (wrap->in.left > 0) {
>   return 1;
>   }
>   ret = LBER_SBIOD_CTRL_NEXT(sbiod, opt, arg);
> @@ -276,7 +314,7 @@ static const Sockbuf_IO ads_saslwrap_sockbuf_io = {
>   ads_saslwrap_close /* sbi_close */
>  };
>  
> -ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads,
> +ADS_STATUS ads_setup_sasl_wrapping(struct ads_saslwrap *wrap, LDAP *ld,
>     const struct ads_saslwrap_ops *ops,
>     void *private_data)
>  {
> @@ -285,26 +323,26 @@ ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads,
>   Sockbuf_IO *io = discard_const_p(Sockbuf_IO, &ads_saslwrap_sockbuf_io);
>   int rc;
>  
> - rc = ldap_get_option(ads->ldap.ld, LDAP_OPT_SOCKBUF, &sb);
> + rc = ldap_get_option(ld, LDAP_OPT_SOCKBUF, &sb);
>   status = ADS_ERROR_LDAP(rc);
>   if (!ADS_ERR_OK(status)) {
>   return status;
>   }
>  
>   /* setup the real wrapping callbacks */
> - rc = ber_sockbuf_add_io(sb, io, LBER_SBIOD_LEVEL_TRANSPORT, ads);
> + rc = ber_sockbuf_add_io(sb, io, LBER_SBIOD_LEVEL_TRANSPORT, wrap);
>   status = ADS_ERROR_LDAP(rc);
>   if (!ADS_ERR_OK(status)) {
>   return status;
>   }
>  
> - ads->ldap.wrap_ops = ops;
> - ads->ldap.wrap_private_data = private_data;
> + wrap->wrap_ops = ops;
> + wrap->wrap_private_data = private_data;
>  
>   return ADS_SUCCESS;
>  }
>  #else
> -ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads,
> +ADS_STATUS ads_setup_sasl_wrapping(struct ads_saslwrap *wrap, LDAP *ld,
>     const struct ads_saslwrap_ops *ops,
>     void *private_data)
>  {
> --
> 2.9.3
>


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] libads: abstract out SASL wrapping code

Samba - samba-technical mailing list
On Fri, May 12, 2017 at 02:33:01PM -0700, Jeremy Allison via samba-technical wrote:

> On Fri, May 05, 2017 at 08:24:43PM +0300, Alexander Bokovoy via samba-technical wrote:
> > Hi,
> >
> > this is a preparatory patch to allow libads to user LDAP management via
> > smbldap instead of doing that directly. The patch has no functional
> > changes yet but untangles SASL code from direct use of ADS structure
> > (apart from initialization).
> >
> > It compiles but I haven't tested yet. Please review.
>
> LGTM Alexander, simple wrap replace. Let's see if it goes
> through autobuild :-).

Fails with:

Join failed
SOCKET_WRAPPER_DEFAULT_IFACE="29" RESOLV_WRAPPER_HOSTS="/space/jra/src/samba/git/master/st/dns_host_file" KRB5_CONFIG="/space/jra/src/samba/git/master/st/ad_member/lib/krb5.conf" SELFTEST_WINBINDD_SOCKET_DIR="/space/jra/src/samba/git/master/st/ad_member/winbindd" ./bin/net join -s /space/jra/src/samba/git/master/st/ad_member/lib/server.conf -UAdministrator%locDCpass1 at /space/jra/src/samba/git/master/selftest/target/Samba3.pm line 469.
failed to start up environment 'ad_member' at /space/jra/src/samba/git/master/selftest/target/Samba.pm line 49.
samba can't start up known environment 'ad_member' at /space/jra/src/samba/git/master/selftest/selftest.pl line 929.
[47(651)/2098 at 15m27s, 1 errors] samba.tests.pam_winbind(ad_member)
ERROR: Testsuite[samba.tests.pam_winbind(ad_member)]
REASON: unable to set up environment ad_member - exiting

Sorry Alexander, I'll re-review once you've got it
passing local make test !

Jeremy.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] libads: abstract out SASL wrapping code

Samba - samba-technical mailing list
On pe, 12 touko 2017, Jeremy Allison wrote:

> On Fri, May 12, 2017 at 02:33:01PM -0700, Jeremy Allison via samba-technical wrote:
> > On Fri, May 05, 2017 at 08:24:43PM +0300, Alexander Bokovoy via samba-technical wrote:
> > > Hi,
> > >
> > > this is a preparatory patch to allow libads to user LDAP management via
> > > smbldap instead of doing that directly. The patch has no functional
> > > changes yet but untangles SASL code from direct use of ADS structure
> > > (apart from initialization).
> > >
> > > It compiles but I haven't tested yet. Please review.
> >
> > LGTM Alexander, simple wrap replace. Let's see if it goes
> > through autobuild :-).
>
> Fails with:
>
> Join failed
> SOCKET_WRAPPER_DEFAULT_IFACE="29" RESOLV_WRAPPER_HOSTS="/space/jra/src/samba/git/master/st/dns_host_file" KRB5_CONFIG="/space/jra/src/samba/git/master/st/ad_member/lib/krb5.conf" SELFTEST_WINBINDD_SOCKET_DIR="/space/jra/src/samba/git/master/st/ad_member/winbindd" ./bin/net join -s /space/jra/src/samba/git/master/st/ad_member/lib/server.conf -UAdministrator%locDCpass1 at /space/jra/src/samba/git/master/selftest/target/Samba3.pm line 469.
> failed to start up environment 'ad_member' at /space/jra/src/samba/git/master/selftest/target/Samba.pm line 49.
> samba can't start up known environment 'ad_member' at /space/jra/src/samba/git/master/selftest/selftest.pl line 929.
> [47(651)/2098 at 15m27s, 1 errors] samba.tests.pam_winbind(ad_member)
> ERROR: Testsuite[samba.tests.pam_winbind(ad_member)]
> REASON: unable to set up environment ad_member - exiting
>
> Sorry Alexander, I'll re-review once you've got it
> passing local make test !
Thanks for trying. :)

I'm able to reproduce it locally. However, it seems that this change
uncovered some bug in source4 ldap server code. After looping in LDAP
server code it times out and says this:

smbsrv_recv
s4_tevent: Destroying timer event 0x560a5ab22780 "tevent_req_timedout"
Terminating connection deferred - 'NT_STATUS_END_OF_FILE'
Terminating connection - 'NT_STATUS_END_OF_FILE'
s4_tevent: Schedule immediate event "tevent_req_trigger": 0x560a5a96c1a0
ipv4:127.0.0.29:13517 closed connection to service IPC$
s4_tevent: Added timed event "tevent_req_timedout": 0x560a5adfbb00
s4_tevent: Run immediate event "tevent_req_trigger": 0x560a5a96c1a0
s4_tevent: Destroying timer event 0x560a5adfbb00 "tevent_req_timedout"
s4_tevent: Schedule immediate event "tevent_req_trigger": 0x560a5a96c1a0
s4_tevent: Added timed event "tevent_req_timedout": 0x560a5adfbb00
s4_tevent: Run immediate event "tevent_req_trigger": 0x560a5a96c1a0
s4_tevent: Destroying timer event 0x560a5adfbb00 "tevent_req_timedout"
Terminating connection - 'ldapsrv_call_loop: tstream_read_pdu_blob_recv() - NT_STATUS_CONNECTION_DISCONNECTED'
msg_dgm_ref_destructor: refs=0x560a59f42250
Join failed
SOCKET_WRAPPER_DEFAULT_IFACE="29" RESOLV_WRAPPER_HOSTS="/home/abokovoy/src/samba/st/dns_host_file" KRB5_CONFIG="/home/abokovoy/src/samba/st/ad_member/lib/krb5.conf" SELFTEST_WINBINDD_SOCKET_DIR="/home/abokovoy/src/samba/st/ad_member/winbindd" ./bin/net '-d50 ldb:0' join -s /home/abokovoy/src/samba/st/ad_member/lib/server.conf -UAdministrator%locDCpass1 at /home/abokovoy/src/samba/selftest/target/Samba3.pm line 470.
failed to start up environment 'ad_member' at /home/abokovoy/src/samba/selftest/target/Samba.pm line 49.
samba can't start up known environment 'ad_member' at /home/abokovoy/src/samba/selftest/selftest.pl line 929.
[1(0)/1 at 0s] samba.tests.pam_winbind(ad_member)
ERROR: Testsuite[samba.tests.pam_winbind(ad_member)]
REASON: unable to set up environment ad_member - exiting


standard_terminate: reason[NT_STATUS_END_OF_FILE]
msg_dgm_ref_destructor: refs=0x560a59f42250
msg_dgm_ref_destructor: refs=(nil)
msg_dgm_ref_destructor: refs=0x560a5a559300
single_terminate: reason[ldapsrv_call_loop: tstream_read_pdu_blob_recv() - NT_STATUS_CONNECTION_DISCONNEC�]
samba: EOF on stdin - PID 3454 terminating
msg_dgm_ref_destructor: refs=(nil)
-------------------------------------------------------------------------------------------------------------

Notice NT_STATUS_CONNECTION_DISCONNECT message garbled?

I'm still trying to understand what broke -- on client side we seem
never get back (my debug statements never get printed) after successful
SASL GSS-SPNEGO bind.


--
/ Alexander Bokovoy

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] libads: abstract out SASL wrapping code

Samba - samba-technical mailing list
On ma, 15 touko 2017, Alexander Bokovoy via samba-technical wrote:

> On pe, 12 touko 2017, Jeremy Allison wrote:
> > On Fri, May 12, 2017 at 02:33:01PM -0700, Jeremy Allison via samba-technical wrote:
> > > On Fri, May 05, 2017 at 08:24:43PM +0300, Alexander Bokovoy via samba-technical wrote:
> > > > Hi,
> > > >
> > > > this is a preparatory patch to allow libads to user LDAP management via
> > > > smbldap instead of doing that directly. The patch has no functional
> > > > changes yet but untangles SASL code from direct use of ADS structure
> > > > (apart from initialization).
> > > >
> > > > It compiles but I haven't tested yet. Please review.
> > >
> > > LGTM Alexander, simple wrap replace. Let's see if it goes
> > > through autobuild :-).
> >
> > Fails with:
> >
> > Join failed
> > SOCKET_WRAPPER_DEFAULT_IFACE="29" RESOLV_WRAPPER_HOSTS="/space/jra/src/samba/git/master/st/dns_host_file" KRB5_CONFIG="/space/jra/src/samba/git/master/st/ad_member/lib/krb5.conf" SELFTEST_WINBINDD_SOCKET_DIR="/space/jra/src/samba/git/master/st/ad_member/winbindd" ./bin/net join -s /space/jra/src/samba/git/master/st/ad_member/lib/server.conf -UAdministrator%locDCpass1 at /space/jra/src/samba/git/master/selftest/target/Samba3.pm line 469.
> > failed to start up environment 'ad_member' at /space/jra/src/samba/git/master/selftest/target/Samba.pm line 49.
> > samba can't start up known environment 'ad_member' at /space/jra/src/samba/git/master/selftest/selftest.pl line 929.
> > [47(651)/2098 at 15m27s, 1 errors] samba.tests.pam_winbind(ad_member)
> > ERROR: Testsuite[samba.tests.pam_winbind(ad_member)]
> > REASON: unable to set up environment ad_member - exiting
> >
> > Sorry Alexander, I'll re-review once you've got it
> > passing local make test !
> Thanks for trying. :)
>
> I'm able to reproduce it locally. However, it seems that this change
> uncovered some bug in source4 ldap server code. After looping in LDAP
> server code it times out and says this:
>
> smbsrv_recv
> s4_tevent: Destroying timer event 0x560a5ab22780 "tevent_req_timedout"
> Terminating connection deferred - 'NT_STATUS_END_OF_FILE'
> Terminating connection - 'NT_STATUS_END_OF_FILE'
> s4_tevent: Schedule immediate event "tevent_req_trigger": 0x560a5a96c1a0
> ipv4:127.0.0.29:13517 closed connection to service IPC$
> s4_tevent: Added timed event "tevent_req_timedout": 0x560a5adfbb00
> s4_tevent: Run immediate event "tevent_req_trigger": 0x560a5a96c1a0
> s4_tevent: Destroying timer event 0x560a5adfbb00 "tevent_req_timedout"
> s4_tevent: Schedule immediate event "tevent_req_trigger": 0x560a5a96c1a0
> s4_tevent: Added timed event "tevent_req_timedout": 0x560a5adfbb00
> s4_tevent: Run immediate event "tevent_req_trigger": 0x560a5a96c1a0
> s4_tevent: Destroying timer event 0x560a5adfbb00 "tevent_req_timedout"
> Terminating connection - 'ldapsrv_call_loop: tstream_read_pdu_blob_recv() - NT_STATUS_CONNECTION_DISCONNECTED'
> msg_dgm_ref_destructor: refs=0x560a59f42250
> Join failed
> SOCKET_WRAPPER_DEFAULT_IFACE="29" RESOLV_WRAPPER_HOSTS="/home/abokovoy/src/samba/st/dns_host_file" KRB5_CONFIG="/home/abokovoy/src/samba/st/ad_member/lib/krb5.conf" SELFTEST_WINBINDD_SOCKET_DIR="/home/abokovoy/src/samba/st/ad_member/winbindd" ./bin/net '-d50 ldb:0' join -s /home/abokovoy/src/samba/st/ad_member/lib/server.conf -UAdministrator%locDCpass1 at /home/abokovoy/src/samba/selftest/target/Samba3.pm line 470.
> failed to start up environment 'ad_member' at /home/abokovoy/src/samba/selftest/target/Samba.pm line 49.
> samba can't start up known environment 'ad_member' at /home/abokovoy/src/samba/selftest/selftest.pl line 929.
> [1(0)/1 at 0s] samba.tests.pam_winbind(ad_member)
> ERROR: Testsuite[samba.tests.pam_winbind(ad_member)]
> REASON: unable to set up environment ad_member - exiting
>
>
> standard_terminate: reason[NT_STATUS_END_OF_FILE]
> msg_dgm_ref_destructor: refs=0x560a59f42250
> msg_dgm_ref_destructor: refs=(nil)
> msg_dgm_ref_destructor: refs=0x560a5a559300
> single_terminate: reason[ldapsrv_call_loop: tstream_read_pdu_blob_recv() - NT_STATUS_CONNECTION_DISCONNEC�]
> samba: EOF on stdin - PID 3454 terminating
> msg_dgm_ref_destructor: refs=(nil)
> -------------------------------------------------------------------------------------------------------------
>
> Notice NT_STATUS_CONNECTION_DISCONNECT message garbled?
>
> I'm still trying to understand what broke -- on client side we seem
> never get back (my debug statements never get printed) after successful
> SASL GSS-SPNEGO bind.
Attached patch passes samba.tests.pam_winbind test.

--
/ Alexander Bokovoy

samba-libads-abstract-sasl-wrapping.patch (33K) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] libads: abstract out SASL wrapping code

Samba - samba-technical mailing list
On Mon, 2017-05-15 at 17:28 +0300, Alexander Bokovoy via samba-
technical wrote:
>
> > Notice NT_STATUS_CONNECTION_DISCONNECT message garbled?
> >
> > I'm still trying to understand what broke -- on client side we seem
> > never get back (my debug statements never get printed) after successful
> > SASL GSS-SPNEGO bind.
>
> Attached patch passes samba.tests.pam_winbind test.

Thanks for all your hard work on this.  What was the problem in the
LDAP server in the end?

Andrew Bartlett

--
Andrew Bartlett                       http://samba.org/~abartlet/
Authentication Developer, Samba Team  http://samba.org
Samba Developer, Catalyst IT          http://catalyst.net.nz/services/samba


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] libads: abstract out SASL wrapping code

Samba - samba-technical mailing list
On ti, 16 touko 2017, Andrew Bartlett wrote:

> On Mon, 2017-05-15 at 17:28 +0300, Alexander Bokovoy via samba-
> technical wrote:
> >
> > > Notice NT_STATUS_CONNECTION_DISCONNECT message garbled?
> > >
> > > I'm still trying to understand what broke -- on client side we seem
> > > never get back (my debug statements never get printed) after successful
> > > SASL GSS-SPNEGO bind.
> >
> > Attached patch passes samba.tests.pam_winbind test.
>
> Thanks for all your hard work on this.  What was the problem in the
> LDAP server in the end?
I haven't found that yet as I fixed one wrong pointer pass in my code
and went away with that. However, if you look at the output in my
previous email, it looks like the error string is garbled at the end, so
there is something off-by-one somewhere.

I also get crash in GUID_buf_string() because I run 'make test' with
high enough log level and source3/locking/share_mode_lock.c:846 causes
an NDR print out of a share mode lock entry for log level 11 or above.
As result, there seem to be a garbled GUID.

The test is samba3.smbtorture_s3.crypt_client(nt4_dc).TORTURE(nt4_dc).


#5  0x00007fb4ab130aa1 in sig_fault (sig=11) at ../lib/util/fault.c:94
No locals.
#6  <signal handler called>
No symbol table info available.
#7  0x00007fb4a3b5e174 in GUID_buf_string (guid=0x55d21b7dd178, dst=0x7ffcd1993960) at ../librpc/ndr/uuid.c:335
No locals.
#8  0x00007fb4a3b5e122 in GUID_string (mem_ctx=0x559a1b884160, guid=0x55d21b7dd178) at ../librpc/ndr/uuid.c:314
        buf = {buf = "`\324m\247\264\177\000\000`W\210\033\232U\000\000ma touko 15 20.59.13 20"}
#9  0x00007fb4a3b623ef in ndr_print_GUID (ndr=0x559a1b884160, name=0x7fb4aa0e80b4 "client_guid", guid=0x55d21b7dd178) at ../librpc/ndr/ndr_misc.c:29
No locals.
#10 0x00007fb4aa09272f in ndr_print_share_mode_lease (ndr=0x559a1b884160, name=0x7fb4aa0e82fb "lease", r=0x55d21b7dd178) at default/source3/librpc/gen_ndr/ndr_open_files.c:69
        _flags_save_STRUCT = 0
#11 0x00007fb4aa09331c in ndr_print_share_mode_entry (ndr=0x559a1b884160, name=0x7fb4aa0e8c56 "share_modes", r=0x559a1b830270) at default/source3/librpc/gen_ndr/ndr_open_files.c:176
No locals.
#12 0x00007fb4aa0960dd in ndr_print_share_mode_data (ndr=0x559a1b884160, name=0x7fb4aaea411d "d", r=0x559a1b858e60) at default/source3/librpc/gen_ndr/ndr_open_files.c:527
        cntr_share_modes_0 = 0
        cntr_leases_0 = 0
        cntr_delete_tokens_0 = 0
#13 0x00007fb4a3b5f2fe in ndr_print_debug (fn=0x7fb4aa095eb4 <ndr_print_share_mode_data>, name=0x7fb4aaea411d "d", ptr=0x559a1b858e60) at ../librpc/ndr/ndr.c:420
        ndr = 0x559a1b884160
        __FUNCTION__ = "ndr_print_debug"
#14 0x00007fb4aad8c995 in share_mode_traverse_fn (rec=0x7ffcd1993ba0, _state=0x7ffcd1993ec0) at ../source3/locking/share_mode_lock.c:846
        state = 0x7ffcd1993ec0
        i = 1
        key = {dptr = 0x559a1b865ff0 <incomplete sequence \375>, dsize = 24}
        value = {dptr = 0x559a1b86600c "\324\f)M\244\333o\301", dsize = 348}
        blob = {data = 0x559a1b86600c "\324\f)M\244\333o\301", length = 348}
        ndr_err = NDR_ERR_SUCCESS
        d = 0x559a1b858e60
        fid = {devid = 64770, inode = 11919960, extid = 0}
        ret = 32764
        __FUNCTION__ = "share_mode_traverse_fn"
#15 0x00007fb4a8eb232e in dbwrap_watched_traverse_fn (rec=0x7ffcd1993c30, private_data=0x7ffcd1993e40) at ../source3/lib/dbwrap/dbwrap_watch.c:438
        state = 0x7ffcd1993e40
        num_watchers = 0
        prec = {db = 0x559a1b83c030, key = {dptr = 0x559a1b865ff0 <incomplete sequence \375>, dsize = 24}, value = {dptr = 0x559a1b86600c "\324\f)M\244\333o\301", dsize = 348}, store = 0x7fb4a4727d4b <db_tdb_store_deny>, delete_rec = 0x7fb4a4727d6e <db_tdb_delete_deny>, private_data = 0x559a1b83c140}
        deleted = false
#16 0x00007fb4a4727e26 in db_tdb_traverse_read_func (tdb=0x559a1b83c3f0, kbuf=..., dbuf=..., private_data=0x7ffcd1993da0) at ../lib/dbwrap/dbwrap_tdb.c:331
        ctx = 0x7ffcd1993da0
        rec = {db = 0x559a1b83c030, key = {dptr = 0x559a1b865ff0 <incomplete sequence \375>, dsize = 24}, value = {dptr = 0x559a1b866008 "", dsize = 352}, store = 0x7fb4a4727d4b <db_tdb_store_deny>, delete_rec = 0x7fb4a4727d6e <db_tdb_delete_deny>, private_data = 0x559a1b83c140}
#17 0x00007fb4a4fd3642 in tdb_traverse_internal (tdb=0x559a1b83c3f0, fn=0x7fb4a4727d7d <db_tdb_traverse_read_func>, private_data=0x7ffcd1993da0, tl=0x7ffcd1993d40) at ../lib/tdb/common/traverse.c:225
        full_len = 376
        nread = 0
        key = {dptr = 0x559a1b865ff0 <incomplete sequence \375>, dsize = 24}
        dbuf = {dptr = 0x559a1b866008 "", dsize = 352}
        rec = {next = 0, rec_len = 476, key_len = 24, data_len = 352, full_hash = 73095361, magic = 637606297}
        ret = 0
        count = 1
        off = 89548
        recbuf_len = 4096
#18 0x00007fb4a4fd3779 in tdb_traverse_read (tdb=0x559a1b83c3f0, fn=0x7fb4a4727d7d <db_tdb_traverse_read_func>, private_data=0x7ffcd1993da0) at ../lib/tdb/common/traverse.c:263
        tl = {next = 0x0, off = 89548, hash = 4233, lock_rw = 0}
        ret = 32692
#19 0x00007fb4a4727e96 in db_tdb_traverse_read (db=0x559a1b83c030, f=0x7fb4a8eb226b <dbwrap_watched_traverse_fn>, private_data=0x7ffcd1993e40) at ../lib/dbwrap/dbwrap_tdb.c:345
        db_ctx = 0x559a1b83c140
        ctx = {db = 0x559a1b83c030, f = 0x7fb4a8eb226b <dbwrap_watched_traverse_fn>, private_data = 0x7ffcd1993e40}
#20 0x00007fb4a47238d4 in dbwrap_traverse_read (db=0x559a1b83c030, f=0x7fb4a8eb226b <dbwrap_watched_traverse_fn>, private_data=0x7ffcd1993e40, count=0x7ffcd1993e34) at ../lib/dbwrap/dbwrap.c:343
        ret = 32764
#21 0x00007fb4a8eb241d in dbwrap_watched_traverse_read (db=0x559a1b83c530, fn=0x7fb4aad8c76d <share_mode_traverse_fn>, private_data=0x7ffcd1993ec0) at ../source3/lib/dbwrap/dbwrap_watch.c:473
        ctx = 0x559a1b83b560
        state = {fn = 0x7fb4aad8c76d <share_mode_traverse_fn>, private_data = 0x7ffcd1993ec0}
        status = {v = 0}
        ret = 0
#22 0x00007fb4a47238d4 in dbwrap_traverse_read (db=0x559a1b83c530, f=0x7fb4aad8c76d <share_mode_traverse_fn>, private_data=0x7ffcd1993ec0, count=0x7ffcd1993ebc) at ../lib/dbwrap/dbwrap.c:343
        ret = 32764
#23 0x00007fb4aad8ca3c in share_mode_forall (fn=0x7fb4aac6f4f8 <files_below_forall_fn>, private_data=0x7ffcd1993f10) at ../source3/locking/share_mode_lock.c:871
        state = {fn = 0x7fb4aac6f4f8 <files_below_forall_fn>, private_data = 0x7ffcd1993f10}
        status = {v = 6}
        count = 0
#24 0x00007fb4aac6f732 in files_below_forall (conn=0x559a1b7e4e20, dir_name=0x559a1b865340, fn=0x7fb4aac6f781 <have_file_open_below_fn>, private_data=0x7ffcd1994f6b) at ../source3/smbd/dir.c:2076
        state = {dirpath = 0x7ffcd1993f30 "/home/abokovoy/src/samba/st/nt4_dc/share/trans2", dirpath_len = 47, fn = 0x7fb4aac6f781 <have_file_open_below_fn>, private_data = 0x7ffcd1994f6b}
        ret = 0
        tmpbuf = "/home/abokovoy/src/samba/st/nt4_dc/share/trans2\000\b@\231\321\374\177\000\000\n\000\000\000\264\177\000\000\060@\231\321\374\177\000\000^[9\247\264\177\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000cD\231\321\374\177\000\000\060E\231\321\374\177\000\000 E\231\321\374\177\000\000H\335ɏ\264\177\000\000\230F\231\321\374\177\000\000\000\000\000\000\000\000\000\000i\335ɏ\264\177\000\000\221a6\247\264\177\000\000\200@\231\321\374\177\000\000\000\000\000\000\000\000\000\000\210@\231\321\374\177\000\000^[9\247\264\177\000\000\260@\231\321\374\177\000\000\001", '\000' <repeats 15 times>...
        to_free = 0x0

--
/ Alexander Bokovoy

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] libads: abstract out SASL wrapping code

Samba - samba-technical mailing list
On Monday, 15 May 2017 20:47:13 CEST Alexander Bokovoy via samba-technical
wrote:

> On ti, 16 touko 2017, Andrew Bartlett wrote:
> > On Mon, 2017-05-15 at 17:28 +0300, Alexander Bokovoy via samba-
> >
> > technical wrote:
> > > > Notice NT_STATUS_CONNECTION_DISCONNECT message garbled?
> > > >
> > > > I'm still trying to understand what broke -- on client side we seem
> > > > never get back (my debug statements never get printed) after
> > > > successful
> > > > SASL GSS-SPNEGO bind.
> > >
> > > Attached patch passes samba.tests.pam_winbind test.
> >
> > Thanks for all your hard work on this.  What was the problem in the
> > LDAP server in the end?
>
> I haven't found that yet as I fixed one wrong pointer pass in my code
> and went away with that. However, if you look at the output in my
> previous email, it looks like the error string is garbled at the end, so
> there is something off-by-one somewhere.
>
> I also get crash in GUID_buf_string() because I run 'make test' with
> high enough log level and source3/locking/share_mode_lock.c:846 causes
> an NDR print out of a share mode lock entry for log level 11 or above.
> As result, there seem to be a garbled GUID.
>
> The test is samba3.smbtorture_s3.crypt_client(nt4_dc).TORTURE(nt4_dc).
>
>
> #5  0x00007fb4ab130aa1 in sig_fault (sig=11) at ../lib/util/fault.c:94
> No locals.
> #6  <signal handler called>
> No symbol table info available.
> #7  0x00007fb4a3b5e174 in GUID_buf_string (guid=0x55d21b7dd178,
> dst=0x7ffcd1993960) at ../librpc/ndr/uuid.c:335 No locals.
> #8  0x00007fb4a3b5e122 in GUID_string (mem_ctx=0x559a1b884160,
> guid=0x55d21b7dd178) at ../librpc/ndr/uuid.c:314 buf = {buf =
> "`\324m\247\264\177\000\000`W\210\033\232U\000\000ma touko 15 20.59.13 20"}
> #9  0x00007fb4a3b623ef in ndr_print_GUID (ndr=0x559a1b884160,
> name=0x7fb4aa0e80b4 "client_guid", guid=0x55d21b7dd178) at
> ../librpc/ndr/ndr_misc.c:29 No locals.
> #10 0x00007fb4aa09272f in ndr_print_share_mode_lease (ndr=0x559a1b884160,
> name=0x7fb4aa0e82fb "lease", r=0x55d21b7dd178) at
> default/source3/librpc/gen_ndr/ndr_open_files.c:69 _flags_save_STRUCT = 0
> #11 0x00007fb4aa09331c in ndr_print_share_mode_entry (ndr=0x559a1b884160,
> name=0x7fb4aa0e8c56 "share_modes", r=0x559a1b830270) at
> default/source3/librpc/gen_ndr/ndr_open_files.c:176 No locals.
> #12 0x00007fb4aa0960dd in ndr_print_share_mode_data (ndr=0x559a1b884160,
> name=0x7fb4aaea411d "d", r=0x559a1b858e60) at
> default/source3/librpc/gen_ndr/ndr_open_files.c:527 cntr_share_modes_0 = 0
>         cntr_leases_0 = 0
>         cntr_delete_tokens_0 = 0
> #13 0x00007fb4a3b5f2fe in ndr_print_debug (fn=0x7fb4aa095eb4
> <ndr_print_share_mode_data>, name=0x7fb4aaea411d "d", ptr=0x559a1b858e60)
> at ../librpc/ndr/ndr.c:420 ndr = 0x559a1b884160
>         __FUNCTION__ = "ndr_print_debug"
> #14 0x00007fb4aad8c995 in share_mode_traverse_fn (rec=0x7ffcd1993ba0,
> _state=0x7ffcd1993ec0) at ../source3/locking/share_mode_lock.c:846 state =
> 0x7ffcd1993ec0
>         i = 1
>         key = {dptr = 0x559a1b865ff0 <incomplete sequence \375>, dsize = 24}
> value = {dptr = 0x559a1b86600c "\324\f)M\244\333o\301", dsize = 348} blob =
> {data = 0x559a1b86600c "\324\f)M\244\333o\301", length = 348} ndr_err =
> NDR_ERR_SUCCESS
>         d = 0x559a1b858e60
>         fid = {devid = 64770, inode = 11919960, extid = 0}
>         ret = 32764
>         __FUNCTION__ = "share_mode_traverse_fn"
> #15 0x00007fb4a8eb232e in dbwrap_watched_traverse_fn (rec=0x7ffcd1993c30,
> private_data=0x7ffcd1993e40) at ../source3/lib/dbwrap/dbwrap_watch.c:438
> state = 0x7ffcd1993e40
>         num_watchers = 0
>         prec = {db = 0x559a1b83c030, key = {dptr = 0x559a1b865ff0
> <incomplete sequence \375>, dsize = 24}, value = {dptr = 0x559a1b86600c
> "\324\f)M\244\333o\301", dsize = 348}, store = 0x7fb4a4727d4b
> <db_tdb_store_deny>, delete_rec = 0x7fb4a4727d6e <db_tdb_delete_deny>,
> private_data = 0x559a1b83c140} deleted = false
> #16 0x00007fb4a4727e26 in db_tdb_traverse_read_func (tdb=0x559a1b83c3f0,
> kbuf=..., dbuf=..., private_data=0x7ffcd1993da0) at
> ../lib/dbwrap/dbwrap_tdb.c:331 ctx = 0x7ffcd1993da0
>         rec = {db = 0x559a1b83c030, key = {dptr = 0x559a1b865ff0 <incomplete
> sequence \375>, dsize = 24}, value = {dptr = 0x559a1b866008 "", dsize =
> 352}, store = 0x7fb4a4727d4b <db_tdb_store_deny>, delete_rec =
> 0x7fb4a4727d6e <db_tdb_delete_deny>, private_data = 0x559a1b83c140} #17
> 0x00007fb4a4fd3642 in tdb_traverse_internal (tdb=0x559a1b83c3f0,
> fn=0x7fb4a4727d7d <db_tdb_traverse_read_func>, private_data=0x7ffcd1993da0,
> tl=0x7ffcd1993d40) at ../lib/tdb/common/traverse.c:225 full_len = 376
>         nread = 0
>         key = {dptr = 0x559a1b865ff0 <incomplete sequence \375>, dsize = 24}
> dbuf = {dptr = 0x559a1b866008 "", dsize = 352}
>         rec = {next = 0, rec_len = 476, key_len = 24, data_len = 352,
> full_hash = 73095361, magic = 637606297} ret = 0
>         count = 1
>         off = 89548
>         recbuf_len = 4096
> #18 0x00007fb4a4fd3779 in tdb_traverse_read (tdb=0x559a1b83c3f0,
> fn=0x7fb4a4727d7d <db_tdb_traverse_read_func>, private_data=0x7ffcd1993da0)
> at ../lib/tdb/common/traverse.c:263 tl = {next = 0x0, off = 89548, hash =
> 4233, lock_rw = 0}
>         ret = 32692
> #19 0x00007fb4a4727e96 in db_tdb_traverse_read (db=0x559a1b83c030,
> f=0x7fb4a8eb226b <dbwrap_watched_traverse_fn>, private_data=0x7ffcd1993e40)
> at ../lib/dbwrap/dbwrap_tdb.c:345 db_ctx = 0x559a1b83c140
>         ctx = {db = 0x559a1b83c030, f = 0x7fb4a8eb226b
> <dbwrap_watched_traverse_fn>, private_data = 0x7ffcd1993e40} #20
> 0x00007fb4a47238d4 in dbwrap_traverse_read (db=0x559a1b83c030,
> f=0x7fb4a8eb226b <dbwrap_watched_traverse_fn>, private_data=0x7ffcd1993e40,
> count=0x7ffcd1993e34) at ../lib/dbwrap/dbwrap.c:343 ret = 32764
> #21 0x00007fb4a8eb241d in dbwrap_watched_traverse_read (db=0x559a1b83c530,
> fn=0x7fb4aad8c76d <share_mode_traverse_fn>, private_data=0x7ffcd1993ec0) at
> ../source3/lib/dbwrap/dbwrap_watch.c:473 ctx = 0x559a1b83b560
>         state = {fn = 0x7fb4aad8c76d <share_mode_traverse_fn>, private_data
> = 0x7ffcd1993ec0} status = {v = 0}
>         ret = 0
> #22 0x00007fb4a47238d4 in dbwrap_traverse_read (db=0x559a1b83c530,
> f=0x7fb4aad8c76d <share_mode_traverse_fn>, private_data=0x7ffcd1993ec0,
> count=0x7ffcd1993ebc) at ../lib/dbwrap/dbwrap.c:343 ret = 32764
> #23 0x00007fb4aad8ca3c in share_mode_forall (fn=0x7fb4aac6f4f8
> <files_below_forall_fn>, private_data=0x7ffcd1993f10) at
> ../source3/locking/share_mode_lock.c:871 state = {fn = 0x7fb4aac6f4f8
> <files_below_forall_fn>, private_data = 0x7ffcd1993f10} status = {v = 6}
>         count = 0
> #24 0x00007fb4aac6f732 in files_below_forall (conn=0x559a1b7e4e20,
> dir_name=0x559a1b865340, fn=0x7fb4aac6f781 <have_file_open_below_fn>,
> private_data=0x7ffcd1994f6b) at ../source3/smbd/dir.c:2076 state = {dirpath
> = 0x7ffcd1993f30 "/home/abokovoy/src/samba/st/nt4_dc/share/trans2",
> dirpath_len = 47, fn = 0x7fb4aac6f781 <have_file_open_below_fn>,
> private_data = 0x7ffcd1994f6b} ret = 0
>         tmpbuf =
> "/home/abokovoy/src/samba/st/nt4_dc/share/trans2\000\b@\231\321\374\177\000
> \000\n\000\000\000\264\177\000\000\060@\231\321\374\177\000\000^[9\247\264\1
> 77\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000cD
> \231\321\374\177\000\000\060E\231\321\374\177\000\000
> E\231\321\374\177\000\000H\335ɏ\264\177\000\000\230F\231\321\374\177\000\00
> 0\000\000\000\000\000\000\000\000i\335ɏ\264\177\000\000\221a6\247\264\177\00
> 0\000\200@\231\321\374\177\000\000\000\000\000\000\000\000\000\000\210@\231\
> 321\374\177\000\000^[9\247\264\177\000\000\260@\231\321\374\177\000\000\001"
> , '\000' <repeats 15 times>... to_free = 0x0


That might be the bug of the faililng test we are seeing from time to time!!
If you have crippled string it could also mean that it is hanging on the wrong
talloc context and the context has already been freed!


        Andreas

--
Andreas Schneider                   GPG-ID: CC014E3D
Samba Team                             [hidden email]
www.samba.org

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] libads: abstract out SASL wrapping code

Samba - samba-technical mailing list
In reply to this post by Samba - samba-technical mailing list
On Monday, 15 May 2017 20:47:13 CEST Alexander Bokovoy via samba-technical
wrote:

> On ti, 16 touko 2017, Andrew Bartlett wrote:
> > On Mon, 2017-05-15 at 17:28 +0300, Alexander Bokovoy via samba-
> >
> > technical wrote:
> > > > Notice NT_STATUS_CONNECTION_DISCONNECT message garbled?
> > > >
> > > > I'm still trying to understand what broke -- on client side we seem
> > > > never get back (my debug statements never get printed) after
> > > > successful
> > > > SASL GSS-SPNEGO bind.
> > >
> > > Attached patch passes samba.tests.pam_winbind test.
> >
> > Thanks for all your hard work on this.  What was the problem in the
> > LDAP server in the end?
>
> I haven't found that yet as I fixed one wrong pointer pass in my code
> and went away with that. However, if you look at the output in my
> previous email, it looks like the error string is garbled at the end, so
> there is something off-by-one somewhere.
>
> I also get crash in GUID_buf_string() because I run 'make test' with
> high enough log level and source3/locking/share_mode_lock.c:846 causes
> an NDR print out of a share mode lock entry for log level 11 or above.
> As result, there seem to be a garbled GUID.
>
> The test is samba3.smbtorture_s3.crypt_client(nt4_dc).TORTURE(nt4_dc).
>
>
> #5  0x00007fb4ab130aa1 in sig_fault (sig=11) at ../lib/util/fault.c:94
> No locals.
> #6  <signal handler called>
> No symbol table info available.
> #7  0x00007fb4a3b5e174 in GUID_buf_string (guid=0x55d21b7dd178,
> dst=0x7ffcd1993960) at ../librpc/ndr/uuid.c:335 No locals.
> #8  0x00007fb4a3b5e122 in GUID_string (mem_ctx=0x559a1b884160,
> guid=0x55d21b7dd178) at ../librpc/ndr/uuid.c:314 buf = {buf =
> "`\324m\247\264\177\000\000`W\210\033\232U\000\000ma touko 15 20.59.13 20"}
> #9  0x00007fb4a3b623ef in ndr_print_GUID (ndr=0x559a1b884160,
> name=0x7fb4aa0e80b4 "client_guid", guid=0x55d21b7dd178) at
> ../librpc/ndr/ndr_misc.c:29 No locals.
> #10 0x00007fb4aa09272f in ndr_print_share_mode_lease (ndr=0x559a1b884160,
> name=0x7fb4aa0e82fb "lease", r=0x55d21b7dd178) at
> default/source3/librpc/gen_ndr/ndr_open_files.c:69 _flags_save_STRUCT = 0
> #11 0x00007fb4aa09331c in ndr_print_share_mode_entry (ndr=0x559a1b884160,
> name=0x7fb4aa0e8c56 "share_modes", r=0x559a1b830270) at
> default/source3/librpc/gen_ndr/ndr_open_files.c:176 No locals.
> #12 0x00007fb4aa0960dd in ndr_print_share_mode_data (ndr=0x559a1b884160,
> name=0x7fb4aaea411d "d", r=0x559a1b858e60) at
> default/source3/librpc/gen_ndr/ndr_open_files.c:527 cntr_share_modes_0 = 0
>         cntr_leases_0 = 0
>         cntr_delete_tokens_0 = 0
> #13 0x00007fb4a3b5f2fe in ndr_print_debug (fn=0x7fb4aa095eb4
> <ndr_print_share_mode_data>, name=0x7fb4aaea411d "d", ptr=0x559a1b858e60)
> at ../librpc/ndr/ndr.c:420 ndr = 0x559a1b884160
>         __FUNCTION__ = "ndr_print_debug"
> #14 0x00007fb4aad8c995 in share_mode_traverse_fn (rec=0x7ffcd1993ba0,
> _state=0x7ffcd1993ec0) at ../source3/locking/share_mode_lock.c:846 state =
> 0x7ffcd1993ec0
>         i = 1
>         key = {dptr = 0x559a1b865ff0 <incomplete sequence \375>, dsize = 24}
> value = {dptr = 0x559a1b86600c "\324\f)M\244\333o\301", dsize = 348} blob =
> {data = 0x559a1b86600c "\324\f)M\244\333o\301", length = 348} ndr_err =
> NDR_ERR_SUCCESS
>         d = 0x559a1b858e60
>         fid = {devid = 64770, inode = 11919960, extid = 0}
>         ret = 32764
>         __FUNCTION__ = "share_mode_traverse_fn"

We traverse the database here and we do have a lease without a client_guid. I
do not find the place where this database entry is written. So we need to find
the place which doesn't add the client_guid.




--
Andreas Schneider                   GPG-ID: CC014E3D
Samba Team                             [hidden email]
www.samba.org

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] libads: abstract out SASL wrapping code

Samba - samba-technical mailing list
On Tuesday, 16 May 2017 09:56:08 CEST Andreas Schneider via samba-technical
wrote:

> On Monday, 15 May 2017 20:47:13 CEST Alexander Bokovoy via samba-technical
>
> wrote:
> > On ti, 16 touko 2017, Andrew Bartlett wrote:
> > > On Mon, 2017-05-15 at 17:28 +0300, Alexander Bokovoy via samba-
> > >
> > > technical wrote:
> > > > > Notice NT_STATUS_CONNECTION_DISCONNECT message garbled?
> > > > >
> > > > > I'm still trying to understand what broke -- on client side we seem
> > > > > never get back (my debug statements never get printed) after
> > > > > successful
> > > > > SASL GSS-SPNEGO bind.
> > > >
> > > > Attached patch passes samba.tests.pam_winbind test.
> > >
> > > Thanks for all your hard work on this.  What was the problem in the
> > > LDAP server in the end?
> >
> > I haven't found that yet as I fixed one wrong pointer pass in my code
> > and went away with that. However, if you look at the output in my
> > previous email, it looks like the error string is garbled at the end, so
> > there is something off-by-one somewhere.
> >
> > I also get crash in GUID_buf_string() because I run 'make test' with
> > high enough log level and source3/locking/share_mode_lock.c:846 causes
> > an NDR print out of a share mode lock entry for log level 11 or above.
> > As result, there seem to be a garbled GUID.
> >
> > The test is samba3.smbtorture_s3.crypt_client(nt4_dc).TORTURE(nt4_dc).
> >
> >
> > #5  0x00007fb4ab130aa1 in sig_fault (sig=11) at ../lib/util/fault.c:94
> > No locals.
> > #6  <signal handler called>
> > No symbol table info available.
> > #7  0x00007fb4a3b5e174 in GUID_buf_string (guid=0x55d21b7dd178,
> > dst=0x7ffcd1993960) at ../librpc/ndr/uuid.c:335 No locals.
> > #8  0x00007fb4a3b5e122 in GUID_string (mem_ctx=0x559a1b884160,
> > guid=0x55d21b7dd178) at ../librpc/ndr/uuid.c:314 buf = {buf =
> > "`\324m\247\264\177\000\000`W\210\033\232U\000\000ma touko 15 20.59.13
> > 20"}
> > #9  0x00007fb4a3b623ef in ndr_print_GUID (ndr=0x559a1b884160,
> > name=0x7fb4aa0e80b4 "client_guid", guid=0x55d21b7dd178) at
> > ../librpc/ndr/ndr_misc.c:29 No locals.
> > #10 0x00007fb4aa09272f in ndr_print_share_mode_lease (ndr=0x559a1b884160,
> > name=0x7fb4aa0e82fb "lease", r=0x55d21b7dd178) at
> > default/source3/librpc/gen_ndr/ndr_open_files.c:69 _flags_save_STRUCT = 0
> > #11 0x00007fb4aa09331c in ndr_print_share_mode_entry (ndr=0x559a1b884160,
> > name=0x7fb4aa0e8c56 "share_modes", r=0x559a1b830270) at
> > default/source3/librpc/gen_ndr/ndr_open_files.c:176 No locals.
> > #12 0x00007fb4aa0960dd in ndr_print_share_mode_data (ndr=0x559a1b884160,
> > name=0x7fb4aaea411d "d", r=0x559a1b858e60) at
> > default/source3/librpc/gen_ndr/ndr_open_files.c:527 cntr_share_modes_0 = 0
> >
> >         cntr_leases_0 = 0
> >         cntr_delete_tokens_0 = 0
> >
> > #13 0x00007fb4a3b5f2fe in ndr_print_debug (fn=0x7fb4aa095eb4
> > <ndr_print_share_mode_data>, name=0x7fb4aaea411d "d", ptr=0x559a1b858e60)
> > at ../librpc/ndr/ndr.c:420 ndr = 0x559a1b884160
> >
> >         __FUNCTION__ = "ndr_print_debug"
> >
> > #14 0x00007fb4aad8c995 in share_mode_traverse_fn (rec=0x7ffcd1993ba0,
> > _state=0x7ffcd1993ec0) at ../source3/locking/share_mode_lock.c:846 state =
> > 0x7ffcd1993ec0
> >
> >         i = 1
> >         key = {dptr = 0x559a1b865ff0 <incomplete sequence \375>, dsize =
> >         24}
> >
> > value = {dptr = 0x559a1b86600c "\324\f)M\244\333o\301", dsize = 348} blob
> > =
> > {data = 0x559a1b86600c "\324\f)M\244\333o\301", length = 348} ndr_err =
> > NDR_ERR_SUCCESS
> >
> >         d = 0x559a1b858e60
> >         fid = {devid = 64770, inode = 11919960, extid = 0}
> >         ret = 32764
> >         __FUNCTION__ = "share_mode_traverse_fn"
>
> We traverse the database here and we do have a lease without a client_guid.
> I do not find the place where this database entry is written. So we need to
> find the place which doesn't add the client_guid.


Reproducer:

make -j test TESTS="samba3.smbtorture_s3.crypt_client" SMBD_OPTIONS=-d11
WINBINDD_OPTIONS=-d11

--
Andreas Schneider                   GPG-ID: CC014E3D
Samba Team                             [hidden email]
www.samba.org

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] libads: abstract out SASL wrapping code

Samba - samba-technical mailing list
On Tue, May 16, 2017 at 10:00:24AM +0200, Andreas Schneider wrote:

> On Tuesday, 16 May 2017 09:56:08 CEST Andreas Schneider via samba-technical
> wrote:
> > On Monday, 15 May 2017 20:47:13 CEST Alexander Bokovoy via samba-technical
> >
> > wrote:
> > > On ti, 16 touko 2017, Andrew Bartlett wrote:
> > > > On Mon, 2017-05-15 at 17:28 +0300, Alexander Bokovoy via samba-
> > > >
> > > > technical wrote:
> > > > > > Notice NT_STATUS_CONNECTION_DISCONNECT message garbled?
> > > > > >
> > > > > > I'm still trying to understand what broke -- on client side we seem
> > > > > > never get back (my debug statements never get printed) after
> > > > > > successful
> > > > > > SASL GSS-SPNEGO bind.
> > > > >
> > > > > Attached patch passes samba.tests.pam_winbind test.
> > > >
> > > > Thanks for all your hard work on this.  What was the problem in the
> > > > LDAP server in the end?
> > >
> > > I haven't found that yet as I fixed one wrong pointer pass in my code
> > > and went away with that. However, if you look at the output in my
> > > previous email, it looks like the error string is garbled at the end, so
> > > there is something off-by-one somewhere.
> > >
> > > I also get crash in GUID_buf_string() because I run 'make test' with
> > > high enough log level and source3/locking/share_mode_lock.c:846 causes
> > > an NDR print out of a share mode lock entry for log level 11 or above.
> > > As result, there seem to be a garbled GUID.
> > >
> > > The test is samba3.smbtorture_s3.crypt_client(nt4_dc).TORTURE(nt4_dc).
> > >
> > >
> > > #5  0x00007fb4ab130aa1 in sig_fault (sig=11) at ../lib/util/fault.c:94
> > > No locals.
> > > #6  <signal handler called>
> > > No symbol table info available.
> > > #7  0x00007fb4a3b5e174 in GUID_buf_string (guid=0x55d21b7dd178,
> > > dst=0x7ffcd1993960) at ../librpc/ndr/uuid.c:335 No locals.
> > > #8  0x00007fb4a3b5e122 in GUID_string (mem_ctx=0x559a1b884160,
> > > guid=0x55d21b7dd178) at ../librpc/ndr/uuid.c:314 buf = {buf =
> > > "`\324m\247\264\177\000\000`W\210\033\232U\000\000ma touko 15 20.59.13
> > > 20"}
> > > #9  0x00007fb4a3b623ef in ndr_print_GUID (ndr=0x559a1b884160,
> > > name=0x7fb4aa0e80b4 "client_guid", guid=0x55d21b7dd178) at
> > > ../librpc/ndr/ndr_misc.c:29 No locals.
> > > #10 0x00007fb4aa09272f in ndr_print_share_mode_lease (ndr=0x559a1b884160,
> > > name=0x7fb4aa0e82fb "lease", r=0x55d21b7dd178) at
> > > default/source3/librpc/gen_ndr/ndr_open_files.c:69 _flags_save_STRUCT = 0
> > > #11 0x00007fb4aa09331c in ndr_print_share_mode_entry (ndr=0x559a1b884160,
> > > name=0x7fb4aa0e8c56 "share_modes", r=0x559a1b830270) at
> > > default/source3/librpc/gen_ndr/ndr_open_files.c:176 No locals.
> > > #12 0x00007fb4aa0960dd in ndr_print_share_mode_data (ndr=0x559a1b884160,
> > > name=0x7fb4aaea411d "d", r=0x559a1b858e60) at
> > > default/source3/librpc/gen_ndr/ndr_open_files.c:527 cntr_share_modes_0 = 0
> > >
> > >         cntr_leases_0 = 0
> > >         cntr_delete_tokens_0 = 0
> > >
> > > #13 0x00007fb4a3b5f2fe in ndr_print_debug (fn=0x7fb4aa095eb4
> > > <ndr_print_share_mode_data>, name=0x7fb4aaea411d "d", ptr=0x559a1b858e60)
> > > at ../librpc/ndr/ndr.c:420 ndr = 0x559a1b884160
> > >
> > >         __FUNCTION__ = "ndr_print_debug"
> > >
> > > #14 0x00007fb4aad8c995 in share_mode_traverse_fn (rec=0x7ffcd1993ba0,
> > > _state=0x7ffcd1993ec0) at ../source3/locking/share_mode_lock.c:846 state =
> > > 0x7ffcd1993ec0
> > >
> > >         i = 1
> > >         key = {dptr = 0x559a1b865ff0 <incomplete sequence \375>, dsize =
> > >         24}
> > >
> > > value = {dptr = 0x559a1b86600c "\324\f)M\244\333o\301", dsize = 348} blob
> > > =
> > > {data = 0x559a1b86600c "\324\f)M\244\333o\301", length = 348} ndr_err =
> > > NDR_ERR_SUCCESS
> > >
> > >         d = 0x559a1b858e60
> > >         fid = {devid = 64770, inode = 11919960, extid = 0}
> > >         ret = 32764
> > >         __FUNCTION__ = "share_mode_traverse_fn"
> >
> > We traverse the database here and we do have a lease without a client_guid.
> > I do not find the place where this database entry is written. So we need to
> > find the place which doesn't add the client_guid.
>
>
> Reproducer:
>
> make -j test TESTS="samba3.smbtorture_s3.crypt_client" SMBD_OPTIONS=-d11
> WINBINDD_OPTIONS=-d11

Thanks Andreas, I'll take a look !

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] libads: abstract out SASL wrapping code

Samba - samba-technical mailing list
In reply to this post by Samba - samba-technical mailing list
On Tue, May 16, 2017 at 10:00:24AM +0200, Andreas Schneider wrote:

> On Tuesday, 16 May 2017 09:56:08 CEST Andreas Schneider via samba-technical
> wrote:
> > On Monday, 15 May 2017 20:47:13 CEST Alexander Bokovoy via samba-technical
> >
> > wrote:
> > > On ti, 16 touko 2017, Andrew Bartlett wrote:
> > > > On Mon, 2017-05-15 at 17:28 +0300, Alexander Bokovoy via samba-
> > > >
> > > > technical wrote:
> > > > > > Notice NT_STATUS_CONNECTION_DISCONNECT message garbled?
> > > > > >
> > > > > > I'm still trying to understand what broke -- on client side we seem
> > > > > > never get back (my debug statements never get printed) after
> > > > > > successful
> > > > > > SASL GSS-SPNEGO bind.
> > > > >
> > > > > Attached patch passes samba.tests.pam_winbind test.
> > > >
> > > > Thanks for all your hard work on this.  What was the problem in the
> > > > LDAP server in the end?
> > >
> > > I haven't found that yet as I fixed one wrong pointer pass in my code
> > > and went away with that. However, if you look at the output in my
> > > previous email, it looks like the error string is garbled at the end, so
> > > there is something off-by-one somewhere.
> > >
> > > I also get crash in GUID_buf_string() because I run 'make test' with
> > > high enough log level and source3/locking/share_mode_lock.c:846 causes
> > > an NDR print out of a share mode lock entry for log level 11 or above.
> > > As result, there seem to be a garbled GUID.
> > >
> > > The test is samba3.smbtorture_s3.crypt_client(nt4_dc).TORTURE(nt4_dc).
> > >
> > >
> > > #5  0x00007fb4ab130aa1 in sig_fault (sig=11) at ../lib/util/fault.c:94
> > > No locals.
> > > #6  <signal handler called>
> > > No symbol table info available.
> > > #7  0x00007fb4a3b5e174 in GUID_buf_string (guid=0x55d21b7dd178,
> > > dst=0x7ffcd1993960) at ../librpc/ndr/uuid.c:335 No locals.
> > > #8  0x00007fb4a3b5e122 in GUID_string (mem_ctx=0x559a1b884160,
> > > guid=0x55d21b7dd178) at ../librpc/ndr/uuid.c:314 buf = {buf =
> > > "`\324m\247\264\177\000\000`W\210\033\232U\000\000ma touko 15 20.59.13
> > > 20"}
> > > #9  0x00007fb4a3b623ef in ndr_print_GUID (ndr=0x559a1b884160,
> > > name=0x7fb4aa0e80b4 "client_guid", guid=0x55d21b7dd178) at
> > > ../librpc/ndr/ndr_misc.c:29 No locals.
> > > #10 0x00007fb4aa09272f in ndr_print_share_mode_lease (ndr=0x559a1b884160,
> > > name=0x7fb4aa0e82fb "lease", r=0x55d21b7dd178) at
> > > default/source3/librpc/gen_ndr/ndr_open_files.c:69 _flags_save_STRUCT = 0
> > > #11 0x00007fb4aa09331c in ndr_print_share_mode_entry (ndr=0x559a1b884160,
> > > name=0x7fb4aa0e8c56 "share_modes", r=0x559a1b830270) at
> > > default/source3/librpc/gen_ndr/ndr_open_files.c:176 No locals.
> > > #12 0x00007fb4aa0960dd in ndr_print_share_mode_data (ndr=0x559a1b884160,
> > > name=0x7fb4aaea411d "d", r=0x559a1b858e60) at
> > > default/source3/librpc/gen_ndr/ndr_open_files.c:527 cntr_share_modes_0 = 0
> > >
> > >         cntr_leases_0 = 0
> > >         cntr_delete_tokens_0 = 0
> > >
> > > #13 0x00007fb4a3b5f2fe in ndr_print_debug (fn=0x7fb4aa095eb4
> > > <ndr_print_share_mode_data>, name=0x7fb4aaea411d "d", ptr=0x559a1b858e60)
> > > at ../librpc/ndr/ndr.c:420 ndr = 0x559a1b884160
> > >
> > >         __FUNCTION__ = "ndr_print_debug"
> > >
> > > #14 0x00007fb4aad8c995 in share_mode_traverse_fn (rec=0x7ffcd1993ba0,
> > > _state=0x7ffcd1993ec0) at ../source3/locking/share_mode_lock.c:846 state =
> > > 0x7ffcd1993ec0
> > >
> > >         i = 1
> > >         key = {dptr = 0x559a1b865ff0 <incomplete sequence \375>, dsize =
> > >         24}
> > >
> > > value = {dptr = 0x559a1b86600c "\324\f)M\244\333o\301", dsize = 348} blob
> > > =
> > > {data = 0x559a1b86600c "\324\f)M\244\333o\301", length = 348} ndr_err =
> > > NDR_ERR_SUCCESS
> > >
> > >         d = 0x559a1b858e60
> > >         fid = {devid = 64770, inode = 11919960, extid = 0}
> > >         ret = 32764
> > >         __FUNCTION__ = "share_mode_traverse_fn"
> >
> > We traverse the database here and we do have a lease without a client_guid.
> > I do not find the place where this database entry is written. So we need to
> > find the place which doesn't add the client_guid.
>
>
> Reproducer:
>
> make -j test TESTS="samba3.smbtorture_s3.crypt_client" SMBD_OPTIONS=-d11
> WINBINDD_OPTIONS=-d11

I think I know what is going on here. Let me see if I can
find an easy fix..

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] libads: abstract out SASL wrapping code

Samba - samba-technical mailing list
In reply to this post by Samba - samba-technical mailing list
On Tue, May 16, 2017 at 10:00:24AM +0200, Andreas Schneider wrote:
>
> Reproducer:
>
> make -j test TESTS="samba3.smbtorture_s3.crypt_client" SMBD_OPTIONS=-d11
> WINBINDD_OPTIONS=-d11

Logged bug:

https://bugzilla.samba.org/show_bug.cgi?id=12793

I have a fix for this I will post shortly once I'm
sure it's passing full make test.

Jeremy.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] libads: abstract out SASL wrapping code

Samba - samba-technical mailing list
In reply to this post by Samba - samba-technical mailing list
On Mon, May 15, 2017 at 05:28:28PM +0300, Alexander Bokovoy wrote:
> Attached patch passes samba.tests.pam_winbind test.

LGTM. Let's try again :-).

> / Alexander Bokovoy

> From b61efb5c9339f76702fd53effc2134ef3056a62c Mon Sep 17 00:00:00 2001
> From: Alexander Bokovoy <[hidden email]>
> Date: Fri, 5 May 2017 15:37:20 +0300
> Subject: [PATCH] libads: abstract out SASL wrapping code
>
> Prepare for rebasing libads on top of libsmbldap.
>
> To make libads using 'struct smbldap_state' instead of direct LDAP
> structure, we need to abstract out libads logic from connection
> handling. SASL wrapping does not really depend on availability of LDAP
> handle and does not need direct access to ADS_STRUCT. As result, we'll
> be able to move SASL wrapping code under smbldap once the latter is able
> to pass settings that libads passes to the SASL wrapping.
>
> Signed-off-by: Alexander Bokovoy <[hidden email]>
> ---
>  source3/include/ads.h          |  68 ++++++-------
>  source3/libads/ads_proto.h     |   8 +-
>  source3/libads/ldap.c          |  17 ++--
>  source3/libads/ndr.c           |  26 +----
>  source3/libads/sasl.c          | 126 +++++++++++++------------
>  source3/libads/sasl_wrapping.c | 210 ++++++++++++++++++++++++-----------------
>  6 files changed, 243 insertions(+), 212 deletions(-)
>
> diff --git a/source3/include/ads.h b/source3/include/ads.h
> index cacb25c..2b25c1c 100644
> --- a/source3/include/ads.h
> +++ b/source3/include/ads.h
> @@ -9,13 +9,13 @@
>  #include "libads/ads_status.h"
>  #include "smb_ldap.h"
>  
> -struct ads_struct;
> +struct ads_saslwrap;
>  
>  struct ads_saslwrap_ops {
>   const char *name;
> - ADS_STATUS (*wrap)(struct ads_struct *, uint8_t *buf, uint32_t len);
> - ADS_STATUS (*unwrap)(struct ads_struct *);
> - void (*disconnect)(struct ads_struct *);
> + ADS_STATUS (*wrap)(struct ads_saslwrap *, uint8_t *buf, uint32_t len);
> + ADS_STATUS (*unwrap)(struct ads_saslwrap *);
> + void (*disconnect)(struct ads_saslwrap *);
>  };
>  
>  enum ads_saslwrap_type {
> @@ -24,6 +24,37 @@ enum ads_saslwrap_type {
>   ADS_SASLWRAP_TYPE_SEAL = 4
>  };
>  
> +struct ads_saslwrap {
> + /* expected SASL wrapping type */
> + enum ads_saslwrap_type wrap_type;
> + /* SASL wrapping operations */
> + const struct ads_saslwrap_ops *wrap_ops;
> +#ifdef HAVE_LDAP_SASL_WRAPPING
> + Sockbuf_IO_Desc *sbiod; /* lowlevel state for LDAP wrapping */
> +#endif /* HAVE_LDAP_SASL_WRAPPING */
> + TALLOC_CTX *mem_ctx;
> + void *wrap_private_data;
> + struct {
> + uint32_t ofs;
> + uint32_t needed;
> + uint32_t left;
> +#define        ADS_SASL_WRAPPING_IN_MAX_WRAPPED        0x0FFFFFFF
> + uint32_t max_wrapped;
> + uint32_t min_wrapped;
> + uint32_t size;
> + uint8_t *buf;
> + } in;
> + struct {
> + uint32_t ofs;
> + uint32_t left;
> +#define        ADS_SASL_WRAPPING_OUT_MAX_WRAPPED       0x00A00000
> + uint32_t max_unwrapped;
> + uint32_t sig_size;
> + uint32_t size;
> + uint8_t *buf;
> + } out;
> +};
> +
>  typedef struct ads_struct {
>   int is_mine; /* do I own this structure's memory? */
>  
> @@ -65,39 +96,12 @@ typedef struct ads_struct {
>  
>   /* info about the current LDAP connection */
>  #ifdef HAVE_LDAP
> + struct ads_saslwrap ldap_wrap_data;
>   struct {
>   LDAP *ld;
>   struct sockaddr_storage ss; /* the ip of the active connection, if any */
>   time_t last_attempt; /* last attempt to reconnect, monotonic clock */
>   int port;
> -
> - enum ads_saslwrap_type wrap_type;
> -
> -#ifdef HAVE_LDAP_SASL_WRAPPING
> - Sockbuf_IO_Desc *sbiod; /* lowlevel state for LDAP wrapping */
> -#endif /* HAVE_LDAP_SASL_WRAPPING */
> - TALLOC_CTX *mem_ctx;
> - const struct ads_saslwrap_ops *wrap_ops;
> - void *wrap_private_data;
> - struct {
> - uint32_t ofs;
> - uint32_t needed;
> - uint32_t left;
> -#define        ADS_SASL_WRAPPING_IN_MAX_WRAPPED        0x0FFFFFFF
> - uint32_t max_wrapped;
> - uint32_t min_wrapped;
> - uint32_t size;
> - uint8_t *buf;
> - } in;
> - struct {
> - uint32_t ofs;
> - uint32_t left;
> -#define        ADS_SASL_WRAPPING_OUT_MAX_WRAPPED       0x00A00000
> - uint32_t max_unwrapped;
> - uint32_t sig_size;
> - uint32_t size;
> - uint8_t *buf;
> - } out;
>   } ldap;
>  #endif /* HAVE_LDAP */
>  } ADS_STRUCT;
> diff --git a/source3/libads/ads_proto.h b/source3/libads/ads_proto.h
> index 425c352..b6d9d9b 100644
> --- a/source3/libads/ads_proto.h
> +++ b/source3/libads/ads_proto.h
> @@ -182,12 +182,12 @@ ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads);
>  
>  /* The following definitions come from libads/sasl_wrapping.c  */
>  
> -ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads,
> -   const struct ads_saslwrap_ops *ops,
> -   void *private_data);
> -ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads,
> +ADS_STATUS ads_setup_sasl_wrapping(struct ads_saslwrap *wrap, LDAP *ld,
>     const struct ads_saslwrap_ops *ops,
>     void *private_data);
> +void ndr_print_ads_saslwrap_struct(struct ndr_print *ndr,
> +   const char *name,
> +   const struct ads_saslwrap *r);
>  
>  /* The following definitions come from libads/util.c  */
>  
> diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
> index c70cdeb..fdb729e 100644
> --- a/source3/libads/ldap.c
> +++ b/source3/libads/ldap.c
> @@ -566,8 +566,9 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
>   char addr[INET6_ADDRSTRLEN];
>  
>   ZERO_STRUCT(ads->ldap);
> + ZERO_STRUCT(ads->ldap_wrap_data);
>   ads->ldap.last_attempt = time_mono(NULL);
> - ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_PLAIN;
> + ads->ldap_wrap_data.wrap_type = ADS_SASLWRAP_TYPE_PLAIN;
>  
>   /* try with a user specified server */
>  
> @@ -643,8 +644,8 @@ got_connection:
>   goto out;
>   }
>  
> - ads->ldap.mem_ctx = talloc_init("ads LDAP connection memory");
> - if (!ads->ldap.mem_ctx) {
> + ads->ldap_wrap_data.mem_ctx = talloc_init("ads LDAP connection memory");
> + if (!ads->ldap_wrap_data.mem_ctx) {
>   status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
>   goto out;
>   }
> @@ -730,13 +731,15 @@ void ads_disconnect(ADS_STRUCT *ads)
>   ldap_unbind(ads->ldap.ld);
>   ads->ldap.ld = NULL;
>   }
> - if (ads->ldap.wrap_ops && ads->ldap.wrap_ops->disconnect) {
> - ads->ldap.wrap_ops->disconnect(ads);
> + if (ads->ldap_wrap_data.wrap_ops &&
> + ads->ldap_wrap_data.wrap_ops->disconnect) {
> + ads->ldap_wrap_data.wrap_ops->disconnect(&ads->ldap_wrap_data);
>   }
> - if (ads->ldap.mem_ctx) {
> - talloc_free(ads->ldap.mem_ctx);
> + if (ads->ldap_wrap_data.mem_ctx) {
> + talloc_free(ads->ldap_wrap_data.mem_ctx);
>   }
>   ZERO_STRUCT(ads->ldap);
> + ZERO_STRUCT(ads->ldap_wrap_data);
>  }
>  
>  /*
> diff --git a/source3/libads/ndr.c b/source3/libads/ndr.c
> index 6cecbb0..1b586c3 100644
> --- a/source3/libads/ndr.c
> +++ b/source3/libads/ndr.c
> @@ -87,31 +87,7 @@ void ndr_print_ads_struct(struct ndr_print *ndr, const char *name, const struct
>   ndr_print_sockaddr_storage(ndr, "ss", &r->ldap.ss);
>   ndr_print_time_t(ndr, "last_attempt", r->ldap.last_attempt);
>   ndr_print_uint32(ndr, "port", r->ldap.port);
> - ndr_print_uint16(ndr, "wrap_type", r->ldap.wrap_type);
> -#ifdef HAVE_LDAP_SASL_WRAPPING
> - ndr_print_ptr(ndr, "sbiod", r->ldap.sbiod);
> -#endif /* HAVE_LDAP_SASL_WRAPPING */
> - ndr_print_ptr(ndr, "mem_ctx", r->ldap.mem_ctx);
> - ndr_print_ptr(ndr, "wrap_ops", r->ldap.wrap_ops);
> - ndr_print_ptr(ndr, "wrap_private_data", r->ldap.wrap_private_data);
> - ndr_print_struct(ndr, name, "in");
> - ndr->depth++;
> - ndr_print_uint32(ndr, "ofs", r->ldap.in.ofs);
> - ndr_print_uint32(ndr, "needed", r->ldap.in.needed);
> - ndr_print_uint32(ndr, "left", r->ldap.in.left);
> - ndr_print_uint32(ndr, "max_wrapped", r->ldap.in.max_wrapped);
> - ndr_print_uint32(ndr, "min_wrapped", r->ldap.in.min_wrapped);
> - ndr_print_uint32(ndr, "size", r->ldap.in.size);
> - ndr_print_array_uint8(ndr, "buf", r->ldap.in.buf, r->ldap.in.size);
> - ndr->depth--;
> - ndr_print_struct(ndr, name, "out");
> - ndr->depth++;
> - ndr_print_uint32(ndr, "ofs", r->ldap.out.ofs);
> - ndr_print_uint32(ndr, "left", r->ldap.out.left);
> - ndr_print_uint32(ndr, "max_unwrapped", r->ldap.out.max_unwrapped);
> - ndr_print_uint32(ndr, "sig_size", r->ldap.out.sig_size);
> - ndr_print_uint32(ndr, "size", r->ldap.out.size);
> - ndr_print_array_uint8(ndr, "buf", r->ldap.out.buf, r->ldap.out.size);
> + ndr_print_ads_saslwrap_struct(ndr, "saslwrap", &(r->ldap_wrap_data));
>   ndr->depth--;
>   ndr->depth--;
>  #endif /* HAVE_LDAP */
> diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c
> index ab79f70..7f7b790 100644
> --- a/source3/libads/sasl.c
> +++ b/source3/libads/sasl.c
> @@ -30,10 +30,11 @@
>  
>  #ifdef HAVE_LDAP
>  
> -static ADS_STATUS ads_sasl_gensec_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t len)
> +static ADS_STATUS ads_sasl_gensec_wrap(struct ads_saslwrap *wrap,
> +       uint8_t *buf, uint32_t len)
>  {
>   struct gensec_security *gensec_security =
> - talloc_get_type_abort(ads->ldap.wrap_private_data,
> + talloc_get_type_abort(wrap->wrap_private_data,
>   struct gensec_security);
>   NTSTATUS nt_status;
>   DATA_BLOB unwrapped, wrapped;
> @@ -47,32 +48,32 @@ static ADS_STATUS ads_sasl_gensec_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t l
>   return ADS_ERROR_NT(nt_status);
>   }
>  
> - if ((ads->ldap.out.size - 4) < wrapped.length) {
> + if ((wrap->out.size - 4) < wrapped.length) {
>   TALLOC_FREE(frame);
>   return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR);
>   }
>  
>   /* copy the wrapped blob to the right location */
> - memcpy(ads->ldap.out.buf + 4, wrapped.data, wrapped.length);
> + memcpy(wrap->out.buf + 4, wrapped.data, wrapped.length);
>  
>   /* set how many bytes must be written to the underlying socket */
> - ads->ldap.out.left = 4 + wrapped.length;
> + wrap->out.left = 4 + wrapped.length;
>  
>   TALLOC_FREE(frame);
>  
>   return ADS_SUCCESS;
>  }
>  
> -static ADS_STATUS ads_sasl_gensec_unwrap(ADS_STRUCT *ads)
> +static ADS_STATUS ads_sasl_gensec_unwrap(struct ads_saslwrap *wrap)
>  {
>   struct gensec_security *gensec_security =
> - talloc_get_type_abort(ads->ldap.wrap_private_data,
> + talloc_get_type_abort(wrap->wrap_private_data,
>   struct gensec_security);
>   NTSTATUS nt_status;
>   DATA_BLOB unwrapped, wrapped;
>   TALLOC_CTX *frame = talloc_stackframe();
>  
> - wrapped = data_blob_const(ads->ldap.in.buf + 4, ads->ldap.in.ofs - 4);
> + wrapped = data_blob_const(wrap->in.buf + 4, wrap->in.ofs - 4);
>  
>   nt_status = gensec_unwrap(gensec_security, frame, &wrapped, &unwrapped);
>   if (!NT_STATUS_IS_OK(nt_status)) {
> @@ -86,27 +87,27 @@ static ADS_STATUS ads_sasl_gensec_unwrap(ADS_STRUCT *ads)
>   }
>  
>   /* copy the wrapped blob to the right location */
> - memcpy(ads->ldap.in.buf + 4, unwrapped.data, unwrapped.length);
> + memcpy(wrap->in.buf + 4, unwrapped.data, unwrapped.length);
>  
>   /* set how many bytes must be written to the underlying socket */
> - ads->ldap.in.left = unwrapped.length;
> - ads->ldap.in.ofs = 4;
> + wrap->in.left = unwrapped.length;
> + wrap->in.ofs = 4;
>  
>   TALLOC_FREE(frame);
>  
>   return ADS_SUCCESS;
>  }
>  
> -static void ads_sasl_gensec_disconnect(ADS_STRUCT *ads)
> +static void ads_sasl_gensec_disconnect(struct ads_saslwrap *wrap)
>  {
>   struct gensec_security *gensec_security =
> - talloc_get_type_abort(ads->ldap.wrap_private_data,
> + talloc_get_type_abort(wrap->wrap_private_data,
>   struct gensec_security);
>  
>   TALLOC_FREE(gensec_security);
>  
> - ads->ldap.wrap_ops = NULL;
> - ads->ldap.wrap_private_data = NULL;
> + wrap->wrap_ops = NULL;
> + wrap->wrap_private_data = NULL;
>  }
>  
>  static const struct ads_saslwrap_ops ads_sasl_gensec_ops = {
> @@ -136,6 +137,7 @@ static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads,
>   bool use_spnego_principal = lp_client_use_spnego_principal();
>   const char *sasl_list[] = { sasl, NULL };
>   NTTIME end_nt_time;
> + struct ads_saslwrap *wrap = &ads->ldap_wrap_data;
>  
>   nt_status = auth_generic_client_prepare(NULL, &auth_generic_state);
>   if (!NT_STATUS_IS_OK(nt_status)) {
> @@ -185,7 +187,7 @@ static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads,
>   use_spnego_principal = false;
>   }
>  
> - switch (ads->ldap.wrap_type) {
> + switch (wrap->wrap_type) {
>   case ADS_SASLWRAP_TYPE_SEAL:
>   gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SIGN);
>   gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SEAL);
> @@ -278,7 +280,7 @@ static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads,
>   data_blob_free(&blob_in);
>   data_blob_free(&blob_out);
>  
> - if (ads->ldap.wrap_type >= ADS_SASLWRAP_TYPE_SEAL) {
> + if (wrap->wrap_type >= ADS_SASLWRAP_TYPE_SEAL) {
>   bool ok;
>  
>   ok = gensec_have_feature(auth_generic_state->gensec_security,
> @@ -297,7 +299,7 @@ static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads,
>   return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE);
>   }
>  
> - } else if (ads->ldap.wrap_type >= ADS_SASLWRAP_TYPE_SIGN) {
> + } else if (wrap->wrap_type >= ADS_SASLWRAP_TYPE_SIGN) {
>   bool ok;
>  
>   ok = gensec_have_feature(auth_generic_state->gensec_security,
> @@ -317,20 +319,24 @@ static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads,
>   ads->auth.tgs_expire = tv.tv_sec;
>   }
>  
> - if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) {
> - size_t max_wrapped = gensec_max_wrapped_size(auth_generic_state->gensec_security);
> - ads->ldap.out.max_unwrapped = gensec_max_input_size(auth_generic_state->gensec_security);
> + if (wrap->wrap_type > ADS_SASLWRAP_TYPE_PLAIN) {
> + size_t max_wrapped =
> + gensec_max_wrapped_size(auth_generic_state->gensec_security);
> + wrap->out.max_unwrapped =
> + gensec_max_input_size(auth_generic_state->gensec_security);
>  
> - ads->ldap.out.sig_size = max_wrapped - ads->ldap.out.max_unwrapped;
> + wrap->out.sig_size = max_wrapped - wrap->out.max_unwrapped;
>   /*
>   * Note that we have to truncate this to 0x2C
>   * (taken from a capture with LDAP unbind), as the
>   * signature size is not constant for Kerberos with
>   * arcfour-hmac-md5.
>   */
> - ads->ldap.in.min_wrapped = MIN(ads->ldap.out.sig_size, 0x2C);
> - ads->ldap.in.max_wrapped = ADS_SASL_WRAPPING_IN_MAX_WRAPPED;
> - status = ads_setup_sasl_wrapping(ads, &ads_sasl_gensec_ops, auth_generic_state->gensec_security);
> + wrap->in.min_wrapped = MIN(wrap->out.sig_size, 0x2C);
> + wrap->in.max_wrapped = ADS_SASL_WRAPPING_IN_MAX_WRAPPED;
> + status = ads_setup_sasl_wrapping(wrap, ads->ldap.ld,
> + &ads_sasl_gensec_ops,
> + auth_generic_state->gensec_security);
>   if (!ADS_ERR_OK(status)) {
>   DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n",
>   ads_errstr(status)));
> @@ -387,9 +393,9 @@ done:
>   return status;
>  }
>  
> -static ADS_STATUS ads_sasl_gssapi_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t len)
> +static ADS_STATUS ads_sasl_gssapi_wrap(struct ads_saslwrap *wrap, uint8_t *buf, uint32_t len)
>  {
> - gss_ctx_id_t context_handle = (gss_ctx_id_t)ads->ldap.wrap_private_data;
> + gss_ctx_id_t context_handle = (gss_ctx_id_t)wrap->wrap_private_data;
>   ADS_STATUS status;
>   int gss_rc;
>   uint32_t minor_status;
> @@ -400,7 +406,7 @@ static ADS_STATUS ads_sasl_gssapi_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t l
>   unwrapped.length = len;
>  
>   /* for now request sign and seal */
> - conf_req_flag = (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL);
> + conf_req_flag = (wrap->wrap_type == ADS_SASLWRAP_TYPE_SEAL);
>  
>   gss_rc = gss_wrap(&minor_status, context_handle,
>    conf_req_flag, GSS_C_QOP_DEFAULT,
> @@ -413,32 +419,32 @@ static ADS_STATUS ads_sasl_gssapi_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t l
>   return ADS_ERROR_NT(NT_STATUS_ACCESS_DENIED);
>   }
>  
> - if ((ads->ldap.out.size - 4) < wrapped.length) {
> + if ((wrap->out.size - 4) < wrapped.length) {
>   return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR);
>   }
>  
>   /* copy the wrapped blob to the right location */
> - memcpy(ads->ldap.out.buf + 4, wrapped.value, wrapped.length);
> + memcpy(wrap->out.buf + 4, wrapped.value, wrapped.length);
>  
>   /* set how many bytes must be written to the underlying socket */
> - ads->ldap.out.left = 4 + wrapped.length;
> + wrap->out.left = 4 + wrapped.length;
>  
>   gss_release_buffer(&minor_status, &wrapped);
>  
>   return ADS_SUCCESS;
>  }
>  
> -static ADS_STATUS ads_sasl_gssapi_unwrap(ADS_STRUCT *ads)
> +static ADS_STATUS ads_sasl_gssapi_unwrap(struct ads_saslwrap *wrap)
>  {
> - gss_ctx_id_t context_handle = (gss_ctx_id_t)ads->ldap.wrap_private_data;
> + gss_ctx_id_t context_handle = (gss_ctx_id_t)wrap->wrap_private_data;
>   ADS_STATUS status;
>   int gss_rc;
>   uint32_t minor_status;
>   gss_buffer_desc unwrapped, wrapped;
>   int conf_state;
>  
> - wrapped.value = ads->ldap.in.buf + 4;
> - wrapped.length = ads->ldap.in.ofs - 4;
> + wrapped.value = wrap->in.buf + 4;
> + wrapped.length = wrap->in.ofs - 4;
>  
>   gss_rc = gss_unwrap(&minor_status, context_handle,
>      &wrapped, &unwrapped,
> @@ -446,7 +452,7 @@ static ADS_STATUS ads_sasl_gssapi_unwrap(ADS_STRUCT *ads)
>   status = ADS_ERROR_GSS(gss_rc, minor_status);
>   if (!ADS_ERR_OK(status)) return status;
>  
> - if (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL && conf_state == 0) {
> + if (wrap->wrap_type == ADS_SASLWRAP_TYPE_SEAL && conf_state == 0) {
>   return ADS_ERROR_NT(NT_STATUS_ACCESS_DENIED);
>   }
>  
> @@ -455,26 +461,26 @@ static ADS_STATUS ads_sasl_gssapi_unwrap(ADS_STRUCT *ads)
>   }
>  
>   /* copy the wrapped blob to the right location */
> - memcpy(ads->ldap.in.buf + 4, unwrapped.value, unwrapped.length);
> + memcpy(wrap->in.buf + 4, unwrapped.value, unwrapped.length);
>  
>   /* set how many bytes must be written to the underlying socket */
> - ads->ldap.in.left = unwrapped.length;
> - ads->ldap.in.ofs = 4;
> + wrap->in.left = unwrapped.length;
> + wrap->in.ofs = 4;
>  
>   gss_release_buffer(&minor_status, &unwrapped);
>  
>   return ADS_SUCCESS;
>  }
>  
> -static void ads_sasl_gssapi_disconnect(ADS_STRUCT *ads)
> +static void ads_sasl_gssapi_disconnect(struct ads_saslwrap *wrap)
>  {
> - gss_ctx_id_t context_handle = (gss_ctx_id_t)ads->ldap.wrap_private_data;
> + gss_ctx_id_t context_handle = (gss_ctx_id_t)wrap->wrap_private_data;
>   uint32_t minor_status;
>  
>   gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER);
>  
> - ads->ldap.wrap_ops = NULL;
> - ads->ldap.wrap_private_data = NULL;
> + wrap->wrap_ops = NULL;
> + wrap->wrap_private_data = NULL;
>  }
>  
>  static const struct ads_saslwrap_ops ads_sasl_gssapi_ops = {
> @@ -827,6 +833,7 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv
>   uint32_t max_msg_size = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED;
>   uint8_t wrap_type = ADS_SASLWRAP_TYPE_PLAIN;
>   ADS_STATUS status;
> + struct ads_saslwrap *wrap = &ads->ldap_wrap_data;
>  
>   input_token.value = NULL;
>   input_token.length = 0;
> @@ -916,13 +923,13 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv
>  
>   gss_release_buffer(&minor_status, &output_token);
>  
> - if (!(wrap_type & ads->ldap.wrap_type)) {
> + if (!(wrap_type & wrap->wrap_type)) {
>   /*
>   * the server doesn't supports the wrap
>   * type we want :-(
>   */
>   DEBUG(0,("The ldap sasl wrap type doesn't match wanted[%d] server[%d]\n",
> - ads->ldap.wrap_type, wrap_type));
> + wrap->wrap_type, wrap_type));
>   DEBUGADD(0,("You may want to set the 'client ldap sasl wrapping' option\n"));
>   status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED);
>   goto failed;
> @@ -943,7 +950,7 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv
>   p = (uint8_t *)output_token.value;
>  
>   RSIVAL(p,0,max_msg_size);
> - SCVAL(p,0,ads->ldap.wrap_type);
> + SCVAL(p,0,wrap->wrap_type);
>  
>   /*
>   * we used to add sprintf("dn:%s", ads->config.bind_path) here.
> @@ -980,20 +987,22 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv
>   goto failed;
>   }
>  
> - if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) {
> + if (wrap->wrap_type > ADS_SASLWRAP_TYPE_PLAIN) {
>   gss_rc = gss_wrap_size_limit(&minor_status, context_handle,
> -     (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL),
> +     (wrap->wrap_type == ADS_SASLWRAP_TYPE_SEAL),
>       GSS_C_QOP_DEFAULT,
> -     max_msg_size, &ads->ldap.out.max_unwrapped);
> +     max_msg_size, &wrap->out.max_unwrapped);
>   if (gss_rc) {
>   status = ADS_ERROR_GSS(gss_rc, minor_status);
>   goto failed;
>   }
>  
> - ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max_unwrapped;
> - ads->ldap.in.min_wrapped = 0x2C; /* taken from a capture with LDAP unbind */
> - ads->ldap.in.max_wrapped = ADS_SASL_WRAPPING_IN_MAX_WRAPPED;
> - status = ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle);
> + wrap->out.sig_size = max_msg_size - wrap->out.max_unwrapped;
> + wrap->in.min_wrapped = 0x2C; /* taken from a capture with LDAP unbind */
> + wrap->in.max_wrapped = ADS_SASL_WRAPPING_IN_MAX_WRAPPED;
> + status = ads_setup_sasl_wrapping(wrap->wrap_private_data, ads->ldap.ld,
> + &ads_sasl_gssapi_ops,
> + context_handle);
>   if (!ADS_ERR_OK(status)) {
>   DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n",
>   ads_errstr(status)));
> @@ -1068,6 +1077,7 @@ ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads)
>   ADS_STATUS status;
>   int i, j;
>   LDAPMessage *res;
> + struct ads_saslwrap *wrap = &ads->ldap_wrap_data;
>  
>   /* get a list of supported SASL mechanisms */
>   status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
> @@ -1076,11 +1086,11 @@ ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads)
>   values = ldap_get_values(ads->ldap.ld, res, "supportedSASLMechanisms");
>  
>   if (ads->auth.flags & ADS_AUTH_SASL_SEAL) {
> - ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SEAL;
> + wrap->wrap_type = ADS_SASLWRAP_TYPE_SEAL;
>   } else if (ads->auth.flags & ADS_AUTH_SASL_SIGN) {
> - ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SIGN;
> + wrap->wrap_type = ADS_SASLWRAP_TYPE_SIGN;
>   } else {
> - ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_PLAIN;
> + wrap->wrap_type = ADS_SASLWRAP_TYPE_PLAIN;
>   }
>  
>   /* try our supported mechanisms in order */
> @@ -1093,11 +1103,11 @@ retry:
>   status = sasl_mechanisms[i].fn(ads);
>   if (status.error_type == ENUM_ADS_ERROR_LDAP &&
>      status.err.rc == LDAP_STRONG_AUTH_REQUIRED &&
> -    ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_PLAIN)
> +    wrap->wrap_type == ADS_SASLWRAP_TYPE_PLAIN)
>   {
>   DEBUG(3,("SASL bin got LDAP_STRONG_AUTH_REQUIRED "
>   "retrying with signing enabled\n"));
> - ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SIGN;
> + wrap->wrap_type = ADS_SASLWRAP_TYPE_SIGN;
>   goto retry;
>   }
>   ldap_value_free(values);
> diff --git a/source3/libads/sasl_wrapping.c b/source3/libads/sasl_wrapping.c
> index c7a58ab..1dbd357 100644
> --- a/source3/libads/sasl_wrapping.c
> +++ b/source3/libads/sasl_wrapping.c
> @@ -20,15 +20,47 @@
>  #include "includes.h"
>  #include "ads.h"
>  
> +void ndr_print_ads_saslwrap_struct(struct ndr_print *ndr, const char *name, const struct ads_saslwrap *r)
> +{
> + ndr_print_struct(ndr, name, "saslwrap");
> + ndr->depth++;
> + ndr_print_uint16(ndr, "wrap_type", r->wrap_type);
> +#ifdef HAVE_LDAP_SASL_WRAPPING
> + ndr_print_ptr(ndr, "sbiod", r->sbiod);
> +#endif /* HAVE_LDAP_SASL_WRAPPING */
> + ndr_print_ptr(ndr, "mem_ctx", r->mem_ctx);
> + ndr_print_ptr(ndr, "wrap_ops", r->wrap_ops);
> + ndr_print_ptr(ndr, "wrap_private_data", r->wrap_private_data);
> + ndr_print_struct(ndr, name, "in");
> + ndr->depth++;
> + ndr_print_uint32(ndr, "ofs", r->in.ofs);
> + ndr_print_uint32(ndr, "needed", r->in.needed);
> + ndr_print_uint32(ndr, "left", r->in.left);
> + ndr_print_uint32(ndr, "max_wrapped", r->in.max_wrapped);
> + ndr_print_uint32(ndr, "min_wrapped", r->in.min_wrapped);
> + ndr_print_uint32(ndr, "size", r->in.size);
> + ndr_print_array_uint8(ndr, "buf", r->in.buf, r->in.size);
> + ndr->depth--;
> + ndr_print_struct(ndr, name, "out");
> + ndr->depth++;
> + ndr_print_uint32(ndr, "ofs", r->out.ofs);
> + ndr_print_uint32(ndr, "left", r->out.left);
> + ndr_print_uint32(ndr, "max_unwrapped", r->out.max_unwrapped);
> + ndr_print_uint32(ndr, "sig_size", r->out.sig_size);
> + ndr_print_uint32(ndr, "size", r->out.size);
> + ndr_print_array_uint8(ndr, "buf", r->out.buf, r->out.size);
> + ndr->depth--;
> +}
> +
>  #ifdef HAVE_LDAP_SASL_WRAPPING
>  
>  static int ads_saslwrap_setup(Sockbuf_IO_Desc *sbiod, void *arg)
>  {
> - ADS_STRUCT *ads = (ADS_STRUCT *)arg;
> + struct ads_saslwrap *wrap = (struct ads_saslwrap *)arg;
>  
> - ads->ldap.sbiod = sbiod;
> + wrap->sbiod = sbiod;
>  
> - sbiod->sbiod_pvt = ads;
> + sbiod->sbiod_pvt = wrap;
>  
>   return 0;
>  }
> @@ -38,78 +70,80 @@ static int ads_saslwrap_remove(Sockbuf_IO_Desc *sbiod)
>   return 0;
>  }
>  
> -static ber_slen_t ads_saslwrap_prepare_inbuf(ADS_STRUCT *ads)
> +static ber_slen_t ads_saslwrap_prepare_inbuf(struct ads_saslwrap *wrap)
>  {
> - ads->ldap.in.ofs = 0;
> - ads->ldap.in.needed = 0;
> - ads->ldap.in.left = 0;
> - ads->ldap.in.size = 4 + ads->ldap.in.min_wrapped;
> - ads->ldap.in.buf = talloc_array(ads->ldap.mem_ctx,
> -       uint8_t, ads->ldap.in.size);
> - if (!ads->ldap.in.buf) {
> + wrap->in.ofs = 0;
> + wrap->in.needed = 0;
> + wrap->in.left = 0;
> + wrap->in.size = 4 + wrap->in.min_wrapped;
> + wrap->in.buf = talloc_array(wrap->mem_ctx,
> +       uint8_t, wrap->in.size);
> + if (!wrap->in.buf) {
>   return -1;
>   }
>  
>   return 0;
>  }
>  
> -static ber_slen_t ads_saslwrap_grow_inbuf(ADS_STRUCT *ads)
> +static ber_slen_t ads_saslwrap_grow_inbuf(struct ads_saslwrap *wrap)
>  {
> - if (ads->ldap.in.size == (4 + ads->ldap.in.needed)) {
> + if (wrap->in.size == (4 + wrap->in.needed)) {
>   return 0;
>   }
>  
> - ads->ldap.in.size = 4 + ads->ldap.in.needed;
> - ads->ldap.in.buf = talloc_realloc(ads->ldap.mem_ctx,
> - ads->ldap.in.buf,
> - uint8_t, ads->ldap.in.size);
> - if (!ads->ldap.in.buf) {
> + wrap->in.size = 4 + wrap->in.needed;
> + wrap->in.buf = talloc_realloc(wrap->mem_ctx,
> + wrap->in.buf,
> + uint8_t, wrap->in.size);
> + if (!wrap->in.buf) {
>   return -1;
>   }
>  
>   return 0;
>  }
>  
> -static void ads_saslwrap_shrink_inbuf(ADS_STRUCT *ads)
> +static void ads_saslwrap_shrink_inbuf(struct ads_saslwrap *wrap)
>  {
> - talloc_free(ads->ldap.in.buf);
> + talloc_free(wrap->in.buf);
>  
> - ads->ldap.in.buf = NULL;
> - ads->ldap.in.size = 0;
> - ads->ldap.in.ofs = 0;
> - ads->ldap.in.needed = 0;
> - ads->ldap.in.left = 0;
> + wrap->in.buf = NULL;
> + wrap->in.size = 0;
> + wrap->in.ofs = 0;
> + wrap->in.needed = 0;
> + wrap->in.left = 0;
>  }
>  
> -static ber_slen_t ads_saslwrap_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
> +static ber_slen_t ads_saslwrap_read(Sockbuf_IO_Desc *sbiod,
> +    void *buf, ber_len_t len)
>  {
> - ADS_STRUCT *ads = (ADS_STRUCT *)sbiod->sbiod_pvt;
> + struct ads_saslwrap *wrap =
> + (struct ads_saslwrap *)sbiod->sbiod_pvt;
>   ber_slen_t ret;
>  
>   /* If ofs < 4 it means we don't have read the length header yet */
> - if (ads->ldap.in.ofs < 4) {
> - ret = ads_saslwrap_prepare_inbuf(ads);
> + if (wrap->in.ofs < 4) {
> + ret = ads_saslwrap_prepare_inbuf(wrap);
>   if (ret < 0) return ret;
>  
>   ret = LBER_SBIOD_READ_NEXT(sbiod,
> -   ads->ldap.in.buf + ads->ldap.in.ofs,
> -   4 - ads->ldap.in.ofs);
> +   wrap->in.buf + wrap->in.ofs,
> +   4 - wrap->in.ofs);
>   if (ret <= 0) return ret;
> - ads->ldap.in.ofs += ret;
> + wrap->in.ofs += ret;
>  
> - if (ads->ldap.in.ofs < 4) goto eagain;
> + if (wrap->in.ofs < 4) goto eagain;
>  
> - ads->ldap.in.needed = RIVAL(ads->ldap.in.buf, 0);
> - if (ads->ldap.in.needed > ads->ldap.in.max_wrapped) {
> + wrap->in.needed = RIVAL(wrap->in.buf, 0);
> + if (wrap->in.needed > wrap->in.max_wrapped) {
>   errno = EINVAL;
>   return -1;
>   }
> - if (ads->ldap.in.needed < ads->ldap.in.min_wrapped) {
> + if (wrap->in.needed < wrap->in.min_wrapped) {
>   errno = EINVAL;
>   return -1;
>   }
>  
> - ret = ads_saslwrap_grow_inbuf(ads);
> + ret = ads_saslwrap_grow_inbuf(wrap);
>   if (ret < 0) return ret;
>   }
>  
> @@ -117,24 +151,24 @@ static ber_slen_t ads_saslwrap_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t
>   * if there's more data needed from the remote end,
>   * we need to read more
>   */
> - if (ads->ldap.in.needed > 0) {
> + if (wrap->in.needed > 0) {
>   ret = LBER_SBIOD_READ_NEXT(sbiod,
> -   ads->ldap.in.buf + ads->ldap.in.ofs,
> -   ads->ldap.in.needed);
> +   wrap->in.buf + wrap->in.ofs,
> +   wrap->in.needed);
>   if (ret <= 0) return ret;
> - ads->ldap.in.ofs += ret;
> - ads->ldap.in.needed -= ret;
> + wrap->in.ofs += ret;
> + wrap->in.needed -= ret;
>  
> - if (ads->ldap.in.needed > 0) goto eagain;
> + if (wrap->in.needed > 0) goto eagain;
>   }
>  
>   /*
>   * if we have a complete packet and have not yet unwrapped it
>   * we need to call the mech specific unwrap() hook
>   */
> - if (ads->ldap.in.needed == 0 && ads->ldap.in.left == 0) {
> + if (wrap->in.needed == 0 && wrap->in.left == 0) {
>   ADS_STATUS status;
> - status = ads->ldap.wrap_ops->unwrap(ads);
> + status = wrap->wrap_ops->unwrap(wrap);
>   if (!ADS_ERR_OK(status)) {
>   errno = EACCES;
>   return -1;
> @@ -144,19 +178,19 @@ static ber_slen_t ads_saslwrap_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t
>   /*
>   * if we have unwrapped data give it to the caller
>   */
> - if (ads->ldap.in.left > 0) {
> - ret = MIN(ads->ldap.in.left, len);
> - memcpy(buf, ads->ldap.in.buf + ads->ldap.in.ofs, ret);
> - ads->ldap.in.ofs += ret;
> - ads->ldap.in.left -= ret;
> + if (wrap->in.left > 0) {
> + ret = MIN(wrap->in.left, len);
> + memcpy(buf, wrap->in.buf + wrap->in.ofs, ret);
> + wrap->in.ofs += ret;
> + wrap->in.left -= ret;
>  
>   /*
>   * if no more is left shrink the inbuf,
>   * this will trigger reading a new SASL packet
>   * from the remote stream in the next call
>   */
> - if (ads->ldap.in.left == 0) {
> - ads_saslwrap_shrink_inbuf(ads);
> + if (wrap->in.left == 0) {
> + ads_saslwrap_shrink_inbuf(wrap);
>   }
>  
>   return ret;
> @@ -171,37 +205,40 @@ eagain:
>   return -1;
>  }
>  
> -static ber_slen_t ads_saslwrap_prepare_outbuf(ADS_STRUCT *ads, uint32_t len)
> +static ber_slen_t ads_saslwrap_prepare_outbuf(struct ads_saslwrap *wrap,
> +      uint32_t len)
>  {
> - ads->ldap.out.ofs = 0;
> - ads->ldap.out.left = 0;
> - ads->ldap.out.size = 4 + ads->ldap.out.sig_size + len;
> - ads->ldap.out.buf = talloc_array(ads->ldap.mem_ctx,
> -       uint8_t, ads->ldap.out.size);
> - if (!ads->ldap.out.buf) {
> + wrap->out.ofs = 0;
> + wrap->out.left = 0;
> + wrap->out.size = 4 + wrap->out.sig_size + len;
> + wrap->out.buf = talloc_array(wrap->mem_ctx,
> +       uint8_t, wrap->out.size);
> + if (!wrap->out.buf) {
>   return -1;
>   }
>  
>   return 0;
>  }
>  
> -static void ads_saslwrap_shrink_outbuf(ADS_STRUCT *ads)
> +static void ads_saslwrap_shrink_outbuf(struct ads_saslwrap *wrap)
>  {
> - talloc_free(ads->ldap.out.buf);
> + talloc_free(wrap->out.buf);
>  
> - ads->ldap.out.buf = NULL;
> - ads->ldap.out.size = 0;
> - ads->ldap.out.ofs = 0;
> - ads->ldap.out.left = 0;
> + wrap->out.buf = NULL;
> + wrap->out.size = 0;
> + wrap->out.ofs = 0;
> + wrap->out.left = 0;
>  }
>  
> -static ber_slen_t ads_saslwrap_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
> +static ber_slen_t ads_saslwrap_write(Sockbuf_IO_Desc *sbiod,
> +     void *buf, ber_len_t len)
>  {
> - ADS_STRUCT *ads = (ADS_STRUCT *)sbiod->sbiod_pvt;
> + struct ads_saslwrap *wrap =
> + (struct ads_saslwrap *)sbiod->sbiod_pvt;
>   ber_slen_t ret, rlen;
>  
>   /* if the buffer is empty, we need to wrap in incoming buffer */
> - if (ads->ldap.out.left == 0) {
> + if (wrap->out.left == 0) {
>   ADS_STATUS status;
>  
>   if (len == 0) {
> @@ -209,31 +246,31 @@ static ber_slen_t ads_saslwrap_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_
>   return -1;
>   }
>  
> - rlen = MIN(len, ads->ldap.out.max_unwrapped);
> + rlen = MIN(len, wrap->out.max_unwrapped);
>  
> - ret = ads_saslwrap_prepare_outbuf(ads, rlen);
> + ret = ads_saslwrap_prepare_outbuf(wrap, rlen);
>   if (ret < 0) return ret;
>  
> - status = ads->ldap.wrap_ops->wrap(ads, (uint8_t *)buf, rlen);
> + status = wrap->wrap_ops->wrap(wrap, (uint8_t *)buf, rlen);
>   if (!ADS_ERR_OK(status)) {
>   errno = EACCES;
>   return -1;
>   }
>  
> - RSIVAL(ads->ldap.out.buf, 0, ads->ldap.out.left - 4);
> + RSIVAL(wrap->out.buf, 0, wrap->out.left - 4);
>   } else {
>   rlen = -1;
>   }
>  
>   ret = LBER_SBIOD_WRITE_NEXT(sbiod,
> -    ads->ldap.out.buf + ads->ldap.out.ofs,
> -    ads->ldap.out.left);
> +    wrap->out.buf + wrap->out.ofs,
> +    wrap->out.left);
>   if (ret <= 0) return ret;
> - ads->ldap.out.ofs += ret;
> - ads->ldap.out.left -= ret;
> + wrap->out.ofs += ret;
> + wrap->out.left -= ret;
>  
> - if (ads->ldap.out.left == 0) {
> - ads_saslwrap_shrink_outbuf(ads);
> + if (wrap->out.left == 0) {
> + ads_saslwrap_shrink_outbuf(wrap);
>   }
>  
>   if (rlen > 0) return rlen;
> @@ -244,12 +281,13 @@ static ber_slen_t ads_saslwrap_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_
>  
>  static int ads_saslwrap_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg)
>  {
> - ADS_STRUCT *ads = (ADS_STRUCT *)sbiod->sbiod_pvt;
> + struct ads_saslwrap *wrap =
> + (struct ads_saslwrap *)sbiod->sbiod_pvt;
>   int ret;
>  
>   switch (opt) {
>   case LBER_SB_OPT_DATA_READY:
> - if (ads->ldap.in.left > 0) {
> + if (wrap->in.left > 0) {
>   return 1;
>   }
>   ret = LBER_SBIOD_CTRL_NEXT(sbiod, opt, arg);
> @@ -276,7 +314,7 @@ static const Sockbuf_IO ads_saslwrap_sockbuf_io = {
>   ads_saslwrap_close /* sbi_close */
>  };
>  
> -ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads,
> +ADS_STATUS ads_setup_sasl_wrapping(struct ads_saslwrap *wrap, LDAP *ld,
>     const struct ads_saslwrap_ops *ops,
>     void *private_data)
>  {
> @@ -285,26 +323,26 @@ ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads,
>   Sockbuf_IO *io = discard_const_p(Sockbuf_IO, &ads_saslwrap_sockbuf_io);
>   int rc;
>  
> - rc = ldap_get_option(ads->ldap.ld, LDAP_OPT_SOCKBUF, &sb);
> + rc = ldap_get_option(ld, LDAP_OPT_SOCKBUF, &sb);
>   status = ADS_ERROR_LDAP(rc);
>   if (!ADS_ERR_OK(status)) {
>   return status;
>   }
>  
>   /* setup the real wrapping callbacks */
> - rc = ber_sockbuf_add_io(sb, io, LBER_SBIOD_LEVEL_TRANSPORT, ads);
> + rc = ber_sockbuf_add_io(sb, io, LBER_SBIOD_LEVEL_TRANSPORT, wrap);
>   status = ADS_ERROR_LDAP(rc);
>   if (!ADS_ERR_OK(status)) {
>   return status;
>   }
>  
> - ads->ldap.wrap_ops = ops;
> - ads->ldap.wrap_private_data = private_data;
> + wrap->wrap_ops = ops;
> + wrap->wrap_private_data = private_data;
>  
>   return ADS_SUCCESS;
>  }
>  #else
> -ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads,
> +ADS_STATUS ads_setup_sasl_wrapping(struct ads_saslwrap *wrap, LDAP *ld,
>     const struct ads_saslwrap_ops *ops,
>     void *private_data)
>  {
> --
> 2.9.3
>


Loading...