[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: LuaLDAP patch to compile against WinLDAP API
- From: Mark Edgar <medgar@...>
- Date: Tue, 24 Jan 2006 17:42:43 -0700
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