lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


The Microsoft WinLDAP API is not terribly different from OpenLDAP's API on which LuaLDAP is based.

Please find attached a patch against lualdap-1.0/src/lualdap.c and an additional header file named ldap.h which "translates" between certain OpenLDAP APIs and their corresponding WinLDAP APIs.

This ldap.h header is a bit hackish. A better long-term solution would be to rewrite parts of lualdap.c in terms of a compatibility API. The ldap.h file should not be used on non-Windows platforms.

I'm not sure where OpenLDAP and WinLDAP diverged, nor the reasons for the seemingly gratuitous API differences. Hopefully someone with some more specific knowledge can point to a better way. I haven't been able to find any documentation of what a "standard" LDAP API should look like.

					-Mark
diff -u -r1.1 -r1.6
--- lualdap-1.0/src/lualdap.c	23 Dec 2005 07:00:10 -0000	1.1
+++ lualdap-1.0-me/src/lualdap.c	31 Dec 2005 02:12:46 -0000	1.6
@@ -9,6 +9,7 @@
 #ifdef WIN32
 #include <Winsock2.h>
 #else
+#define DECLSPEC_EXPORT
 #include <sys/time.h>
 #endif
 
@@ -18,6 +19,14 @@
 #include "lauxlib.h"
 #include "compat-5.1.h"
 
+#ifdef WINLDAPAPI
+#define timeval l_timeval
+typedef ULONG ldapi_t;
+#else
+#include <sys/time.h>
+typedef int ldapi_t;
+#endif
+
 
 #define LUALDAP_PREFIX "LuaLDAP: "
 #define LUALDAP_TABLENAME "lualdap"
@@ -228,40 +237,41 @@
 		value_error (L, n);
 		return NULL;
 	}
-	a->bvals[a->bi].bv_len = lua_strlen (L, -1);
-	a->bvals[a->bi].bv_val = (char *)lua_tostring (L, -1);
+	ret->bv_len = lua_strlen (L, -1);
+	ret->bv_val = (char *)lua_tostring (L, -1);
 	a->bi++;
 	return ret;
 }
 
 
 /*
-** Store a pointer to the value on top of the stack on the attributes structure.
+** Store a pointer to the value on top of the stack or NULL on the attributes structure.
 */
