[SCM] Samba Shared Repository - branch master updated

Garming Sam garming at samba.org
Wed Feb 17 05:55:04 UTC 2016


The branch, master has been updated
       via  7eab9e5 s4:selftest: run samba4.ldap.notification.python
       via  df04a2e s4:dsdb/tests: add notification.py with some basic tests
       via  e7dd980 s4:dsdb: let samba_dsdb make use of the dsdb_notification module
       via  6e88639 s4:ldap_server: add support for async notification requests
       via  46243e4 s4:dsdb: add dsdb_notification module
       via  3f0fbfa s4:dsdb/samldb: check for valid lDAPDisplayName vaues on add()
       via  ab16d11 s4:dsdb/tests: don't use spaces in lDAPDisplayName in urgent_replication.py
       via  29e3fc1 s4:ldap_server: make sure we only have one tstream_read_pdu_blob_send() on a connection
       via  d104d6e s4:libcli/ldap: add support for LDB_CONTROL_DIRSYNC_EX_OID
       via  fb705e1 ldb: version 1.1.26
       via  ad2b5fa ldb: add support for LDB_CONTROL_DIRSYNC_EX
       via  f721f27 ldb: add LDB_ATTR_FLAG_FORCE_BASE64_LDIF support
       via  6c8ab59 pyldb: eliminate warnings from python api test
       via  13e981d pyldb: add api tests for search_iterator()
       via  77ca078 pyldb: add ldb.search_iterator()
       via  e96fa7b pyldb: fix help message for ldb.search()
       via  2c2a254 pyldb: fix memory leak in py_ldb_search()
       via  e7bdd30 pyldb: Free correct context when pyldb_Object_AsDn() fails
       via  2b1cd4a ldb: allow a timeout of -1 result in no timeout timer at all.
       via  5db9f86 ldb-samba: fix the timeout setup in ildb_request_send()
       via  cd77b0bb s4:libcli/ldap: send AbandonRequests for cancelled requests
      from  a077e2a FIXUP: s3: VFS: Modify SMB_VFS_GET_NT_ACL to take a const struct smb_filename *

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


- Log -----------------------------------------------------------------
commit 7eab9e5fbd40e336d0345bea63b1a2541894ac64
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Feb 1 12:27:18 2016 +0100

    s4:selftest: run samba4.ldap.notification.python
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Garming Sam <garming at samba.org>
    Autobuild-Date(master): Wed Feb 17 06:54:48 CET 2016 on sn-devel-144

