[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Re: API use in Shared objects?
I see a number of errors in your code which are likely to cause problems
you may erroneusly refer to the object being shared.
> I am not sure if I am posting my questions to the correct list.
>
> I am attempting to create a shared objecs (.so) for use on a linux
> platform which utilizes OpenLDAP API calls, everything works fine until
> I attempt to make a second connection on an unsuccessful search...
>
> ex.
> I connect for the first time and search for a bit of information on the
> LDAP server, it results nothing for the user input, I connect again
> looking for a different piece of information and it crashes. This
> result happens everytime for any ldap() API calls within' the shared
> object.
>
> If i use the same API calls within a binary or executable application it
> works fine, it tells me there is nothing for that input and allows me to
> try a second search.
>
> In the shared object which I am compiling with the following bit of code:
> CC=gcc
> CFLAGS=-fPIC
> LDFLAGS=-x --shared
> LIBS=-lnsl -lpam -lldap -lc
> SRCS=pam_ldap_lookup.c
> OBJS=pam_ldap_lookup.o
> LIBSHARED=pam_ldap_lookup.so
> LIBCONF=looser.conf
> SECUREDIRECTORY=/lib/security
> CONFDIR=/etc
> CONFMODE=700
> SECUREMODE=755
> INSTALL=install
>
> all: $(LIBSHARED)
>
> install: all
> $(INSTALL) -m $(SECUREMODE) $(LIBSHARED) $(SECUREDIRECTORY);
> $(INSTALL) -m $(CONFMODE) $(LIBCONF) $(CONFDIR);
>
> $(LIBSHARED): $(OBJS)
> $(LD) $(LDFLAGS) -o $@ $? $(LIBS)
>
> $(OBJS): $(SRCS)
> $(CC) $(CFLAGS) -o $@ -c $*.c
>
> and the function I have created to do the simple search is here...
> static int _ldap_search(udataptr myUser)
> {
> LDAP *ld;
> LDAPMessage *res, *e, **result;
> LDAPMessage *entry;
> LDAPMessage *msg;
> int i, y;
> char *x, *dn;
> char *attr;
> char **vals;
> char buffer[80];
> char errors[256];
> BerElement **berptr;
> BerElement * ber;
>
> struct timeval myTime;
> myTime.tv_sec=15;
> myTime.tv_usec=30;
> struct timeval *timeout = &myTime;
>
> berptr = &ber;
>
> sprintf(buffer, "\"(cn=%s,%s)\"", myUser->usrname, dflts[10]);
^^^ are you sure "buffer" is large enough?
use snprintf AND TEST THE RETURN VALUE
>
> /* initialize a connection */
> if((ld = ldap_init(dflts[7], *dflts[8])) == NULL) {
> _pam_log(LOG_ERR, "Connection failed for %s", dflts[7]);
> return 0;
> }
> _pam_log(LOG_ERR, "Connection succeeded for %s", dflts[7]);
>
> if(!ldap_simple_bind(ld, dflts[9], dflts[12])) {
> _pam_log(LOG_ERR, "Couldn't bind to %s", dflts[9]);
> return 0;
> }
^^^ ldap_simple_bind(), although being deprecated,
returns the message id to be used in a subsequent
call to ldap_result. If you proceed any further
without calling ldap_result you'll have no chance
of knowing if bind succeeded or not. Your code seems
to work the first time because you interpret message
id 0 as success, while further message is show up
as errors. Use ldap_simple_bind_s() instead.
> _pam_log(LOG_ERR, "Bind to %s successful", dflts[9]);
> if(!ldap_search_s(ld, dflts[10], LDAP_SCOPE_SUBTREE,
> buffer, NULL, 0, &res)) {
> _pam_log(LOG_ERR, "LDAP Search failed for: %s", buffer);
> return 0;
> }
> _pam_log(LOG_ERR, "LDAP Search succeeded for: %s", buffer);
>
> for(e = ldap_first_entry(ld, res); e == NULL; e =
^^^^ the logic of the test
is reversed; the loop should continue while e != NULL, work
with the entry and exit when it's NULL; here you're asking
for ldap_next_entry() in case of failure! Note that, according
to the manual, ldap_next_entry() wants the "entry" field, not
"res".
> ldap_next_entry(ld, res)) {
> _pam_log(LOG_ERR, "No results for %s", buffer);
> ldap_msgfree(res);
> ldap_unbind_s(ld);
> return 0;
> }
> _pam_log(LOG_ERR, "Results for %s were found", buffer);
>
> vals = ldap_get_values(ld, e, x);
> _pam_log(LOG_ERR, "Assigned ldap_get_values() to vals[]");
> for(i = 0; vals[i] != NULL; i++) {
> _pam_log(LOG_ERR, "Value: %s", vals[i]);
> ldap_value_free(vals);
> return 0;
> }
>
> ldap_msgfree(res);
> ldap_unbind_s(ld);
> return 0;
> }
>
> As you can see I am at this point only trying to log everything to
> syslog, and you can also see that the appropriate calls to
> ldap_msgfree() & ldap_unbind() are being made.
>
> I have been scouring the online documentation and so far it looks as if
> what I am doing is correct, but like I said, it works up until the point
> of making a second request of the ldap api then crashes. Do I need to
> do some memory allocation for the ldap api calls when compiled as a
> shared object?
I suggest you fix the above problems and give a better look to the man
pages before getting to any unspecified "online documentation" (google?)
p.
--
Pierangelo Masarati
mailto:pierangelo.masarati@sys-net.it
SysNet - via Dossi,8 27100 Pavia Tel: +390382573859 Fax: +390382476497