Line data Source code
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 <ldb.h>
26 : #include <ldb_errors.h>
27 : #include "ldb_wrap.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"
33 : #include <ctype.h>
34 :
35 1 : bool torture_ldap_sort(struct torture_context *torture)
36 : {
37 0 : struct ldb_context *ldb;
38 :
39 1 : bool ret = false;
40 1 : const char *host = torture_setting_string(torture, "host", NULL);
41 0 : char *url;
42 0 : codepoint_t j;
43 0 : struct ldb_message_element *elem;
44 0 : struct ldb_message *msg;
45 :
46 0 : struct ldb_server_sort_control **control;
47 0 : struct ldb_request *req;
48 0 : struct ldb_result *ctx;
49 1 : struct ldb_val *prev = NULL;
50 1 : const char *prev_txt = NULL;
51 1 : int prev_len = 0;
52 1 : struct ldb_val *cur = NULL;
53 1 : const char *cur_txt = NULL;
54 1 : int cur_len = 0;
55 0 : struct ldb_dn *dn;
56 :
57 :
58 : /* TALLOC_CTX* ctx;*/
59 :
60 1 : url = talloc_asprintf(torture, "ldap://%s/", host);
61 :
62 1 : ldb = ldb_wrap_connect(torture, torture->ev, torture->lp_ctx, url,
63 : NULL,
64 : samba_cmdline_get_creds(),
65 : 0);
66 1 : torture_assert(torture, ldb, "Failed to make LDB connection to target");
67 :
68 1 : ctx = talloc_zero(ldb, struct ldb_result);
69 :
70 1 : control = talloc_array(ctx, struct ldb_server_sort_control *, 2);
71 1 : control[0] = talloc(control, struct ldb_server_sort_control);
72 1 : control[0]->attributeName = talloc_strdup(control, "cn");
73 1 : control[0]->orderingRule = NULL;
74 1 : control[0]->reverse = 0;
75 1 : control[1] = NULL;
76 :
77 1 : dn = ldb_get_default_basedn(ldb);
78 1 : ldb_dn_add_child_fmt(dn, "cn=users");
79 1 : 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 1 : torture_assert(torture, ret == LDB_SUCCESS, "Failed to build search request");
86 :
87 1 : ret = ldb_request_add_control(req, LDB_CONTROL_SERVER_SORT_OID, true, control);
88 1 : torture_assert(torture, ret == LDB_SUCCESS, "Failed to add control to search request");
89 :
90 1 : ret = ldb_request(ldb, req);
91 1 : torture_assert(torture, ret == LDB_SUCCESS, ldb_errstring(ldb));
92 :
93 1 : ret = ldb_wait(req->handle, LDB_WAIT_ALL);
94 1 : torture_assert(torture, ret == LDB_SUCCESS, ldb_errstring(ldb));
95 :
96 1 : ret = true;
97 1 : if (ctx->count > 1) {
98 : unsigned int i;
99 31 : for (i=0;i<ctx->count;i++) {
100 30 : msg = ctx->msgs[i];
101 30 : elem = ldb_msg_find_element(msg,"cn");
102 30 : torture_assert_not_null(torture, elem, "msg lacks CN");
103 30 : cur = elem->values;
104 30 : torture_comment(torture, "cn: %s\n",cur->data);
105 30 : if (prev != NULL)
106 : {
107 : /* Do only the ascii case right now ... */
108 29 : cur_txt = (const char *) cur->data;
109 29 : cur_len = cur->length;
110 29 : prev_txt = (const char *) prev->data;
111 29 : prev_len = prev->length;
112 : /* Remove leading whitespace as the sort function do so ... */
113 29 : while ( cur_txt[0] == cur_txt[1] ) { cur_txt++; cur_len--;}
114 29 : while ( prev_txt[0] == prev_txt[1] ) { prev_txt++; prev_len--;}
115 91 : while( *(cur_txt) && *(prev_txt) && cur_len && prev_len ) {
116 91 : j = toupper_m(*(prev_txt))-toupper_m(*(cur_txt));
117 91 : if ( j > 0 ) {
118 : /* Just check that is not due to trailing white space in prev_txt
119 : * That is to say *cur_txt = 0 and prev_txt = 20 */
120 : /* Remove trailing whitespace */
121 29 : while ( *prev_txt == ' ' ) { prev_txt++; prev_len--;}
122 29 : 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
125 : */
126 29 : torture_assert(torture, *cur_txt && *prev_txt, "Data wrongly sorted");
127 29 : break;
128 : }
129 : else
130 : {
131 62 : if ( j == 0 )
132 : {
133 62 : if ( *(cur_txt) == ' ') {
134 5 : while ( cur_txt[0] == cur_txt[1] ) { cur_txt++; cur_len--;}
135 5 : while ( prev_txt[0] == prev_txt[1] ) { prev_txt++; prev_len--;}
136 : }
137 62 : cur_txt++;
138 62 : prev_txt++;
139 62 : prev_len--;
140 62 : cur_len--;
141 : }
142 : else
143 : {
144 0 : break;
145 : }
146 : }
147 : }
148 29 : if ( ret != 1 ) {
149 0 : break;
150 : }
151 : }
152 30 : prev = cur;
153 : }
154 :
155 : }
156 :
157 1 : return ret;
158 : }
|