#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(); if (ldap == NULL) s48_raise_os_error(error()); else 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_FALSE_P(base) ? NULL : 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), r == LDAP_SUCCESS ? scsh_enter_ldapmessage(*msg) : S48_FALSE); 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), r == LDAP_SUCCESS ? scsh_enter_ldapmessage(*msg) : S48_FALSE); 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, rc; LDAP *ld; void *outvalue; s48_value res, res_list; S48_DECLARE_GC_PROTECT(6); S48_GC_PROTECT(ldap, option, set, inval, res, res_list); FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type); FFIT_CHECK_BOOLEAN(set); ld = scsh_extract_ldap(ldap); res = S48_UNSPECIFIC; switch (opt) { case LDAP_OPT_API_INFO: { if (S48_TRUE_P(set)) raise_ldap_read_only_option(); rc = ldap_get_option(ld, opt, outvalue); if (rc == LDAP_OPT_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); rc = ldap_set_option(ld, opt, &l); } else if ((rc = 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); rc = ldap_set_option(ld, opt, S48_TRUE_P(inval) ? LDAP_OPT_ON : LDAP_OPT_OFF); } else if ((rc = 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); rc = ldap_set_option(ld, opt, &v); } else if ((rc = 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(); } } res_list = s48_list_2(rc == LDAP_OPT_SUCCESS ? S48_TRUE : S48_FALSE, rc == LDAP_OPT_SUCCESS ? res : S48_UNSPECIFIC); S48_GC_UNPROTECT(); return res_list; } /* ************************************************************************ */ /* 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); }