#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); FFIT_MAKE_ENTER_RECORD(scsh_enter_berelement, scsh_berelement_record_type, BerElement *); 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(errno); else return scsh_enter_ldap(ldap); } s48_value scsh_ldap_simple_bind_s(s48_value ldap, s48_value user, s48_value cred) { int r; LDAP *l; S48_DECLARE_GC_PROTECT(3); S48_GC_PROTECT_3(ldap, user, cred); r = ldap_simple_bind_s(scsh_extract_ldap(ldap), S48_FALSE_P(user) ? NULL : s48_extract_string(user), S48_FALSE_P(cred) ? NULL : 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) { 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) { ldap_memfree(scsh_extract_ldap(ldap)); return S48_UNSPECIFIC; } s48_value scsh_ldap_msgfree(s48_value ldapmsg) { ldap_msgfree(scsh_extract_ldapmessage(ldapmsg)); return S48_UNSPECIFIC; } s48_value scsh_ldap_ber_free(s48_value ber, s48_value sfbuf) { int fbuf; S48_DECLARE_GC_PROTECT(2); S48_GC_PROTECT_2(ber, sfbuf); fbuf = s48_extract_integer(sfbuf); S48_GC_UNPROTECT(); ber_free(scsh_extract_berelement(ber), fbuf); } 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); 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_FALSE_P(filter) ? NULL : 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_DECLARE_GC_PROTECT(9); S48_GC_PROTECT_9(ldap, base, scope, filter, attrs, attrsonly, res, timeout_sec, timeout_usec); 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_FALSE_P(base) ? NULL : s48_extract_string(base), s48_extract_integer(scope), S48_FALSE_P(filter) ? NULL : 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); 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); r = ldap_count_entries(scsh_extract_ldap(ldap), scsh_extract_ldapmessage(lm)); S48_GC_UNPROTECT(); return (r == -1) ? S48_FALSE : s48_enter_integer(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); 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); 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); 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); 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); 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); 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); 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); 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_first_attribute(s48_value ldap, s48_value entry) { BerElement *ber; char *name; s48_value res_list = S48_FALSE; S48_DECLARE_GC_PROTECT(3); S48_GC_PROTECT_3(ldap, entry, res_list); if ((ber = ber_alloc_t(LBER_USE_DER)) == NULL) raise_ldap_memory_alloc_error(); name = ldap_first_attribute(scsh_extract_ldap(ldap), scsh_extract_ldapmessage(entry), &ber); if (name == NULL) res_list = s48_list_2(S48_FALSE, S48_FALSE); else res_list = s48_list_2(s48_enter_string(name), scsh_enter_berelement(ber)); S48_GC_UNPROTECT(); return res_list; } s48_value scsh_ldap_next_attribute(s48_value ldap, s48_value entry, s48_value ber) { char *name; s48_value res; S48_DECLARE_GC_PROTECT(4); S48_GC_PROTECT_4(ldap, entry, ber, res); name = ldap_next_attribute(scsh_extract_ldap(ldap), scsh_extract_ldapmessage(entry), scsh_extract_berelement(ber)); res = (name != NULL) ? s48_enter_string(name) : S48_FALSE; S48_GC_UNPROTECT(); return res; } s48_value scsh_ldap_msgtype(s48_value lm) { int r; r = ldap_msgtype(scsh_extract_ldapmessage(lm)); return (r == -1) ? S48_FALSE : s48_enter_integer(r); } s48_value scsh_ldap_msgid(s48_value lm) { int r; r = ldap_msgid(scsh_extract_ldapmessage(lm)); return (r == -1) ? S48_FALSE : s48_enter_integer(r); } /* may raise ldap error */ s48_value scsh_ldap_get_dn(s48_value ldap, s48_value entry) { char *s; s48_value res; S48_DECLARE_GC_PROTECT(3); S48_GC_PROTECT_3(ldap, entry, res); s = ldap_get_dn(scsh_extract_ldap(ldap), scsh_extract_ldapmessage(entry)); res = (s == NULL) ? S48_FALSE : s48_enter_string(s); S48_GC_UNPROTECT(); ldap_memfree(s); return res; } 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_DECLARE_GC_PROTECT(4); S48_GC_PROTECT_4(ldap, entry, attr, res); val = ldap_get_values(scsh_extract_ldap(ldap), scsh_extract_ldapmessage(entry), s48_extract_string(attr)); res = (val == NULL) ? S48_FALSE : ffit_enter_string_array(val); if (val != NULL) 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); 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); 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); 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); r = ldap_abandon(scsh_extract_ldap(ldap), s48_extract_integer(msgid)); S48_GC_UNPROTECT(); return s48_enter_integer(r); } /* FIXME: Options missing here! */ s48_value scsh_ldap_get_set_option(s48_value ldap, s48_value option, s48_value set, s48_value inval) { int opt, rc; LDAP *ld; s48_value res, res_list; S48_DECLARE_GC_PROTECT(6); S48_GC_PROTECT_6(ldap, option, set, inval, res, res_list); FFIT_CHECK_BOOLEAN(set); ld = scsh_extract_ldap(ldap); opt = s48_extract_integer(option); res = S48_UNSPECIFIC; switch (opt) { case LDAP_OPT_API_INFO: { LDAPAPIInfo *inf; if (S48_TRUE_P(set)) raise_ldap_read_only_option(); rc = ldap_get_option(ld, opt, &inf); if (rc == LDAP_OPT_SUCCESS) res = scsh_enter_ldapiinfo(inf); break; } case LDAP_OPT_DEREF: case LDAP_OPT_SIZELIMIT: case LDAP_OPT_TIMELIMIT: case LDAP_OPT_PROTOCOL_VERSION: case LDAP_OPT_ERROR_NUMBER: { int l; int ov; 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, &ov)) == LDAP_SUCCESS) res = s48_enter_integer(ov); break; } case LDAP_OPT_REFERRALS: case LDAP_OPT_RESTART: { int ov; 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, &ov)) == LDAP_SUCCESS) res = ov == 0 ? S48_TRUE : S48_FALSE; break; } case LDAP_OPT_SERVER_CONTROLS: case LDAP_OPT_CLIENT_CONTROLS: { raise_ldap_read_only_option(); } case LDAP_OPT_ERROR_STRING: { char *ov; if (S48_TRUE_P(set)) raise_ldap_read_only_option(); if ((rc = ldap_get_option(ld, opt, &ov)) == LDAP_SUCCESS) res = s48_enter_string(ov); break; } default: { raise_ldap_feature_not_supported(); } } 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(); /* generated by ffi-tools */ 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(); /* generated by ffi-tools */ scsh_ldap_constants_export_bindings(); /* generated by ffi-tools */ FFIT_RECORD_TYPE_INIT(scsh_ldap_record_type, "ldap-session"); 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); FFIT_RECORD_TYPE_INIT(scsh_berelement_record_type, "ber-element"); 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_ber_free); 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_first_attribute); S48_EXPORT_FUNCTION(scsh_ldap_next_attribute); 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); }