1/* 2 Unix SMB/CIFS implementation. 3 4 Test LDB attribute functions 5 6 Copyright (C) Andrew Bartlet <abartlet@samba.org> 2008-2009 7 Copyright (C) Matthieu Patou <mat@matws.net> 2009 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see <http://www.gnu.org/licenses/>. 21*/ 22 23#include "includes.h" 24#include "lib/events/events.h" 25#include "lib/ldb/include/ldb.h" 26#include "lib/ldb/include/ldb_errors.h" 27#include "ldb_wrap.h" 28#include "param/param.h" 29#include "lib/cmdline/popt_common.h" 30#include "torture/smbtorture.h" 31#include "torture/local/proto.h" 32#include <ctype.h> 33bool torture_ldap_sort(struct torture_context *torture) 34{ 35 36 struct ldb_context *ldb; 37 38 bool ret = false; 39 const char *host = torture_setting_string(torture, "host", NULL); 40 char *url; 41 int i; 42 codepoint_t j; 43 struct ldb_message_element *elem; 44 struct ldb_message *msg; 45 46 struct ldb_server_sort_control **control; 47 struct ldb_request *req; 48 struct ldb_result *ctx; 49 struct ldb_val* prev = NULL; 50 const char *prev_txt = NULL; 51 int prev_len = 0; 52 struct ldb_val* cur = NULL; 53 const char *cur_txt = NULL; 54 int cur_len = 0; 55 struct ldb_dn* dn; 56 57 58 /* TALLOC_CTX* ctx;*/ 59 60 url = talloc_asprintf(torture, "ldap://%s/", host); 61 62 ldb = ldb_wrap_connect(torture, torture->ev, torture->lp_ctx, url, 63 NULL, 64 cmdline_credentials, 65 0, NULL); 66 torture_assert(torture, ldb, "Failed to make LDB connection to target"); 67 68 ctx = talloc_zero(ldb, struct ldb_result); 69 70 control = talloc_array(ctx, struct ldb_server_sort_control *, 2); 71 control[0] = talloc(control, struct ldb_server_sort_control); 72 control[0]->attributeName = talloc_strdup(control, "cn"); 73 control[0]->orderingRule = NULL; 74 control[0]->reverse = 0; 75 control[1] = NULL; 76 77 dn = ldb_get_root_basedn(ldb); 78 ldb_dn_add_child_fmt(dn, "cn=users"); 79 ret = ldb_build_search_req(&req, ldb, ctx, 80 dn, 81 LDB_SCOPE_SUBTREE, 82 "(objectClass=*)", NULL, 83 NULL, 84 ctx, ldb_search_default_callback, NULL); 85 torture_assert(torture, ret == LDB_SUCCESS, "Failed to build search request"); 86 87 ret = ldb_request_add_control(req, LDB_CONTROL_SERVER_SORT_OID, true, control); 88 torture_assert(torture, ret == LDB_SUCCESS, "Failed to add control to search request"); 89 90 ret = ldb_request(ldb, req); 91 torture_assert(torture, ret == LDB_SUCCESS, ldb_errstring(ldb)); 92 93 ret = ldb_wait(req->handle, LDB_WAIT_ALL); 94 torture_assert(torture, ret == LDB_SUCCESS, ldb_errstring(ldb)); 95 96 ret = true; 97 if (ctx->count > 1) { 98 for (i=0;i<ctx->count;i++) { 99 msg = ctx->msgs[i]; 100 elem = ldb_msg_find_element(msg,"cn"); 101 cur = elem->values; 102 torture_comment(torture, "cn: %s\n",cur->data); 103 if (prev != NULL) 104 { 105 /* Do only the ascii case right now ... */ 106 cur_txt=cur->data; 107 cur_len=cur->length; 108 prev_txt=prev->data; 109 prev_len=prev->length; 110 /* Remove leading whitespace as the sort function do so ... */ 111 while ( cur_txt[0] == cur_txt[1] ) { cur_txt++; cur_len--;} 112 while ( prev_txt[0] == prev_txt[1] ) { prev_txt++; prev_len--;} 113 while( *(cur_txt) && *(prev_txt) && cur_len && prev_len ) { 114 j = toupper_m(*(prev_txt))-toupper_m(*(cur_txt)); 115 if ( j > 0 ) { 116 /* Just check that is not due to trailling white space in prev_txt 117 * That is to say *cur_txt = 0 and prev_txt = 20 */ 118 /* Remove trailling whitespace */ 119 while ( *prev_txt == ' ' ) { prev_txt++; prev_len--;} 120 while ( *cur_txt == ' ' ) { cur_txt++; cur_len--;} 121 /* Now that potential whitespace are removed if we are at the end 122 * of the cur_txt then it means that in fact strings were identical 123 */ 124 torture_assert(torture, *cur_txt && *prev_txt, "Data wrongly sorted"); 125 break; 126 } 127 else 128 { 129 if ( j == 0 ) 130 { 131 if ( *(cur_txt) == ' ') { 132 while ( cur_txt[0] == cur_txt[1] ) { cur_txt++; cur_len--;} 133 while ( prev_txt[0] == prev_txt[1] ) { prev_txt++; prev_len--;} 134 } 135 cur_txt++; 136 prev_txt++; 137 prev_len--; 138 cur_len--; 139 } 140 else 141 { 142 break; 143 } 144 } 145 } 146 if ( ret != 1 ) { 147 break; 148 } 149 } 150 prev = cur; 151 } 152 153 } 154 155 return ret; 156} 157