2 Unix SMB/CIFS implementation.
4 Test LDB attribute functions
6 Copyright (C) Andrew Bartlet <abartlet@samba.org> 2008-2009
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/>.
24 #include "lib/events/events.h"
26 #include <ldb_errors.h>
28 #include "param/param.h"
29 #include "lib/cmdline/cmdline.h"
30 #include "libcli/ldap/ldap_client.h"
31 #include "torture/smbtorture.h"
32 #include "torture/ldap/proto.h"
35 bool torture_ldap_sort(struct torture_context
*torture
)
37 struct ldb_context
*ldb
;
40 const char *host
= torture_setting_string(torture
, "host", NULL
);
43 struct ldb_message_element
*elem
;
44 struct ldb_message
*msg
;
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
;
52 struct ldb_val
*cur
= NULL
;
53 const char *cur_txt
= NULL
;
60 url
= talloc_asprintf(torture
, "ldap://%s/", host
);
62 ldb
= ldb_wrap_connect(torture
, torture
->ev
, torture
->lp_ctx
, url
,
64 samba_cmdline_get_creds(),
66 torture_assert(torture
, ldb
, "Failed to make LDB connection to target");
68 ctx
= talloc_zero(ldb
, struct ldb_result
);
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;
77 dn
= ldb_get_default_basedn(ldb
);
78 ldb_dn_add_child_fmt(dn
, "cn=users");
79 ret
= ldb_build_search_req(&req
, ldb
, ctx
,
82 "(objectClass=*)", NULL
,
84 ctx
, ldb_search_default_callback
, NULL
);
85 torture_assert(torture
, ret
== LDB_SUCCESS
, "Failed to build search request");
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");
90 ret
= ldb_request(ldb
, req
);
91 torture_assert(torture
, ret
== LDB_SUCCESS
, ldb_errstring(ldb
));
93 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
94 torture_assert(torture
, ret
== LDB_SUCCESS
, ldb_errstring(ldb
));
99 for (i
=0;i
<ctx
->count
;i
++) {
101 elem
= ldb_msg_find_element(msg
,"cn");
102 torture_assert_not_null(torture
, elem
, "msg lacks CN");
104 torture_comment(torture
, "cn: %s\n",cur
->data
);
107 /* Do only the ascii case right now ... */
108 cur_txt
= (const char *) cur
->data
;
109 cur_len
= cur
->length
;
110 prev_txt
= (const char *) prev
->data
;
111 prev_len
= prev
->length
;
112 /* Remove leading whitespace as the sort function do so ... */
113 while ( cur_txt
[0] == cur_txt
[1] ) { cur_txt
++; cur_len
--;}
114 while ( prev_txt
[0] == prev_txt
[1] ) { prev_txt
++; prev_len
--;}
115 while( *(cur_txt
) && *(prev_txt
) && cur_len
&& prev_len
) {
116 j
= toupper_m(*(prev_txt
))-toupper_m(*(cur_txt
));
118 /* Just check that is not due to trailling white space in prev_txt
119 * That is to say *cur_txt = 0 and prev_txt = 20 */
120 /* Remove trailling whitespace */
121 while ( *prev_txt
== ' ' ) { prev_txt
++; prev_len
--;}
122 while ( *cur_txt
== ' ' ) { cur_txt
++; cur_len
--;}
123 /* Now that potential whitespace are removed if we are at the end
124 * of the cur_txt then it means that in fact strings were identical
126 torture_assert(torture
, *cur_txt
&& *prev_txt
, "Data wrongly sorted");
133 if ( *(cur_txt
) == ' ') {
134 while ( cur_txt
[0] == cur_txt
[1] ) { cur_txt
++; cur_len
--;}
135 while ( prev_txt
[0] == prev_txt
[1] ) { prev_txt
++; prev_len
--;}