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

📄 ldb_ildap.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    ldb database library - ildap backend   Copyright (C) Andrew Tridgell  2005   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_ildap * *  Component: ldb ildap backend * *  Description: This is a ldb backend for the internal ldap *  client library in Samba4. By using this backend we are *  independent of a system ldap library * *  Author: Andrew Tridgell * *  Modifications: * *  - description: make the module use asyncronous calls *    date: Feb 2006 *    author: Simo Sorce */#include "includes.h"#include "ldb_includes.h"#include "lib/events/events.h"#include "libcli/ldap/ldap.h"#include "libcli/ldap/ldap_client.h"#include "auth/auth.h"#include "auth/credentials/credentials.h"#include "param/param.h"struct ildb_private {	struct ldap_connection *ldap;	struct ldb_module *module;};struct ildb_context {	struct ildb_private *ildb;	struct ldb_handle *handle;	struct ldap_request *req;	void *context;	int (*callback)(struct ldb_context *, void *, struct ldb_reply *);};/*  convert a ldb_message structure to a list of ldap_mod structures  ready for ildap_add() or ildap_modify()*/static struct ldap_mod **ildb_msg_to_mods(void *mem_ctx, int *num_mods,					  const struct ldb_message *msg, int use_flags){	struct ldap_mod **mods;	unsigned int i;	int n = 0;	/* allocate maximum number of elements needed */	mods = talloc_array(mem_ctx, struct ldap_mod *, 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[n] = talloc(mods, struct ldap_mod);		if (!mods[n]) {			goto failed;		}		mods[n + 1] = NULL;		mods[n]->type = 0;		mods[n]->attrib = *el;		if (use_flags) {			switch (el->flags & LDB_FLAG_MOD_MASK) {			case LDB_FLAG_MOD_ADD:				mods[n]->type = LDAP_MODIFY_ADD;				break;			case LDB_FLAG_MOD_DELETE:				mods[n]->type = LDAP_MODIFY_DELETE;				break;			case LDB_FLAG_MOD_REPLACE:				mods[n]->type = LDAP_MODIFY_REPLACE;				break;			}		}		n++;	}	*num_mods = n;	return mods;failed:	talloc_free(mods);	return NULL;}/*  map an ildap NTSTATUS to a ldb error code*/static int ildb_map_error(struct ildb_private *ildb, NTSTATUS status){	TALLOC_CTX *mem_ctx = talloc_new(ildb);	if (NT_STATUS_IS_OK(status)) {		return LDB_SUCCESS;	}	if (!mem_ctx) {		ldb_oom(ildb->module->ldb);		return LDB_ERR_OPERATIONS_ERROR;	}	ldb_set_errstring(ildb->module->ldb, ldap_errstr(ildb->ldap, mem_ctx, status));	talloc_free(mem_ctx);	if (NT_STATUS_IS_LDAP(status)) {		return NT_STATUS_LDAP_CODE(status);	}	return LDB_ERR_OPERATIONS_ERROR;}static void ildb_request_timeout(struct event_context *ev, struct timed_event *te,				 struct timeval t, void *private_data){	struct ildb_context *ac = talloc_get_type(private_data, struct ildb_context);	struct ldb_handle *handle = ac->handle;	if (ac->req->state == LDAP_REQUEST_PENDING) {		DLIST_REMOVE(ac->req->conn->pending, ac->req);	}	handle->status = LDB_ERR_TIME_LIMIT_EXCEEDED;	return;}static void ildb_callback(struct ldap_request *req){	struct ildb_context *ac = talloc_get_type(req->async.private_data, struct ildb_context);	struct ldb_handle *handle = ac->handle;	struct ildb_private *ildb = ac->ildb;	NTSTATUS status;	int i;	handle->status = LDB_SUCCESS;	if (!NT_STATUS_IS_OK(req->status)) {		handle->status = ildb_map_error(ildb, req->status);		return;	}	if (req->num_replies < 1) {		handle->status = LDB_ERR_OPERATIONS_ERROR;		return;	} 			switch (req->type) {	case LDAP_TAG_ModifyRequest:		if (req->replies[0]->type != LDAP_TAG_ModifyResponse) {			handle->status = LDB_ERR_PROTOCOL_ERROR;			return;		}		status = ldap_check_response(req->conn, &req->replies[0]->r.GeneralResult);		handle->status = ildb_map_error(ildb, status);		if (ac->callback && handle->status == LDB_SUCCESS) {			/* FIXME: build a corresponding ares to pass on */			handle->status = ac->callback(ac->ildb->module->ldb, ac->context, NULL);		}		handle->state = LDB_ASYNC_DONE;		break;	case LDAP_TAG_AddRequest:		if (req->replies[0]->type != LDAP_TAG_AddResponse) {			handle->status = LDB_ERR_PROTOCOL_ERROR;			return;		}		status = ldap_check_response(req->conn, &req->replies[0]->r.GeneralResult);		handle->status = ildb_map_error(ildb, status);		if (ac->callback && handle->status == LDB_SUCCESS) {			/* FIXME: build a corresponding ares to pass on */			handle->status = ac->callback(ac->ildb->module->ldb, ac->context, NULL);		}		handle->state = LDB_ASYNC_DONE;		break;	case LDAP_TAG_DelRequest:		if (req->replies[0]->type != LDAP_TAG_DelResponse) {			handle->status = LDB_ERR_PROTOCOL_ERROR;			return;		}		status = ldap_check_response(req->conn, &req->replies[0]->r.GeneralResult);		handle->status = ildb_map_error(ildb, status);		if (ac->callback && handle->status == LDB_SUCCESS) {			/* FIXME: build a corresponding ares to pass on */			handle->status = ac->callback(ac->ildb->module->ldb, ac->context, NULL);		}		handle->state = LDB_ASYNC_DONE;		break;	case LDAP_TAG_ModifyDNRequest:		if (req->replies[0]->type != LDAP_TAG_ModifyDNResponse) {			handle->status = LDB_ERR_PROTOCOL_ERROR;			return;		}		status = ldap_check_response(req->conn, &req->replies[0]->r.GeneralResult);		handle->status = ildb_map_error(ildb, status);		if (ac->callback && handle->status == LDB_SUCCESS) {			/* FIXME: build a corresponding ares to pass on */			handle->status = ac->callback(ac->ildb->module->ldb, ac->context, NULL);		}		handle->state = LDB_ASYNC_DONE;		break;	case LDAP_TAG_SearchRequest:		/* loop over all messages */		for (i = 0; i < req->num_replies; i++) {			struct ldap_SearchResEntry *search;			struct ldb_reply *ares = NULL;			struct ldap_message *msg;			int ret;			ares = talloc_zero(ac, struct ldb_reply);			if (!ares) {				handle->status = LDB_ERR_OPERATIONS_ERROR;				return;			}			msg = req->replies[i];			switch (msg->type) {			case LDAP_TAG_SearchResultDone:				status = ldap_check_response(req->conn, &msg->r.GeneralResult);				if (!NT_STATUS_IS_OK(status)) {					handle->status = ildb_map_error(ildb, status);					return;				}								ares->controls = talloc_move(ares, &msg->controls);				if (msg->r.SearchResultDone.resultcode) {					if (msg->r.SearchResultDone.errormessage) {						ldb_set_errstring(ac->ildb->module->ldb, msg->r.SearchResultDone.errormessage);					}				}				handle->status = msg->r.SearchResultDone.resultcode;				handle->state = LDB_ASYNC_DONE;				ares->type = LDB_REPLY_DONE;				break;			case LDAP_TAG_SearchResultEntry:				ares->message = ldb_msg_new(ares);				if (!ares->message) {					handle->status = LDB_ERR_OPERATIONS_ERROR;					return;				}				search = &(msg->r.SearchResultEntry);						ares->message->dn = ldb_dn_new(ares->message, ac->ildb->module->ldb, search->dn);				if ( ! ldb_dn_validate(ares->message->dn)) {					handle->status = LDB_ERR_OPERATIONS_ERROR;					return;				}				ares->message->num_elements = search->num_attributes;				ares->message->elements = talloc_move(ares->message,								      &search->attributes);				handle->status = LDB_SUCCESS;				handle->state = LDB_ASYNC_PENDING;				ares->type = LDB_REPLY_ENTRY;				break;			case LDAP_TAG_SearchResultReference:				ares->referral = talloc_strdup(ares, msg->r.SearchResultReference.referral);								handle->status = LDB_SUCCESS;				handle->state = LDB_ASYNC_PENDING;				ares->type = LDB_REPLY_REFERRAL;				break;			default:				/* TAG not handled, fail ! */				handle->status = LDB_ERR_PROTOCOL_ERROR;				return;			}			ret = ac->callback(ac->ildb->module->ldb, ac->context, ares);			if (ret) {				handle->status = ret;			}		}		talloc_free(req->replies);		req->replies = NULL;		req->num_replies = 0;		break;			default:		handle->status = LDB_ERR_PROTOCOL_ERROR;		return;	}}static struct ildb_context *init_ildb_handle(struct ildb_private *ildb,					     struct ldb_request *req){	struct ildb_context *ildb_ac;	struct ldb_handle *h;	h = talloc_zero(req, struct ldb_handle);	if (h == NULL) {		ldb_set_errstring(ildb->module->ldb, "Out of Memory");		return NULL;	}	h->module = ildb->module;	ildb_ac = talloc(h, struct ildb_context);	if (ildb_ac == NULL) {		ldb_set_errstring(ildb->module->ldb, "Out of Memory");		talloc_free(h);		return NULL;	}	h->private_data = ildb_ac;	h->state = LDB_ASYNC_INIT;	h->status = LDB_SUCCESS;	ildb_ac->ildb = ildb;	ildb_ac->handle = h;	ildb_ac->context = req->context;	ildb_ac->callback = req->callback;	req->handle = h;	return ildb_ac;}static int ildb_request_send(struct ildb_private *ildb, struct ldap_message *msg, struct ldb_request *r){	struct ildb_context *ildb_ac = init_ildb_handle(ildb, r);	struct ldap_request *req;	if (!ildb_ac) {		return LDB_ERR_OPERATIONS_ERROR;			}	req = ldap_request_send(ildb->ldap, msg);	if (req == NULL) {		ldb_set_errstring(ildb->module->ldb, "async send request failed");		return LDB_ERR_OPERATIONS_ERROR;	}	ildb_ac->req = talloc_steal(ildb_ac, req);	if (!req->conn) {		ldb_set_errstring(ildb->module->ldb, "connection to remote LDAP server dropped?");		return LDB_ERR_OPERATIONS_ERROR;	}	talloc_free(req->time_event);	req->time_event = NULL;	if (r->timeout) {		req->time_event = event_add_timed(req->conn->event.event_ctx, ildb_ac, 						  timeval_current_ofs(r->timeout, 0),						  ildb_request_timeout, ildb_ac);	}	req->async.fn = ildb_callback;	req->async.private_data = ildb_ac;	return LDB_SUCCESS;}static int ildb_request_noop(struct ildb_private *ildb, struct ldb_request *req) {	struct ildb_context *ildb_ac = init_ildb_handle(ildb, req);	int ret = LDB_SUCCESS;	if (!ildb_ac) {		return LDB_ERR_OPERATIONS_ERROR;			}	if (ildb_ac->callback) {		ret = ildb_ac->callback(ildb->module->ldb, ildb_ac->context, NULL);	}	ildb_ac->handle->state = LDB_ASYNC_DONE;	return ret;}/*  search for matching records using an asynchronous function */static int ildb_search(struct ldb_module *module, struct ldb_request *req){	struct ildb_private *ildb = talloc_get_type(module->private_data, struct ildb_private);

⌨️ 快捷键说明

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