aboutsummaryrefslogtreecommitdiffstats
path: root/lualdap/src
diff options
context:
space:
mode:
authorTomas Guisasola <tomas@luaforge.net>2003-06-16 16:41:15 +0000
committerTomas Guisasola <tomas@luaforge.net>2003-06-16 16:41:15 +0000
commitbf486bd844df001e0bd515e4c244f9fb5ef3e901 (patch)
tree1a629a39e72b10caa72eb0b45a6eab4960985ce4 /lualdap/src
parentRemocao de comentarios. (diff)
downloadlualdap-bf486bd844df001e0bd515e4c244f9fb5ef3e901.tar.xz
lualdap-bf486bd844df001e0bd515e4c244f9fb5ef3e901.zip
Acrescimo da operacao de adicao.
Diffstat (limited to 'lualdap/src')
-rwxr-xr-xlualdap/src/lualdap.c432
1 files changed, 297 insertions, 135 deletions
diff --git a/lualdap/src/lualdap.c b/lualdap/src/lualdap.c
index 41b1a90..1f9079e 100755
--- a/lualdap/src/lualdap.c
+++ b/lualdap/src/lualdap.c
@@ -1,6 +1,6 @@
/*
** LuaLDAP
-** $Id: lualdap.c,v 1.3 2003-06-16 10:36:01 tomas Exp $
+** $Id: lualdap.c,v 1.4 2003-06-16 16:41:15 tomas Exp $
*/
#include <stdlib.h>
@@ -49,26 +49,45 @@ static conn_data *getconnection (lua_State *L) {
/*
+** Copy a Lua string to a C string optionally indicating length.
+*/
+static char *luastrcpy (lua_State *L, int index, size_t *length) {
+ size_t len = lua_strlen (L, index);
+ char *str = malloc (len * sizeof(char));
+ memcpy (str, lua_tostring (L, index), len);
+ if (length)
+ *length = len;
+ return str;
+}
+
+
+/*
** Create a NULL-terminated array of C-strings from a Lua table.
-** @param tab stack index of the table.
+** It also works for one string (instead of a table with a unique value).
+** @param tab stack index of the table (or string).
** @return NULL-terminated array of C-strings.
*/
static char **table2strarray (lua_State *L, int tab) {
char **array;
int i;
- int n = luaL_getn (L, tab);
- array = malloc ((n+1) * sizeof(char *));
- for (i = 0; i < n; i++) {
- lua_rawgeti (L, tab, i+1); /* get table element */
- if (lua_isstring (L, -1)) {
- int len = lua_strlen (L, -1);
- array[i] = malloc (len * sizeof(char));
- memcpy (array[i], lua_tostring (L, -1), len);
- } else {
+ int n;
+ if (lua_istable (L, tab)) {
+ n = luaL_getn (L, tab);
+ array = malloc ((n+1) * sizeof(char *));
+ for (i = 0; i < n; i++) {
+ lua_rawgeti (L, tab, i+1); /* push table element */
+ if (lua_isstring (L, -1))
+ array[i] = luastrcpy (L, -1, NULL);
+ else {
+ luaL_error (L, LUALDAP_PREFIX"invalid value");
+ }
}
+ lua_pop (L, n);
+ } else if (lua_isstring (L, tab)) {
+ array = malloc (2 * sizeof(char *));
+ array[0] = luastrcpy (L, -1, NULL);
}
array[n] = NULL;
- lua_pop (L, n);
return array;
}
@@ -87,6 +106,55 @@ static void free_strarray (char **array) {
/*
+** Create a NULL-terminated array of berval strings from a Lua table.
+** It also works for one string (instead of a table with a unique value).
+** @param tab stack index of the table (or string).
+** @return NULL-terminated array of berval strings.
+*/
+static BerValue **table2bervalarray (lua_State *L, int tab) {
+ BerValue **array;
+ int i;
+ int n;
+ if (lua_istable (L, tab)) {
+ n = luaL_getn (L, tab);
+ array = malloc ((n+1) * sizeof(BerValue *));
+ for (i = 0; i < n; i++) {
+ lua_rawgeti (L, tab, i+1); /* push table element */
+ if (lua_isstring (L, -1)) {
+ array[i] = (BerValue *)malloc (sizeof (BerValue));
+ array[i]->bv_val = luastrcpy (L, -1, &(array[i]->bv_len));
+ } else {
+ luaL_error (L, LUALDAP_PREFIX"invalid value");
+ }
+ }
+ lua_pop (L, n);
+ } else if (lua_isstring (L, tab)) {
+ n = 1;
+ array = (BerValue **)malloc (2 * sizeof(BerValue *));
+ array[0] = (BerValue *)malloc (sizeof (BerValue));
+ array[0]->bv_val = luastrcpy (L, -1, &(array[0]->bv_len));
+ }
+ array[n] = NULL;
+ return array;
+}
+
+
+/*
+** Free a NULL-terminated array of bervalstrings.
+*/
+static void free_bervalarray (BerValue **array) {
+ if (array) {
+ int i;
+ for (i = 0; array[i] != NULL; i++) {
+ free (array[i]->bv_val);
+ free (array[i]);
+ }
+ free (array);
+ }
+}
+
+
+/*
** Unbind from the directory.
** @param #1 LDAP connection.
** @return 1 in case of success; nothing when already closed.
@@ -106,160 +174,95 @@ static int lualdap_close (lua_State *L) {
/*
-** Push an attribute value (or a table of values) on top of the stack.
-** @param entry Current entry.
-** @param attr Name of entry's attribute to get values from.
-** @return 1 in case of success.
+** Counts the number of string keys of a given table.
*/
-static int pushvalues (lua_State *L, LDAP *ld, LDAPMessage *entry, char *attr) {
- int i, n;
- BerValue **vals = ldap_get_values_len (ld, entry, attr);
- if ((n = ldap_count_values_len (vals)) == 1)
- lua_pushlstring (L, vals[0]->bv_val, vals[0]->bv_len);
- else { /* Multiple values */
- lua_newtable (L);
- for (i = 0; i < n; i++) {
- lua_pushlstring (L, vals[i]->bv_val, vals[i]->bv_len);
- lua_rawseti (L, -2, i);
- }
+static size_t nstrkeys (lua_State *L, int tab) {
+ int n = 0;
+ lua_pushnil (L);
+ while (lua_next(L, tab) != 0) {
+ lua_pop (L, 1);
+ if (lua_isstring (L, -1))
+ n++;
}
- ldap_value_free_len (vals);
- return 1;
+ return n;
}
/*
-** Store entry's distinguished name at the given table.
-** @param entry Current entry.
-** @param tab Absolute stack index of the table.
+** Convert a pair (string, value) into a LDAPMod structure.
+** Assume that string is at index -2 and value at -1.
*/
-static void setdn (lua_State *L, LDAP *ld, LDAPMessage *entry, int tab) {
- char *dn = ldap_get_dn (ld, entry);
- lua_pushstring (L, "dn");
- lua_pushstring (L, dn);
- lua_rawset (L, tab);
- ldap_memfree (dn);
+static LDAPMod *attr2mod (lua_State *L, int op) {
+ LDAPMod *mod = (LDAPMod *)malloc (sizeof (LDAPMod));
+ mod->mod_op = op;
+ mod->mod_type = luastrcpy (L, -2, NULL);
+ mod->mod_bvalues = table2bervalarray (L, lua_gettop(L));
+ return mod;
}
/*
-** Store entry's attributes and values at the given table.
-** @param entry Current entry.
-** @param tab Absolute stack index of the table.
+** Free an LDAPMod structure.
*/
-static void setattribs (lua_State *L, LDAP *ld, LDAPMessage *entry, int tab) {
- char *attr;
- BerElement *ber = NULL;
- for (attr = ldap_first_attribute (ld, entry, &ber);
- attr != NULL;
- attr = ldap_next_attribute (ld, entry, ber))
- {
- lua_pushstring (L, attr);
- pushvalues (L, ld, entry, attr);
- lua_rawset (L, tab); /* tab[attr] = vals */
- ldap_memfree (attr);
- }
- if (ber)
- ber_free (ber, 0);
+static void free_mod (LDAPMod *mod) {
+ if (mod->mod_type)
+ free (mod->mod_type);
+ free_bervalarray (mod->mod_bvalues);
+ free (mod);
}
/*
-** Retrieve the next message and all of its attributes and values.
-** @param #1 LDAP connection.
-** @param #2 previous entry (or nil if first call).
-** @return #1 current entry (or nil if no more entries).
-** @return #2 table with entry's attributes and values.
+** Convert a Lua table into an array of attributes.
+** An array of attributes is a NULL-terminated array of LDAPMod's.
*/
-static int search_entries (lua_State *L) {
- conn_data *conn = (conn_data *)lua_touserdata (L, 1);
- LDAPMessage *entry;
-
- /* get next (or first) entry */
- if (lua_isnil (L, 2)) /* first call */
- entry = ldap_first_entry (conn->ld,
- (LDAPMessage *)lua_topointer (L, lua_upvalueindex (1)));
- else /* get next message */
- entry = ldap_next_entry (conn->ld, (LDAPMessage *)lua_topointer(L,2));
-
- if (entry == NULL) { /* no more messages */
- ldap_msgfree ((LDAPMessage *)lua_topointer (L, lua_upvalueindex(1)));
- lua_pushnil (L);
- return 1;
- } else { /* build table of attributes and its values */
- int tab;
- lua_pushlightuserdata (L, entry); /* push current entry */
- lua_newtable (L);
- tab = lua_gettop (L);
- setdn (L, conn->ld, entry, tab);
- setattribs (L, conn->ld, entry, tab);
- return 2;
+static LDAPMod **table2attrarray (lua_State *L, int tab) {
+ LDAPMod **array;
+ size_t n = nstrkeys (L, tab);
+ array = (LDAPMod **)malloc ((n+1) * sizeof (LDAPMod *));
+ array[n] = NULL;
+ n = 0;
+ lua_pushnil (L);
+ while (lua_next (L, tab) != 0) {
+ if (lua_isstring (L, -1)) {
+ array[n] = attr2mod (L, LDAP_MOD_ADD);
+ n++;
+ }
+ lua_pop (L, 1);
}
+ return array;
}
/*
-** Convert a string to one of the possible scopes of the search.
+** Free an LDAPMod array.
*/
-static int string2scope (const char *s) {
- switch (*s) {
- case 'b':
- return LDAP_SCOPE_BASE;
- case 'o':
- return LDAP_SCOPE_ONELEVEL;
- case 's':
- return LDAP_SCOPE_SUBTREE;
- default:
- return LDAP_SCOPE_DEFAULT;
- }
+static void free_attrarray (LDAPMod **array) {
+ int i;
+ for (i = 0; array[i] != NULL; i++)
+ free_mod (array[i]);
+ free (array);
}
/*
-** Perform a search operation.
+** Add a new entry to the directory.
** @param #1 LDAP connection.
-** @param #2 String with base entry's DN.
-** @param #3 String with search scope.
-** @param #4 String with search filter.
-** @param #5 Table with names of attributes to retrieve.
-** @return #1 Function to iterate over the result entries.
-** @return #2 LDAP connection.
-** @return #3 nil as first entry.
-** The search result is defined as an upvalue of the iterator.
+** @param #2 String with new entry's DN.
+** @param #3 Table with new entry's attributes and values.
+** @return ??
*/
-static int lualdap_search_attribs (lua_State *L) {
+static int lualdap_add (lua_State *L) {
conn_data *conn = (conn_data *)getconnection (L);
- const char *base = luaL_check_string (L, 2);
- int scope = string2scope (luaL_check_string (L, 3));
- const char *filter = luaL_check_string (L, 4);
- char **attrs = NULL;
- int attrsonly = 0; /* types and values. parameter? */
- int msgid;
- int rc;
- LDAPMessage *res;
- struct timeval *timeout = NULL; /* ??? function parameter ??? */
- int sizelimit = LDAP_NO_LIMIT; /* ??? function parameter ??? */
-
- if (lua_istable (L, 5))
- attrs = table2strarray (L, 5);
- rc = ldap_search_ext (conn->ld, base, scope, filter, attrs, attrsonly,
- NULL, NULL, timeout, sizelimit, &msgid);
- free_strarray (attrs);
- if (rc != LDAP_SUCCESS)
+ const char *dn = luaL_check_string (L, 2);
+ LDAPMod **attrs = table2attrarray (L, 3);
+ int rc = ldap_add_ext_s (conn->ld, dn, attrs, NULL, NULL);
+ free_attrarray (attrs);
+ if (rc == LDAP_SUCCESS) {
+ lua_pushboolean (L, 1);
+ return 1;
+ } else
return faildirect (L, ldap_err2string (rc));
-
- rc = ldap_result (conn->ld, LDAP_RES_ANY, LDAP_MSG_ALL, timeout, &res);
- if (rc == 0)
- return faildirect (L, LUALDAP_PREFIX"result timeout expired");
- else if (rc == -1)
- return faildirect (L, LUALDAP_PREFIX"result error");
-
- lua_pushlightuserdata (L, res); /* push result as upvalue for iterator */
- lua_pushcclosure (L, search_entries, 1); /* push iterator function */
- lua_pushvalue (L, 1); /* push connection as "state" to iterator */
- lua_pushnil (L); /* push nil as "initial value" for iterator */
-
- return 3;
}
@@ -453,6 +456,164 @@ static int lualdap_modify (lua_State *L) {
/*
+** Push an attribute value (or a table of values) on top of the stack.
+** @param entry Current entry.
+** @param attr Name of entry's attribute to get values from.
+** @return 1 in case of success.
+*/
+static int pushvalues (lua_State *L, LDAP *ld, LDAPMessage *entry, char *attr) {
+ int i, n;
+ BerValue **vals = ldap_get_values_len (ld, entry, attr);
+ if ((n = ldap_count_values_len (vals)) == 1)
+ lua_pushlstring (L, vals[0]->bv_val, vals[0]->bv_len);
+ else { /* Multiple values */
+ lua_newtable (L);
+ for (i = 0; i < n; i++) {
+ lua_pushlstring (L, vals[i]->bv_val, vals[i]->bv_len);
+ lua_rawseti (L, -2, i);
+ }
+ }
+ ldap_value_free_len (vals);
+ return 1;
+}
+
+
+/*
+** Store entry's distinguished name at the given table.
+** @param entry Current entry.
+** @param tab Absolute stack index of the table.
+*/
+static void setdn (lua_State *L, LDAP *ld, LDAPMessage *entry, int tab) {
+ char *dn = ldap_get_dn (ld, entry);
+ lua_pushstring (L, "dn");
+ lua_pushstring (L, dn);
+ lua_rawset (L, tab);
+ ldap_memfree (dn);
+}
+
+
+/*
+** Store entry's attributes and values at the given table.
+** @param entry Current entry.
+** @param tab Absolute stack index of the table.
+*/
+static void setattribs (lua_State *L, LDAP *ld, LDAPMessage *entry, int tab) {
+ char *attr;
+ BerElement *ber = NULL;
+ for (attr = ldap_first_attribute (ld, entry, &ber);
+ attr != NULL;
+ attr = ldap_next_attribute (ld, entry, ber))
+ {
+ lua_pushstring (L, attr);
+ pushvalues (L, ld, entry, attr);
+ lua_rawset (L, tab); /* tab[attr] = vals */
+ ldap_memfree (attr);
+ }
+ if (ber)
+ ber_free (ber, 0);
+}
+
+
+/*
+** Retrieve the next message and all of its attributes and values.
+** @param #1 LDAP connection.
+** @param #2 previous entry (or nil if first call).
+** @return #1 current entry (or nil if no more entries).
+** @return #2 table with entry's attributes and values.
+*/
+static int search_entries (lua_State *L) {
+ conn_data *conn = (conn_data *)lua_touserdata (L, 1);
+ LDAPMessage *entry;
+
+ /* get next (or first) entry */
+ if (lua_isnil (L, 2)) /* first call */
+ entry = ldap_first_entry (conn->ld,
+ (LDAPMessage *)lua_topointer (L, lua_upvalueindex (1)));
+ else /* get next message */
+ entry = ldap_next_entry (conn->ld, (LDAPMessage *)lua_topointer(L,2));
+
+ if (entry == NULL) { /* no more messages */
+ ldap_msgfree ((LDAPMessage *)lua_topointer (L, lua_upvalueindex(1)));
+ lua_pushnil (L);
+ return 1;
+ } else { /* build table of attributes and its values */
+ int tab;
+ lua_pushlightuserdata (L, entry); /* push current entry */
+ lua_newtable (L);
+ tab = lua_gettop (L);
+ setdn (L, conn->ld, entry, tab);
+ setattribs (L, conn->ld, entry, tab);
+ return 2;
+ }
+}
+
+
+/*
+** Convert a string to one of the possible scopes of the search.
+*/
+static int string2scope (const char *s) {
+ switch (*s) {
+ case 'b':
+ return LDAP_SCOPE_BASE;
+ case 'o':
+ return LDAP_SCOPE_ONELEVEL;
+ case 's':
+ return LDAP_SCOPE_SUBTREE;
+ default:
+ return LDAP_SCOPE_DEFAULT;
+ }
+}
+
+
+/*
+** Perform a search operation.
+** @param #1 LDAP connection.
+** @param #2 String with base entry's DN.
+** @param #3 String with search scope.
+** @param #4 String with search filter.
+** @param #5 Table with names of attributes to retrieve.
+** @return #1 Function to iterate over the result entries.
+** @return #2 LDAP connection.
+** @return #3 nil as first entry.
+** The search result is defined as an upvalue of the iterator.
+*/
+static int lualdap_search_attribs (lua_State *L) {
+ conn_data *conn = (conn_data *)getconnection (L);
+ const char *base = luaL_check_string (L, 2);
+ int scope = string2scope (luaL_check_string (L, 3));
+ const char *filter = luaL_check_string (L, 4);
+ char **attrs = NULL;
+ int attrsonly = 0; /* types and values. parameter? */
+ int msgid;
+ int rc;
+ LDAPMessage *res;
+ struct timeval *timeout = NULL; /* ??? function parameter ??? */
+ int sizelimit = LDAP_NO_LIMIT; /* ??? function parameter ??? */
+
+ if (lua_istable (L, 5))
+ attrs = table2strarray (L, 5);
+ rc = ldap_search_ext (conn->ld, base, scope, filter, attrs, attrsonly,
+ NULL, NULL, timeout, sizelimit, &msgid);
+ free_strarray (attrs);
+ if (rc != LDAP_SUCCESS)
+ return faildirect (L, ldap_err2string (rc));
+
+ rc = ldap_result (conn->ld, LDAP_RES_ANY, LDAP_MSG_ALL, timeout, &res);
+ if (rc == 0)
+ return faildirect (L, LUALDAP_PREFIX"result timeout expired");
+ else if (rc == -1)
+ return faildirect (L, LUALDAP_PREFIX"result error");
+
+ lua_pushlightuserdata (L, res); /* push result as upvalue for iterator */
+ lua_pushcclosure (L, search_entries, 1); /* push iterator function */
+ lua_pushvalue (L, 1); /* push connection as "state" to iterator */
+ lua_pushnil (L); /* push nil as "initial value" for iterator */
+
+ return 3;
+}
+
+
+/*
** Set metatable of userdata on top of the stack.
*/
static void lualdap_setmeta (lua_State *L) {
@@ -467,6 +628,7 @@ static void lualdap_setmeta (lua_State *L) {
static int lualdap_createmeta (lua_State *L) {
const luaL_reg methods[] = {
{"close", lualdap_close},
+ {"add", lualdap_add},
{"compare", lualdap_compare},
{"delete", lualdap_delete},
{"modify", lualdap_modify},