commit df04a2eee26499066985431f7d930cdf0a4a74aa
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Feb 1 10:58:41 2016 +0100

    s4:dsdb/tests: add notification.py with some basic tests
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit e7dd9808b1970b56c50510d8847af7d5a542bd5a
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jul 23 12:09:45 2015 +0200

    s4:dsdb: let samba_dsdb make use of the dsdb_notification module
    
    This means our LDAP server will support LDB_CONTROL_NOTIFICATION_OID now.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 6e88639ed99564b92da9a069ae6c42d1ebe09678
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jul 23 12:08:42 2015 +0200

    s4:ldap_server: add support for async notification requests
    
    This is a simplified version that works with the current
    dsdb_notification module that requires the caller to retry
    periodically. We do that every 5 seconds or 100 microseconds
    if we're forcing a retry.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 46243e4d80b7a1df8920d80af70c7ecca380b5a5
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jul 23 12:09:45 2015 +0200

    s4:dsdb: add dsdb_notification module
    
    This adds a simple implementation of LDB_CONTROL_NOTIFICATION_OID.
    It requires caller (the ldap server task) to retry the request peridically,
    using the same ldb_control structure in order to get some progress and
    the never ending search behaviour an LDAP client expects.
    
    For now we remember the known_usn in a cookie stored
    in the otherwise unused ldb_control->data fielf
    and we do a simple search using (uSNChanged>=${known_usn}+1).
    
    In future we may do things based on the uSNChanged value.
    
    for (i = old_highest + 1; i <= current_highest; i) {
    	search for (uSNChanged=i)
    }
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 3f0fbfa7b2eac8e54ce165564cf6f33dd1821644
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Feb 1 23:04:04 2016 +0100

    s4:dsdb/samldb: check for valid lDAPDisplayName vaues on add()
    
    This still leaves modifies(), but that's a task for another day.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit ab16d11e322d3183d7f43fd0cef6f36440ce8639
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Feb 1 23:02:14 2016 +0100

    s4:dsdb/tests: don't use spaces in lDAPDisplayName in urgent_replication.py
    
    This should result in LDAP_UNWILLING_TO_PERFORM/WERR_DS_INVALID_LDAP_DISPLAY_NAME,
    so better use a useful value without spaces.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 29e3fc1cff557525fde2cc2d7347b540672440de
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jul 23 12:06:11 2015 +0200

    s4:ldap_server: make sure we only have one tstream_read_pdu_blob_send() on a connection
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit d104d6e04ff8ad8274db1a63f53a5c2b93e3e10b
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jan 26 09:37:13 2016 +0100

    s4:libcli/ldap: add support for LDB_CONTROL_DIRSYNC_EX_OID
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit fb705e19e8a8e727908c8913604c4cbffdb30c96
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Feb 2 10:04:20 2016 +0100

    ldb: version 1.1.26
    
    * let a timeout of -1 indicate no timeout for a given request
    * fix memory leaks in pyldb ldb.search()
    * build fixes
    * improve pyldb ldb.search() help message
    * add pyldb ldb.search_iterator() api
    * add LDB_ATTR_FLAG_FORCE_BASE64_LDIF as optional argument
      to ldb_schema_attribute_add()
    * add client support for LDB_CONTROL_DIRSYNC_EX
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit ad2b5fae7f9b1437e6fcf73a0be3ca5d3ba0d5dc
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jan 26 09:36:56 2016 +0100

    ldb: add support for LDB_CONTROL_DIRSYNC_EX
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit f721f27da5f9ebb41639b70986ad1acb83206ed6
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Feb 5 13:55:31 2016 +0100

    ldb: add LDB_ATTR_FLAG_FORCE_BASE64_LDIF support
    
    This can be used to force ldb_write_ldif() to use base64 for
    a specific attribute.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 6c8ab59d068101caa40f9b15ed70a115b5612f47
Author: Michael Adam <obnox at samba.org>
Date:   Sun Feb 14 16:50:38 2016 +0100

    pyldb: eliminate warnings from python api test
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 13e981d3d822876f6f6e741606dc5a772ab2cca5
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Feb 1 02:30:56 2016 +0100

    pyldb: add api tests for search_iterator()
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 77ca07801c81558d95b95e9120511cb2e00f3d03
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 22 00:06:45 2016 +0100

    pyldb: add ldb.search_iterator()
    
    This is able to handle async requests, e.g. with a notification control
    and processes results as they arrive instead of waiting for all results
    before returning.
    
    search_handle = ldb.search_iterator(...)
    
    for e in search_handle:
        if not isinstance(msg, ldb.Message):
            # referral
            continue
    
        name = e["name"][0]
    
    result = search_handle.result()
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit e96fa7b10c5c6ee2cdd57c2aa553593c9372f87b
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 22 00:06:04 2016 +0100

    pyldb: fix help message for ldb.search()
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 2c2a2540f4076debdf2993781958b546c269aa49
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 22 00:05:09 2016 +0100

    pyldb: fix memory leak in py_ldb_search()
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit e7bdd30be54f3652cf060f4252f9eed3ea82078f
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Jan 5 17:59:32 2016 +1300

    pyldb: Free correct context when pyldb_Object_AsDn() fails
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 2b1cd4a1147a8d5ba10ddcef4c2d258df2bd5dd4
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 22 08:53:57 2016 +0100

    ldb: allow a timeout of -1 result in no timeout timer at all.
    
    This is required in order to have long running async searches,
    e.g. with LDB_CONTROL_NOTIFICATION_OID.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 5db9f865bca818da8d2334208f3141f7f5c7286d
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 22 08:53:57 2016 +0100

    ldb-samba: fix the timeout setup in ildb_request_send()
    
    We need to use the startime as reference not the current time.
    
    We also allow timeout == -1 to indicate no timeout at all.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit cd77b0bba434139e13db5ec2096ca99b6b3f084d
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Feb 1 11:00:14 2016 +0100

    s4:libcli/ldap: send AbandonRequests for cancelled requests
    
    This happens on a local timeout of an talloc_free() of the request.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

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

