LuaLDAP patch to compile against WinLDAP API

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

LuaLDAP patch to compile against WinLDAP API

Mark Edgar
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