⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ldb_ldap.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    ldb database library   Copyright (C) Andrew Tridgell  2004   Copyright (C) Simo Sorce       2006     ** NOTE! The following LGPL license applies to the ldb     ** library. This does NOT imply that all of Samba is released     ** under the LGPL      This library is free software; you can redistribute it and/or   modify it under the terms of the GNU Lesser General Public   License as published by the Free Software Foundation; either   version 3 of the License, or (at your option) any later version.   This library is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   Lesser General Public License for more details.   You should have received a copy of the GNU Lesser General Public   License along with this library; if not, see <http://www.gnu.org/licenses/>.*//* *  Name: ldb_ldap * *  Component: ldb ldap backend * *  Description: core files for LDAP backend * *  Author: Andrew Tridgell * *  Modifications: * *  - description: make the module use asyncronous calls *    date: Feb 2006 *    author: Simo Sorce */#include "ldb_includes.h"#define LDAP_DEPRECATED 1#include <ldap.h>struct lldb_private {	LDAP *ldap;	struct ldb_module *module;};struct lldb_context {	struct lldb_private *lldb;	struct ldb_handle *handle;	int msgid;	int timeout;	time_t starttime;	void *context;	int (*callback)(struct ldb_context *, void *, struct ldb_reply *);};static int lldb_ldap_to_ldb(int err) {	/* Ldap errors and ldb errors are defined to the same values */	return err;}static struct lldb_context *init_lldb_handle(struct lldb_private *lldb, struct ldb_request *req){	struct lldb_context *ac;	struct ldb_handle *h;	h = talloc_zero(req, struct ldb_handle);	if (h == NULL) {		ldb_set_errstring(lldb->module->ldb, "Out of Memory");		return NULL;	}	h->module = lldb->module;	ac = talloc(h, struct lldb_context);	if (ac == NULL) {		ldb_set_errstring(lldb->module->ldb, "Out of Memory");		talloc_free(h);		return NULL;	}	h->private_data = ac;	h->state = LDB_ASYNC_INIT;	h->status = LDB_SUCCESS;	ac->lldb = lldb;	ac->handle = h;	ac->context = req->context;	ac->callback = req->callback;	ac->timeout = req->timeout;	ac->starttime = req->starttime;	ac->msgid = 0;	req->handle = h;	return ac;}/*  convert a ldb_message structure to a list of LDAPMod structures  ready for ldap_add() or ldap_modify()*/static LDAPMod **lldb_msg_to_mods(void *mem_ctx, const struct ldb_message *msg, int use_flags){	LDAPMod **mods;	unsigned int i, j;	int num_mods = 0;	/* allocate maximum number of elements needed */	mods = talloc_array(mem_ctx, LDAPMod *, msg->num_elements+1);	if (!mods) {		errno = ENOMEM;		return NULL;	}	mods[0] = NULL;	for (i=0;i<msg->num_elements;i++) {		const struct ldb_message_element *el = &msg->elements[i];		mods[num_mods] = talloc(mods, LDAPMod);		if (!mods[num_mods]) {			goto failed;		}		mods[num_mods+1] = NULL;		mods[num_mods]->mod_op = LDAP_MOD_BVALUES;		if (use_flags) {			switch (el->flags & LDB_FLAG_MOD_MASK) {			case LDB_FLAG_MOD_ADD:				mods[num_mods]->mod_op |= LDAP_MOD_ADD;				break;			case LDB_FLAG_MOD_DELETE:				mods[num_mods]->mod_op |= LDAP_MOD_DELETE;				break;			case LDB_FLAG_MOD_REPLACE:				mods[num_mods]->mod_op |= LDAP_MOD_REPLACE;				break;			}		}		mods[num_mods]->mod_type = discard_const_p(char, el->name);		mods[num_mods]->mod_vals.modv_bvals = talloc_array(mods[num_mods], 								   struct berval *,								   1+el->num_values);		if (!mods[num_mods]->mod_vals.modv_bvals) {			goto failed;		}		for (j=0;j<el->num_values;j++) {			mods[num_mods]->mod_vals.modv_bvals[j] = talloc(mods[num_mods]->mod_vals.modv_bvals,									struct berval);			if (!mods[num_mods]->mod_vals.modv_bvals[j]) {				goto failed;			}			mods[num_mods]->mod_vals.modv_bvals[j]->bv_val = el->values[j].data;			mods[num_mods]->mod_vals.modv_bvals[j]->bv_len = el->values[j].length;		}		mods[num_mods]->mod_vals.modv_bvals[j] = NULL;		num_mods++;	}	return mods;failed:	talloc_free(mods);	return NULL;}/*  add a single set of ldap message values to a ldb_message*/static int lldb_add_msg_attr(struct ldb_context *ldb,			     struct ldb_message *msg, 			     const char *attr, struct berval **bval){	int count, i;	struct ldb_message_element *el;	count = ldap_count_values_len(bval);	if (count <= 0) {		return -1;	}	el = talloc_realloc(msg, msg->elements, struct ldb_message_element, 			      msg->num_elements + 1);	if (!el) {		errno = ENOMEM;		return -1;	}	msg->elements = el;	el = &msg->elements[msg->num_elements];	el->name = talloc_strdup(msg->elements, attr);	if (!el->name) {		errno = ENOMEM;		return -1;	}	el->flags = 0;	el->num_values = 0;	el->values = talloc_array(msg->elements, struct ldb_val, count);	if (!el->values) {		errno = ENOMEM;		return -1;	}	for (i=0;i<count;i++) {		/* we have to ensure this is null terminated so that		   ldb_msg_find_attr_as_string() can work */		el->values[i].data = talloc_size(el->values, bval[i]->bv_len+1);		if (!el->values[i].data) {			errno = ENOMEM;			return -1;		}		memcpy(el->values[i].data, bval[i]->bv_val, bval[i]->bv_len);		el->values[i].data[bval[i]->bv_len] = 0;		el->values[i].length = bval[i]->bv_len;		el->num_values++;	}	msg->num_elements++;	return 0;}/*  search for matching records*/static int lldb_search(struct ldb_module *module, struct ldb_request *req){	struct lldb_private *lldb = talloc_get_type(module->private_data, struct lldb_private);	struct lldb_context *lldb_ac;	struct timeval tv;	int ldap_scope;	char *search_base;	char *expression;	int ret;	if (!req->callback || !req->context) {		ldb_set_errstring(module->ldb, "Async interface called with NULL callback function or NULL context");		return LDB_ERR_OPERATIONS_ERROR;	}	if (req->op.search.tree == NULL) {		ldb_set_errstring(module->ldb, "Invalid expression parse tree");		return LDB_ERR_OPERATIONS_ERROR;	}	if (req->controls != NULL) {		ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls are not yet supported by ldb_ldap backend!\n");	}	lldb_ac = init_lldb_handle(lldb, req);	if (lldb_ac == NULL) {		return LDB_ERR_OPERATIONS_ERROR;	}	search_base = ldb_dn_alloc_linearized(lldb_ac, req->op.search.base);	if (req->op.search.base == NULL) {		search_base = talloc_strdup(lldb_ac, "");	}	if (search_base == NULL) {		return LDB_ERR_OPERATIONS_ERROR;	}	expression = ldb_filter_from_tree(lldb_ac, req->op.search.tree);	if (expression == NULL) {		return LDB_ERR_OPERATIONS_ERROR;	}	switch (req->op.search.scope) {	case LDB_SCOPE_BASE:		ldap_scope = LDAP_SCOPE_BASE;		break;	case LDB_SCOPE_ONELEVEL:		ldap_scope = LDAP_SCOPE_ONELEVEL;		break;	default:		ldap_scope = LDAP_SCOPE_SUBTREE;		break;	}	tv.tv_sec = req->timeout;	tv.tv_usec = 0;	ret = ldap_search_ext(lldb->ldap, search_base, ldap_scope, 			    expression, 			    discard_const_p(char *, req->op.search.attrs), 			    0,			    NULL,			    NULL,			    &tv,			    LDAP_NO_LIMIT,			    &lldb_ac->msgid);	if (ret != LDAP_SUCCESS) {		ldb_set_errstring(module->ldb, ldap_err2string(ret));	}	return lldb_ldap_to_ldb(ret);}/*  add a record*/static int lldb_add(struct ldb_module *module, struct ldb_request *req){	struct lldb_private *lldb = talloc_get_type(module->private_data, struct lldb_private);	struct lldb_context *lldb_ac;	LDAPMod **mods;	char *dn;	int ret;	/* ltdb specials should not reach this point */	if (ldb_dn_is_special(req->op.add.message->dn)) {		return LDB_ERR_INVALID_DN_SYNTAX;	}	lldb_ac = init_lldb_handle(lldb, req);	if (lldb_ac == NULL) {		return LDB_ERR_OPERATIONS_ERROR;	}	mods = lldb_msg_to_mods(lldb_ac, req->op.add.message, 0);	if (mods == NULL) {		return LDB_ERR_OPERATIONS_ERROR;	}	dn = ldb_dn_alloc_linearized(lldb_ac, req->op.add.message->dn);	if (dn == NULL) {		return LDB_ERR_OPERATIONS_ERROR;	}	ret = ldap_add_ext(lldb->ldap, dn, mods,			   NULL,			   NULL,			   &lldb_ac->msgid);	if (ret != LDAP_SUCCESS) {		ldb_set_errstring(module->ldb, ldap_err2string(ret));	}	return lldb_ldap_to_ldb(ret);}/*  modify a record*/static int lldb_modify(struct ldb_module *module, struct ldb_request *req){	struct lldb_private *lldb = talloc_get_type(module->private_data, struct lldb_private);	struct lldb_context *lldb_ac;	LDAPMod **mods;	char *dn;	int ret;	/* ltdb specials should not reach this point */	if (ldb_dn_is_special(req->op.mod.message->dn)) {		return LDB_ERR_INVALID_DN_SYNTAX;	}	lldb_ac = init_lldb_handle(lldb, req);	if (req->handle == NULL) {		return LDB_ERR_OPERATIONS_ERROR;	}	mods = lldb_msg_to_mods(lldb_ac, req->op.mod.message, 1);	if (mods == NULL) {		return LDB_ERR_OPERATIONS_ERROR;	}	dn = ldb_dn_alloc_linearized(lldb_ac, req->op.mod.message->dn);	if (dn == NULL) {		return LDB_ERR_OPERATIONS_ERROR;	}	ret = ldap_modify_ext(lldb->ldap, dn, mods,			      NULL,			      NULL,			      &lldb_ac->msgid);	if (ret != LDAP_SUCCESS) {		ldb_set_errstring(module->ldb, ldap_err2string(ret));	}	return lldb_ldap_to_ldb(ret);}/*  delete a record*/static int lldb_delete(struct ldb_module *module, struct ldb_request *req){	struct lldb_private *lldb = talloc_get_type(module->private_data, struct lldb_private);	struct lldb_context *lldb_ac;	char *dnstr;	int ret;		/* ltdb specials should not reach this point */	if (ldb_dn_is_special(req->op.del.dn)) {		return LDB_ERR_INVALID_DN_SYNTAX;	}	lldb_ac = init_lldb_handle(lldb, req);	if (lldb_ac == NULL) {		return LDB_ERR_OPERATIONS_ERROR;	}	dnstr = ldb_dn_alloc_linearized(lldb_ac, req->op.del.dn);	ret = ldap_delete_ext(lldb->ldap, dnstr,			      NULL,			      NULL,			      &lldb_ac->msgid);	if (ret != LDAP_SUCCESS) {		ldb_set_errstring(module->ldb, ldap_err2string(ret));	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -