s4:torture Add test for correct server-side sorting over LDAP
[Samba/gebeck_regimport.git] / source4 / torture / ldb / modules / ldb_module.c
blob64f95f7619c7dfd6d6c3bf398cfaeeda7ac26bb4
1 /*
2 Unix SMB/CIFS implementation.
4 Test LDB attribute functions
6 Copyright (C) Andrew Bartlet <abartlet@samba.org> 2008
7 Copyright (C) Matthieu Patou <mat@matws.net> 2009
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.
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.
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/>.
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"
33 static bool torture_ldb_mod_sort(struct torture_context *torture)
36 struct ldb_context *ldb;
38 bool ret = false;
39 const char *host = torture_setting_string(torture, "host", NULL);
40 char *url;
41 char *basedn;
42 int i;
43 int j;
44 struct ldb_message_element *elem;
45 struct ldb_message *msg;
46 struct dsdb_schema *schema = NULL;
47 struct ldb_control **ctrl;
49 struct ldb_server_sort_control ** control;
50 struct ldb_request *req;
51 struct ldb_result *ctx;
52 struct ldb_val* prev = NULL;
53 char *prev_txt = NULL;
54 int prev_len = 0;
55 struct ldb_val* cur = NULL;
56 char *cur_txt = NULL;
57 int cur_len = 0;
58 struct ldb_dn* dn;
59 char* user_cn = "Users";
62 /* TALLOC_CTX* ctx;*/
64 url = talloc_asprintf(torture, "ldap://%s/", host);
66 ldb = ldb_wrap_connect(torture, torture->ev, torture->lp_ctx, url,
67 NULL,
68 cmdline_credentials,
69 0, NULL);
70 if (!ldb) goto failed;
71 ret = false;
72 fprintf(stderr,"Ici \n");
74 ctx = talloc_zero(ldb, struct ldb_result);
76 ctrl = talloc_array(ctx, struct ldb_control *, 2);
77 ctrl[0] = talloc(ctrl, struct ldb_control);
78 ctrl[0]->oid = LDB_CONTROL_SERVER_SORT_OID;
79 ctrl[0]->critical = true;
81 control = talloc_array(ctrl[0], struct ldb_server_sort_control *, 2);
82 control[0] = talloc(control, struct ldb_server_sort_control);
83 control[0]->attributeName = talloc_strdup(control, "cn");
84 control[0]->orderingRule = NULL;
85 control[0]->reverse = 0;
86 control[1] = NULL;
87 ctrl[0]->data = control;
88 ctrl[1] = NULL;
90 dn = ldb_get_root_basedn(ldb);
91 ldb_dn_add_child_fmt(dn, "cn=%s", user_cn);
92 ret = ldb_build_search_req(&req, ldb, ctx,
93 dn,
94 LDB_SCOPE_SUBTREE,
95 "(objectClass=*)", NULL,
96 ctrl,
97 ctx, ldb_search_default_callback, NULL);
99 ret = ldb_request(ldb, req);
100 if (ret != LDB_SUCCESS) {
101 d_printf("search failed - %s\n", ldb_errstring(ldb));
102 talloc_free(req);
103 return false;
106 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
108 if (ret != LDB_SUCCESS) {
109 d_printf("search error - %s\n", ldb_errstring(ldb));
110 talloc_free(req);
111 return false;
113 ret = 1;
114 if (ctx->count > 1) {
115 for (i=0;i<ctx->count;i++) {
116 msg = ctx->msgs[i];
117 elem = ldb_msg_find_element(msg,"cn");
118 cur = elem->values;
119 d_printf("cn: %s\n",cur->data);
120 if (prev != NULL)
122 /* Do only the ascii case right now ... */
123 cur_txt=cur->data;
124 cur_len=cur->length;
125 prev_txt=prev->data;
126 prev_len=prev->length;
127 /* Remove leading whitespace as the sort function do so ... */
128 while ( cur_txt[0] == cur_txt[1] ) { cur_txt++; cur_len--;}
129 while ( prev_txt[0] == prev_txt[1] ) { prev_txt++; prev_len--;}
130 while( *(cur_txt) && *(prev_txt) && cur_len && prev_len ) {
131 j = (int)toupper(*(prev_txt))-(int)toupper(*(cur_txt));
132 if ( j > 0 ) {
133 /* Just check that is not due to trailling white space in prev_txt
134 * That is to say *cur_txt = 0 and prev_txt = 20 */
135 /* Remove trailling whitespace */
136 while ( *prev_txt == ' ' ) { prev_txt++; prev_len--;}
137 while ( *cur_txt == ' ' ) { cur_txt++; cur_len--;}
138 /* Now that potential whitespace are removed if we are at the end
139 * of the cur_txt then it means that in fact strings were identical
141 if ( *cur_txt || *prev_txt ) {
142 ret = 0;
143 torture->last_reason = talloc_strdup(torture, "Data wrongly sorted");
145 break;
147 else
149 if ( j == 0 )
151 if ( *(cur_txt) == ' ') {
152 while ( cur_txt[0] == cur_txt[1] ) { cur_txt++; cur_len--;}
153 while ( prev_txt[0] == prev_txt[1] ) { prev_txt++; prev_len--;}
155 cur_txt++;
156 prev_txt++;
157 prev_len--;
158 cur_len--;
160 else
162 break;
166 if ( ret != 1 ) {
167 break;
170 prev = cur;
175 failed:
176 return ret;
180 NTSTATUS torture_ldb_module_init(void)
182 struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "LDB_MODULE");
183 torture_suite_add_simple_test(suite, "SORT", torture_ldb_mod_sort);
184 suite->description = talloc_strdup(suite, "LDB MODULES (samba-specific behaviour) tests");
186 torture_register_suite(suite);
188 return NT_STATUS_OK;