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

📄 ldb_parse.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    ldb database library   Copyright (C) Andrew Tridgell  2004     ** 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 expression parsing * *  Description: parse LDAP-like search expressions * *  Author: Andrew Tridgell *//*  TODO:      - add RFC2254 binary string handling      - possibly add ~=, <= and >= handling      - expand the test suite      - add better parse error handling*/#include "ldb_includes.h"#include "system/locale.h"/*a filter is defined by:               <filter> ::= '(' <filtercomp> ')'               <filtercomp> ::= <and> | <or> | <not> | <simple>               <and> ::= '&' <filterlist>               <or> ::= '|' <filterlist>               <not> ::= '!' <filter>               <filterlist> ::= <filter> | <filter> <filterlist>               <simple> ::= <attributetype> <filtertype> <attributevalue>               <filtertype> ::= '=' | '~=' | '<=' | '>='*//*   decode a RFC2254 binary string representation of a buffer.   Used in LDAP filters.*/struct ldb_val ldb_binary_decode(void *mem_ctx, const char *str){	int i, j;	struct ldb_val ret;	int slen = str?strlen(str):0;	ret.data = (uint8_t *)talloc_size(mem_ctx, slen+1);	ret.length = 0;	if (ret.data == NULL) return ret;	for (i=j=0;i<slen;i++) {		if (str[i] == '\\') {			unsigned c;			if (sscanf(&str[i+1], "%02X", &c) != 1) {				talloc_free(ret.data);				memset(&ret, 0, sizeof(ret));				return ret;			}			((uint8_t *)ret.data)[j++] = c;			i += 2;		} else {			((uint8_t *)ret.data)[j++] = str[i];		}	}	ret.length = j;	((uint8_t *)ret.data)[j] = 0;	return ret;}/*   encode a blob as a RFC2254 binary string, escaping any   non-printable or '\' characters*/char *ldb_binary_encode(void *mem_ctx, struct ldb_val val){	int i;	char *ret;	int len = val.length;	unsigned char *buf = val.data;	for (i=0;i<val.length;i++) {		if (!isprint(buf[i]) || strchr(" *()\\&|!\"", buf[i])) {			len += 2;		}	}	ret = talloc_array(mem_ctx, char, len+1);	if (ret == NULL) return NULL;	len = 0;	for (i=0;i<val.length;i++) {		if (!isprint(buf[i]) || strchr(" *()\\&|!\"", buf[i])) {			snprintf(ret+len, 4, "\\%02X", buf[i]);			len += 3;		} else {			ret[len++] = buf[i];		}	}	ret[len] = 0;	return ret;	}/*   encode a string as a RFC2254 binary string, escaping any   non-printable or '\' characters.  This routine is suitable for use   in escaping user data in ldap filters.*/char *ldb_binary_encode_string(void *mem_ctx, const char *string){	struct ldb_val val;	val.data = discard_const_p(uint8_t, string);	val.length = strlen(string);	return ldb_binary_encode(mem_ctx, val);}/* find the first matching wildcard */static char *ldb_parse_find_wildcard(char *value){	while (*value) {		value = strpbrk(value, "\\*");		if (value == NULL) return NULL;		if (value[0] == '\\') {			if (value[1] == '\0') return NULL;			value += 2;			continue;		}		if (value[0] == '*') return value;	}	return NULL;}/* return a NULL terminated list of binary strings representing the value   chunks separated by wildcards that makes the value portion of the filter*/static struct ldb_val **ldb_wildcard_decode(void *mem_ctx, const char *string){	struct ldb_val **ret = NULL;	int val = 0;	char *wc, *str;	wc = talloc_strdup(mem_ctx, string);	if (wc == NULL) return NULL;	while (wc && *wc) {		str = wc;		wc = ldb_parse_find_wildcard(str);		if (wc && *wc) {			if (wc == str) {				wc++;				continue;			}			*wc = 0;			wc++;		}		ret = talloc_realloc(mem_ctx, ret, struct ldb_val *, val + 2);		if (ret == NULL) return NULL;		ret[val] = talloc(mem_ctx, struct ldb_val);		if (ret[val] == NULL) return NULL;		*(ret[val]) = ldb_binary_decode(mem_ctx, str);		if ((ret[val])->data == NULL) return NULL;		val++;	}	if (ret != NULL) {		ret[val] = NULL;	}	return ret;}static struct ldb_parse_tree *ldb_parse_filter(void *mem_ctx, const char **s);/*  parse an extended match  possible forms:        (attr:oid:=value)        (attr:dn:oid:=value)        (attr:dn:=value)        (:dn:oid:=value)  the ':dn' part sets the dnAttributes boolean if present  the oid sets the rule_id string  */static struct ldb_parse_tree *ldb_parse_extended(struct ldb_parse_tree *ret, 						 char *attr, char *value){	char *p1, *p2;	ret->operation = LDB_OP_EXTENDED;	ret->u.extended.value = ldb_binary_decode(ret, value);	if (ret->u.extended.value.data == NULL) goto failed;	p1 = strchr(attr, ':');	if (p1 == NULL) goto failed;	p2 = strchr(p1+1, ':');	*p1 = 0;	if (p2) *p2 = 0;	ret->u.extended.attr = attr;	if (strcmp(p1+1, "dn") == 0) {		ret->u.extended.dnAttributes = 1;		if (p2) {			ret->u.extended.rule_id = talloc_strdup(ret, p2+1);			if (ret->u.extended.rule_id == NULL) goto failed;		} else {			ret->u.extended.rule_id = NULL;		}	} else {		ret->u.extended.dnAttributes = 0;		ret->u.extended.rule_id = talloc_strdup(ret, p1+1);		if (ret->u.extended.rule_id == NULL) goto failed;	}	return ret;failed:	talloc_free(ret);	return NULL;}static enum ldb_parse_op ldb_parse_filtertype(void *mem_ctx, char **type, char **value, const char **s){	enum ldb_parse_op filter = 0;	char *name, *val, *k;	const char *p = *s;	const char *t, *t1;	/* retrieve attributetype name */	t = p;	if (*p == '@') { /* for internal attributes the first char can be @ */		p++;	}	while ((isascii(*p) && isalnum((unsigned char)*p)) || (*p == '-')) { /* attribute names can only be alphanums */		p++;	}	if (*p == ':') { /* but extended searches have : and . chars too */		p = strstr(p, ":=");		if (p == NULL) { /* malformed attribute name */			return 0;		}	}	t1 = p;	while (isspace((unsigned char)*p)) p++;	if (!strchr("=<>~:", *p)) {		return 0;	}	/* save name */	name = (char *)talloc_memdup(mem_ctx, t, t1 - t + 1);	if (name == NULL) return 0;	name[t1 - t] = '\0';	/* retrieve filtertype */	if (*p == '=') {		filter = LDB_OP_EQUALITY;	} else if (*(p + 1) == '=') {		switch (*p) {		case '<':			filter = LDB_OP_LESS;			p++;			break;		case '>':			filter = LDB_OP_GREATER;			p++;			break;		case '~':			filter = LDB_OP_APPROX;			p++;			break;		case ':':			filter = LDB_OP_EXTENDED;			p++;			break;		}	}	if (!filter) {		talloc_free(name);		return filter;	}	p++;	while (isspace((unsigned char)*p)) p++;	/* retieve value */	t = p;	while (*p && ((*p != ')') || ((*p == ')') && (*(p - 1) == '\\')))) p++;	val = (char *)talloc_memdup(mem_ctx, t, p - t + 1);	if (val == NULL) {		talloc_free(name);		return 0;	}	val[p - t] = '\0';	k = &(val[p - t]);	/* remove trailing spaces from value */	while ((k > val) && (isspace((unsigned char)*(k - 1)))) k--;	*k = '\0';	*type = name;	*value = val;	*s = p;	return filter;}/*  <simple> ::= <attributetype> <filtertype> <attributevalue>*/static struct ldb_parse_tree *ldb_parse_simple(void *mem_ctx, const char **s){	char *attr, *value;	struct ldb_parse_tree *ret;	enum ldb_parse_op filtertype;	ret = talloc(mem_ctx, struct ldb_parse_tree);	if (!ret) {		errno = ENOMEM;		return NULL;	}	filtertype = ldb_parse_filtertype(ret, &attr, &value, s);	if (!filtertype) {		talloc_free(ret);		return NULL;	}	switch (filtertype) {		case LDB_OP_PRESENT:			ret->operation = LDB_OP_PRESENT;			ret->u.present.attr = attr;			break;		case LDB_OP_EQUALITY:			if (strcmp(value, "*") == 0) {				ret->operation = LDB_OP_PRESENT;				ret->u.present.attr = attr;				break;			}			if (ldb_parse_find_wildcard(value) != NULL) {				ret->operation = LDB_OP_SUBSTRING;				ret->u.substring.attr = attr;				ret->u.substring.start_with_wildcard = 0;				ret->u.substring.end_with_wildcard = 0;				ret->u.substring.chunks = ldb_wildcard_decode(ret, value);				if (ret->u.substring.chunks == NULL){					talloc_free(ret);					return NULL;				}				if (value[0] == '*')					ret->u.substring.start_with_wildcard = 1;				if (value[strlen(value) - 1] == '*')					ret->u.substring.end_with_wildcard = 1;				talloc_free(value);				break;			}			ret->operation = LDB_OP_EQUALITY;			ret->u.equality.attr = attr;			ret->u.equality.value = ldb_binary_decode(ret, value);			if (ret->u.equality.value.data == NULL) {				talloc_free(ret);				return NULL;

⌨️ 快捷键说明

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