scsh-ldap/c/ldap.c

648 lines
18 KiB
C

#include "scsh-ldap.h"
FFIT_MAKE_ENTER_RECORD(scsh_enter_ldap, scsh_ldap_record_type,
LDAP*);
FFIT_MAKE_ENTER_RECORD(scsh_enter_ldapmessage, scsh_ldapmessage_record_type,
LDAPMessage*);
FFIT_MAKE_ENTER_RECORD(scsh_enter_ldapmod, scsh_ldapmod_record_type,
LDAPMod*);
FFIT_MAKE_ENTER_RECORD(scsh_enter_ldapiinfo, scsh_ldapapiinfo_record_type,
LDAPAPIInfo*);
FFIT_STRUCT_GET_INT(scsh_ldapapiinfo_get_info_version,
scsh_ldapapiinfo_record_type, LDAPAPIInfo*,
ldapai_info_version);
FFIT_STRUCT_GET_INT(scsh_ldapapiinfo_get_api_version,
scsh_ldapapiinfo_record_type, LDAPAPIInfo*,
ldapai_api_version);
FFIT_STRUCT_GET_INT(scsh_ldapapiinfo_get_protocol_version,
scsh_ldapapiinfo_record_type, LDAPAPIInfo*,
ldapai_protocol_version);
FFIT_STRUCT_GET_STRING(scsh_ldapapiinfo_get_vendor_name,
scsh_ldapapiinfo_record_type, LDAPAPIInfo*,
ldapai_vendor_name);
FFIT_STRUCT_GET_INT(scsh_ldapapiinfo_get_vendor_version,
scsh_ldapapiinfo_record_type, LDAPAPIInfo*,
ldapai_vendor_version);
FFIT_STRUCT_GET(scsh_ldapapiinfo_get_extensions,
scsh_ldapapiinfo_record_type, LDAPAPIInfo*,
ldapai_extensions, ffit_enter_string_array);
s48_value scsh_ldap_init(s48_value host, s48_value port)
{
LDAP *ldap;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(host, port);
ldap = ldap_init(s48_extract_string(host), s48_extract_integer(port));
S48_GC_UNPROTECT();
return ldap == NULL ? S48_FALSE : scsh_enter_ldap(ldap);
}
s48_value scsh_ldap_simple_bind_s(s48_value ldap, s48_value user, s48_value cred)
{
int r;
S48_DECLARE_GC_PROTECT(3);
S48_GC_PROTECT_3(ldap, user, cred);
r = ldap_simple_bind_s(scsh_extract_ldap(ldap), s48_extract_string(user),
s48_extract_string(cred));
S48_GC_UNPROTECT();
return s48_enter_integer(r);
}
s48_value scsh_ldap_sasl_bind_s(s48_value ldap, s48_value dn,
s48_value mechanism, s48_value cred,
s48_value server_controls,
s48_value client_controls,
s48_value server_cred_p)
{
/* need to implement bindings for berval stuff first */
return S48_FALSE;
}
s48_value scsh_ldap_unbind_s(s48_value ldap)
{
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
return s48_enter_integer(ldap_unbind_s(scsh_extract_ldap(ldap)));
}
s48_value scsh_ldap_error_string(s48_value errcode)
{
FFIT_CHECK_INTEGER(errcode);
return s48_enter_string(ldap_err2string(s48_extract_integer(errcode)));
}
s48_value scsh_ldap_result_error(s48_value ldap, s48_value res)
{
int r;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, res);
r = s48_enter_integer(ldap_result2error(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(res), 0));
S48_GC_UNPROTECT();
return s48_enter_integer(r);
}
s48_value scsh_ldap_memfree(s48_value ldap)
{
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
ldap_memfree(scsh_extract_ldap(ldap));
return S48_UNSPECIFIC;
}
s48_value scsh_ldap_msgfree(s48_value ldapmsg)
{
FFIT_CHECK_RECORD_TYPE(ldapmsg, scsh_ldapmessage_record_type);
ldap_msgfree(scsh_extract_ldapmessage(ldapmsg));
return S48_UNSPECIFIC;
}
s48_value scsh_ldap_search_s(s48_value ldap, s48_value base,
s48_value scope, s48_value filter,
s48_value attrs, s48_value attrsonly)
{
int r;
char** a;
LDAPMessage **msg;
s48_value res;
S48_DECLARE_GC_PROTECT(7);
S48_GC_PROTECT_7(ldap, base, scope, filter, attrs, attrsonly, res);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
a = ffit_extract_list_of_strings(attrs);
r = ldap_search_s(scsh_extract_ldap(ldap),
s48_extract_string(base),
s48_extract_integer(scope),
s48_extract_string(filter),
a,
S48_TRUE_P(attrsonly),
msg);
free(a);
res = s48_list_2(s48_enter_integer(r), scsh_enter_ldapmessage(*msg));
S48_GC_UNPROTECT();
return res;
}
s48_value scsh_ldap_search_st(s48_value ldap, s48_value base,
s48_value scope, s48_value filter,
s48_value attrs, s48_value attrsonly,
s48_value timeout_sec, s48_value timeout_usec)
{
int r;
char** a;
LDAPMessage **msg;
struct timeval timeout;
s48_value res = S48_FALSE;
S48_DECLARE_GC_PROTECT(9);
S48_GC_PROTECT_9(ldap, base, scope, filter, attrs, attrsonly, res,
timeout_sec, timeout_usec);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
timeout.tv_sec = s48_extract_integer(timeout_sec);
timeout.tv_usec = s48_extract_integer(timeout_usec);
a = ffit_extract_list_of_strings(attrs);
r = ldap_search_st(scsh_extract_ldap(ldap), s48_extract_string(base),
s48_extract_integer(scope), s48_extract_string(filter),
a, S48_TRUE_P(attrsonly), &timeout, msg);
free(a);
res = s48_list_2(s48_enter_integer(r), scsh_enter_ldapmessage(*msg));
S48_GC_UNPROTECT();
return res;
}
s48_value scsh_ldap_compare_s(s48_value ldap, s48_value dn,
s48_value attr, s48_value value)
{
s48_value res;
int r;
S48_DECLARE_GC_PROTECT(5);
S48_GC_PROTECT_5(ldap, dn, attr, value, res);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
r = ldap_compare_s(scsh_extract_ldap(ldap), s48_extract_string(dn),
s48_extract_string(attr), s48_extract_string(value));
S48_GC_UNPROTECT();
switch (r) {
case LDAP_COMPARE_TRUE: return S48_TRUE;
case LDAP_COMPARE_FALSE: return S48_FALSE;
default: return s48_enter_integer(r);
}
}
s48_value scsh_ldap_count_entries(s48_value ldap, s48_value lm)
{
int r;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, lm);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
r = ldap_count_entries(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(lm));
S48_GC_UNPROTECT();
return r;
}
s48_value scsh_ldap_first_entry(s48_value ldap, s48_value lm)
{
LDAPMessage *lm_new;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, lm);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
lm_new = ldap_first_entry(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(lm));
S48_GC_UNPROTECT();
return (lm_new == NULL) ? S48_FALSE : scsh_enter_ldapmessage(lm_new);
}
s48_value scsh_ldap_next_entry(s48_value ldap, s48_value lm)
{
LDAPMessage *lm_new;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, lm);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
lm_new = ldap_next_entry(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(lm));
S48_GC_UNPROTECT();
return (lm_new == NULL) ? S48_FALSE : scsh_enter_ldapmessage(lm_new);
}
s48_value scsh_ldap_first_message(s48_value ldap, s48_value lm)
{
LDAPMessage *first;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, lm);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
first = ldap_first_message(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(lm));
S48_GC_UNPROTECT();
return (first == NULL) ? S48_FALSE : scsh_enter_ldapmessage(first);
}
s48_value scsh_ldap_next_message(s48_value ldap, s48_value lm)
{
LDAPMessage *next;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, lm);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
next = ldap_next_message(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(lm));
S48_GC_UNPROTECT();
return (next == NULL) ? S48_FALSE : scsh_enter_ldapmessage(next);
}
s48_value scsh_ldap_count_messages(s48_value ldap, s48_value lm)
{
int c;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, lm);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
c = ldap_count_messages(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(lm));
S48_GC_UNPROTECT();
return (c == -1) ? S48_FALSE : s48_enter_integer(c);
}
s48_value scsh_ldap_first_reference(s48_value ldap, s48_value lm)
{
LDAPMessage *new_lm;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, lm);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
new_lm = ldap_first_reference(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(lm));
S48_GC_UNPROTECT();
return (new_lm == NULL) ? S48_FALSE : scsh_enter_ldapmessage(new_lm);
}
s48_value scsh_ldap_next_reference(s48_value ldap, s48_value lm)
{
LDAPMessage *new_lm;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, lm);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
new_lm = ldap_next_reference(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(lm));
S48_GC_UNPROTECT();
return (new_lm == NULL) ? S48_FALSE : scsh_enter_ldapmessage(new_lm);
}
s48_value scsh_ldap_count_references(s48_value ldap, s48_value lm)
{
int c;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, lm);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
c = ldap_count_references(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(lm));
S48_GC_UNPROTECT();
return (c == -1) ? S48_FALSE : s48_enter_integer(c);
}
s48_value scsh_ldap_msgtype(s48_value lm)
{
int r;
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
r = ldap_msgtype(scsh_extract_ldapmessage(lm));
return s48_enter_integer(r);
}
s48_value scsh_ldap_msgid(s48_value lm)
{
int r;
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
r = ldap_msgid(scsh_extract_ldapmessage(lm));
return s48_enter_integer(r);
}
/* may raise ldap error */
s48_value scsh_ldap_get_dn(s48_value ldap, s48_value entry)
{
char *s;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, entry);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(entry, scsh_ldapmessage_record_type);
s = ldap_get_dn(scsh_extract_ldap(ldap), scsh_extract_ldapmessage(entry));
S48_GC_UNPROTECT();
return (s == NULL) ? S48_FALSE : s48_enter_string(s);
}
s48_value scsh_ldap_explode_dn(s48_value dn, s48_value notypes)
{
char **a;
s48_value res = S48_FALSE;
S48_DECLARE_GC_PROTECT(3);
S48_GC_PROTECT_3(dn, notypes, res);
a = ldap_explode_dn(s48_extract_string(dn),
S48_TRUE_P(notypes) ? 0 : 1);
res = ffit_enter_string_array(a);
S48_GC_UNPROTECT();
ldap_value_free(a);
return res;
}
s48_value scsh_ldap_explode_rdn(s48_value rdn, s48_value notypes)
{
char **a;
s48_value res = S48_FALSE;
S48_DECLARE_GC_PROTECT(3);
S48_GC_PROTECT_3(rdn, notypes, res);
a = ldap_explode_rdn(s48_extract_string(rdn),
S48_TRUE_P(notypes) ? 0 : 1);
res = ffit_enter_string_array(a);
S48_GC_UNPROTECT();
ldap_value_free(a);
return res;
}
s48_value scsh_ldap_dn2ufn(s48_value dn)
{
char *a;
s48_value res = S48_FALSE;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(dn, res);
a = ldap_dn2ufn(s48_extract_string(dn));
res = s48_enter_string(a);
S48_GC_UNPROTECT();
ldap_memfree(a);
return res;
}
s48_value scsh_ldap_get_values(s48_value ldap, s48_value entry,
s48_value attr)
{
char **val;
s48_value res = S48_FALSE;
S48_DECLARE_GC_PROTECT(4);
S48_GC_PROTECT_4(ldap, entry, attr, res);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(entry, scsh_ldapmessage_record_type);
val = ldap_get_values(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(entry),
s48_extract_string(attr));
res = ffit_enter_string_array(val);
ldap_value_free(val);
S48_GC_UNPROTECT();
return res;
}
s48_value scsh_ldap_modify(s48_value ldap, s48_value dn, s48_value mods)
{
int r;
S48_DECLARE_GC_PROTECT(3);
S48_GC_PROTECT_3(ldap, dn, mods);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
r = ldap_modify_s(scsh_extract_ldap(ldap), s48_extract_string(dn),
scsh_extract_ldapmod_vector(mods));
S48_GC_UNPROTECT();
return s48_enter_integer(r);
}
s48_value scsh_ldap_add(s48_value ldap, s48_value dn, s48_value mods)
{
int r;
S48_DECLARE_GC_PROTECT(3);
S48_GC_PROTECT_3(ldap, dn, mods);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
if (!S48_VECTOR_P(mods))
s48_raise_argument_type_error(mods);
r = ldap_add_s(scsh_extract_ldap(ldap), s48_extract_string(dn),
scsh_extract_ldapmod_vector(mods));
S48_GC_UNPROTECT();
return s48_enter_integer(r);
}
s48_value scsh_ldap_delete(s48_value ldap, s48_value dn)
{
int r;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, dn);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
r = ldap_delete_s(scsh_extract_ldap(ldap), s48_extract_string(dn));
S48_GC_UNPROTECT();
return s48_enter_integer(r);
}
s48_value scsh_ldap_abandon(s48_value ldap, s48_value msgid)
{
int r;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, msgid);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
r = ldap_abandon(scsh_extract_ldap(ldap), s48_extract_integer(msgid));
S48_GC_UNPROTECT();
return s48_enter_integer(r);
}
s48_value scsh_ldap_get_set_option(s48_value ldap, s48_value option,
s48_value set, s48_value inval)
{
int opt, r;
LDAP *ld;
void *outvalue;
s48_value res = S48_UNSPECIFIC;
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_BOOLEAN(set);
ld = scsh_extract_ldap(ldap);
switch (opt) {
case LDAP_OPT_API_INFO:
{
if (S48_TRUE_P(set))
raise_ldap_read_only_option();
r = ldap_get_option(ld, opt, outvalue);
if (r == LDAP_SUCCESS)
res = scsh_enter_ldapiinfo((LDAPAPIInfo *) outvalue);
break;
}
case LDAP_OPT_DEREF:
{
}
case LDAP_OPT_SIZELIMIT:
case LDAP_OPT_TIMELIMIT:
{
int l;
if (S48_TRUE_P(set)) {
FFIT_CHECK_INTEGER(inval);
l = s48_extract_integer(inval);
r = ldap_set_option(ld, opt, &l);
}
else
if ((r = ldap_get_option(ld, opt, outvalue)) == LDAP_SUCCESS)
res = s48_enter_integer(*((int*)outvalue));
break;
}
case LDAP_OPT_REFERRALS:
case LDAP_OPT_RESTART:
{
if (S48_TRUE_P(set)) {
FFIT_CHECK_BOOLEAN(inval);
r = ldap_set_option(ld, opt, S48_TRUE_P(inval) ? LDAP_OPT_ON : LDAP_OPT_OFF);
}
else
if ((r = ldap_get_option(ld, opt, outvalue)) == LDAP_SUCCESS)
res = outvalue == 0 ? S48_TRUE : S48_FALSE;
break;
}
case LDAP_OPT_PROTOCOL_VERSION:
{
int v;
if (S48_TRUE_P(set)) {
FFIT_CHECK_INTEGER(inval);
v = s48_extract_integer(inval);
r = ldap_set_option(ld, opt, &v);
}
else
if ((r = ldap_get_option(ld, opt, outvalue)) == LDAP_SUCCESS)
res = s48_enter_integer(*(int *)outvalue);
break;
}
case LDAP_OPT_SERVER_CONTROLS:
case LDAP_OPT_CLIENT_CONTROLS:
{
raise_ldap_read_only_option();
}
}
}
/* ************************************************************************ */
/* FIXME: support modv_bvals (binary values) */
s48_value scsh_ldapmod_create(s48_value op, s48_value type, s48_value data_vector)
{
LDAPMod *m;
S48_DECLARE_GC_PROTECT(3);
S48_GC_PROTECT_3(op, type, data_vector);
if ((m = (LDAPMod*) calloc(1, sizeof(LDAPMod))) == NULL)
raise_ldap_memory_alloc_error();
m->mod_op = s48_extract_integer(op);
m->mod_type = s48_extract_string(type);
m->mod_vals.modv_strvals = ffit_extract_list_of_strings(data_vector);
return scsh_enter_ldapmod(m);
}
LDAPMod** scsh_extract_ldapmod_vector(s48_value vector)
{
LDAPMod **a;
int l, i;
S48_DECLARE_GC_PROTECT(1);
S48_GC_PROTECT_1(vector);
l = S48_VECTOR_LENGTH(vector);
if ((*a = (LDAPMod *) calloc(l+1, sizeof(LDAPMod*))) == NULL)
raise_ldap_memory_alloc_error();
for (i = 0; i < l; i++)
a[i] = scsh_extract_ldapmod(S48_VECTOR_REF(vector, i));
a[l] = NULL;
S48_GC_UNPROTECT();
return a;
}
void raise_ldap_memory_alloc_error(void)
{
s48_raise_scheme_exception(condition_ldap_memory_alloc_error, 0);
}
void raise_ldap_feature_not_supported(void)
{
s48_raise_scheme_exception(condition_ldap_feature_not_supported, 0);
}
void raise_ldap_read_only_option(void)
{
s48_raise_scheme_exception(condition_ldap_read_only_option, 0);
}
void scsh_init_ldap_bindings(void)
{
ffit_init_hook();
scsh_ldap_gc_protect_globals();
S48_GC_PROTECT_GLOBAL(condition_ldap_memory_alloc_error);
S48_GC_PROTECT_GLOBAL(condition_ldap_feature_not_supported);
S48_GC_PROTECT_GLOBAL(condition_ldap_read_only_option);
condition_ldap_memory_alloc_error =
s48_get_imported_binding("condition-ldap-memory-alloc-error");
condition_ldap_feature_not_supported =
s48_get_imported_binding("condition-ldap-feature-not-supported");
condition_ldap_read_only_option =
s48_get_imported_binding("condition-ldap-read-only-option");
scsh_ldap_enter_ldap_constants();
FFIT_RECORD_TYPE_INIT(scsh_ldap_record_type, ldap);
FFIT_RECORD_TYPE_INIT(scsh_ldapmessage_record_type, ldap-message);
FFIT_RECORD_TYPE_INIT(scsh_ldapmod_record_type, ldap-modification);
FFIT_RECORD_TYPE_INIT(scsh_ldapapiinfo_record_type, ldap-api-info);
S48_EXPORT_FUNCTION(scsh_ldapapiinfo_get_info_version);
S48_EXPORT_FUNCTION(scsh_ldapapiinfo_get_protocol_version);
S48_EXPORT_FUNCTION(scsh_ldapapiinfo_get_vendor_name);
S48_EXPORT_FUNCTION(scsh_ldapapiinfo_get_vendor_version);
S48_EXPORT_FUNCTION(scsh_ldapapiinfo_get_extensions);
S48_EXPORT_FUNCTION(scsh_ldap_init);
S48_EXPORT_FUNCTION(scsh_ldap_simple_bind_s);
S48_EXPORT_FUNCTION(scsh_ldap_sasl_bind_s);
S48_EXPORT_FUNCTION(scsh_ldap_unbind_s);
S48_EXPORT_FUNCTION(scsh_ldap_error_string);
S48_EXPORT_FUNCTION(scsh_ldap_result_error);
S48_EXPORT_FUNCTION(scsh_ldap_memfree);
S48_EXPORT_FUNCTION(scsh_ldap_msgfree);
S48_EXPORT_FUNCTION(scsh_ldap_search_s);
S48_EXPORT_FUNCTION(scsh_ldap_search_st);
S48_EXPORT_FUNCTION(scsh_ldap_compare_s);
S48_EXPORT_FUNCTION(scsh_ldap_count_entries);
S48_EXPORT_FUNCTION(scsh_ldap_first_entry);
S48_EXPORT_FUNCTION(scsh_ldap_next_entry);
S48_EXPORT_FUNCTION(scsh_ldap_first_message);
S48_EXPORT_FUNCTION(scsh_ldap_next_message);
S48_EXPORT_FUNCTION(scsh_ldap_count_messages);
S48_EXPORT_FUNCTION(scsh_ldap_first_reference);
S48_EXPORT_FUNCTION(scsh_ldap_next_reference);
S48_EXPORT_FUNCTION(scsh_ldap_count_references);
S48_EXPORT_FUNCTION(scsh_ldap_msgtype);
S48_EXPORT_FUNCTION(scsh_ldap_msgid);
S48_EXPORT_FUNCTION(scsh_ldap_get_dn);
S48_EXPORT_FUNCTION(scsh_ldap_explode_dn);
S48_EXPORT_FUNCTION(scsh_ldap_explode_rdn);
S48_EXPORT_FUNCTION(scsh_ldap_dn2ufn);
S48_EXPORT_FUNCTION(scsh_ldap_get_values);
S48_EXPORT_FUNCTION(scsh_ldap_modify);
S48_EXPORT_FUNCTION(scsh_ldap_add);
S48_EXPORT_FUNCTION(scsh_ldap_delete);
S48_EXPORT_FUNCTION(scsh_ldap_abandon);
S48_EXPORT_FUNCTION(scsh_ldap_get_set_option);
S48_EXPORT_FUNCTION(scsh_ldapmod_create);
}