[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha8-38-g4aade27

Volker Lendecke vlendec at samba.org
Sat Jun 20 16:55:05 GMT 2009


The branch, master has been updated
       via  4aade2768b40b805b50578ec6fa99fe57525b147 (commit)
       via  a3eb0a32a9f36cc9799e11e43f4b95fa0df272a9 (commit)
       via  22cb9bdfd3c3a6a036db08c9c10d7c2530167fc3 (commit)
       via  ecf8cebf322717d6aea3f9f05ec9d210ffbb4aa6 (commit)
       via  361db1866812f7b189a3ea550e061c3977c15425 (commit)
       via  6abd9e42ffbda78a3bc28984b220e7bd726a324b (commit)
       via  d45cf0146b62bf196ff207cd1ec52bbc39ef67ca (commit)
       via  63a70ba0ad306e39311db3145d85323276e02c02 (commit)
      from  62eb817c06458070d090c1698e9c0a99914c6d78 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 4aade2768b40b805b50578ec6fa99fe57525b147
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Jun 20 18:43:58 2009 +0200

    Add tldap paged searches, together with two helper routines

commit a3eb0a32a9f36cc9799e11e43f4b95fa0df272a9
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Jun 20 18:42:18 2009 +0200

    Reorganize retrieving errors and server-sent controls
    
    This attaches the data to the tldap_message instead of the tevent_req.
    
    It adds tldap_ctx_lastmsg() to retrieve the last message for the users of
    the sync wrappers.

commit 22cb9bdfd3c3a6a036db08c9c10d7c2530167fc3
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Jun 19 18:20:20 2009 +0200

    Move asn1_load_nocopy() to lib/util/asn1.c

commit ecf8cebf322717d6aea3f9f05ec9d210ffbb4aa6
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Jun 19 17:39:13 2009 +0200

    Move asn1_blob() to lib/util/asn1.c

commit 361db1866812f7b189a3ea550e061c3977c15425
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Jun 19 14:01:10 2009 +0200

    Add tldap_supports_control

commit 6abd9e42ffbda78a3bc28984b220e7bd726a324b
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Jun 19 14:00:31 2009 +0200

    Add tldap_entry_has_attrvalue

commit d45cf0146b62bf196ff207cd1ec52bbc39ef67ca
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Jun 6 23:21:01 2009 +0200

    tldap control support

commit 63a70ba0ad306e39311db3145d85323276e02c02
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Jun 6 21:06:33 2009 +0200

    Prepare control support
    
    We will have arrays of controls passed to tldap.c. Follow a mantra from the
    classic book "Thinking Forth" by Leo Brodie: Favor counts over terminators :-)
    
    This makes the parameter lists to tldap pretty long, but everyone will have
    wrapper routines anyway, see for example tldap_search_fmt. And the OpenLDAP
    manpages call the non-_ext routines deprecated, probably for a reason.

-----------------------------------------------------------------------

Summary of changes:
 lib/util/asn1.c              |   26 ++++
 lib/util/asn1.h              |    2 +
 source3/include/tldap.h      |   70 ++++++----
 source3/include/tldap_util.h |   32 ++++
 source3/lib/tldap.c          |  319 +++++++++++++++++++++++++++---------------
 source3/lib/tldap_util.c     |  296 ++++++++++++++++++++++++++++++++++++++-
 source3/passdb/pdb_ads.c     |   21 ++--
 source3/torture/torture.c    |   55 +++++++
 8 files changed, 669 insertions(+), 152 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/util/asn1.c b/lib/util/asn1.c
