1 /*
2 test_myldap.c - simple test for the myldap module
3 This file is part of the nss-pam-ldapd library.
4
5 Copyright (C) 2007-2014 Arthur de Jong
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301 USA
21 */
22
23 #include "config.h"
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <pthread.h>
28 #include <errno.h>
29 #include <assert.h>
30 #include <signal.h>
31
32 #include "common.h"
33
34 #include "nslcd/log.h"
35 #include "nslcd/cfg.h"
36 #include "nslcd/myldap.h"
37
38 struct worker_args {
39 int id;
40 };
41
42 /* the maxium number of results to print (all results are retrieved) */
43 #define MAXRESULTS 10
44
45 /* This is a very basic search test, it performs a test to get certain
46 entries from the database. It currently just prints out the DNs for
47 the entries. */
test_search(void)48 static void test_search(void)
49 {
50 MYLDAP_SESSION *session;
51 MYLDAP_SEARCH *search;
52 MYLDAP_ENTRY *entry;
53 const char *attrs[] = { "uid", "cn", "gid", NULL };
54 int i;
55 int rc;
56 /* initialize session */
57 printf("test_myldap: test_search(): getting session...\n");
58 session = myldap_create_session();
59 assert(session != NULL);
60 /* perform search */
61 printf("test_myldap: test_search(): doing search...\n");
62 search = myldap_search(session, nslcd_cfg->bases[0], LDAP_SCOPE_SUBTREE,
63 "(objectclass=posixAccount)", attrs, NULL);
64 assert(search != NULL);
65 /* go over results */
66 printf("test_myldap: test_search(): get results...\n");
67 for (i = 0; (entry = myldap_get_entry(search, &rc)) != NULL; i++)
68 {
69 if (i < MAXRESULTS)
70 printf("test_myldap: test_search(): [%d] DN %s\n",
71 i, myldap_get_dn(entry));
72 else if (i == MAXRESULTS)
73 printf("test_myldap: test_search(): ...\n");
74 }
75 printf("test_myldap: test_search(): %d entries returned: %s\n",
76 i, ldap_err2string(rc));
77 assert(rc == LDAP_SUCCESS);
78 /* perform another search */
79 printf("test_myldap: test_search(): doing search...\n");
80 search = myldap_search(session, nslcd_cfg->bases[0], LDAP_SCOPE_SUBTREE,
81 "(objectclass=posixGroup)", attrs, NULL);
82 assert(search != NULL);
83 /* go over results */
84 printf("test_myldap: test_search(): get results...\n");
85 for (i = 0; (entry = myldap_get_entry(search, &rc)) != NULL; i++)
86 {
87 if (i < MAXRESULTS)
88 printf("test_myldap: test_search(): [%d] DN %s\n",
89 i, myldap_get_dn(entry));
90 else if (i == MAXRESULTS)
91 printf("test_myldap: test_search(): ...\n");
92 }
93 printf("test_myldap: test_search(): %d entries returned: %s\n",
94 i, ldap_err2string(rc));
95 assert(rc == LDAP_SUCCESS);
96 /* clean up */
97 myldap_session_close(session);
98 }
99
test_get(void)100 static void test_get(void)
101 {
102 MYLDAP_SESSION *session;
103 MYLDAP_SEARCH *search1, *search2;
104 MYLDAP_ENTRY *entry;
105 const char *attrs1[] = { "cn", "userPassword", "memberUid", "gidNumber", "member", NULL };
106 const char *attrs2[] = { "uid", NULL };
107 int rc;
108 /* initialize session */
109 printf("test_myldap: test_get(): getting session...\n");
110 session = myldap_create_session();
111 assert(session != NULL);
112 /* perform search */
113 printf("test_myldap: test_get(): doing search...\n");
114 search1 = myldap_search(session, nslcd_cfg->bases[0], LDAP_SCOPE_SUBTREE,
115 "(&(|(objectClass=posixGroup)(objectClass=groupOfNames))(cn=testgroup2))",
116 attrs1, NULL);
117 assert(search1 != NULL);
118 /* get one entry */
119 entry = myldap_get_entry(search1, &rc);
120 assert(entry != NULL);
121 printf("test_myldap: test_get(): got DN %s\n", myldap_get_dn(entry));
122 /* get some attribute values */
123 assert(myldap_get_values(entry, "gidNumber") != NULL);
124 assert(myldap_get_values(entry, "memberUid") == NULL);
125 assert(myldap_get_values(entry, "member") != NULL);
126 /* perform another search */
127 printf("test_myldap: test_get(): doing get...\n");
128 search2 = myldap_search(session, "cn=Test User2,ou=people,dc=test,dc=tld",
129 LDAP_SCOPE_BASE,
130 "(objectclass=posixAccount)", attrs2, NULL);
131 assert(search2 != NULL);
132 /* get one entry */
133 entry = myldap_get_entry(search2, &rc);
134 assert(entry != NULL);
135 printf("test_myldap: test_get(): got DN %s\n", myldap_get_dn(entry));
136 /* test if searches are ok */
137 assert(myldap_get_entry(search1, &rc) == NULL);
138 assert(myldap_get_entry(search2, &rc) == NULL);
139 /* clean up */
140 myldap_session_close(session);
141 }
142
143 /* This search prints a number of attributes from a search */
test_get_values(void)144 static void test_get_values(void)
145 {
146 MYLDAP_SESSION *session;
147 MYLDAP_SEARCH *search;
148 MYLDAP_ENTRY *entry;
149 const char *attrs[] = { "uidNumber", "cn", "gidNumber", "uid", "objectClass", NULL };
150 const char **vals;
151 const char *rdnval;
152 int i;
153 /* initialize session */
154 printf("test_myldap: test_get_values(): getting session...\n");
155 session = myldap_create_session();
156 assert(session != NULL);
157 /* perform search */
158 search = myldap_search(session, nslcd_cfg->bases[0], LDAP_SCOPE_SUBTREE,
159 "(&(objectClass=posixAccount)(uid=*))", attrs, NULL);
160 assert(search != NULL);
161 /* go over results */
162 for (i = 0; (entry = myldap_get_entry(search, NULL)) != NULL; i++)
163 {
164 if (i < MAXRESULTS)
165 printf("test_myldap: test_get_values(): [%d] DN %s\n",
166 i, myldap_get_dn(entry));
167 else if (i == MAXRESULTS)
168 printf("test_myldap: test_get_values(): ...\n");
169 /* try to get uid from attribute */
170 vals = myldap_get_values(entry, "uidNumber");
171 assert((vals != NULL) && (vals[0] != NULL));
172 if (i < MAXRESULTS)
173 printf("test_myldap: test_get_values(): [%d] uidNumber=%s\n",
174 i, vals[0]);
175 /* try to get gid from attribute */
176 vals = myldap_get_values(entry, "gidNumber");
177 assert((vals != NULL) && (vals[0] != NULL));
178 if (i < MAXRESULTS)
179 printf("test_myldap: test_get_values(): [%d] gidNumber=%s\n",
180 i, vals[0]);
181 /* write LDF_STRING(PASSWD_NAME) */
182 vals = myldap_get_values(entry, "uid");
183 assert((vals != NULL) && (vals[0] != NULL));
184 if (i < MAXRESULTS)
185 printf("test_myldap: test_get_values(): [%d] uid=%s\n", i, vals[0]);
186 /* get rdn values */
187 rdnval = myldap_get_rdn_value(entry, "cn");
188 if (i < MAXRESULTS)
189 printf("test_myldap: test_get_values(): [%d] cdrdn=%s\n",
190 i, rdnval == NULL ? "NULL" : rdnval);
191 rdnval = myldap_get_rdn_value(entry, "uid");
192 if (i < MAXRESULTS)
193 printf("test_myldap: test_get_values(): [%d] uidrdn=%s\n",
194 i, rdnval == NULL ? "NULL" : rdnval);
195 /* check objectclass */
196 assert(myldap_has_objectclass(entry, "posixAccount"));
197 }
198 /* clean up */
199 myldap_session_close(session);
200 }
201
test_get_rdnvalues(void)202 static void test_get_rdnvalues(void)
203 {
204 MYLDAP_SESSION *session;
205 MYLDAP_SEARCH *search;
206 MYLDAP_ENTRY *entry;
207 const char *attrs[] = { "cn", "uid", NULL };
208 int rc;
209 char buf[80];
210 const char *rdnval;
211 /* initialize session */
212 printf("test_myldap: test_get_rdnvalues(): getting session...\n");
213 session = myldap_create_session();
214 assert(session != NULL);
215 /* perform search */
216 printf("test_myldap: test_get_rdnvalues(): doing search...\n");
217 search = myldap_search(session, "cn=Aka Ashbach+uid=aashbach,ou=lotsofpeople,dc=test,dc=tld",
218 LDAP_SCOPE_BASE, "(objectClass=*)", attrs, NULL);
219 assert(search != NULL);
220 /* get one entry */
221 entry = myldap_get_entry(search, &rc);
222 assert(entry != NULL);
223 printf("test_myldap: test_get_rdnvalues(): got DN %s\n",
224 myldap_get_dn(entry));
225 /* get some values from DN */
226 rdnval = myldap_get_rdn_value(entry, "uid");
227 printf("test_myldap: test_get_rdnvalues(): DN.uid=%s\n",
228 rdnval == NULL ? "NULL" : rdnval);
229 rdnval = myldap_get_rdn_value(entry, "cn");
230 printf("test_myldap: test_get_rdnvalues(): DN.cn=%s\n",
231 rdnval == NULL ? "NULL" : rdnval);
232 rdnval = myldap_get_rdn_value(entry, "uidNumber");
233 printf("test_myldap: test_get_rdnvalues(): DN.uidNumber=%s\n",
234 rdnval == NULL ? "NULL" : rdnval);
235 /* clean up */
236 myldap_session_close(session);
237 /* some tests */
238 rdnval = myldap_cpy_rdn_value("cn=Aka Ashbach+uid=aashbach,ou=lotsofpeople,dc=test,dc=tld",
239 "uid", buf, sizeof(buf));
240 printf("test_myldap: test_get_rdnvalues(): DN.uid=%s\n",
241 rdnval == NULL ? "NULL" : rdnval);
242 rdnval = myldap_cpy_rdn_value("cn=Aka Ashbach+uid=aashbach,ou=lotsofpeople,dc=test,dc=tld",
243 "cn", buf, sizeof(buf));
244 printf("test_myldap: test_get_rdnvalues(): DN.cn=%s\n",
245 rdnval == NULL ? "NULL" : rdnval);
246 rdnval = myldap_cpy_rdn_value("cn=Aka Ashbach+uid=aashbach,ou=lotsofpeople,dc=test,dc=tld",
247 "uidNumber", buf, sizeof(buf));
248 printf("test_myldap: test_get_rdnvalues(): DN.uidNumber=%s\n",
249 rdnval == NULL ? "NULL" : rdnval);
250 }
251
252 /* this method tests to see if we can perform two searches within
253 one session */
test_two_searches(void)254 static void test_two_searches(void)
255 {
256 MYLDAP_SESSION *session;
257 MYLDAP_SEARCH *search1, *search2;
258 MYLDAP_ENTRY *entry;
259 const char *attrs[] = { "uidNumber", "cn", "gidNumber", "uid", "objectClass", NULL };
260 const char **vals;
261 /* initialize session */
262 printf("test_myldap: test_two_searches(): getting session...\n");
263 session = myldap_create_session();
264 assert(session != NULL);
265 /* perform search1 */
266 search1 = myldap_search(session, nslcd_cfg->bases[0], LDAP_SCOPE_SUBTREE,
267 "(&(objectClass=posixAccount)(uid=*))",
268 attrs, NULL);
269 assert(search1 != NULL);
270 /* get a result from search1 */
271 entry = myldap_get_entry(search1, NULL);
272 assert(entry != NULL);
273 printf("test_myldap: test_two_searches(): [search1] DN %s\n",
274 myldap_get_dn(entry));
275 vals = myldap_get_values(entry, "cn");
276 assert((vals != NULL) && (vals[0] != NULL));
277 printf("test_myldap: test_two_searches(): [search1] cn=%s\n", vals[0]);
278 /* start a second search */
279 search2 = myldap_search(session, nslcd_cfg->bases[0], LDAP_SCOPE_SUBTREE,
280 "(&(objectclass=posixGroup)(gidNumber=*))",
281 attrs, NULL);
282 assert(search2 != NULL);
283 /* get a result from search2 */
284 entry = myldap_get_entry(search2, NULL);
285 assert(entry != NULL);
286 printf("test_myldap: test_two_searches(): [search2] DN %s\n",
287 myldap_get_dn(entry));
288 vals = myldap_get_values(entry, "cn");
289 assert((vals != NULL) && (vals[0] != NULL));
290 printf("test_myldap: test_two_searches(): [search2] cn=%s\n", vals[0]);
291 /* get another result from search1 */
292 entry = myldap_get_entry(search1, NULL);
293 assert(entry != NULL);
294 printf("test_myldap: test_two_searches(): [search1] DN %s\n",
295 myldap_get_dn(entry));
296 vals = myldap_get_values(entry, "cn");
297 assert((vals != NULL) && (vals[0] != NULL));
298 printf("test_myldap: test_two_searches(): [search1] cn=%s\n", vals[0]);
299 /* stop search1 */
300 myldap_search_close(search1);
301 /* get another result from search2 */
302 entry = myldap_get_entry(search2, NULL);
303 assert(entry != NULL);
304 printf("test_myldap: test_two_searches(): [search2] DN %s\n",
305 myldap_get_dn(entry));
306 vals = myldap_get_values(entry, "cn");
307 assert((vals != NULL) && (vals[0] != NULL));
308 printf("test_myldap: test_two_searches(): [search2] cn=%s\n", vals[0]);
309 /* clean up */
310 myldap_session_close(session);
311 }
312
313 /* perform a simple search */
worker(void * arg)314 static void *worker(void *arg)
315 {
316 MYLDAP_SESSION *session;
317 MYLDAP_SEARCH *search;
318 MYLDAP_ENTRY *entry;
319 const char *attrs[] = { "uid", "cn", "gid", NULL };
320 struct worker_args *args = (struct worker_args *)arg;
321 int i;
322 int rc;
323 /* initialize session */
324 session = myldap_create_session();
325 assert(session != NULL);
326 /* perform search */
327 search = myldap_search(session, nslcd_cfg->bases[0], LDAP_SCOPE_SUBTREE,
328 "(objectclass=posixAccount)", attrs, NULL);
329 assert(search != NULL);
330 /* go over results */
331 for (i = 0; (entry = myldap_get_entry(search, &rc)) != NULL; i++)
332 {
333 if (i < MAXRESULTS)
334 printf("test_myldap: test_threads(): [worker %d] [%d] DN %s\n",
335 args->id, i, myldap_get_dn(entry));
336 else if (i == MAXRESULTS)
337 printf("test_myldap: test_threads(): [worker %d] ...\n", args->id);
338 }
339 printf("test_myldap: test_threads(): [worker %d] DONE: %s\n",
340 args->id, ldap_err2string(rc));
341 assert(rc == LDAP_SUCCESS);
342 /* clean up */
343 myldap_session_close(session);
344 return 0;
345 }
346
347 /* thread ids of all running threads */
348 #define NUM_THREADS 5
349 pthread_t my_threads[NUM_THREADS];
350
test_threads(void)351 static void test_threads(void)
352 {
353 int i;
354 struct worker_args args[NUM_THREADS];
355 /* start worker threads */
356 for (i = 0; i < NUM_THREADS; i++)
357 {
358 args[i].id = i;
359 assert(pthread_create(&my_threads[i], NULL, worker, &(args[i])) == 0);
360 }
361 /* wait for all threads to die */
362 for (i = 0; i < NUM_THREADS; i++)
363 {
364 assert(pthread_join(my_threads[i], NULL) == 0);
365 }
366 }
367
test_connections(void)368 static void test_connections(void)
369 {
370 MYLDAP_SESSION *session;
371 MYLDAP_SEARCH *search;
372 const char *attrs[] = { "uid", "cn", "gid", NULL };
373 char *old_uris[NSS_LDAP_CONFIG_MAX_URIS + 1];
374 int i;
375 /* save the old URIs */
376 for (i = 0; i < (NSS_LDAP_CONFIG_MAX_URIS + 1); i++)
377 {
378 old_uris[i] = nslcd_cfg->uris[i].uri;
379 nslcd_cfg->uris[i].uri = NULL;
380 }
381 /* set new URIs */
382 i = 0;
383 nslcd_cfg->uris[i++].uri = "ldapi://%2fdev%2fnull/";
384 nslcd_cfg->uris[i++].uri = "ldap://10.10.10.10/";
385 nslcd_cfg->uris[i++].uri = "ldapi://%2fdev%2fnonexistent/";
386 nslcd_cfg->uris[i++].uri = "ldap://nosuchhost/";
387 nslcd_cfg->uris[i++].uri = NULL;
388 /* initialize session */
389 printf("test_myldap: test_connections(): getting session...\n");
390 session = myldap_create_session();
391 assert(session != NULL);
392 /* perform search */
393 printf("test_myldap: test_connections(): doing search...\n");
394 search = myldap_search(session, nslcd_cfg->bases[0], LDAP_SCOPE_SUBTREE,
395 "(objectclass=posixAccount)", attrs, NULL);
396 assert(search == NULL);
397 /* clean up */
398 myldap_session_close(session);
399 /* restore the old URIs */
400 for (i = 0; i < (NSS_LDAP_CONFIG_MAX_URIS + 1); i++)
401 nslcd_cfg->uris[i].uri = old_uris[i];
402 }
403
404 /* test whether myldap_escape() handles buffer overlows correctly */
test_escape(void)405 static void test_escape(void)
406 {
407 char buffer[1024];
408 assert(myldap_escape("test", buffer, 4) != 0);
409 assert(myldap_escape("t*st", buffer, 5) != 0);
410 assert(myldap_escape("t*st", buffer, 20) == 0);
411 assertstreq(buffer, "t\\2ast");
412 }
413
414 /* the main program... */
main(int UNUSED (argc),char UNUSED (* argv[]))415 int main(int UNUSED(argc), char UNUSED(*argv[]))
416 {
417 char *srcdir;
418 char fname[100];
419 struct sigaction act;
420 /* build the name of the file */
421 srcdir = getenv("srcdir");
422 if (srcdir == NULL)
423 srcdir = ".";
424 snprintf(fname, sizeof(fname), "%s/nslcd-test.conf", srcdir);
425 fname[sizeof(fname) - 1] = '\0';
426 /* initialize configuration */
427 cfg_init(fname);
428 /* partially initialize logging */
429 log_setdefaultloglevel(LOG_DEBUG);
430 /* ignore SIGPIPE */
431 memset(&act, 0, sizeof(struct sigaction));
432 act.sa_handler = SIG_IGN;
433 sigemptyset(&act.sa_mask);
434 act.sa_flags = SA_RESTART | SA_NOCLDSTOP;
435 assert(sigaction(SIGPIPE, &act, NULL) == 0);
436 /* do tests */
437 test_search();
438 test_get();
439 test_get_values();
440 test_get_rdnvalues();
441 test_two_searches();
442 test_threads();
443 test_connections();
444 test_escape();
445 return 0;
446 }
447