1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-12 09:18:10 +03:00

r7418: work in progress

(This used to be commit 2a13e7655b)
This commit is contained in:
Derrell Lipman 2005-06-09 02:47:26 +00:00 committed by Gerald (Jerry) Carter
parent 322f0df3f1
commit a6717fae68
5 changed files with 184 additions and 99 deletions

View File

@ -30,82 +30,67 @@
} while(0)
/*
* Forward declarations
*/
static char
octet_from_hex(char * p,
char * ret)
{
unsigned char low_char;
unsigned char high_char;
unsigned char low_binary;
unsigned char high_binary;
if (p[0] == '\0' || p[1] == '\0') {
return -1;
}
high_char = p[0];
low_char = p[1];
if (high_char >= '0' && high_char <= '9') {
high_binary = high_char - '0';
} else if (high_char >= 'A' && high_char <= 'F') {
high_binary = 10 + (high_char - 'A');
} else if (high_char >= 'a' && high_char <= 'f') {
high_binary = 10 + (high_char - 'a');
} else {
return -1;
}
if (low_char >= '0' && low_char <= '9') {
low_binary = low_char - '0';
} else if (low_char >= 'A' && low_char <= 'F') {
low_binary = 10 + (low_char - 'A');
} else if (low_char >= 'a' && low_char <= 'f') {
low_binary = 10 + (low_char - 'a');
} else {
return -1;
}
*ret = (char) ((high_binary << 4) | low_binary);
return 0;
}
char * ret);
static char *
parse_slash(char *p,
char *end)
{
switch (*(p + 1)) {
case ',':
case '=':
case '\n':
case '+':
case '<':
case '>':
case '#':
case ';':
case '\\':
case '"':
memmove(p, p + 1, end - (p + 1));
return (end - 1);
char *end);
default:
if (*(p + 1) != '\0' && *(p + 2) != '\0') {
if (octet_from_hex(p + 1, p) < 0) {
return NULL;
}
memmove(p + 1, p + 3, end - (p + 3));
return (end - 2);
} else {
return NULL;
}
}
}
/*
* Public functions
*/
/*
* ldb_explode_dn()
*
* Explode, normalize, and optionally case-fold a DN string. The result is a
* structure containing arrays of the constituent RDNs.
*
* Parameters:
* mem_ctx -
* talloc context on which all allocated memory is hung
*
* orig_dn -
* The distinguished name, in string format, to be exploded
*
* hUserData -
* Data handle provided by the caller, and passed back to the caller in
* the case_fold_attr_fn callback function. This handle is not otherwise
* used within this function.
*
* case_fold_attr_fn -
* Pointer to a callback function which will be called to determine if a
* particular attribute type (name) requires case-folding of its values.
* If this function pointer is non-null, then attribute names will always
* be case-folded. Additionally, the function pointed to by
* case_fold_attr_fn will be called with the data handle (hUserData) and
* an attribute name as its parameters, and should return TRUE or FALSE to
* indicate whether values of that attribute type should be case-folded.
*
* If case_fold_attr_fn is null, then neither attribute names nor
* attribute values will be case-folded.
*
* Returns:
* Upon success, an ldb_dn structure pointer is returned, containing the
* exploded DN.
*
* If memory could not be allocated or if the DN was improperly formatted,
* NULL is returned.
*/
struct ldb_dn *
ldb_explode_dn(void *mem_ctx,
const char *orig_dn)
ldb_explode_dn(void * mem_ctx,
const char * orig_dn,
void * hUserData,
int (*case_fold_attr_fn)(void * hUserData,
char * attr))
{
struct ldb_dn * dn;
struct ldb_dn_component * component;
@ -222,6 +207,14 @@ ldb_explode_dn(void *mem_ctx,
goto failed;
}
/* attribute names are always case-folded */
p = attribute->name;
if ((attribute->name =
ldb_casefold(attribute, p)) == NULL) {
goto failed;
}
talloc_free(p);
ldb_debug(mem_ctx,
LDB_DEBUG_TRACE,
"attribute name: [%s]\n", attribute->name);
@ -314,6 +307,19 @@ ldb_explode_dn(void *mem_ctx,
goto failed;
}
/* see if this attribute value needs case folding */
if (case_fold_attr_fn != NULL &&
(* case_fold_attr_fn)(hUserData,
attribute->name)) {
/* yup, case-fold it. */
p = attribute->value;
if ((attribute->value =
ldb_casefold(attribute, p)) == NULL) {
goto failed;
}
talloc_free(p);
}
ldb_debug(mem_ctx,
LDB_DEBUG_TRACE,
"attribute value: [%s]\n", attribute->value);
@ -460,3 +466,77 @@ failed:
ldb_debug(mem_ctx, LDB_DEBUG_TRACE, "Failed to parse %s\n", orig_dn);
return NULL;
}
static char
octet_from_hex(char * p,
char * ret)
{
unsigned char low_char;
unsigned char high_char;
unsigned char low_binary;
unsigned char high_binary;
if (p[0] == '\0' || p[1] == '\0') {
return -1;
}
high_char = p[0];
low_char = p[1];
if (high_char >= '0' && high_char <= '9') {
high_binary = high_char - '0';
} else if (high_char >= 'A' && high_char <= 'F') {
high_binary = 10 + (high_char - 'A');
} else if (high_char >= 'a' && high_char <= 'f') {
high_binary = 10 + (high_char - 'a');
} else {
return -1;
}
if (low_char >= '0' && low_char <= '9') {
low_binary = low_char - '0';
} else if (low_char >= 'A' && low_char <= 'F') {
low_binary = 10 + (low_char - 'A');
} else if (low_char >= 'a' && low_char <= 'f') {
low_binary = 10 + (low_char - 'a');
} else {
return -1;
}
*ret = (char) ((high_binary << 4) | low_binary);
return 0;
}
static char *
parse_slash(char *p,
char *end)
{
switch (*(p + 1)) {
case ',':
case '=':
case '\n':
case '+':
case '<':
case '>':
case '#':
case ';':
case '\\':
case '"':
memmove(p, p + 1, end - (p + 1));
return (end - 1);
default:
if (*(p + 1) != '\0' && *(p + 2) != '\0') {
if (octet_from_hex(p + 1, p) < 0) {
return NULL;
}
memmove(p + 1, p + 3, end - (p + 3));
return (end - 2);
} else {
return NULL;
}
}
}