index aadaf86..184aeec 100644
--- a/lib/util/asn1.c
+++ b/lib/util/asn1.c
@@ -764,6 +764,32 @@ bool asn1_write_enumerated(struct asn1_data *data, uint8_t v)
 }
 
 /*
+  Get us the data just written without copying
+*/
+bool asn1_blob(const struct asn1_data *asn1, DATA_BLOB *blob)
+{
+	if (asn1->has_error) {
+		return false;
+	}
+	if (asn1->nesting != NULL) {
+		return false;
+	}
+	blob->data = asn1->data;
+	blob->length = asn1->length;
+	return true;
+}
+
+/*
+  Fill in an asn1 struct without making a copy
+*/
+void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len)
+{
+	ZERO_STRUCTP(data);
+	data->data = buf;
+	data->length = len;
+}
+
+/*
   check if a ASN.1 blob is a full tag
 */
 NTSTATUS asn1_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size)
diff --git a/lib/util/asn1.h b/lib/util/asn1.h
index 0f41ae3..b147ccc 100644
--- a/lib/util/asn1.h
+++ b/lib/util/asn1.h
@@ -93,6 +93,8 @@ bool asn1_read_Integer(struct asn1_data *data, int *i);
 bool asn1_read_enumerated(struct asn1_data *data, int *v);
 bool asn1_check_enumerated(struct asn1_data *data, int v);
 bool asn1_write_enumerated(struct asn1_data *data, uint8_t v);
+bool asn1_blob(const struct asn1_data *asn1, DATA_BLOB *blob);
+void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len);
 NTSTATUS asn1_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size);
 
 #endif /* _ASN_1_H */
diff --git a/source3/include/tldap.h b/source3/include/tldap.h
index 9627244..1d920f8 100644
--- a/source3/include/tldap.h
+++ b/source3/include/tldap.h
@@ -29,7 +29,7 @@ struct tldap_message;
 struct tldap_control {
 	const char *oid;
 	DATA_BLOB value;
-	bool iscritical;
+	bool critical;
 };
 
 struct tldap_attribute {
@@ -58,15 +58,19 @@ struct tevent_req *tldap_sasl_bind_send(TALLOC_CTX *mem_ctx,
 					const char *dn,
 					const char *mechanism,
 					DATA_BLOB *creds,
-					struct tldap_control **sctrls,
-					struct tldap_control **cctrls);
+					struct tldap_control *sctrls,
+					int num_sctrls,
+					struct tldap_control *cctrls,
+					int num_cctrls);
 int tldap_sasl_bind_recv(struct tevent_req *req);
 int tldap_sasl_bind(struct tldap_context *ldap,
 		    const char *dn,
 		    const char *mechanism,
 		    DATA_BLOB *creds,
-		    struct tldap_control **sctrls,
-		    struct tldap_control **cctrls);
+		    struct tldap_control *sctrls,
+		    int num_sctrls,
+		    struct tldap_control *cctrls,
+		    int num_ctrls);
 
 struct tevent_req *tldap_simple_bind_send(TALLOC_CTX *mem_ctx,
 					  struct tevent_context *ev,
@@ -85,8 +89,10 @@ struct tevent_req *tldap_search_send(TALLOC_CTX *mem_ctx,
 				     const char **attrs,
 				     int num_attrs,
 				     int attrsonly,
-				     struct tldap_control **sctrls,
-				     struct tldap_control **cctrls,
+				     struct tldap_control *sctrls,
+				     int num_sctrls,
+				     struct tldap_control *cctrls,
+				     int num_cctrls,
 				     int timelimit,
 				     int sizelimit,
 				     int deref);
@@ -95,9 +101,10 @@ int tldap_search_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 int tldap_search(struct tldap_context *ld,
 		 const char *base, int scope, const char *filter,
 		 const char **attrs, int num_attrs, int attrsonly,
-		 struct tldap_control **sctrls, struct tldap_control **cctrls,
+		 struct tldap_control *sctrls, int num_sctrls,
+		 struct tldap_control *cctrls, int num_cctrls,
 		 int timelimit, int sizelimit, int deref,
-		 TALLOC_CTX *mem_ctx, struct tldap_message ***pentries,
+		 TALLOC_CTX *mem_ctx, struct tldap_message ***entries,
 		 struct tldap_message ***refs);
 bool tldap_entry_dn(struct tldap_message *msg, char **dn);
 bool tldap_entry_attributes(struct tldap_message *msg, int *num_attributes,
@@ -107,47 +114,54 @@ struct tevent_req *tldap_add_send(TALLOC_CTX *mem_ctx,
 				  struct tevent_context *ev,
 				  struct tldap_context *ld,
 				  const char *dn,
-				  int num_attributes,
 				  struct tldap_mod *attributes,
-				  struct tldap_control **sctrls,
-				  struct tldap_control **cctrls);
+				  int num_attributes,
+				  struct tldap_control *sctrls,
+				  int num_sctrls,
+				  struct tldap_control *cctrls,
+				  int num_cctrls);
 int tldap_add_recv(struct tevent_req *req);
 int tldap_add(struct tldap_context *ld, const char *dn,
 	      int num_attributes, struct tldap_mod *attributes,
-	      struct tldap_control **sctrls, struct tldap_control **cctrls);
+	      struct tldap_control *sctrls, int num_sctrls,
+	      struct tldap_control *cctrls, int num_cctrls);
 
 struct tevent_req *tldap_modify_send(TALLOC_CTX *mem_ctx,
 				     struct tevent_context *ev,
 				     struct tldap_context *ld,
 				     const char *dn,
 				     int num_mods, struct tldap_mod *mods,
-				     struct tldap_control **sctrls,
-				     struct tldap_control **cctrls);
+				     struct tldap_control *sctrls,
+				     int num_sctrls,
+				     struct tldap_control *cctrls,
+				     int num_cctrls);
 int tldap_modify_recv(struct tevent_req *req);
 int tldap_modify(struct tldap_context *ld, const char *dn,
 		 int num_mods, struct tldap_mod *mods,
-		 struct tldap_control **sctrls, struct tldap_control **cctrls);
-
+		 struct tldap_control *sctrls, int num_sctrls,
+		 struct tldap_control *cctrls, int num_cctrls);
 
 struct tevent_req *tldap_delete_send(TALLOC_CTX *mem_ctx,
 				     struct tevent_context *ev,
 				     struct tldap_context *ld,
 				     const char *dn,
-				     struct tldap_control **sctrls,
-				     struct tldap_control **cctrls);
+				     struct tldap_control *sctrls,
+				     int num_sctrls,
+				     struct tldap_control *cctrls,
+				     int num_cctrls);
 int tldap_delete_recv(struct tevent_req *req);
 int tldap_delete(struct tldap_context *ld, const char *dn,
-		 struct tldap_control **sctrls, struct tldap_control **cctrls);
-
+		 struct tldap_control *sctrls, int num_sctrls,
+		 struct tldap_control *cctrls, int num_cctrls);
 
 int tldap_msg_id(const struct tldap_message *msg);
 int tldap_msg_type(const struct tldap_message *msg);