Summary of changes:
 lib/ldb-samba/ldb_ildap.c                          |  12 +-
 lib/ldb/ABI/{ldb-1.1.25.sigs => ldb-1.1.26.sigs}   |   0
 ...ldb-util-1.1.10.sigs => pyldb-util-1.1.26.sigs} |   0
 ...util-1.1.10.sigs => pyldb-util.py3-1.1.26.sigs} |   0
 lib/ldb/common/ldb_controls.c                      |  65 ++++
 lib/ldb/common/ldb_ldif.c                          |  14 +-
 lib/ldb/include/ldb.h                              |   7 +
 lib/ldb/ldb_ldap/ldb_ldap.c                        |  18 +-
 lib/ldb/ldb_sqlite3/ldb_sqlite3.c                  |  11 +-
 lib/ldb/ldb_tdb/ldb_tdb.c                          |  14 +-
 lib/ldb/pyldb.c                                    | 385 ++++++++++++++++++++-
 lib/ldb/tests/python/api.py                        | 108 +++++-
 lib/ldb/tools/cmdline.c                            |  33 ++
 lib/ldb/wscript                                    |   2 +-
 source4/dsdb/samdb/ldb_modules/dsdb_notification.c | 262 ++++++++++++++
 source4/dsdb/samdb/ldb_modules/samba_dsdb.c        |   1 +
 source4/dsdb/samdb/ldb_modules/samldb.c            |  30 ++
 .../dsdb/samdb/ldb_modules/wscript_build_server    |   9 +
 source4/dsdb/tests/python/notification.py          | 352 +++++++++++++++++++
 source4/dsdb/tests/python/urgent_replication.py    |   8 +-
 source4/ldap_server/ldap_backend.c                 |  82 ++++-
 source4/ldap_server/ldap_bind.c                    |  22 +-
 source4/ldap_server/ldap_extended.c                |   8 +-
 source4/ldap_server/ldap_server.c                  | 146 +++++++-
 source4/ldap_server/ldap_server.h                  |  16 +
 source4/libcli/ldap/ldap_client.c                  |  50 +++
 source4/libcli/ldap/ldap_controls.c                |   1 +
 source4/selftest/tests.py                          |   1 +
 28 files changed, 1603 insertions(+), 54 deletions(-)
 copy lib/ldb/ABI/{ldb-1.1.25.sigs => ldb-1.1.26.sigs} (100%)
 copy lib/ldb/ABI/{pyldb-util-1.1.10.sigs => pyldb-util-1.1.26.sigs} (100%)
 copy lib/ldb/ABI/{pyldb-util-1.1.10.sigs => pyldb-util.py3-1.1.26.sigs} (100%)
 create mode 100644 source4/dsdb/samdb/ldb_modules/dsdb_notification.c
 create mode 100755 source4/dsdb/tests/python/notification.py


Changeset truncated at 500 lines:

