#include "includes.h"
#include "ldb/include/ldb.h"
#include "ldb/include/ldb_private.h"
+#include "ldb/include/ldb_errors.h"
#include "libcli/ldap/ldap.h"
#include "libcli/ldap/ldap_client.h"
#include "lib/cmdline/popt_common.h"
+#include "auth/auth.h"
struct ildb_private {
struct ldap_connection *ldap;
- NTSTATUS last_rc;
struct ldb_message *rootDSE;
+ struct ldb_context *ldb;
};
+
+/*
+ map an ildap NTSTATUS to a ldb error code
+*/
+static int ildb_map_error(struct ildb_private *ildb, NTSTATUS status)
+{
+ if (NT_STATUS_IS_OK(status)) {
+ return LDB_SUCCESS;
+ }
+ talloc_free(ildb->ldb->err_string);
+ ildb->ldb->err_string = talloc_strdup(ildb, ldap_errstr(ildb->ldap, status));
+ if (NT_STATUS_IS_LDAP(status)) {
+ return NT_STATUS_LDAP_CODE(status);
+ }
+ return LDB_ERR_OPERATIONS_ERROR;
+}
+
/*
rename a record
*/
int ret = 0;
char *old_dn;
char *newrdn, *parentdn;
+ NTSTATUS status;
/* ignore ltdb specials */
if (ldb_dn_is_special(olddn) || ldb_dn_is_special(newdn)) {
- return 0;
+ return LDB_SUCCESS;
}
local_ctx = talloc_named(ildb, 0, "ildb_rename local context");
if (local_ctx == NULL) {
- return -1;
+ ret = LDB_ERR_OPERATIONS_ERROR;
+ goto failed;
}
old_dn = ldb_dn_linearize(local_ctx, olddn);
if (old_dn == NULL) {
+ ret = LDB_ERR_INVALID_DN_SYNTAX;
goto failed;
}
newdn->components[0].name,
ldb_dn_escape_value(ildb, newdn->components[0].value));
if (newrdn == NULL) {
+ ret = LDB_ERR_OPERATIONS_ERROR;
goto failed;
}
parentdn = ldb_dn_linearize(local_ctx, ldb_dn_get_parent(ildb, newdn));
if (parentdn == NULL) {
+ ret = LDB_ERR_INVALID_DN_SYNTAX;
goto failed;
}
- ildb->last_rc = ildap_rename(ildb->ldap, old_dn, newrdn, parentdn, True);
- if (!NT_STATUS_IS_OK(ildb->last_rc)) {
- ret = -1;
- }
-
- talloc_free(local_ctx);
- return ret;
+ status = ildap_rename(ildb->ldap, old_dn, newrdn, parentdn, True);
+ ret = ildb_map_error(ildb, status);
failed:
talloc_free(local_ctx);
- return -1;
+ return ret;
}
/*
struct ildb_private *ildb = module->private_data;
char *del_dn;
int ret = 0;
+ NTSTATUS status;
/* ignore ltdb specials */
if (ldb_dn_is_special(dn)) {
- return 0;
+ return LDB_SUCCESS;
}
del_dn = ldb_dn_linearize(ildb, dn);
-
- ildb->last_rc = ildap_delete(ildb->ldap, del_dn);
- if (!NT_STATUS_IS_OK(ildb->last_rc)) {
- ret = -1;
+ if (del_dn == NULL) {
+ return LDB_ERR_INVALID_DN_SYNTAX;
}
+ status = ildap_delete(ildb->ldap, del_dn);
+ ret = ildb_map_error(ildb, status);
+
talloc_free(del_dn);
return ret;
static void ildb_rootdse(struct ldb_module *module);
/*
- search for matching records
+ search for matching records using a ldb_parse_tree
*/
-static int ildb_search(struct ldb_module *module, const struct ldb_dn *base,
- enum ldb_scope scope, const char *expression,
- const char * const *attrs, struct ldb_message ***res)
+static int ildb_search_bytree(struct ldb_module *module, const struct ldb_dn *base,
+ enum ldb_scope scope, struct ldb_parse_tree *tree,
+ const char * const *attrs, struct ldb_result **res)
{
struct ildb_private *ildb = module->private_data;
int count, i;
struct ldap_message **ldapres, *msg;
char *search_base;
+ NTSTATUS status;
if (scope == LDB_SCOPE_DEFAULT) {
scope = LDB_SCOPE_SUBTREE;
search_base = ldb_dn_linearize(ildb, base);
}
if (search_base == NULL) {
- return -1;
+ ldb_set_errstring(module, talloc_asprintf(module, "Unable to determine baseDN"));
+ return LDB_ERR_OTHER;
+ }
+ if (tree == NULL) {
+ ldb_set_errstring(module, talloc_asprintf(module, "Invalid expression parse tree"));
+ return LDB_ERR_OTHER;
}
- if (expression == NULL || expression[0] == '\0') {
- expression = "objectClass=*";
+ (*res) = talloc(ildb, struct ldb_result);
+ if (! *res) {
+ return LDB_ERR_OTHER;
}
+ (*res)->count = 0;
+ (*res)->msgs = NULL;
- ildb->last_rc = ildap_search(ildb->ldap, search_base, scope, expression, attrs,
- 0, &ldapres);
+ status = ildap_search_bytree(ildb->ldap, search_base, scope, tree, attrs,
+ 0, &ldapres);
talloc_free(search_base);
- if (!NT_STATUS_IS_OK(ildb->last_rc)) {
- return -1;
+ if (!NT_STATUS_IS_OK(status)) {
+ ildb_map_error(ildb, status);
+ return LDB_ERR_OTHER;
}
count = ildap_count_entries(ildb->ldap, ldapres);
- if (count == -1 || count == 0) {
+ if (count == -1) {
talloc_free(ldapres);
- return count;
+ return LDB_ERR_OTHER;
}
- (*res) = talloc_array(ildb, struct ldb_message *, count+1);
- if (! *res) {
+ if (count == 0) {
talloc_free(ldapres);
- return -1;
+ return LDB_SUCCESS;
+ }
+
+ (*res)->msgs = talloc_array(*res, struct ldb_message *, count + 1);
+ if (! (*res)->msgs) {
+ talloc_free(ldapres);
+ return LDB_ERR_OTHER;
}
- (*res)[0] = NULL;
+ (*res)->msgs[0] = NULL;
/* loop over all messages */
for (i=0;i<count;i++) {
msg = ldapres[i];
search = &msg->r.SearchResultEntry;
- (*res)[i] = talloc(*res, struct ldb_message);
- if (!(*res)[i]) {
+ (*res)->msgs[i] = talloc(*res, struct ldb_message);
+ if (!(*res)->msgs[i]) {
goto failed;
}
- (*res)[i+1] = NULL;
+ (*res)->msgs[i+1] = NULL;
- (*res)[i]->dn = ldb_dn_explode((*res)[i], search->dn);
- if ((*res)[i]->dn == NULL) {
+ (*res)->msgs[i]->dn = ldb_dn_explode((*res)->msgs[i], search->dn);
+ if ((*res)->msgs[i]->dn == NULL) {
goto failed;
}
- (*res)[i]->num_elements = search->num_attributes;
- (*res)[i]->elements = talloc_steal((*res)[i], search->attributes);
- (*res)[i]->private_data = NULL;
+ (*res)->msgs[i]->num_elements = search->num_attributes;
+ (*res)->msgs[i]->elements = talloc_steal((*res)->msgs[i], search->attributes);
+ (*res)->msgs[i]->private_data = NULL;
}
talloc_free(ldapres);
- return count;
+ (*res)->count = count;
+ return LDB_SUCCESS;
failed:
if (*res) talloc_free(*res);
- return -1;
-}
-
-
-/*
- search for matching records using a ldb_parse_tree
-*/
-static int ildb_search_bytree(struct ldb_module *module, const struct ldb_dn *base,
- enum ldb_scope scope, struct ldb_parse_tree *tree,
- const char * const *attrs, struct ldb_message ***res)
-{
- struct ildb_private *ildb = module->private_data;
- char *expression;
- int ret;
-
- expression = ldb_filter_from_tree(ildb, tree);
- if (expression == NULL) {
- return -1;
- }
- ret = ildb_search(module, base, scope, expression, attrs, res);
- talloc_free(expression);
- return ret;
+ return LDB_ERR_OTHER;
}
struct ldap_mod **mods;
char *dn;
int ret = 0;
+ NTSTATUS status;
/* ignore ltdb specials */
if (ldb_dn_is_special(msg->dn)) {
- return 0;
+ return LDB_SUCCESS;
}
mods = ildb_msg_to_mods(ldb, msg, 0);
if (mods == NULL) {
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
dn = ldb_dn_linearize(mods, msg->dn);
if (dn == NULL) {
talloc_free(mods);
- return -1;
+ return LDB_ERR_INVALID_DN_SYNTAX;
}
- ildb->last_rc = ildap_add(ildb->ldap, dn, mods);
- if (!NT_STATUS_IS_OK(ildb->last_rc)) {
- ret = -1;
- }
+ status = ildap_add(ildb->ldap, dn, mods);
+ ret = ildb_map_error(ildb, status);
talloc_free(mods);
struct ldap_mod **mods;
char *dn;
int ret = 0;
+ NTSTATUS status;
/* ignore ltdb specials */
if (ldb_dn_is_special(msg->dn)) {
- return 0;
+ return LDB_SUCCESS;
}
mods = ildb_msg_to_mods(ldb, msg, 1);
if (mods == NULL) {
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
dn = ldb_dn_linearize(mods, msg->dn);
if (dn == NULL) {
talloc_free(mods);
- return -1;
+ return LDB_ERR_INVALID_DN_SYNTAX;
}
- ildb->last_rc = ildap_modify(ildb->ldap, dn, mods);
- if (!NT_STATUS_IS_OK(ildb->last_rc)) {
- ret = -1;
- }
+ status = ildap_modify(ildb->ldap, dn, mods);
+ ret = ildb_map_error(ildb, status);
talloc_free(mods);
return ret;
}
-static int ildb_lock(struct ldb_module *module, const char *lockname)
+static int ildb_start_trans(struct ldb_module *module)
{
- int ret = 0;
-
- if (lockname == NULL) {
- return -1;
- }
-
/* TODO implement a local locking mechanism here */
- return ret;
+ return 0;
}
-static int ildb_unlock(struct ldb_module *module, const char *lockname)
+static int ildb_end_trans(struct ldb_module *module)
{
- int ret = 0;
+ /* TODO implement a local transaction mechanism here */
- if (lockname == NULL) {
- return -1;
- }
+ return 0;
+}
- /* TODO implement a local unlocking mechanism here */
+static int ildb_del_trans(struct ldb_module *module)
+{
+ /* TODO implement a local locking mechanism here */
- return ret;
+ return 0;
}
-/*
- return extended error information
-*/
-static const char *ildb_errstring(struct ldb_module *module)
+static int ildb_request(struct ldb_module *module, struct ldb_request *req)
{
- struct ildb_private *ildb = talloc_get_type(module->private_data,
- struct ildb_private);
- if (ildb == NULL) {
- return "ildap not connected";
+ switch (req->operation) {
+
+ case LDB_REQ_SEARCH:
+ return ildb_search_bytree(module,
+ req->op.search.base,
+ req->op.search.scope,
+ req->op.search.tree,
+ req->op.search.attrs,
+ &req->op.search.res);
+
+ case LDB_REQ_ADD:
+ return ildb_add(module, req->op.add.message);
+
+ case LDB_REQ_MODIFY:
+ return ildb_modify(module, req->op.mod.message);
+
+ case LDB_REQ_DELETE:
+ return ildb_delete(module, req->op.del.dn);
+
+ case LDB_REQ_RENAME:
+ return ildb_rename(module,
+ req->op.rename.olddn,
+ req->op.rename.newdn);
+
+ default:
+ return -1;
+
}
- return ldap_errstr(ildb->ldap, ildb->last_rc);
}
-
static const struct ldb_module_ops ildb_ops = {
- .name = "ldap",
- .search = ildb_search,
- .search_bytree = ildb_search_bytree,
- .add_record = ildb_add,
- .modify_record = ildb_modify,
- .delete_record = ildb_delete,
- .rename_record = ildb_rename,
- .named_lock = ildb_lock,
- .named_unlock = ildb_unlock,
- .errstring = ildb_errstring
+ .name = "ldap",
+ .request = ildb_request,
+ .start_transaction = ildb_start_trans,
+ .end_transaction = ildb_end_trans,
+ .del_transaction = ildb_del_trans
};
static void ildb_rootdse(struct ldb_module *module)
{
struct ildb_private *ildb = module->private_data;
- struct ldb_message **res = NULL;
+ struct ldb_result *res = NULL;
struct ldb_dn *empty_dn = ldb_dn_new(ildb);
int ret;
- ret = ildb_search(module, empty_dn, LDB_SCOPE_BASE, "dn=dc=rootDSE", NULL, &res);
- if (ret == 1) {
- ildb->rootDSE = talloc_steal(ildb, res[0]);
+ ret = ildb_search_bytree(module, empty_dn, LDB_SCOPE_BASE,
+ ldb_parse_tree(empty_dn, "dn=dc=rootDSE"),
+ NULL, &res);
+ if (ret == LDB_SUCCESS && res->count == 1) {
+ ildb->rootDSE = talloc_steal(ildb, res->msgs[0]);
}
- if (ret != -1) talloc_free(res);
+ if (ret == LDB_SUCCESS) talloc_free(res);
talloc_free(empty_dn);
}
{
struct ildb_private *ildb = NULL;
NTSTATUS status;
+ struct cli_credentials *creds;
ildb = talloc(ldb, struct ildb_private);
if (!ildb) {
}
ildb->rootDSE = NULL;
+ ildb->ldb = ldb;
ildb->ldap = ldap_new_connection(ildb, ldb_get_opaque(ldb, "EventContext"));
if (!ildb->ldap) {
ldb->modules->private_data = ildb;
ldb->modules->ops = &ildb_ops;
- if (cmdline_credentials != NULL && cli_credentials_authentication_requested(cmdline_credentials)) {
- status = ldap_bind_sasl(ildb->ldap, cmdline_credentials);
+ /* caller can optionally setup credentials using the opaque token 'credentials' */
+ creds = talloc_get_type(ldb_get_opaque(ldb, "credentials"), struct cli_credentials);
+ if (creds == NULL) {
+ struct auth_session_info *session_info = talloc_get_type(ldb_get_opaque(ldb, "sessionInfo"), struct auth_session_info);
+ if (session_info && session_info->credentials) {
+ creds = session_info->credentials;
+ } else {
+ creds = cmdline_credentials;
+ }
+ }
+
+ if (creds != NULL && cli_credentials_authentication_requested(creds)) {
+ status = ldap_bind_sasl(ildb->ldap, creds);
if (!NT_STATUS_IS_OK(status)) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s\n",
ldap_errstr(ildb->ldap, status));