-const char *tldap_req_matcheddn(struct tevent_req *req);
-const char *tldap_req_diagnosticmessage(struct tevent_req *req);
-const char *tldap_req_referral(struct tevent_req *req);
-const char *tldap_ctx_matcheddn(struct tldap_context *ctx);
-const char *tldap_ctx_diagnosticmessage(struct tldap_context *ctx);
-const char *tldap_ctx_referral(struct tldap_context *ctx);
+const char *tldap_msg_matcheddn(struct tldap_message *msg);
+const char *tldap_msg_diagnosticmessage(struct tldap_message *msg);
+const char *tldap_msg_referral(struct tldap_message *msg);
+void tldap_msg_sctrls(struct tldap_message *msg, int *num_sctrls,
+		      struct tldap_control **sctrls);
+struct tldap_message *tldap_ctx_lastmsg(struct tldap_context *ld);
 const char *tldap_err2string(int rc);
 
 /* DEBUG */
@@ -259,4 +273,6 @@ void tldap_set_debug(struct tldap_context *ld,
 #define TLDAP_SCOPE_ONE (1)
 #define TLDAP_SCOPE_SUB (2)
 
+#define TLDAP_CONTROL_PAGEDRESULTS "1.2.840.113556.1.4.319"
+
 #endif
diff --git a/source3/include/tldap_util.h b/source3/include/tldap_util.h
index 8869d1e..9b0393e 100644
--- a/source3/include/tldap_util.h
+++ b/source3/include/tldap_util.h
@@ -61,4 +61,36 @@ int tldap_fetch_rootdse_recv(struct tevent_req *req);
 int tldap_fetch_rootdse(struct tldap_context *ld);
 struct tldap_message *tldap_rootdse(struct tldap_context *ld);
 
+bool tldap_entry_has_attrvalue(struct tldap_message *msg,
+			       const char *attribute,
+			       const DATA_BLOB blob);
+bool tldap_supports_control(struct tldap_context *ld, const char *oid);
+
+struct tldap_control *tldap_add_control(TALLOC_CTX *mem_ctx,
+					struct tldap_control *ctrls,
+					int num_ctrls,
+					struct tldap_control *ctrl);
+struct tldap_control *tldap_msg_findcontrol(struct tldap_message *msg,
+					    const char *oid);
+
+struct tevent_req *tldap_search_paged_send(TALLOC_CTX *mem_ctx,
+					   struct tevent_context *ev,
+					   struct tldap_context *ld,
+					   const char *base, int scope,
+					   const char *filter,
+					   const char **attrs,
+					   int num_attrs,
+					   int attrsonly,
+					   struct tldap_control *sctrls,
+					   int num_sctrls,
+					   struct tldap_control *cctrls,
+					   int num_cctrls,
+					   int timelimit,
+					   int sizelimit,
+					   int deref,
+					   int page_size);
+int tldap_search_paged_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+			    struct tldap_message **pmsg);
+
+
 #endif
