1/* 2 Unix SMB/CIFS mplementation. 3 LDAP replUpToDateVector tests 4 5 Copyright (C) Stefan Metzmacher 2007 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. 19 20*/ 21 22#include "includes.h" 23#include "libcli/ldap/ldap_client.h" 24#include "lib/cmdline/popt_common.h" 25#include "ldb_wrap.h" 26#include "lib/ldb/include/ldb.h" 27#include "lib/ldb/include/ldb_errors.h" 28#include "dsdb/samdb/samdb.h" 29#include "../lib/util/dlinklist.h" 30 31#include "torture/torture.h" 32#include "torture/ldap/proto.h" 33 34#include "librpc/ndr/libndr.h" 35#include "librpc/gen_ndr/ndr_drsblobs.h" 36 37#include "param/param.h" 38 39static bool test_check_uptodatevector(struct torture_context *torture, 40 struct ldb_context *ldb, 41 struct ldb_dn *partition_dn) 42{ 43 bool ok = true; 44 uint32_t i; 45 int ret; 46 enum ndr_err_code ndr_err; 47 struct ldb_result *r; 48 const struct ldb_val *utdv_val1; 49 struct replUpToDateVectorBlob utdv1; 50 static const char *attrs[] = { 51 "uSNChanged", 52 "replUpToDateVector", 53 "description", 54 NULL 55 }; 56 57 torture_comment(torture, "Check replUpToDateVector on partition[%s]\n", 58 ldb_dn_get_linearized(partition_dn)); 59 60 ret = ldb_search(ldb, torture, &r, partition_dn, LDB_SCOPE_BASE, attrs, 61 "(objectClass=*)"); 62 if (ret != LDB_SUCCESS) { 63 return false; 64 } else if (r->count != 1) { 65 talloc_free(r); 66 return false; 67 } 68 69 ZERO_STRUCT(utdv1); 70 utdv_val1 = ldb_msg_find_ldb_val(r->msgs[0], "replUpToDateVector"); 71 if (utdv_val1) { 72 ndr_err = ndr_pull_struct_blob_all(utdv_val1, torture, 73 lp_iconv_convenience(torture->lp_ctx), &utdv1, 74 (ndr_pull_flags_fn_t)ndr_pull_replUpToDateVectorBlob); 75 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 76 return false; 77 } 78 } 79 80 for (i=0; i < 2; i++) { 81 const struct ldb_val *utdv_val; 82 struct replUpToDateVectorBlob utdv; 83 struct ldb_message *msg; 84 char *description; 85 uint32_t j; 86 bool no_match = false; 87 88 /* make a 'modify' msg, and only for serverReference */ 89 msg = ldb_msg_new(torture); 90 if (!msg) return false; 91 msg->dn = partition_dn; 92 93 description = talloc_asprintf(msg, "torture replUpToDateVector[%u]", i); 94 if (!description) return false; 95 96 ret = ldb_msg_add_string(msg, "description", description); 97 if (ret != 0) return false; 98 99 for (j=0;j<msg->num_elements;j++) { 100 msg->elements[j].flags = LDB_FLAG_MOD_REPLACE; 101 } 102 103 ret = ldb_modify(ldb, msg); 104 if (ret != LDB_SUCCESS) return false; 105 106 ret = ldb_search(ldb, msg, &r, partition_dn, LDB_SCOPE_BASE, 107 attrs, "(objectClass=*)"); 108 if (ret != LDB_SUCCESS) { 109 return false; 110 } else if (r->count != 1) { 111 talloc_free(r); 112 return false; 113 } 114 115 ZERO_STRUCT(utdv); 116 utdv_val = ldb_msg_find_ldb_val(r->msgs[0], "replUpToDateVector"); 117 if (utdv_val) { 118 ndr_err = ndr_pull_struct_blob_all(utdv_val, torture, 119 lp_iconv_convenience(torture->lp_ctx), &utdv, 120 (ndr_pull_flags_fn_t)ndr_pull_replUpToDateVectorBlob); 121 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 122 return false; 123 } 124 } 125 126 if (!utdv_val1 && utdv_val) { 127 no_match = true; 128 } else if (utdv_val1 && !utdv_val) { 129 no_match = true; 130 } else if (!utdv_val1 && !utdv_val) { 131 } else if (utdv_val1->length != utdv_val->length) { 132 no_match = true; 133 } else if (utdv_val1->length && memcmp(utdv_val1->data, utdv_val->data, utdv_val->length) != 0) { 134 no_match = true; 135 } 136 137 torture_comment(torture, "[%u]: uSNChanged[%llu] description[%s] replUpToDateVector[%s]\n", i, 138 (unsigned long long)samdb_result_uint64(r->msgs[0], "uSNChanged", 0), 139 samdb_result_string(r->msgs[0], "description", NULL), 140 (no_match ? "changed!: not ok" : "not changed: ok")); 141 142 if (no_match) { 143 NDR_PRINT_DEBUG(replUpToDateVectorBlob, &utdv1); 144 NDR_PRINT_DEBUG(replUpToDateVectorBlob, &utdv); 145 ok = false; 146 } 147 148 talloc_free(msg); 149 } 150 151 return ok; 152} 153 154bool torture_ldap_uptodatevector(struct torture_context *torture) 155{ 156 struct ldb_context *ldb; 157 bool ret = true; 158 const char *host = torture_setting_string(torture, "host", NULL); 159 char *url; 160 161 url = talloc_asprintf(torture, "ldap://%s/", host); 162 if (!url) goto failed; 163 164 ldb = ldb_wrap_connect(torture, torture->ev, torture->lp_ctx, url, 165 NULL, 166 cmdline_credentials, 167 0, NULL); 168 if (!ldb) goto failed; 169 170 ret &= test_check_uptodatevector(torture, ldb, samdb_base_dn(ldb)); 171 ret &= test_check_uptodatevector(torture, ldb, samdb_config_dn(ldb)); 172 ret &= test_check_uptodatevector(torture, ldb, samdb_schema_dn(ldb)); 173 174 return ret; 175failed: 176 return false; 177} 178