-static BerValue **A_setval (lua_State *L, attrs_data *a, const char *n) {
+static BerValue **A_setnval (lua_State *L, attrs_data *a, const char *n) {
 	BerValue **ret = &(a->values[a->vi]);
 	if (a->vi >= LUALDAP_ARRAY_VALUES_SIZE) {
 		luaL_error (L, LUALDAP_PREFIX"too many values");
 		return NULL;
 	}
-	a->values[a->vi] = A_setbval (L, a, n);
+	*ret = n ? A_setbval (L, a, n) : NULL;
 	a->vi++;
 	return ret;
 }
 
 
 /*
+** Store a pointer to the value on top of the stack on the attributes structure.
+*/
+static BerValue **A_setval (lua_State *L, attrs_data *a, const char *n) {
+        return A_setnval(L, a, n);
+}
+
+
+/*
 ** Store a NULL pointer on the attributes structure.
 */
 static BerValue **A_nullval (lua_State *L, attrs_data *a) {
-	BerValue **ret = &(a->values[a->vi]);
-	if (a->vi >= LUALDAP_ARRAY_VALUES_SIZE) {
-		luaL_error (L, LUALDAP_PREFIX"too many values");
-		return NULL;
-	}
-	a->values[a->vi] = NULL;
-	a->vi++;
-	return ret;
+        return A_setnval(L, a, NULL);
 }
 
 
@@ -380,20 +390,21 @@
 static int result_message (lua_State *L) {
 	struct timeval *timeout = NULL; /* ??? function parameter ??? */
 	LDAPMessage *res;
-	int rc;
+	ldapi_t rc;
 	conn_data *conn = (conn_data *)lua_touserdata (L, lua_upvalueindex (1));
-	int msgid = (int)lua_tonumber (L, lua_upvalueindex (2));
+	ldapi_t msgid = (int)lua_tonumber (L, lua_upvalueindex (2));
 	/*int res_code = (int)lua_tonumber (L, lua_upvalueindex (3));*/
 
 	luaL_argcheck (L, conn->ld, 1, LUALDAP_PREFIX"LDAP connection is closed");
 	rc = ldap_result (conn->ld, msgid, LDAP_MSG_ONE, timeout, &res);
 	if (rc == 0)
 		return faildirect (L, LUALDAP_PREFIX"result timeout expired");
-	else if (rc < 0) {
+	else if (rc == (ldapi_t)-1) {
 		ldap_msgfree (res);
 		return faildirect (L, LUALDAP_PREFIX"result error");
 	} else {
-		int err, ret = 1;
+		ldapi_t err;
+		int ret = 1;
 		char *mdn, *msg;
 		rc = ldap_parse_result (conn->ld, res, &err, &mdn, &msg, NULL, NULL, 1);
 		if (rc != LDAP_SUCCESS)
@@ -425,7 +436,7 @@
 /*
 ** Push a function to process the LDAP result.
 */
-static int create_future (lua_State *L, int rc, int conn, int msgid, int code) {
+static int create_future (lua_State *L, ldapi_t rc, int conn, ldapi_t msgid, int code) {
 	if (rc != LDAP_SUCCESS)
 		return faildirect (L, ldap_err2string (rc));
 	lua_pushvalue (L, conn); /* push connection as #1 upvalue */
@@ -464,7 +475,7 @@
 	conn_data *conn = getconnection (L);
 	const char *dn = luaL_check_string (L, 2);
 	attrs_data attrs;
-	int rc, msgid;
+	ldapi_t rc, msgid;
 	A_init (&attrs);
 	if (lua_istable (L, 3))
 		A_tab2mod (L, &attrs, 3, LUALDAP_MOD_ADD);
@@ -487,7 +498,7 @@
 	const char *dn = luaL_check_string (L, 2);
 	const char *attr = luaL_check_string (L, 3);
 	BerValue bvalue;
-	int rc, msgid;
+	ldapi_t rc, msgid;
 	bvalue.bv_val = (char *)luaL_check_string (L, 4);
 	bvalue.bv_len = lua_strlen (L, 4);
 	rc = ldap_compare_ext (conn->ld, dn, attr, &bvalue, NULL, NULL, &msgid);
@@ -504,7 +515,7 @@
 static int lualdap_delete (lua_State *L) {
 	conn_data *conn = getconnection (L);
 	const char *dn = luaL_check_string (L, 2);
-	int rc, msgid;
+	ldapi_t rc, msgid;
 	rc = ldap_delete_ext (conn->ld, dn, NULL, NULL, &msgid);
 	return create_future (L, rc, 1, msgid, LDAP_RES_DELETE);
 }
@@ -540,7 +551,8 @@
 	conn_data *conn = getconnection (L);
 	const char *dn = luaL_check_string (L, 2);
 	attrs_data attrs;
-	int rc, msgid, param = 3;
+	ldapi_t rc, msgid;
+	int param = 3;
 	A_init (&attrs);
 	while (lua_istable (L, param)) {
 		int op;
@@ -568,8 +580,8 @@
 	const char *rdn = luaL_check_string (L, 3);
 	const char *par = luaL_optlstring (L, 4, NULL, NULL);
 	const int del = luaL_optnumber (L, 5, 0);
-	int msgid;
-	int rc = ldap_rename (conn->ld, dn, rdn, par, del, NULL, NULL, &msgid);
+	ldapi_t msgid;
+	ldapi_t rc = ldap_rename (conn->ld, dn, rdn, par, del, NULL, NULL, &msgid);
 	return create_future (L, rc, 1, msgid, LDAP_RES_MODDN);
 }
 
@@ -652,7 +664,7 @@
 	conn_data *conn;
 	struct timeval *timeout = NULL; /* ??? function parameter ??? */
 	LDAPMessage *res;
-	int rc;
+	ldapi_t rc;
 	int ret;
 
 	lua_rawgeti (L, LUA_REGISTRYINDEX, search->conn);
@@ -661,7 +673,7 @@
 	rc = ldap_result (conn->ld, search->msgid, LDAP_MSG_ONE, timeout, &res);
 	if (rc == 0)
 		return faildirect (L, LUALDAP_PREFIX"result timeout expired");
-	else if (rc == -1)
+	else if (rc == (ldapi_t)-1)
 		return faildirect (L, LUALDAP_PREFIX"result error");
 	else if (rc == LDAP_RES_SEARCH_RESULT) { /* last message => nil */
 		/* close search object to avoid reuse */
@@ -736,7 +748,7 @@
 /*
 ** Create a search object and leaves it on top of the stack.
 */
-static void create_search (lua_State *L, int conn_index, int msgid) {
+static void create_search (lua_State *L, int conn_index, ldapi_t msgid) {
 	search_data *search = (search_data *)lua_newuserdata (L, sizeof (search_data));
 	lualdap_setmeta (L, LUALDAP_SEARCH_METATABLE);
 	search->conn = LUA_NOREF;
@@ -789,7 +801,7 @@
 	conn_data *conn = getconnection (L);
 	const char *base, *filter;
 	char *attrs[LUALDAP_MAX_ATTRS];
-	int scope, attrsonly, msgid, rc, sizelimit;
+	ldapi_t scope, attrsonly, msgid, rc, sizelimit;
 	struct timeval st, *timeout;
 
 	if (!lua_istable (L, 2))
@@ -825,7 +837,7 @@
 	if (conn->ld == NULL)
 		strcpy (buff, "closed");
 	else
-		sprintf (buff, "%p", conn);
+		sprintf (buff, "%p", (void *)conn);
 	lua_pushfstring (L, "%s (%s)", LUALDAP_CONNECTION_METATABLE, buff);
 	return 1;
 }
@@ -842,7 +854,7 @@
 	if (search->conn == LUA_NOREF)
 		strcpy (buff, "closed");
 	else
-		sprintf (buff, "%p", search);
+		sprintf (buff, "%p", (void *)search);
 	lua_pushfstring (L, "%s (%s)", LUALDAP_SEARCH_METATABLE, buff);
 	return 1;
 }
@@ -957,11 +969,8 @@
 	lua_pushliteral (L, "_DESCRIPTION");
 	lua_pushliteral (L, "LuaLDAP is a simple interface from Lua to an LDAP client");
 	lua_settable (L, -3);
-	lua_pushliteral (L, "_NAME");
-	lua_pushliteral (L, "LuaLDAP");
-	lua_settable (L, -3);
 	lua_pushliteral (L, "_VERSION");
-	lua_pushliteral (L, "1.0");
+	lua_pushliteral (L, "LuaLDAP 1.0.1-me");
 	lua_settable (L, -3);
 }
 
@@ -969,7 +978,7 @@
 /*
 ** Create ldap table and register the open method.
 */
-int luaopen_lualdap (lua_State *L) {
+DECLSPEC_EXPORT int luaopen_lualdap (lua_State *L) {
 	struct luaL_reg lualdap[] = {
 		{"open_simple", lualdap_open_simple},
 		{NULL, NULL},
#include <winldap.h>

/* For some reason MSDN mentions LDAP_RES_MODDN, but not LDAP_RES_MODRDN. */
#ifndef LDAP_RES_MODDN
#define LDAP_RES_MODDN LDAP_RES_MODRDN
#endif

/* MSDN doesn't mention this function at all.  Unfortunately, LDAPMessage an opaque type. */
#define ldap_msgtype(m) ((m)->lm_msgtype)

#define ldap_first_message ldap_first_entry

/* The WinLDAP API allows comparisons against either string or binary values */
#undef ldap_compare_ext

/* The WinLDAP API uses ULONG seconds instead of a struct timeval. */
#undef ldap_search_ext

/* The WinLDAP API has a different number of arguments for this */
#undef ldap_start_tls_s

#ifdef UNICODE
#define ldap_compare_ext(ld,dn,a,v,sc,cc,msg) \
        ldap_compare_extW(ld,dn,a,0,v,sc,cc,msg)
#define ldap_search_ext(ld,base,scope,f,a,o,sc,cc,t,s,msg) \
        ldap_search_extW(ld,base,scope,f,a,o,sc,cc,(t)?(t)->tv_sec:0,s,msg)
#define ldap_start_tls_s(ld,sc,cc) \
        ldap_start_tls_sW(ld,0,0,sc,cc)
#else
#define ldap_compare_ext(ld,dn,a,v,sc,cc,msg) \
        ldap_compare_extA(ld,dn,a,0,v,sc,cc,msg)
#define ldap_search_ext(ld,base,scope,f,a,o,sc,cc,t,s,msg) \
        ldap_search_extA(ld,base,scope,f,a,o,sc,cc,(t)?(t)->tv_sec:0,s,msg)
#define ldap_start_tls_s(ld,sc,cc) \
        ldap_start_tls_sA(ld,0,0,sc,cc)
#endif