diff --git a/source3/lib/tldap.c b/source3/lib/tldap.c
index b76e203..376e03f 100644
--- a/source3/lib/tldap.c
+++ b/source3/lib/tldap.c
@@ -60,10 +60,7 @@ struct tldap_context {
 	struct tevent_req **pending;
 
 	/* For the sync wrappers we need something like get_last_error... */
-	int lderr;
-	char *res_matcheddn;
-	char *res_diagnosticmessage;
-	char *res_referral;
+	struct tldap_message *last_msg;
 
 	/* debug */
 	void (*log_fn)(void *context, enum tldap_debug_level level,
@@ -82,6 +79,16 @@ struct tldap_message {
 	/* RESULT_ENTRY */
 	char *dn;
 	struct tldap_attribute *attribs;
+
+	/* Error data sent by the server */
+	int lderr;
+	char *res_matcheddn;
+	char *res_diagnosticmessage;
+	char *res_referral;
+	struct tldap_control *res_sctrls;
+
+	/* Controls sent by the server */
+	struct tldap_control *ctrls;
 };
 
 void tldap_set_debug(struct tldap_context *ld,
@@ -317,26 +324,6 @@ static ssize_t read_ldap_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 	return talloc_get_size(*pbuf);
 }
 
-static bool asn1_blob(const struct asn1_data *asn1, DATA_BLOB *blob)
-{
-	if (asn1->has_error) {
-		return false;
-	}
-	if (asn1->nesting != NULL) {
-		return false;
-	}
-	blob->data = asn1->data;
-	blob->length = asn1->length;
-	return true;
-}
-
-static void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len)
-{
-	ZERO_STRUCTP(data);
-	data->data = buf;
-	data->length = len;
-}
-
 struct tldap_msg_state {
 	struct tldap_context *ld;
 	struct tevent_context *ev;
@@ -347,13 +334,44 @@ struct tldap_msg_state {
 	uint8_t *inbuf;
 };
 
+static void tldap_push_controls(struct asn1_data *data,
+				struct tldap_control *sctrls,
+				int num_sctrls)
+{
+	int i;
+
+	if ((sctrls == NULL) || (num_sctrls == 0)) {
+		return;
+	}
+
+	asn1_push_tag(data, ASN1_CONTEXT(0));
+
+	for (i=0; i<num_sctrls; i++) {
+		struct tldap_control *c = &sctrls[i];
+		asn1_push_tag(data, ASN1_SEQUENCE(0));
+		asn1_write_OctetString(data, c->oid, strlen(c->oid));
+		if (c->critical) {
+			asn1_write_BOOLEAN(data, true);
+		}
+		if (c->value.data != NULL) {
+			asn1_write_OctetString(data, c->value.data,
+					       c->value.length);
+		}
+		asn1_pop_tag(data); /* ASN1_SEQUENCE(0) */
+	}
+
+	asn1_pop_tag(data); /* ASN1_CONTEXT(0) */
+}
+
 static void tldap_msg_sent(struct tevent_req *subreq);
 static void tldap_msg_received(struct tevent_req *subreq);
 
 static struct tevent_req *tldap_msg_send(TALLOC_CTX *mem_ctx,
 					 struct tevent_context *ev,
 					 struct tldap_context *ld,
-					 int id, struct asn1_data *data)
+					 int id, struct asn1_data *data,
+					 struct tldap_control *sctrls,
+					 int num_sctrls)
 {
 	struct tevent_req *req, *subreq;
 	struct tldap_msg_state *state;
@@ -370,6 +388,8 @@ static struct tevent_req *tldap_msg_send(TALLOC_CTX *mem_ctx,
 	state->ev = ev;
 	state->id = id;
 
+	tldap_push_controls(data, sctrls, num_sctrls);
+
 	asn1_pop_tag(data);
 
 	if (!asn1_blob(data, &blob)) {
@@ -635,11 +655,6 @@ struct tldap_req_state {
 	int id;
 	struct asn1_data *out;
 	struct tldap_message *result;
-
-	int lderr;
-	char *res_matcheddn;
-	char *res_diagnosticmessage;
-	char *res_referral;
 };
 
 static struct tevent_req *tldap_req_create(TALLOC_CTX *mem_ctx,
@@ -669,21 +684,13 @@ static struct tevent_req *tldap_req_create(TALLOC_CTX *mem_ctx,
 	return req;
 }
 
-static void tldap_save_errors(struct tldap_context *ctx,
-			      struct tevent_req *req)
+static void tldap_save_msg(struct tldap_context *ld, struct tevent_req *req)
 {
 	struct tldap_req_state *state = tevent_req_data(
 		req, struct tldap_req_state);
 
-	TALLOC_FREE(ctx->res_matcheddn);
-	TALLOC_FREE(ctx->res_diagnosticmessage);
-	TALLOC_FREE(ctx->res_referral);
-
-	ctx->lderr = state->lderr;
-	ctx->res_matcheddn = talloc_move(ctx, &state->res_matcheddn);
-	ctx->res_diagnosticmessage = talloc_move(
-		ctx, &state->res_diagnosticmessage);
-	ctx->res_referral = talloc_move(ctx, &state->res_referral);
+	TALLOC_FREE(ld->last_msg);
+	ld->last_msg = talloc_move(ld, &state->result);
 }
 
 static char *blob2string_talloc(TALLOC_CTX *mem_ctx, DATA_BLOB blob)
@@ -706,22 +713,25 @@ static bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx,
 	return true;
 }
 
+static bool tldap_decode_controls(struct tldap_req_state *state);
+
 static bool tldap_decode_response(struct tldap_req_state *state)
 {
 	struct asn1_data *data = state->result->data;
+	struct tldap_message *msg = state->result;
 	bool ok = true;
 
-	ok &= asn1_read_enumerated(data, &state->lderr);
-	ok &= asn1_read_OctetString_talloc(state, data, &state->res_matcheddn);
-	ok &= asn1_read_OctetString_talloc(state, data,
-					   &state->res_diagnosticmessage);
+	ok &= asn1_read_enumerated(data, &msg->lderr);
+	ok &= asn1_read_OctetString_talloc(msg, data, &msg->res_matcheddn);
+	ok &= asn1_read_OctetString_talloc(msg, data,
+					   &msg->res_diagnosticmessage);
 	if (asn1_peek_tag(data, ASN1_CONTEXT(3))) {
 		ok &= asn1_start_tag(data, ASN1_CONTEXT(3));
-		ok &= asn1_read_OctetString_talloc(
-			state, data, &state->res_referral);
+		ok &= asn1_read_OctetString_talloc(msg, data,
+						   &msg->res_referral);
 		ok &= asn1_end_tag(data);
 	} else {
-		state->res_referral = NULL;
+		msg->res_referral = NULL;
 	}
 
 	return ok;
@@ -735,8 +745,10 @@ struct tevent_req *tldap_sasl_bind_send(TALLOC_CTX *mem_ctx,
 					const char *dn,
 					const char *mechanism,
 					DATA_BLOB *creds,
-					struct tldap_control **sctrls,
-					struct tldap_control **cctrls)
+					struct tldap_control *sctrls,
+					int num_sctrls,
+					struct tldap_control *cctrls,
+					int num_cctrls)
 {
 	struct tevent_req *req, *subreq;
 	struct tldap_req_state *state;
@@ -774,7 +786,8 @@ struct tevent_req *tldap_sasl_bind_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = tldap_msg_send(state, ev, ld, state->id, state->out);
+	subreq = tldap_msg_send(state, ev, ld, state->id, state->out,
+				sctrls, num_sctrls);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
@@ -809,8 +822,8 @@ static void tldap_sasl_bind_done(struct tevent_req *subreq)
 	/*
 	 * TODO: pull the reply blob
 	 */
-	if (state->lderr != TLDAP_SUCCESS) {
-		tevent_req_error(req, state->lderr);
+	if (state->result->lderr != TLDAP_SUCCESS) {
+		tevent_req_error(req, state->result->lderr);
 		return;
 	}
 	tevent_req_done(req);
@@ -830,8 +843,10 @@ int tldap_sasl_bind(struct tldap_context *ld,
 		    const char *dn,
 		    const char *mechanism,
 		    DATA_BLOB *creds,
-		    struct tldap_control **sctrls,
-		    struct tldap_control **cctrls)
+		    struct tldap_control *sctrls,
+		    int num_sctrls,
+		    struct tldap_control *cctrls,
+		    int num_cctrls)
 {
 	TALLOC_CTX *frame = talloc_stackframe();
 	struct tevent_context *ev;
@@ -845,7 +860,7 @@ int tldap_sasl_bind(struct tldap_context *ld,
 	}
 
 	req = tldap_sasl_bind_send(frame, ev, ld, dn, mechanism, creds,
-				   sctrls, cctrls);
+				   sctrls, num_sctrls, cctrls, num_cctrls);
 	if (req == NULL) {
 		result = TLDAP_NO_MEMORY;
 		goto fail;
@@ -857,7 +872,7 @@ int tldap_sasl_bind(struct tldap_context *ld,
 	}
 
 	result = tldap_sasl_bind_recv(req);
-	tldap_save_errors(ld, req);
+	tldap_save_msg(ld, req);
  fail:
 	TALLOC_FREE(frame);
 	return result;
@@ -878,8 +893,8 @@ struct tevent_req *tldap_simple_bind_send(TALLOC_CTX *mem_ctx,
 		cred.data = (uint8_t *)"";
 		cred.length = 0;
 	}
-	return tldap_sasl_bind_send(mem_ctx, ev, ld, dn, NULL, &cred, NULL,
-				    NULL);
+	return tldap_sasl_bind_send(mem_ctx, ev, ld, dn, NULL, &cred, NULL, 0,
+				    NULL, 0);
 }
 
 int tldap_simple_bind_recv(struct tevent_req *req)
@@ -899,7 +914,7 @@ int tldap_simple_bind(struct tldap_context *ld, const char *dn,
 		cred.data = (uint8_t *)"";
 		cred.length = 0;
 	}
-	return tldap_sasl_bind(ld, dn, NULL, &cred, NULL, NULL);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list