torture: Test ldap session expiry
authorVolker Lendecke <vl@samba.org>
Wed, 12 Aug 2020 13:50:58 +0000 (15:50 +0200)
committerStefan Metzmacher <metze@samba.org>
Thu, 3 Sep 2020 13:34:10 +0000 (13:34 +0000)
LDAP connections should time out when the kerberos ticket used to authenticate
expires. Windows does this with a RFC4511 section 4.4.1 message (that as of
August 2020 is encoded not according to the RFC) followed by a TCP disconnect.

ldb sees the section 4.4.1 as a protocol violation and returns
LDB_ERR_PROTOCOL_ERROR.

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

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
(cherry picked from commit 35c4bb0b0c55a65490fe199edb1a534548104e95)

selftest/knownfail.d/ldap
source4/selftest/tests.py
source4/torture/ldap/common.c
source4/torture/ldap/session_expiry.c [new file with mode: 0644]
source4/torture/wscript_build

index 0331d3687d41a6e27f52505aca16d3edf1da7305..21c1aca7e6e72b3b37bb639682e1a703671503fc 100644 (file)
@@ -1,3 +1,4 @@
 # the attributes too long test returns the wrong error
 ^samba4.ldap.python.+test_attribute_ranges_too_long
 samba4.ldap.python\(ad_dc_default\).*__main__.BasicTests.test_ldapSearchNoAttributes
+^samba4.ldap.session-expiry.session-expiry\(ad_dc_default\)
index f4d91520a121749bc7f03867499bf976f75075d5..0b74b6c898402c5cd4ce51708b63dcdfe50a336c 100755 (executable)
@@ -156,6 +156,10 @@ for options in ['-U"$USERNAME%$PASSWORD"']:
 for t in smbtorture4_testsuites("ldap."):
     if t == "ldap.nested-search":
         plansmbtorture4testsuite(t, "ad_dc_default_smb1", '-U"$USERNAME%$PASSWORD" //$SERVER_IP/_none_')
+    elif t == "ldap.session-expiry":
+        # This requires kerberos and thus the server name
+        plansmbtorture4testsuite(
+            t, "ad_dc_default", '-U"$USERNAME%$PASSWORD" //$DC_SERVER/_none_')
     else:
         plansmbtorture4testsuite(t, "ad_dc_default", '-U"$USERNAME%$PASSWORD" //$SERVER_IP/_none_')
 
index 9482e0392bcc97862cbb4445e5379d1ec04c82f9..d16f611fa771c8e90ddb501840c560054414c80d 100644 (file)
@@ -124,6 +124,8 @@ NTSTATUS torture_ldap_init(TALLOC_CTX *ctx)
        torture_suite_add_simple_test(suite, "schema", torture_ldap_schema);
        torture_suite_add_simple_test(suite, "uptodatevector", torture_ldap_uptodatevector);
        torture_suite_add_simple_test(suite, "nested-search", test_ldap_nested_search);
+       torture_suite_add_simple_test(
+               suite, "session-expiry", torture_ldap_session_expiry);
 
        suite->description = talloc_strdup(suite, "LDAP and CLDAP tests");
 
diff --git a/source4/torture/ldap/session_expiry.c b/source4/torture/ldap/session_expiry.c
new file mode 100644 (file)
index 0000000..35dda43
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Test LDB attribute functions
+ *
+ * Copyright (C) Andrew Bartlet <abartlet@samba.org> 2008-2009
+ * Copyright (C) Matthieu Patou <mat@matws.net> 2009
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.        See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.    If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+#include "lib/events/events.h"
+#include <ldb.h>
+#include <ldb_errors.h>
+#include "ldb_wrap.h"
+#include "param/param.h"
+#include "lib/cmdline/popt_common.h"
+#include "auth/credentials/credentials.h"
+#include "libcli/ldap/ldap_client.h"
+#include "torture/smbtorture.h"
+#include "torture/ldap/proto.h"
+
+bool torture_ldap_session_expiry(struct torture_context *torture)
+{
+       const char *host = torture_setting_string(torture, "host", NULL);
+       struct cli_credentials *credentials = popt_get_cmdline_credentials();
+       struct ldb_context *ldb = NULL;
+       const char *url = NULL;
+       bool ret = false;
+       bool ok;
+       struct ldb_dn *rootdn = NULL;
+       struct ldb_result *result = NULL;
+       int rc = LDB_SUCCESS;
+
+       /*
+        * Further down we request a ticket lifetime of 4
+        * seconds. Give the server 10 seconds for this to kick in
+        */
+       const struct timeval endtime = timeval_current_ofs(10, 0);
+
+       url = talloc_asprintf(torture, "ldap://%s/", host);
+       torture_assert_goto(
+               torture, url!=NULL, ret, fail, "talloc_asprintf failed");
+
+       cli_credentials_set_kerberos_state(
+               credentials, CRED_MUST_USE_KERBEROS);
+
+       ok = lpcfg_set_option(
+               torture->lp_ctx, "gensec_gssapi:requested_life_time=4");
+       torture_assert_goto(
+               torture, ok, ret, fail, "lpcfg_set_option failed");
+
+       ldb = ldb_wrap_connect(
+               torture,
+               torture->ev,
+               torture->lp_ctx,
+               url,
+               NULL,
+               credentials,
+               0);
+       torture_assert_goto(
+               torture, ldb!=NULL, ret, fail, "ldb_wrap_connect failed");
+
+       rootdn = ldb_dn_new(ldb, ldb, NULL);
+       torture_assert_goto(
+               torture, rootdn!=NULL, ret, fail, "ldb_dn_new failed");
+
+       rc = ldb_search(
+               ldb,                /* ldb */
+               ldb,                /* mem_ctx */
+               &result,            /* result */
+               rootdn,             /* base */
+               LDB_SCOPE_BASE,     /* scope */
+               NULL,               /* attrs */
+               "(objectclass=*)"); /* exp_fmt */
+       torture_assert_goto(
+               torture, rc==LDB_SUCCESS, ret, fail, "1st ldb_search failed");
+
+       do {
+               smb_msleep(1000);
+
+               rc = ldb_search(
+                       ldb,            /* ldb */
+                       ldb,            /* mem_ctx */
+                       &result,        /* result */
+                       rootdn,         /* base */
+                       LDB_SCOPE_BASE, /* scope */
+                       NULL,           /* attrs */
+                       "(objectclass=*)"); /* exp_fmt */
+               printf("ldb_search returned %s\n", ldb_strerror(rc));
+               TALLOC_FREE(result);
+
+               if (rc != LDB_SUCCESS) {
+                       break;
+               }
+       } while (!timeval_expired(&endtime));
+
+       torture_assert_goto(
+               torture,
+               rc==LDB_ERR_PROTOCOL_ERROR,
+               ret,
+               fail,
+               "expected LDB_ERR_PROTOCOL_ERROR after 4 seconds");
+
+       ret = true;
+fail:
+       TALLOC_FREE(ldb);
+       return ret;
+}
index 10b486b1dedb4b7e17804067e8edad745104423c..1b781266e430e45ec82fe7bcecc08c0f3f52e410 100644 (file)
@@ -259,6 +259,7 @@ bld.SAMBA_MODULE('TORTURE_LDAP',
             ldap/cldapbench.c
             ldap/ldap_sort.c
             ldap/nested_search.c
+            ldap/session_expiry.c
             ''',
        subsystem='smbtorture',
        deps='cli-ldap cli_cldap samdb popt POPT_CREDENTIALS torture ldbsamba',