diff --git a/lib/ldb-samba/ldb_ildap.c b/lib/ldb-samba/ldb_ildap.c
index 6ec363d..65f11db 100644
--- a/lib/ldb-samba/ldb_ildap.c
+++ b/lib/ldb-samba/ldb_ildap.c
@@ -418,11 +418,13 @@ static int ildb_request_send(struct ildb_context *ac, struct ldap_message *msg)
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-	talloc_free(req->time_event);
-	req->time_event = NULL;
-	if (ac->req->timeout) {
-		req->time_event = tevent_add_timer(ac->ildb->event_ctx, ac,
-						   timeval_current_ofs(ac->req->timeout, 0),
+	TALLOC_FREE(req->time_event);
+	if (ac->req->timeout > 0) {
+		struct timeval tv = {
+			.tv_sec = ac->req->starttime + ac->req->timeout,
+		};
+
+		req->time_event = tevent_add_timer(ac->ildb->event_ctx, ac, tv,
 						   ildb_request_timeout, ac);
 	}
 
diff --git a/lib/ldb/ABI/ldb-1.1.25.sigs b/lib/ldb/ABI/ldb-1.1.26.sigs
similarity index 100%
copy from lib/ldb/ABI/ldb-1.1.25.sigs
copy to lib/ldb/ABI/ldb-1.1.26.sigs
diff --git a/lib/ldb/ABI/pyldb-util-1.1.10.sigs b/lib/ldb/ABI/pyldb-util-1.1.26.sigs
similarity index 100%
copy from lib/ldb/ABI/pyldb-util-1.1.10.sigs
copy to lib/ldb/ABI/pyldb-util-1.1.26.sigs
diff --git a/lib/ldb/ABI/pyldb-util-1.1.10.sigs b/lib/ldb/ABI/pyldb-util.py3-1.1.26.sigs
similarity index 100%
copy from lib/ldb/ABI/pyldb-util-1.1.10.sigs
copy to lib/ldb/ABI/pyldb-util.py3-1.1.26.sigs
diff --git a/lib/ldb/common/ldb_controls.c b/lib/ldb/common/ldb_controls.c
index 7346326..af056d0 100644
--- a/lib/ldb/common/ldb_controls.c
+++ b/lib/ldb/common/ldb_controls.c
@@ -367,6 +367,26 @@ char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *contr
 		talloc_free(cookie);
 		return res;
 	}
+	if (strcmp(control->oid, LDB_CONTROL_DIRSYNC_EX_OID) == 0) {
+		char *cookie;
+		struct ldb_dirsync_control *rep_control = talloc_get_type(control->data,
+								struct ldb_dirsync_control);
+
+		cookie = ldb_base64_encode(mem_ctx, rep_control->cookie,
+				rep_control->cookie_len);
+		if (cookie == NULL) {
+			return NULL;
+		}
+		res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%s",
+					LDB_CONTROL_DIRSYNC_EX_NAME,
+					control->critical,
+					rep_control->flags,
+					rep_control->max_attributes,
+					cookie);
+
+		talloc_free(cookie);
+		return res;
+	}
 
 	if (strcmp(control->oid, LDB_CONTROL_VERIFY_NAME_OID) == 0) {
 		struct ldb_verify_name_control *rep_control = talloc_get_type(control->data, struct ldb_verify_name_control);
@@ -525,6 +545,51 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 
 		return ctrl;
 	}
