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

📄 ldb_sqlite3.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 4 页
字号:
/*    ldb database library      Copyright (C) Derrell Lipman  2005   Copyright (C) Simo Sorce 2005-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 * *  Component: ldb sqlite3 backend * *  Description: core files for SQLITE3 backend * *  Author: Derrell Lipman (based on Andrew Tridgell's LDAP backend) */#include "ldb_includes.h"#include <sqlite3.h>struct lsqlite3_private {	int trans_count;	char **options;        sqlite3 *sqlite;};struct lsql_context {	struct ldb_module *module;	/* search stuff */	long long current_eid;	const char * const * attrs;	struct ldb_reply *ares;	/* async stuff */	void *context;	int (*callback)(struct ldb_context *, void *, struct ldb_reply *);};static struct ldb_handle *init_handle(struct lsqlite3_private *lsqlite3,					struct ldb_module *module,					struct ldb_request *req){	struct lsql_context *ac;	struct ldb_handle *h;	h = talloc_zero(lsqlite3, struct ldb_handle);	if (h == NULL) {		ldb_set_errstring(module->ldb, "Out of Memory");		return NULL;	}	h->module = module;	ac = talloc(h, struct lsql_context);	if (ac == NULL) {		ldb_set_errstring(module->ldb, "Out of Memory");		talloc_free(h);		return NULL;	}	h->private_data = (void *)ac;	h->state = LDB_ASYNC_INIT;	h->status = LDB_SUCCESS;	ac->module = module;	ac->context = req->context;	ac->callback = req->callback;	return h;}/* * Macros used throughout */#ifndef FALSE# define FALSE  (0)# define TRUE   (! FALSE)#endif#define RESULT_ATTR_TABLE       "temp_result_attrs"//#define TEMPTAB                 /* for testing, create non-temporary table */#define TEMPTAB                 "TEMPORARY"/* * Static variables */sqlite3_stmt *  stmtGetEID = NULL;static char *lsqlite3_tprintf(TALLOC_CTX *mem_ctx, const char *fmt, ...){	char *str, *ret;	va_list ap;	va_start(ap, fmt);        str = sqlite3_vmprintf(fmt, ap);	va_end(ap);	if (str == NULL) return NULL;	ret = talloc_strdup(mem_ctx, str);	if (ret == NULL) {		sqlite3_free(str);		return NULL;	}	sqlite3_free(str);	return ret;}static char base160tab[161] = {        48 ,49 ,50 ,51 ,52 ,53 ,54 ,55 ,56 ,57 , /* 0-9 */        58 ,59 ,65 ,66 ,67 ,68 ,69 ,70 ,71 ,72 , /* : ; A-H */        73 ,74 ,75 ,76 ,77 ,78 ,79 ,80 ,81 ,82 , /* I-R */        83 ,84 ,85 ,86 ,87 ,88 ,89 ,90 ,97 ,98 , /* S-Z , a-b */        99 ,100,101,102,103,104,105,106,107,108, /* c-l */        109,110,111,112,113,114,115,116,117,118, /* m-v */        119,120,121,122,160,161,162,163,164,165, /* w-z, latin1 */        166,167,168,169,170,171,172,173,174,175, /* latin1 */        176,177,178,179,180,181,182,183,184,185, /* latin1 */        186,187,188,189,190,191,192,193,194,195, /* latin1 */        196,197,198,199,200,201,202,203,204,205, /* latin1 */        206,207,208,209,210,211,212,213,214,215, /* latin1 */        216,217,218,219,220,221,222,223,224,225, /* latin1 */        226,227,228,229,230,231,232,233,234,235, /* latin1 */        236,237,238,239,240,241,242,243,244,245, /* latin1 */        246,247,248,249,250,251,252,253,254,255, /* latin1 */        '\0'};/* * base160() * * Convert an unsigned long integer into a base160 representation of the * number. * * Parameters: *   val -- *     value to be converted * *   result -- *     character array, 5 bytes long, into which the base160 representation *     will be placed.  The result will be a four-digit representation of the *     number (with leading zeros prepended as necessary), and null *     terminated. * * Returns: *   Nothing */static voidbase160_sql(sqlite3_context * hContext,            int argc,            sqlite3_value ** argv){    int             i;    long long       val;    char            result[5];    val = sqlite3_value_int64(argv[0]);    for (i = 3; i >= 0; i--) {                result[i] = base160tab[val % 160];        val /= 160;    }    result[4] = '\0';    sqlite3_result_text(hContext, result, -1, SQLITE_TRANSIENT);}/* * base160next_sql() * * This function enhances sqlite by adding a "base160_next()" function which is * accessible via queries. * * Retrieve the next-greater number in the base160 sequence for the terminal * tree node (the last four digits).  Only one tree level (four digits) is * operated on. * * Input: *   A character string: either an empty string (in which case no operation is *   performed), or a string of base160 digits with a length of a multiple of *   four digits. * * Output: *   Upon return, the trailing four digits (one tree level) will have been *   incremented by 1. */static voidbase160next_sql(sqlite3_context * hContext,                int argc,                sqlite3_value ** argv){        int                         i;        int                         len;        char *             pTab;        char *             pBase160 = strdup((const char *)sqlite3_value_text(argv[0]));        char *             pStart = pBase160;        /*         * We need a minimum of four digits, and we will always get a multiple         * of four digits.         */        if (pBase160 != NULL &&            (len = strlen(pBase160)) >= 4 &&            len % 4 == 0) {                if (pBase160 == NULL) {                        sqlite3_result_null(hContext);                        return;                }                pBase160 += strlen(pBase160) - 1;                /* We only carry through four digits: one level in the tree */                for (i = 0; i < 4; i++) {                        /* What base160 value does this digit have? */                        pTab = strchr(base160tab, *pBase160);                        /* Is there a carry? */                        if (pTab < base160tab + sizeof(base160tab) - 1) {                                /*                                 * Nope.  Just increment this value and we're                                 * done.                                 */                                *pBase160 = *++pTab;                                break;                        } else {                                /*                                 * There's a carry.  This value gets                                 * base160tab[0], we decrement the buffer                                 * pointer to get the next higher-order digit,                                 * and continue in the loop.                                 */                                *pBase160-- = base160tab[0];                        }                }                sqlite3_result_text(hContext,                                    pStart,                                    strlen(pStart),                                    free);        } else {                sqlite3_result_value(hContext, argv[0]);                if (pBase160 != NULL) {                        free(pBase160);                }        }}static char *parsetree_to_sql(struct ldb_module *module,			      void *mem_ctx,			      const struct ldb_parse_tree *t){	const struct ldb_schema_attribute *a;	struct ldb_val value, subval;	char *wild_card_string;	char *child, *tmp;	char *ret = NULL;	char *attr;	int i;	switch(t->operation) {	case LDB_OP_AND:		tmp = parsetree_to_sql(module, mem_ctx, t->u.list.elements[0]);		if (tmp == NULL) return NULL;		for (i = 1; i < t->u.list.num_elements; i++) {			child = parsetree_to_sql(module, mem_ctx, t->u.list.elements[i]);			if (child == NULL) return NULL;			tmp = talloc_asprintf_append(tmp, " INTERSECT %s ", child);			if (tmp == NULL) return NULL;		}		ret = talloc_asprintf(mem_ctx, "SELECT * FROM ( %s )\n", tmp);		return ret;                	case LDB_OP_OR:		tmp = parsetree_to_sql(module, mem_ctx, t->u.list.elements[0]);		if (tmp == NULL) return NULL;		for (i = 1; i < t->u.list.num_elements; i++) {			child = parsetree_to_sql(module, mem_ctx, t->u.list.elements[i]);			if (child == NULL) return NULL;			tmp = talloc_asprintf_append(tmp, " UNION %s ", child);			if (tmp == NULL) return NULL;		}		return talloc_asprintf(mem_ctx, "SELECT * FROM ( %s ) ", tmp);	case LDB_OP_NOT:		child = parsetree_to_sql(module, mem_ctx, t->u.isnot.child);		if (child == NULL) return NULL;		return talloc_asprintf(mem_ctx,					"SELECT eid FROM ldb_entry "					"WHERE eid NOT IN ( %s ) ", child);	case LDB_OP_EQUALITY:		/*		 * For simple searches, we want to retrieve the list of EIDs that		 * match the criteria.		*/		attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr);		if (attr == NULL) return NULL;		a = ldb_schema_attribute_by_name(module->ldb, attr);		/* Get a canonicalised copy of the data */		a->syntax->canonicalise_fn(module->ldb, mem_ctx, &(t->u.equality.value), &value);		if (value.data == NULL) {			return NULL;		}		if (strcasecmp(t->u.equality.attr, "objectclass") == 0) {		/*		 * For object classes, we want to search for all objectclasses		 * that are subclasses as well.		*/			return lsqlite3_tprintf(mem_ctx,					"SELECT eid  FROM ldb_attribute_values\n"					"WHERE norm_attr_name = 'OBJECTCLASS' "					"AND norm_attr_value IN\n"					"  (SELECT class_name FROM ldb_object_classes\n"					"   WHERE tree_key GLOB\n"					"     (SELECT tree_key FROM ldb_object_classes\n"					"      WHERE class_name = '%q'\n"					"     ) || '*'\n"					"  )\n", value.data);		} else if (strcasecmp(t->u.equality.attr, "dn") == 0) {			/* DN query is a special ldb case */		 	const char *cdn = ldb_dn_get_casefold(						ldb_dn_new(mem_ctx, module->ldb,							      (const char *)value.data));			return lsqlite3_tprintf(mem_ctx,						"SELECT eid FROM ldb_entry "						"WHERE norm_dn = '%q'", cdn);		} else {			/* A normal query. */			return lsqlite3_tprintf(mem_ctx,						"SELECT eid FROM ldb_attribute_values "						"WHERE norm_attr_name = '%q' "						"AND norm_attr_value = '%q'",						attr,						value.data);		}	case LDB_OP_SUBSTRING:		wild_card_string = talloc_strdup(mem_ctx,					(t->u.substring.start_with_wildcard)?"*":"");		if (wild_card_string == NULL) return NULL;		for (i = 0; t->u.substring.chunks[i]; i++) {			wild_card_string = talloc_asprintf_append(wild_card_string, "%s*",							t->u.substring.chunks[i]->data);			if (wild_card_string == NULL) return NULL;		}		if ( ! t->u.substring.end_with_wildcard ) {			/* remove last wildcard */			wild_card_string[strlen(wild_card_string) - 1] = '\0';		}		attr = ldb_attr_casefold(mem_ctx, t->u.substring.attr);		if (attr == NULL) return NULL;		a = ldb_schema_attribute_by_name(module->ldb, attr);		subval.data = (void *)wild_card_string;		subval.length = strlen(wild_card_string) + 1;		/* Get a canonicalised copy of the data */		a->syntax->canonicalise_fn(module->ldb, mem_ctx, &(subval), &value);		if (value.data == NULL) {			return NULL;		}		return lsqlite3_tprintf(mem_ctx,					"SELECT eid FROM ldb_attribute_values "					"WHERE norm_attr_name = '%q' "					"AND norm_attr_value GLOB '%q'",					attr,					value.data);	case LDB_OP_GREATER:		attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr);		if (attr == NULL) return NULL;		a = ldb_schema_attribute_by_name(module->ldb, attr);		/* Get a canonicalised copy of the data */		a->syntax->canonicalise_fn(module->ldb, mem_ctx, &(t->u.equality.value), &value);		if (value.data == NULL) {			return NULL;		}		return lsqlite3_tprintf(mem_ctx,					"SELECT eid FROM ldb_attribute_values "					"WHERE norm_attr_name = '%q' "					"AND ldap_compare(norm_attr_value, '>=', '%q', '%q') ",					attr,					value.data,					attr);	case LDB_OP_LESS:		attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr);		if (attr == NULL) return NULL;		a = ldb_schema_attribute_by_name(module->ldb, attr);		/* Get a canonicalised copy of the data */		a->syntax->canonicalise_fn(module->ldb, mem_ctx, &(t->u.equality.value), &value);		if (value.data == NULL) {			return NULL;		}		return lsqlite3_tprintf(mem_ctx,					"SELECT eid FROM ldb_attribute_values "					"WHERE norm_attr_name = '%q' "					"AND ldap_compare(norm_attr_value, '<=', '%q', '%q') ",					attr,					value.data,					attr);	case LDB_OP_PRESENT:		if (strcasecmp(t->u.present.attr, "dn") == 0) {			return talloc_strdup(mem_ctx, "SELECT eid FROM ldb_entry");		}		attr = ldb_attr_casefold(mem_ctx, t->u.present.attr);		if (attr == NULL) return NULL;		return lsqlite3_tprintf(mem_ctx,					"SELECT eid FROM ldb_attribute_values "					"WHERE norm_attr_name = '%q' ",					attr);	case LDB_OP_APPROX:		attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr);

⌨️ 快捷键说明

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