View File

@ -41,10 +41,10 @@
TODO:
a simple case folding function - will be replaced by a UTF8 aware function later
*/
char *ldb_casefold(struct ldb_context *ldb, const char *s)
char *ldb_casefold(void *mem_ctx, const char *s)
{
int i;
char *ret = talloc_strdup(ldb, s);
char *ret = talloc_strdup(mem_ctx, s);
if (!s) {
errno = ENOMEM;
return NULL;

View File

@ -203,7 +203,7 @@ const char *ldb_errstring(struct ldb_context *ldb);
/*
casefold a string (should be UTF8, but at the moment it isn't)
*/
char *ldb_casefold(struct ldb_context *ldb, const char *s);
char *ldb_casefold(void *mem_ctx, const char *s);
/*
ldif manipulation functions

View File

@ -39,5 +39,8 @@ struct ldb_dn {
extern struct ldb_dn *
ldb_explode_dn(void *mem_ctx,
const char *orig_dn);
ldb_explode_dn(void * mem_ctx,
const char * orig_dn,
void * hUserData,
int (*case_fold_attr_fn)(void * hUserData,
char * attr));

View File

@ -37,6 +37,7 @@
#include "ldb/include/ldb.h"
#include "ldb/include/ldb_private.h"
#include "ldb/include/ldb_parse.h"
#include "ldb/include/ldb_explode_dn.h"
#include "ldb/ldb_sqlite3/ldb_sqlite3.h"
#ifndef FALSE
@ -172,9 +173,11 @@ lsqlite3_option_find(const struct lsqlite3_private *lsqlite3,
callback function used in call to ldb_dn_fold() for determining whether an
attribute type requires case folding.
*/
static int lsqlite3_case_fold_attr_required(struct ldb_module *module,
char *attr)
static int lsqlite3_case_fold_attr_required(void * hUserData,
char *attr)
{
// struct ldb_module * module = hUserData;
#warning "currently, all attributes require case folding"
return TRUE;
}
@ -184,9 +187,9 @@ static int lsqlite3_case_fold_attr_required(struct ldb_module *module,
* rename a record
*/
static int
lsqlite3_rename(struct ldb_module *module,
const char *olddn,
const char *newdn)
lsqlite3_rename(struct ldb_module * module,
const char * olddn,
const char * newdn)
{
/* ignore ltdb specials */
if (olddn[0] == '@' ||newdn[0] == '@') {
@ -478,7 +481,7 @@ lsqlite3_search(struct ldb_module * module,
{
int ret;
int bLoop;
long long eid;
long long eid = 0;
char * sql;
char * sql_constraints;
char * table_list;
@ -509,7 +512,7 @@ lsqlite3_search(struct ldb_module * module,
pTail,
-1,
&pStmt,
&pTail)) != SQLITE_OK) {
NULL)) != SQLITE_OK) {
ret = -1;
break;
}
@ -541,17 +544,24 @@ lsqlite3_search(struct ldb_module * module,
* Normal condition is only one time through loop. Loop is
* rerun in error conditions, via "continue", above.
*/
sqlite3_free(discard_const_p(char, pTail));
ret = 0;
bLoop = FALSE;
}
if (ret != 0) {
sqlite3_free(discard_const_p(char, pTail));
return -1;
}
/* Parse the filter expression into a tree we can work with */
if ((pTree = ldb_parse_tree(module->ldb, pExpression)) == NULL) {
sqlite3_free(discard_const_p(char, pTail));
return -1;
}
/* Allocate a temporary talloc context */
hTalloc = talloc_new(module);
hTalloc = talloc_new(module->ldb);
/* Move the parse tree to our temporary context */
talloc_steal(hTalloc, pTree);
@ -756,28 +766,20 @@ lsqlite3_new_dn(struct ldb_module * module,
char * pDN,
long long * pEID)
{
char * pName;
char * pValue;
struct ldb_dn * pExplodedDN;
struct ldb_context * ldb = module->ldb;
// struct lsqlite3_private * lsqlite3 = module->private_data;
/* Normalize the distinguished name */
pDN = ldb_dn_fold(module, pDN, lsqlite3_case_fold_attr_required);
/* Parse the DN into its constituent components */
#warning "this simple parse of DN ignores escaped '=' and ','. fix it."
while (pDN != NULL) {
pName = strsep(&pValue, "=");
if (pDN == NULL) {
/* Attribute name without value? Should not occur. */
return -1;
}
pValue = pName;
strsep(&pValue, "=");
#warning "*** lsqlite3_new_dn() not yet fully implemented ***"
/* Explode and normalize the DN */
if ((pExplodedDN =
ldb_explode_dn(ldb,
pDN,
ldb,
lsqlite3_case_fold_attr_required)) == NULL) {
return -1;
}
#warning "*** lsqlite3_new_dn() not yet fully implemented ***"
return -1;
}