/* test_myldap.c - simple test for the myldap module This file is part of the nss-pam-ldapd library. Copyright (C) 2007-2014 Arthur de Jong This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include #include #include #include #include "common.h" #include "nslcd/log.h" #include "nslcd/cfg.h" #include "nslcd/myldap.h" struct worker_args { int id; }; /* the maxium number of results to print (all results are retrieved) */ #define MAXRESULTS 10 /* This is a very basic search test, it performs a test to get certain entries from the database. It currently just prints out the DNs for the entries. */ static void test_search(void) { MYLDAP_SESSION *session; MYLDAP_SEARCH *search; MYLDAP_ENTRY *entry; const char *attrs[] = { "uid", "cn", "gid", NULL }; int i; int rc; /* initialize session */ printf("test_myldap: test_search(): getting session...\n"); session = myldap_create_session(); assert(session != NULL); /* perform search */ printf("test_myldap: test_search(): doing search...\n"); search = myldap_search(session, nslcd_cfg->bases[0], LDAP_SCOPE_SUBTREE, "(objectclass=posixAccount)", attrs, NULL); assert(search != NULL); /* go over results */ printf("test_myldap: test_search(): get results...\n"); for (i = 0; (entry = myldap_get_entry(search, &rc)) != NULL; i++) { if (i < MAXRESULTS) printf("test_myldap: test_search(): [%d] DN %s\n", i, myldap_get_dn(entry)); else if (i == MAXRESULTS) printf("test_myldap: test_search(): ...\n"); } printf("test_myldap: test_search(): %d entries returned: %s\n", i, ldap_err2string(rc)); assert(rc == LDAP_SUCCESS); /* perform another search */ printf("test_myldap: test_search(): doing search...\n"); search = myldap_search(session, nslcd_cfg->bases[0], LDAP_SCOPE_SUBTREE, "(objectclass=posixGroup)", attrs, NULL); assert(search != NULL); /* go over results */ printf("test_myldap: test_search(): get results...\n"); for (i = 0; (entry = myldap_get_entry(search, &rc)) != NULL; i++) { if (i < MAXRESULTS) printf("test_myldap: test_search(): [%d] DN %s\n", i, myldap_get_dn(entry)); else if (i == MAXRESULTS) printf("test_myldap: test_search(): ...\n"); } printf("test_myldap: test_search(): %d entries returned: %s\n", i, ldap_err2string(rc)); assert(rc == LDAP_SUCCESS); /* clean up */ myldap_session_close(session); } static void test_get(void) { MYLDAP_SESSION *session; MYLDAP_SEARCH *search1, *search2; MYLDAP_ENTRY *entry; const char *attrs1[] = { "cn", "userPassword", "memberUid", "gidNumber", "member", NULL }; const char *attrs2[] = { "uid", NULL }; int rc; /* initialize session */ printf("test_myldap: test_get(): getting session...\n"); session = myldap_create_session(); assert(session != NULL); /* perform search */ printf("test_myldap: test_get(): doing search...\n"); search1 = myldap_search(session, nslcd_cfg->bases[0], LDAP_SCOPE_SUBTREE, "(&(|(objectClass=posixGroup)(objectClass=groupOfNames))(cn=testgroup2))", attrs1, NULL); assert(search1 != NULL); /* get one entry */ entry = myldap_get_entry(search1, &rc); assert(entry != NULL); printf("test_myldap: test_get(): got DN %s\n", myldap_get_dn(entry)); /* get some attribute values */ assert(myldap_get_values(entry, "gidNumber") != NULL); assert(myldap_get_values(entry, "memberUid") == NULL); assert(myldap_get_values(entry, "member") != NULL); /* perform another search */ printf("test_myldap: test_get(): doing get...\n"); search2 = myldap_search(session, "cn=Test User2,ou=people,dc=test,dc=tld", LDAP_SCOPE_BASE, "(objectclass=posixAccount)", attrs2, NULL); assert(search2 != NULL); /* get one entry */ entry = myldap_get_entry(search2, &rc); assert(entry != NULL); printf("test_myldap: test_get(): got DN %s\n", myldap_get_dn(entry)); /* test if searches are ok */ assert(myldap_get_entry(search1, &rc) == NULL); assert(myldap_get_entry(search2, &rc) == NULL); /* clean up */ myldap_session_close(session); } /* This search prints a number of attributes from a search */ static void test_get_values(void) { MYLDAP_SESSION *session; MYLDAP_SEARCH *search; MYLDAP_ENTRY *entry; const char *attrs[] = { "uidNumber", "cn", "gidNumber", "uid", "objectClass", NULL }; const char **vals; const char *rdnval; int i; /* initialize session */ printf("test_myldap: test_get_values(): getting session...\n"); session = myldap_create_session(); assert(session != NULL); /* perform search */ search = myldap_search(session, nslcd_cfg->bases[0], LDAP_SCOPE_SUBTREE, "(&(objectClass=posixAccount)(uid=*))", attrs, NULL); assert(search != NULL); /* go over results */ for (i = 0; (entry = myldap_get_entry(search, NULL)) != NULL; i++) { if (i < MAXRESULTS) printf("test_myldap: test_get_values(): [%d] DN %s\n", i, myldap_get_dn(entry)); else if (i == MAXRESULTS) printf("test_myldap: test_get_values(): ...\n"); /* try to get uid from attribute */ vals = myldap_get_values(entry, "uidNumber"); assert((vals != NULL) && (vals[0] != NULL)); if (i < MAXRESULTS) printf("test_myldap: test_get_values(): [%d] uidNumber=%s\n", i, vals[0]); /* try to get gid from attribute */ vals = myldap_get_values(entry, "gidNumber"); assert((vals != NULL) && (vals[0] != NULL)); if (i < MAXRESULTS) printf("test_myldap: test_get_values(): [%d] gidNumber=%s\n", i, vals[0]); /* write LDF_STRING(PASSWD_NAME) */ vals = myldap_get_values(entry, "uid"); assert((vals != NULL) && (vals[0] != NULL)); if (i < MAXRESULTS) printf("test_myldap: test_get_values(): [%d] uid=%s\n", i, vals[0]); /* get rdn values */ rdnval = myldap_get_rdn_value(entry, "cn"); if (i < MAXRESULTS) printf("test_myldap: test_get_values(): [%d] cdrdn=%s\n", i, rdnval == NULL ? "NULL" : rdnval); rdnval = myldap_get_rdn_value(entry, "uid"); if (i < MAXRESULTS) printf("test_myldap: test_get_values(): [%d] uidrdn=%s\n", i, rdnval == NULL ? "NULL" : rdnval); /* check objectclass */ assert(myldap_has_objectclass(entry, "posixAccount")); } /* clean up */ myldap_session_close(session); } static void test_get_rdnvalues(void) { MYLDAP_SESSION *session; MYLDAP_SEARCH *search; MYLDAP_ENTRY *entry; const char *attrs[] = { "cn", "uid", NULL }; int rc; char buf[80]; const char *rdnval; /* initialize session */ printf("test_myldap: test_get_rdnvalues(): getting session...\n"); session = myldap_create_session(); assert(session != NULL); /* perform search */ printf("test_myldap: test_get_rdnvalues(): doing search...\n"); search = myldap_search(session, "cn=Aka Ashbach+uid=aashbach,ou=lotsofpeople,dc=test,dc=tld", LDAP_SCOPE_BASE, "(objectClass=*)", attrs, NULL); assert(search != NULL); /* get one entry */ entry = myldap_get_entry(search, &rc); assert(entry != NULL); printf("test_myldap: test_get_rdnvalues(): got DN %s\n", myldap_get_dn(entry)); /* get some values from DN */ rdnval = myldap_get_rdn_value(entry, "uid"); printf("test_myldap: test_get_rdnvalues(): DN.uid=%s\n", rdnval == NULL ? "NULL" : rdnval); rdnval = myldap_get_rdn_value(entry, "cn"); printf("test_myldap: test_get_rdnvalues(): DN.cn=%s\n", rdnval == NULL ? "NULL" : rdnval); rdnval = myldap_get_rdn_value(entry, "uidNumber"); printf("test_myldap: test_get_rdnvalues(): DN.uidNumber=%s\n", rdnval == NULL ? "NULL" : rdnval); /* clean up */ myldap_session_close(session); /* some tests */ rdnval = myldap_cpy_rdn_value("cn=Aka Ashbach+uid=aashbach,ou=lotsofpeople,dc=test,dc=tld", "uid", buf, sizeof(buf)); printf("test_myldap: test_get_rdnvalues(): DN.uid=%s\n", rdnval == NULL ? "NULL" : rdnval); rdnval = myldap_cpy_rdn_value("cn=Aka Ashbach+uid=aashbach,ou=lotsofpeople,dc=test,dc=tld", "cn", buf, sizeof(buf)); printf("test_myldap: test_get_rdnvalues(): DN.cn=%s\n", rdnval == NULL ? "NULL" : rdnval); rdnval = myldap_cpy_rdn_value("cn=Aka Ashbach+uid=aashbach,ou=lotsofpeople,dc=test,dc=tld", "uidNumber", buf, sizeof(buf)); printf("test_myldap: test_get_rdnvalues(): DN.uidNumber=%s\n", rdnval == NULL ? "NULL" : rdnval); } /* this method tests to see if we can perform two searches within one session */ static void test_two_searches(void) { MYLDAP_SESSION *session; MYLDAP_SEARCH *search1, *search2; MYLDAP_ENTRY *entry; const char *attrs[] = { "uidNumber", "cn", "gidNumber", "uid", "objectClass", NULL }; const char **vals; /* initialize session */ printf("test_myldap: test_two_searches(): getting session...\n"); session = myldap_create_session(); assert(session != NULL); /* perform search1 */ search1 = myldap_search(session, nslcd_cfg->bases[0], LDAP_SCOPE_SUBTREE, "(&(objectClass=posixAccount)(uid=*))", attrs, NULL); assert(search1 != NULL); /* get a result from search1 */ entry = myldap_get_entry(search1, NULL); assert(entry != NULL); printf("test_myldap: test_two_searches(): [search1] DN %s\n", myldap_get_dn(entry)); vals = myldap_get_values(entry, "cn"); assert((vals != NULL) && (vals[0] != NULL)); printf("test_myldap: test_two_searches(): [search1] cn=%s\n", vals[0]); /* start a second search */ search2 = myldap_search(session, nslcd_cfg->bases[0], LDAP_SCOPE_SUBTREE, "(&(objectclass=posixGroup)(gidNumber=*))", attrs, NULL); assert(search2 != NULL); /* get a result from search2 */ entry = myldap_get_entry(search2, NULL); assert(entry != NULL); printf("test_myldap: test_two_searches(): [search2] DN %s\n", myldap_get_dn(entry)); vals = myldap_get_values(entry, "cn"); assert((vals != NULL) && (vals[0] != NULL)); printf("test_myldap: test_two_searches(): [search2] cn=%s\n", vals[0]); /* get another result from search1 */ entry = myldap_get_entry(search1, NULL); assert(entry != NULL); printf("test_myldap: test_two_searches(): [search1] DN %s\n", myldap_get_dn(entry)); vals = myldap_get_values(entry, "cn"); assert((vals != NULL) && (vals[0] != NULL)); printf("test_myldap: test_two_searches(): [search1] cn=%s\n", vals[0]); /* stop search1 */ myldap_search_close(search1); /* get another result from search2 */ entry = myldap_get_entry(search2, NULL); assert(entry != NULL); printf("test_myldap: test_two_searches(): [search2] DN %s\n", myldap_get_dn(entry)); vals = myldap_get_values(entry, "cn"); assert((vals != NULL) && (vals[0] != NULL)); printf("test_myldap: test_two_searches(): [search2] cn=%s\n", vals[0]); /* clean up */ myldap_session_close(session); } /* perform a simple search */ static void *worker(void *arg) { MYLDAP_SESSION *session; MYLDAP_SEARCH *search; MYLDAP_ENTRY *entry; const char *attrs[] = { "uid", "cn", "gid", NULL }; struct worker_args *args = (struct worker_args *)arg; int i; int rc; /* initialize session */ session = myldap_create_session(); assert(session != NULL); /* perform search */ search = myldap_search(session, nslcd_cfg->bases[0], LDAP_SCOPE_SUBTREE, "(objectclass=posixAccount)", attrs, NULL); assert(search != NULL); /* go over results */ for (i = 0; (entry = myldap_get_entry(search, &rc)) != NULL; i++) { if (i < MAXRESULTS) printf("test_myldap: test_threads(): [worker %d] [%d] DN %s\n", args->id, i, myldap_get_dn(entry)); else if (i == MAXRESULTS) printf("test_myldap: test_threads(): [worker %d] ...\n", args->id); } printf("test_myldap: test_threads(): [worker %d] DONE: %s\n", args->id, ldap_err2string(rc)); assert(rc == LDAP_SUCCESS); /* clean up */ myldap_session_close(session); return 0; } /* thread ids of all running threads */ #define NUM_THREADS 5 pthread_t my_threads[NUM_THREADS]; static void test_threads(void) { int i; struct worker_args args[NUM_THREADS]; /* start worker threads */ for (i = 0; i < NUM_THREADS; i++) { args[i].id = i; assert(pthread_create(&my_threads[i], NULL, worker, &(args[i])) == 0); } /* wait for all threads to die */ for (i = 0; i < NUM_THREADS; i++) { assert(pthread_join(my_threads[i], NULL) == 0); } } static void test_connections(void) { MYLDAP_SESSION *session; MYLDAP_SEARCH *search; const char *attrs[] = { "uid", "cn", "gid", NULL }; char *old_uris[NSS_LDAP_CONFIG_MAX_URIS + 1]; int i; /* save the old URIs */ for (i = 0; i < (NSS_LDAP_CONFIG_MAX_URIS + 1); i++) { old_uris[i] = nslcd_cfg->uris[i].uri; nslcd_cfg->uris[i].uri = NULL; } /* set new URIs */ i = 0; nslcd_cfg->uris[i++].uri = "ldapi://%2fdev%2fnull/"; nslcd_cfg->uris[i++].uri = "ldap://10.10.10.10/"; nslcd_cfg->uris[i++].uri = "ldapi://%2fdev%2fnonexistent/"; nslcd_cfg->uris[i++].uri = "ldap://nosuchhost/"; nslcd_cfg->uris[i++].uri = NULL; /* initialize session */ printf("test_myldap: test_connections(): getting session...\n"); session = myldap_create_session(); assert(session != NULL); /* perform search */ printf("test_myldap: test_connections(): doing search...\n"); search = myldap_search(session, nslcd_cfg->bases[0], LDAP_SCOPE_SUBTREE, "(objectclass=posixAccount)", attrs, NULL); assert(search == NULL); /* clean up */ myldap_session_close(session); /* restore the old URIs */ for (i = 0; i < (NSS_LDAP_CONFIG_MAX_URIS + 1); i++) nslcd_cfg->uris[i].uri = old_uris[i]; } /* test whether myldap_escape() handles buffer overlows correctly */ static void test_escape(void) { char buffer[1024]; assert(myldap_escape("test", buffer, 4) != 0); assert(myldap_escape("t*st", buffer, 5) != 0); assert(myldap_escape("t*st", buffer, 20) == 0); assertstreq(buffer, "t\\2ast"); } /* the main program... */ int main(int UNUSED(argc), char UNUSED(*argv[])) { char *srcdir; char fname[100]; struct sigaction act; /* build the name of the file */ srcdir = getenv("srcdir"); if (srcdir == NULL) srcdir = "."; snprintf(fname, sizeof(fname), "%s/nslcd-test.conf", srcdir); fname[sizeof(fname) - 1] = '\0'; /* initialize configuration */ cfg_init(fname); /* partially initialize logging */ log_setdefaultloglevel(LOG_DEBUG); /* ignore SIGPIPE */ memset(&act, 0, sizeof(struct sigaction)); act.sa_handler = SIG_IGN; sigemptyset(&act.sa_mask); act.sa_flags = SA_RESTART | SA_NOCLDSTOP; assert(sigaction(SIGPIPE, &act, NULL) == 0); /* do tests */ test_search(); test_get(); test_get_values(); test_get_rdnvalues(); test_two_searches(); test_threads(); test_connections(); test_escape(); return 0; }