+	if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DIRSYNC_EX_NAME) == 0) {
+		struct ldb_dirsync_control *control;
+		const char *p;
+		char cookie[1024];
+		int crit, max_attrs, ret;
+		uint32_t flags;
+
+		cookie[0] = '\0';
+		p = &(control_strings[sizeof(LDB_CONTROL_DIRSYNC_EX_NAME)]);
+		ret = sscanf(p, "%d:%u:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie);
+
+		if ((ret < 3) || (crit < 0) || (crit > 1) || (max_attrs < 0)) {
+			error_string = talloc_asprintf(mem_ctx, "invalid %s control syntax\n",
+						       LDB_CONTROL_DIRSYNC_EX_NAME);
+			error_string = talloc_asprintf_append(error_string, " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n");
+			error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number, o = b64 binary blob");
+			ldb_set_errstring(ldb, error_string);
+			talloc_free(error_string);
+			talloc_free(ctrl);
+			return NULL;
+		}
+
+		/* w2k3 seems to ignore the parameter,
+		 * but w2k sends a wrong cookie when this value is to small
+		 * this would cause looping forever, while getting
+		 * the same data and same cookie forever
+		 */
+		if (max_attrs == 0) max_attrs = 0x0FFFFFFF;
+
+		ctrl->oid = LDB_CONTROL_DIRSYNC_EX_OID;
+		ctrl->critical = crit;
+		control = talloc(ctrl, struct ldb_dirsync_control);
+		control->flags = flags;
+		control->max_attributes = max_attrs;
+		if (*cookie) {
+			control->cookie_len = ldb_base64_decode(cookie);
+			control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len);
+		} else {
+			control->cookie = NULL;
+			control->cookie_len = 0;
+		}
+		ctrl->data = control;
+
+		return ctrl;
+	}
 
 	if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_ASQ_NAME) == 0) {
 		struct ldb_asq_control *control;
diff --git a/lib/ldb/common/ldb_ldif.c b/lib/ldb/common/ldb_ldif.c
index 07de517..0aeda94b 100644
--- a/lib/ldb/common/ldb_ldif.c
+++ b/lib/ldb/common/ldb_ldif.c
@@ -348,13 +348,21 @@ static int ldb_ldif_write_trace(struct ldb_context *ldb,
 
 		for (j=0;j<msg->elements[i].num_values;j++) {
 			struct ldb_val v;
-			bool use_b64_encode;
+			bool use_b64_encode = false;
+
 			ret = a->syntax->ldif_write_fn(ldb, mem_ctx, &msg->elements[i].values[j], &v);
 			if (ret != LDB_SUCCESS) {
 				v = msg->elements[i].values[j];
 			}
-			use_b64_encode = !(ldb->flags & LDB_FLG_SHOW_BINARY)
-					&& ldb_should_b64_encode(ldb, &v);
+
+			if (ldb->flags & LDB_FLG_SHOW_BINARY) {
+				use_b64_encode = false;
+			} else if (a->flags & LDB_ATTR_FLAG_FORCE_BASE64_LDIF) {
+				use_b64_encode = true;
+			} else {
+				use_b64_encode = ldb_should_b64_encode(ldb, &v);
+			}
+
 			if (ret != LDB_SUCCESS || use_b64_encode) {
 				ret = fprintf_fn(private_data, "%s:: ",
 						 msg->elements[i].name);
diff --git a/lib/ldb/include/ldb.h b/lib/ldb/include/ldb.h
index f48f753..e715b92 100644
--- a/lib/ldb/include/ldb.h
+++ b/lib/ldb/include/ldb.h
@@ -422,6 +422,11 @@ const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_c
  */
 #define LDB_ATTR_FLAG_SINGLE_VALUE (1<<4)
 
+/*
+ * The values should always be base64 encoded
+ */
+#define LDB_ATTR_FLAG_FORCE_BASE64_LDIF        (1<<5)
+
 /**
   LDAP attribute syntax for a DN
 
@@ -652,6 +657,8 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
 */
 #define LDB_CONTROL_DIRSYNC_OID		"1.2.840.113556.1.4.841"
 #define LDB_CONTROL_DIRSYNC_NAME	"dirsync"
+#define LDB_CONTROL_DIRSYNC_EX_OID	"1.2.840.113556.1.4.2090"
+#define LDB_CONTROL_DIRSYNC_EX_NAME	"dirsync_ex"
 
 
 /**
diff --git a/lib/ldb/ldb_ldap/ldb_ldap.c b/lib/ldb/ldb_ldap/ldb_ldap.c
index 7e6ac90..29f8938 100644
--- a/lib/ldb/ldb_ldap/ldb_ldap.c
+++ b/lib/ldb/ldb_ldap/ldb_ldap.c
@@ -252,8 +252,11 @@ static int lldb_search(struct lldb_context *lldb_ac)
 		break;
 	}
 
-	tv.tv_sec = req->timeout;
+	tv.tv_sec = 0;
 	tv.tv_usec = 0;
+	if (req->timeout > 0) {
+		tv.tv_sec = req->timeout;
+	}
 
 	ret = ldap_search_ext(lldb->ldap, search_base, ldap_scope, 
 			      expression, 
@@ -836,12 +839,13 @@ static int lldb_handle_request(struct ldb_module *module, struct ldb_request *re
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-
-	tv.tv_sec = req->starttime + req->timeout;
-	tv.tv_usec = 0;
-	te = tevent_add_timer(ev, ac, tv, lldb_timeout, ac);
-	if (NULL == te) {
-		return LDB_ERR_OPERATIONS_ERROR;
+	if (req->timeout > 0) {
+		tv.tv_sec = req->starttime + req->timeout;
+		tv.tv_usec = 0;
+		te = tevent_add_timer(ev, ac, tv, lldb_timeout, ac);
+		if (NULL == te) {
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
 	}
 
 	return LDB_SUCCESS;
diff --git a/lib/ldb/ldb_sqlite3/ldb_sqlite3.c b/lib/ldb/ldb_sqlite3/ldb_sqlite3.c
index 223868a..60b39e8 100644
--- a/lib/ldb/ldb_sqlite3/ldb_sqlite3.c
+++ b/lib/ldb/ldb_sqlite3/ldb_sqlite3.c
@@ -1566,10 +1566,13 @@ static int lsql_handle_request(struct ldb_module *module, struct ldb_request *re
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-	tv.tv_sec = req->starttime + req->timeout;
-	ac->timeout_event = tevent_add_timer(ev, ac, tv, lsql_timeout, ac);
-	if (NULL == ac->timeout_event) {
-		return LDB_ERR_OPERATIONS_ERROR;
+	if (req->timeout > 0) {
+		tv.tv_sec = req->starttime + req->timeout;
+		tv.tv_usec = 0;
+		ac->timeout_event = tevent_add_timer(ev, ac, tv, lsql_timeout, ac);
+		if (NULL == ac->timeout_event) {
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
 	}
 
 	return LDB_SUCCESS;
diff --git a/lib/ldb/ldb_tdb/ldb_tdb.c b/lib/ldb/ldb_tdb/ldb_tdb.c
index bcb8f0f..8d1fd36 100644
--- a/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -1469,11 +1469,15 @@ static int ltdb_handle_request(struct ldb_module *module,
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-	tv.tv_sec = req->starttime + req->timeout;
-	ac->timeout_event = tevent_add_timer(ev, ac, tv, ltdb_timeout, ac);
-	if (NULL == ac->timeout_event) {
-		talloc_free(ac);
-		return LDB_ERR_OPERATIONS_ERROR;
+	if (req->timeout > 0) {
+		tv.tv_sec = req->starttime + req->timeout;
+		tv.tv_usec = 0;
+		ac->timeout_event = tevent_add_timer(ev, ac, tv,
+						     ltdb_timeout, ac);
+		if (NULL == ac->timeout_event) {
+			talloc_free(ac);
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
 	}
 
 	/* set a spy so that we do not try to use the request context
diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c
index 3daed96..bea837f 100644
--- a/lib/ldb/pyldb.c
+++ b/lib/ldb/pyldb.c
@@ -32,6 +32,27 @@
 #include "ldb_private.h"
 #include "ldb_handlers.h"
 #include "pyldb.h"
+#include "dlinklist.h"
+
+struct py_ldb_search_iterator_reply;
+
+typedef struct {
+	PyObject_HEAD
+	TALLOC_CTX *mem_ctx;
+	PyLdbObject *ldb;
+	struct {
+		struct ldb_request *req;
+		struct py_ldb_search_iterator_reply *next;
+		struct py_ldb_search_iterator_reply *result;
+		PyObject *exception;
+	} state;
+} PyLdbSearchIteratorObject;
+
+struct py_ldb_search_iterator_reply {
+	struct py_ldb_search_iterator_reply *prev, *next;
+	PyLdbSearchIteratorObject *py_iter;
+	PyObject *obj;
+};
 
 void initldb(void);
 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
@@ -39,6 +60,7 @@ static PyObject *PyExc_LdbError;
 
 static PyTypeObject PyLdbControl;
 static PyTypeObject PyLdbResult;
+static PyTypeObject PyLdbSearchIterator;
 static PyTypeObject PyLdbMessage;
 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
 static PyTypeObject PyLdbModule;
@@ -1807,8 +1829,8 @@ static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwar
 	if (py_base == Py_None) {
 		base = ldb_get_default_basedn(ldb_ctx);
 	} else {
-		if (!pyldb_Object_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
-			talloc_free(attrs);
+		if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) {
+			talloc_free(mem_ctx);
 			return NULL;
 		}
 	}
@@ -1869,6 +1891,200 @@ static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwar
 	return py_ret;
 }
 
+static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply)
+{
+	if (reply->py_iter != NULL) {
+		DLIST_REMOVE(reply->py_iter->state.next, reply);
+		if (reply->py_iter->state.result == reply) {
+			reply->py_iter->state.result = NULL;
+		}
+		reply->py_iter = NULL;
+	}
+
+	if (reply->obj != NULL) {
+		Py_DECREF(reply->obj);
+		reply->obj = NULL;
+	}
+
+	return 0;
+}
+
+static int py_ldb_search_iterator_callback(struct ldb_request *req,
+					   struct ldb_reply *ares)
+{
+	PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context;
+	struct ldb_result result = { .msgs = NULL };
+	struct py_ldb_search_iterator_reply *reply = NULL;
+
+	if (ares == NULL) {
+		return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
+	}
+
+	if (ares->error != LDB_SUCCESS) {
+		int ret = ares->error;
+		TALLOC_FREE(ares);
+		return ldb_request_done(req, ret);
+	}
+
+	reply = talloc_zero(py_iter->mem_ctx,
+			    struct py_ldb_search_iterator_reply);
+	if (reply == NULL) {
+		TALLOC_FREE(ares);
+		return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
+	}
+	reply->py_iter = py_iter;
+	talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor);
+
+	switch (ares->type) {
+	case LDB_REPLY_ENTRY:
+		reply->obj = PyLdbMessage_FromMessage(ares->message);
+		if (reply->obj == NULL) {
+			TALLOC_FREE(ares);
+			return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
+		}
+		DLIST_ADD_END(py_iter->state.next, reply);
+		TALLOC_FREE(ares);
+		return LDB_SUCCESS;
+
+	case LDB_REPLY_REFERRAL:
+		reply->obj = PyStr_FromString(ares->referral);
+		if (reply->obj == NULL) {
+			TALLOC_FREE(ares);
+			return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
+		}
+		DLIST_ADD_END(py_iter->state.next, reply);
+		TALLOC_FREE(ares);
+		return LDB_SUCCESS;
+
+	case LDB_REPLY_DONE:
+		result = (struct ldb_result) { .controls = ares->controls };
+		reply->obj = PyLdbResult_FromResult(&result);
+		if (reply->obj == NULL) {
+			TALLOC_FREE(ares);
+			return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
+		}
+		py_iter->state.result = reply;
+		TALLOC_FREE(ares);
+		return ldb_request_done(req, LDB_SUCCESS);
+	}
+
+	TALLOC_FREE(ares);
+	return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
+}
+
+static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs)
+{
+	PyObject *py_base = Py_None;
+	int scope = LDB_SCOPE_DEFAULT;
+	int timeout = 0;
+	char *expr = NULL;
+	PyObject *py_attrs = Py_None;
+	PyObject *py_controls = Py_None;
+	const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL };
+	int ret;
+	const char **attrs;
+	struct ldb_context *ldb_ctx;
+	struct ldb_control **parsed_controls;
+	struct ldb_dn *base;
+	PyLdbSearchIteratorObject *py_iter;
+
+	/* type "int" rather than "enum" for "scope" is intentional */
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi",
+					 discard_const_p(char *, kwnames),
+					 &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout))
+		return NULL;
+
+	py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0);
+	if (py_iter == NULL) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+	py_iter->ldb = self;
+	Py_INCREF(self);
+	ZERO_STRUCT(py_iter->state);
+	py_iter->mem_ctx = talloc_new(NULL);
+	if (py_iter->mem_ctx == NULL) {
+		Py_DECREF(py_iter);
+		PyErr_NoMemory();
+		return NULL;
+	}
+
+	ldb_ctx = pyldb_Ldb_AsLdbContext(self);
+
+	if (py_attrs == Py_None) {
+		attrs = NULL;
+	} else {
+		attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs");
+		if (attrs == NULL) {
+			Py_DECREF(py_iter);
+			PyErr_NoMemory();
+			return NULL;
+		}
+	}
+
+	if (py_base == Py_None) {
+		base = ldb_get_default_basedn(ldb_ctx);
+	} else {
+		if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) {
+			Py_DECREF(py_iter);
+			PyErr_NoMemory();
+			return NULL;
+		}
+	}
+
+	if (py_controls == Py_None) {
+		parsed_controls = NULL;
+	} else {
+		const char **controls = NULL;
+
+		controls = PyList_AsStrList(py_iter->mem_ctx,
+					    py_controls, "controls");
+		if (controls == NULL) {
+			Py_DECREF(py_iter);
+			PyErr_NoMemory();
+			return NULL;
+		}
+
+		parsed_controls = ldb_parse_control_strings(ldb_ctx,
+							    py_iter->mem_ctx,
+							    controls);
+		if (controls[0] != NULL && parsed_controls == NULL) {
+			Py_DECREF(py_iter);
+			PyErr_NoMemory();
+			return NULL;
+		}
+		talloc_free(controls);
+	}
+
+	ret = ldb_build_search_req(&py_iter->state.req,
+				   ldb_ctx,
+				   py_iter->mem_ctx,
+				   base,
+				   scope,
+				   expr,
+				   attrs,
+				   parsed_controls,
+				   py_iter,
+				   py_ldb_search_iterator_callback,
+				   NULL);
+	if (ret != LDB_SUCCESS) {
+		Py_DECREF(py_iter);
+		PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
+		return NULL;
+	}
+
+	ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout);
+
+	ret = ldb_request(ldb_ctx, py_iter->state.req);
+	if (ret != LDB_SUCCESS) {
+		Py_DECREF(py_iter);
+		PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
+		return NULL;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list