diff options
Diffstat (limited to 'source4/torture/ldap/uptodatevector.c')
-rw-r--r-- | source4/torture/ldap/uptodatevector.c | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/source4/torture/ldap/uptodatevector.c b/source4/torture/ldap/uptodatevector.c new file mode 100644 index 0000000..01c85ab --- /dev/null +++ b/source4/torture/ldap/uptodatevector.c @@ -0,0 +1,173 @@ +/* + Unix SMB/CIFS Implementation. + LDAP replUpToDateVector tests + + Copyright (C) Stefan Metzmacher 2007 + + 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 "libcli/ldap/ldap_client.h" +#include "lib/cmdline/cmdline.h" +#include "ldb_wrap.h" +#include "dsdb/samdb/samdb.h" + +#include "torture/torture.h" +#include "torture/ldap/proto.h" + +#include "librpc/gen_ndr/ndr_drsblobs.h" + +#include "param/param.h" + +static bool test_check_uptodatevector(struct torture_context *torture, + struct ldb_context *ldb, + struct ldb_dn *partition_dn) +{ + bool ok = true; + uint32_t i; + int ret; + enum ndr_err_code ndr_err; + struct ldb_result *r; + const struct ldb_val *utdv_val1; + struct replUpToDateVectorBlob utdv1; + static const char *attrs[] = { + "uSNChanged", + "replUpToDateVector", + "description", + NULL + }; + + torture_comment(torture, "Check replUpToDateVector on partition[%s]\n", + ldb_dn_get_linearized(partition_dn)); + + ret = ldb_search(ldb, torture, &r, partition_dn, LDB_SCOPE_BASE, attrs, + "(objectClass=*)"); + if (ret != LDB_SUCCESS) { + return false; + } else if (r->count != 1) { + talloc_free(r); + return false; + } + + ZERO_STRUCT(utdv1); + utdv_val1 = ldb_msg_find_ldb_val(r->msgs[0], "replUpToDateVector"); + if (utdv_val1) { + ndr_err = ndr_pull_struct_blob_all(utdv_val1, torture, + &utdv1, + (ndr_pull_flags_fn_t)ndr_pull_replUpToDateVectorBlob); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return false; + } + } + + for (i=0; i < 2; i++) { + const struct ldb_val *utdv_val; + struct replUpToDateVectorBlob utdv; + struct ldb_message *msg; + char *description; + uint32_t j; + bool no_match = false; + + /* make a 'modify' msg, and only for serverReference */ + msg = ldb_msg_new(torture); + if (!msg) return false; + msg->dn = partition_dn; + + description = talloc_asprintf(msg, "torture replUpToDateVector[%u]", i); + if (!description) return false; + + ret = ldb_msg_add_string(msg, "description", description); + if (ret != 0) return false; + + for (j=0;j<msg->num_elements;j++) { + msg->elements[j].flags = LDB_FLAG_MOD_REPLACE; + } + + ret = ldb_modify(ldb, msg); + if (ret != LDB_SUCCESS) return false; + + ret = ldb_search(ldb, msg, &r, partition_dn, LDB_SCOPE_BASE, + attrs, "(objectClass=*)"); + if (ret != LDB_SUCCESS) { + return false; + } else if (r->count != 1) { + talloc_free(r); + return false; + } + + ZERO_STRUCT(utdv); + utdv_val = ldb_msg_find_ldb_val(r->msgs[0], "replUpToDateVector"); + if (utdv_val) { + ndr_err = ndr_pull_struct_blob_all(utdv_val, torture, + &utdv, + (ndr_pull_flags_fn_t)ndr_pull_replUpToDateVectorBlob); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return false; + } + } + + if (!utdv_val1 && utdv_val) { + no_match = true; + } else if (utdv_val1 && !utdv_val) { + no_match = true; + } else if (!utdv_val1 && !utdv_val) { + } else if (utdv_val1->length != utdv_val->length) { + no_match = true; + } else if (utdv_val1->length && memcmp(utdv_val1->data, utdv_val->data, utdv_val->length) != 0) { + no_match = true; + } + + torture_comment(torture, "[%u]: uSNChanged[%llu] description[%s] replUpToDateVector[%s]\n", i, + (unsigned long long)ldb_msg_find_attr_as_uint64(r->msgs[0], "uSNChanged", 0), + ldb_msg_find_attr_as_string(r->msgs[0], "description", NULL), + (no_match ? "changed!: not ok" : "not changed: ok")); + + if (no_match) { + NDR_PRINT_DEBUG(replUpToDateVectorBlob, &utdv1); + NDR_PRINT_DEBUG(replUpToDateVectorBlob, &utdv); + ok = false; + } + + talloc_free(msg); + } + + return ok; +} + +bool torture_ldap_uptodatevector(struct torture_context *torture) +{ + struct ldb_context *ldb; + bool ret = true; + const char *host = torture_setting_string(torture, "host", NULL); + char *url; + + url = talloc_asprintf(torture, "ldap://%s/", host); + if (!url) goto failed; + + ldb = ldb_wrap_connect(torture, torture->ev, torture->lp_ctx, url, + NULL, + samba_cmdline_get_creds(), + 0); + if (!ldb) goto failed; + + ret &= test_check_uptodatevector(torture, ldb, ldb_get_default_basedn(ldb)); + ret &= test_check_uptodatevector(torture, ldb, ldb_get_config_basedn(ldb)); + ret &= test_check_uptodatevector(torture, ldb, ldb_get_schema_basedn(ldb)); + + return ret; +failed: + return false; +} |