libndr: Avoid assigning duplicate versions to symbols
[amitay/samba.git] / source4 / torture / ldap / cldap.c
1 /* 
2    Unix SMB/CIFS Implementation.
3
4    test CLDAP operations
5    
6    Copyright (C) Andrew Tridgell 2005
7    Copyright (C) Matthias Dieter Wallnöfer 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
24 #include "includes.h"
25 #include "libcli/cldap/cldap.h"
26 #include "libcli/ldap/ldap_client.h"
27 #include "libcli/resolve/resolve.h"
28 #include "param/param.h"
29 #include "../lib/tsocket/tsocket.h"
30
31 #include "torture/torture.h"
32 #include "torture/ldap/proto.h"
33
34 #define CHECK_STATUS(status, correct) torture_assert_ntstatus_equal(tctx, status, correct, "incorrect status")
35
36 #define CHECK_VAL(v, correct) torture_assert_int_equal(tctx, (v), (correct), "incorrect value");
37
38 #define CHECK_STRING(v, correct) torture_assert_str_equal(tctx, v, correct, "incorrect value");
39
40 /*
41   convert a ldap result message to a ldb message. This allows us to
42   use the convenient ldif dump routines in ldb to print out cldap
43   search results
44 */
45 static struct ldb_message *ldap_msg_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct ldap_SearchResEntry *res)
46 {
47         struct ldb_message *msg;
48
49         msg = ldb_msg_new(mem_ctx);
50         msg->dn = ldb_dn_new(msg, ldb, res->dn);
51         msg->num_elements = res->num_attributes;
52         msg->elements = talloc_steal(msg, res->attributes);
53         return msg;
54 }
55
56 /*
57   dump a set of cldap results
58 */
59 static void cldap_dump_results(struct cldap_search *search)
60 {
61         struct ldb_ldif ldif;
62         struct ldb_context *ldb;
63
64         if (!search || !(search->out.response)) {
65                 return;
66         }
67
68         /* we need a ldb context to use ldb_ldif_write_file() */
69         ldb = ldb_init(NULL, NULL);
70
71         ZERO_STRUCT(ldif);
72         ldif.msg = ldap_msg_to_ldb(ldb, ldb, search->out.response);
73
74         ldb_ldif_write_file(ldb, stdout, &ldif);
75
76         talloc_free(ldb);
77 }
78
79 /*
80   test generic cldap operations
81 */
82 static bool test_cldap_generic(struct torture_context *tctx, const char *dest)
83 {
84         struct cldap_socket *cldap;
85         NTSTATUS status;
86         struct cldap_search search;
87         const char *attrs1[] = { "currentTime", "highestCommittedUSN", NULL };
88         const char *attrs2[] = { "currentTime", "highestCommittedUSN", "netlogon", NULL };
89         const char *attrs3[] = { "netlogon", NULL };
90         struct tsocket_address *dest_addr;
91         const char *ip;
92         struct nbt_name nbt_name;
93         int ret;
94
95         make_nbt_name_server(&nbt_name, dest);
96
97         status = resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx),
98                                  0, 0, &nbt_name, tctx, &ip, tctx->ev);
99         torture_assert_ntstatus_ok(tctx, status,
100                         talloc_asprintf(tctx,"Failed to resolve %s: %s",
101                                         nbt_name.name, nt_errstr(status)));
102
103         ret = tsocket_address_inet_from_strings(tctx, "ip",
104                                                 ip,
105                                                 lpcfg_cldap_port(tctx->lp_ctx),
106                                                 &dest_addr);
107         CHECK_VAL(ret, 0);
108
109         /* cldap_socket_init should now know about the dest. address */
110         status = cldap_socket_init(tctx, NULL, dest_addr, &cldap);
111         CHECK_STATUS(status, NT_STATUS_OK);
112
113         ZERO_STRUCT(search);
114         search.in.dest_address = NULL;
115         search.in.dest_port = 0;
116         search.in.timeout = 10;
117         search.in.retries = 3;
118
119         status = cldap_search(cldap, tctx, &search);
120         CHECK_STATUS(status, NT_STATUS_OK);
121
122         printf("fetching whole rootDSE\n");
123         search.in.filter = "(objectclass=*)";
124         search.in.attributes = NULL;
125
126         status = cldap_search(cldap, tctx, &search);
127         CHECK_STATUS(status, NT_STATUS_OK);
128
129         if (DEBUGLVL(3)) cldap_dump_results(&search);
130
131         printf("fetching currentTime and USN\n");
132         search.in.filter = "(objectclass=*)";
133         search.in.attributes = attrs1;
134
135         status = cldap_search(cldap, tctx, &search);
136         CHECK_STATUS(status, NT_STATUS_OK);
137         
138         if (DEBUGLVL(3)) cldap_dump_results(&search);
139
140         printf("Testing currentTime, USN and netlogon\n");
141         search.in.filter = "(objectclass=*)";
142         search.in.attributes = attrs2;
143
144         status = cldap_search(cldap, tctx, &search);
145         CHECK_STATUS(status, NT_STATUS_OK);
146
147         if (DEBUGLVL(3)) cldap_dump_results(&search);
148
149         printf("Testing objectClass=* and netlogon\n");
150         search.in.filter = "(objectclass=*)";
151         search.in.attributes = attrs3;
152
153         status = cldap_search(cldap, tctx, &search);
154         CHECK_STATUS(status, NT_STATUS_OK);
155
156         if (DEBUGLVL(3)) cldap_dump_results(&search);
157
158         printf("Testing a false expression\n");
159         search.in.filter = "(&(objectclass=*)(highestCommittedUSN=2))";
160         search.in.attributes = attrs1;
161
162         status = cldap_search(cldap, tctx, &search);
163         CHECK_STATUS(status, NT_STATUS_OK);
164
165         if (DEBUGLVL(3)) cldap_dump_results(&search);   
166
167         return true;    
168 }
169
170 bool torture_cldap(struct torture_context *torture)
171 {
172         bool ret = true;
173         const char *host = torture_setting_string(torture, "host", NULL);
174
175         ret &= test_cldap_generic(torture, host);
176
177         return ret;
178 }
179