mirror of
https://github.com/samba-team/samba.git
synced 2025-09-18 09:44:19 +03:00
r8082: large rewite of ldb_dn.c
- we do not support multpiple attribute components anymore, makes code a lot easier
they will be readded later if we found out they are really used, so far my tests
show w2k3 do not handle them as well
- fix escaping issues, move component value to be in an ldb_val structure
still need to handle binary values case
- make cononicalize functions leak less memory by giving a specific memory context
- fix tests scripts so that test-ldap can start
- make test not delete databases on completion so that I can inspect them
(This used to be commit 624a73148d
)
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
2e419725b0
commit
1c5105065a
@@ -34,10 +34,10 @@
|
|||||||
/*
|
/*
|
||||||
default handler that just copies a ldb_val.
|
default handler that just copies a ldb_val.
|
||||||
*/
|
*/
|
||||||
int ldb_handler_copy(struct ldb_context *ldb,
|
int ldb_handler_copy(struct ldb_context *ldb, void *mem_ctx,
|
||||||
const struct ldb_val *in, struct ldb_val *out)
|
const struct ldb_val *in, struct ldb_val *out)
|
||||||
{
|
{
|
||||||
*out = ldb_val_dup(ldb, in);
|
*out = ldb_val_dup(mem_ctx, in);
|
||||||
if (out->data == NULL) {
|
if (out->data == NULL) {
|
||||||
ldb_oom(ldb);
|
ldb_oom(ldb);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -49,11 +49,11 @@ int ldb_handler_copy(struct ldb_context *ldb,
|
|||||||
a case folding copy handler, removing leading and trailing spaces and
|
a case folding copy handler, removing leading and trailing spaces and
|
||||||
multiple internal spaces
|
multiple internal spaces
|
||||||
*/
|
*/
|
||||||
static int ldb_handler_fold(struct ldb_context *ldb,
|
static int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx,
|
||||||
const struct ldb_val *in, struct ldb_val *out)
|
const struct ldb_val *in, struct ldb_val *out)
|
||||||
{
|
{
|
||||||
uint8_t *s1, *s2;
|
uint8_t *s1, *s2;
|
||||||
out->data = talloc_size(ldb, strlen(in->data)+1);
|
out->data = talloc_size(mem_ctx, strlen(in->data)+1);
|
||||||
if (out->data == NULL) {
|
if (out->data == NULL) {
|
||||||
ldb_oom(ldb);
|
ldb_oom(ldb);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -78,20 +78,20 @@ static int ldb_handler_fold(struct ldb_context *ldb,
|
|||||||
a case folding copy handler, removing leading and trailing spaces and
|
a case folding copy handler, removing leading and trailing spaces and
|
||||||
multiple internal spaces, and checking for wildcard characters
|
multiple internal spaces, and checking for wildcard characters
|
||||||
*/
|
*/
|
||||||
static int ldb_handler_fold_wildcard(struct ldb_context *ldb,
|
static int ldb_handler_fold_wildcard(struct ldb_context *ldb, void *mem_ctx,
|
||||||
const struct ldb_val *in, struct ldb_val *out)
|
const struct ldb_val *in, struct ldb_val *out)
|
||||||
{
|
{
|
||||||
if (strchr(in->data, '*')) {
|
if (strchr(in->data, '*')) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return ldb_handler_fold(ldb, in, out);
|
return ldb_handler_fold(ldb, mem_ctx, in, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
canonicalise a ldap Integer
|
canonicalise a ldap Integer
|
||||||
rfc2252 specifies it should be in decimal form
|
rfc2252 specifies it should be in decimal form
|
||||||
*/
|
*/
|
||||||
static int ldb_canonicalise_Integer(struct ldb_context *ldb,
|
static int ldb_canonicalise_Integer(struct ldb_context *ldb, void *mem_ctx,
|
||||||
const struct ldb_val *in, struct ldb_val *out)
|
const struct ldb_val *in, struct ldb_val *out)
|
||||||
{
|
{
|
||||||
char *end;
|
char *end;
|
||||||
@@ -99,7 +99,7 @@ static int ldb_canonicalise_Integer(struct ldb_context *ldb,
|
|||||||
if (*end != 0) {
|
if (*end != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
out->data = talloc_asprintf(ldb, "%lld", i);
|
out->data = talloc_asprintf(mem_ctx, "%lld", i);
|
||||||
if (out->data == NULL) {
|
if (out->data == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -110,7 +110,7 @@ static int ldb_canonicalise_Integer(struct ldb_context *ldb,
|
|||||||
/*
|
/*
|
||||||
compare two Integers
|
compare two Integers
|
||||||
*/
|
*/
|
||||||
static int ldb_comparison_Integer(struct ldb_context *ldb,
|
static int ldb_comparison_Integer(struct ldb_context *ldb, void *mem_ctx,
|
||||||
const struct ldb_val *v1, const struct ldb_val *v2)
|
const struct ldb_val *v1, const struct ldb_val *v2)
|
||||||
{
|
{
|
||||||
return strtoll(v1->data, NULL, 0) - strtoll(v2->data, NULL, 0);
|
return strtoll(v1->data, NULL, 0) - strtoll(v2->data, NULL, 0);
|
||||||
@@ -119,7 +119,7 @@ static int ldb_comparison_Integer(struct ldb_context *ldb,
|
|||||||
/*
|
/*
|
||||||
compare two binary blobs
|
compare two binary blobs
|
||||||
*/
|
*/
|
||||||
int ldb_comparison_binary(struct ldb_context *ldb,
|
int ldb_comparison_binary(struct ldb_context *ldb, void *mem_ctx,
|
||||||
const struct ldb_val *v1, const struct ldb_val *v2)
|
const struct ldb_val *v1, const struct ldb_val *v2)
|
||||||
{
|
{
|
||||||
if (v1->length != v2->length) {
|
if (v1->length != v2->length) {
|
||||||
@@ -133,7 +133,7 @@ int ldb_comparison_binary(struct ldb_context *ldb,
|
|||||||
and leading and trailing whitespace
|
and leading and trailing whitespace
|
||||||
see rfc2252 section 8.1
|
see rfc2252 section 8.1
|
||||||
*/
|
*/
|
||||||
static int ldb_comparison_fold(struct ldb_context *ldb,
|
static int ldb_comparison_fold(struct ldb_context *ldb, void *mem_ctx,
|
||||||
const struct ldb_val *v1, const struct ldb_val *v2)
|
const struct ldb_val *v1, const struct ldb_val *v2)
|
||||||
{
|
{
|
||||||
const char *s1=v1->data, *s2=v2->data;
|
const char *s1=v1->data, *s2=v2->data;
|
||||||
@@ -159,7 +159,8 @@ static int ldb_comparison_fold(struct ldb_context *ldb,
|
|||||||
see rfc2252 section 8.1
|
see rfc2252 section 8.1
|
||||||
handles wildcards
|
handles wildcards
|
||||||
*/
|
*/
|
||||||
static int ldb_comparison_fold_wildcard(struct ldb_context *ldb,
|
static int ldb_comparison_fold_wildcard(struct ldb_context *ldb,
|
||||||
|
void *mem_ctx,
|
||||||
const struct ldb_val *v1,
|
const struct ldb_val *v1,
|
||||||
const struct ldb_val *v2)
|
const struct ldb_val *v2)
|
||||||
{
|
{
|
||||||
@@ -187,40 +188,49 @@ static int ldb_comparison_fold_wildcard(struct ldb_context *ldb,
|
|||||||
/*
|
/*
|
||||||
canonicalise a attribute in DN format
|
canonicalise a attribute in DN format
|
||||||
*/
|
*/
|
||||||
static int ldb_canonicalise_dn(struct ldb_context *ldb,
|
static int ldb_canonicalise_dn(struct ldb_context *ldb, void *mem_ctx,
|
||||||
const struct ldb_val *in, struct ldb_val *out)
|
const struct ldb_val *in, struct ldb_val *out)
|
||||||
{
|
{
|
||||||
struct ldb_dn *dn2=NULL, *dn1 = ldb_dn_explode(ldb, in->data);
|
struct ldb_dn *dn1, *dn2;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
out->length = 0;
|
||||||
out->data = NULL;
|
out->data = NULL;
|
||||||
|
|
||||||
|
dn1 = ldb_dn_explode(mem_ctx, in->data);
|
||||||
if (dn1 == NULL) {
|
if (dn1 == NULL) {
|
||||||
goto failed;
|
return -1;
|
||||||
}
|
}
|
||||||
dn2 = ldb_dn_casefold(ldb, dn1);
|
dn2 = ldb_dn_casefold(ldb, dn1);
|
||||||
if (dn2 == NULL) goto failed;
|
if (dn2 == NULL) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
out->data = ldb_dn_linearize(ldb, dn2);
|
out->data = ldb_dn_linearize(mem_ctx, dn2);
|
||||||
if (out->data == NULL) goto failed;
|
if (out->data == NULL) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
out->length = strlen(out->data);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
done:
|
||||||
talloc_free(dn1);
|
talloc_free(dn1);
|
||||||
talloc_free(dn2);
|
talloc_free(dn2);
|
||||||
return 0;
|
|
||||||
|
|
||||||
failed:
|
return ret;
|
||||||
talloc_free(dn1);
|
|
||||||
talloc_free(dn2);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
compare two dns
|
compare two dns
|
||||||
*/
|
*/
|
||||||
static int ldb_comparison_dn(struct ldb_context *ldb,
|
static int ldb_comparison_dn(struct ldb_context *ldb, void *mem_ctx,
|
||||||
const struct ldb_val *v1, const struct ldb_val *v2)
|
const struct ldb_val *v1, const struct ldb_val *v2)
|
||||||
{
|
{
|
||||||
struct ldb_val cv1, cv2;
|
struct ldb_val cv1, cv2;
|
||||||
int ret;
|
int ret;
|
||||||
if (ldb_canonicalise_dn(ldb, v1, &cv1) != 0 ||
|
if (ldb_canonicalise_dn(ldb, mem_ctx, v1, &cv1) != 0 ||
|
||||||
ldb_canonicalise_dn(ldb, v2, &cv2) != 0) {
|
ldb_canonicalise_dn(ldb, mem_ctx, v2, &cv2) != 0) {
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
ret = strcmp(cv1.data, cv2.data);
|
ret = strcmp(cv1.data, cv2.data);
|
||||||
@@ -236,12 +246,12 @@ failed:
|
|||||||
/*
|
/*
|
||||||
compare two objectclasses, looking at subclasses
|
compare two objectclasses, looking at subclasses
|
||||||
*/
|
*/
|
||||||
static int ldb_comparison_objectclass(struct ldb_context *ldb,
|
static int ldb_comparison_objectclass(struct ldb_context *ldb, void *mem_ctx,
|
||||||
const struct ldb_val *v1, const struct ldb_val *v2)
|
const struct ldb_val *v1, const struct ldb_val *v2)
|
||||||
{
|
{
|
||||||
int ret, i;
|
int ret, i;
|
||||||
const char **subclasses;
|
const char **subclasses;
|
||||||
ret = ldb_comparison_fold(ldb, v1, v2);
|
ret = ldb_comparison_fold(ldb, mem_ctx, v1, v2);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -253,7 +263,7 @@ static int ldb_comparison_objectclass(struct ldb_context *ldb,
|
|||||||
struct ldb_val vs;
|
struct ldb_val vs;
|
||||||
vs.data = discard_const(subclasses[i]);
|
vs.data = discard_const(subclasses[i]);
|
||||||
vs.length = strlen(subclasses[i]);
|
vs.length = strlen(subclasses[i]);
|
||||||
if (ldb_comparison_objectclass(ldb, &vs, v2) == 0) {
|
if (ldb_comparison_objectclass(ldb, mem_ctx, &vs, v2) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -60,10 +60,16 @@ int ldb_set_attrib_handlers(struct ldb_context *ldb,
|
|||||||
default function for read/write/canonicalise
|
default function for read/write/canonicalise
|
||||||
*/
|
*/
|
||||||
static int ldb_default_copy(struct ldb_context *ldb,
|
static int ldb_default_copy(struct ldb_context *ldb,
|
||||||
|
void *mem_ctx,
|
||||||
const struct ldb_val *in,
|
const struct ldb_val *in,
|
||||||
struct ldb_val *out)
|
struct ldb_val *out)
|
||||||
{
|
{
|
||||||
*out = *in;
|
*out = ldb_val_dup(mem_ctx, in);
|
||||||
|
|
||||||
|
if (out->length == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,6 +77,7 @@ static int ldb_default_copy(struct ldb_context *ldb,
|
|||||||
default function for comparison
|
default function for comparison
|
||||||
*/
|
*/
|
||||||
static int ldb_default_cmp(struct ldb_context *ldb,
|
static int ldb_default_cmp(struct ldb_context *ldb,
|
||||||
|
void *mem_ctx,
|
||||||
const struct ldb_val *v1,
|
const struct ldb_val *v1,
|
||||||
const struct ldb_val *v2)
|
const struct ldb_val *v2)
|
||||||
{
|
{
|
||||||
|
@@ -37,63 +37,74 @@
|
|||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
#include "ldb/include/ldb.h"
|
#include "ldb/include/ldb.h"
|
||||||
#include "ldb/include/ldb_private.h"
|
#include "ldb/include/ldb_private.h"
|
||||||
#include "ldb/include/ldb_dn.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed
|
#define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed
|
||||||
|
|
||||||
static char *escape_string(void *mem_ctx, const char *src)
|
static char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
|
||||||
{
|
{
|
||||||
const char *p, *s;
|
const char *p, *s, *src;
|
||||||
char *d, *dst=NULL;
|
char *d, *dst;
|
||||||
|
int len;
|
||||||
|
|
||||||
LDB_DN_NULL_FAILED(src);
|
if (!value.length)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
p = s = src = (const char *)value.data;
|
||||||
|
len = value.length;
|
||||||
|
|
||||||
/* allocate destination string, it will be at most 3 times the source */
|
/* allocate destination string, it will be at most 3 times the source */
|
||||||
dst = d = talloc_array(mem_ctx, char, strlen(src) * 3 + 1);
|
dst = d = talloc_array(mem_ctx, char, len * 3 + 1);
|
||||||
LDB_DN_NULL_FAILED(dst);
|
LDB_DN_NULL_FAILED(dst);
|
||||||
|
|
||||||
p = s = src;
|
while (p - src < len) {
|
||||||
|
|
||||||
while (*p) {
|
|
||||||
p += strcspn(p, ",=\n+<>#;\\\"");
|
p += strcspn(p, ",=\n+<>#;\\\"");
|
||||||
if (*p == '\0') /* no special s found, all ok */
|
|
||||||
|
if (p - src == len) /* found no escapable chars */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (*p) { /* copy part of the string and escape */
|
memcpy(d, s, p - s); /* copy the part of the string before the stop */
|
||||||
memcpy(d, s, p - s);
|
d += (p - s); /* move to current position */
|
||||||
d += (p - s);
|
|
||||||
|
if (*p) { /* it is a normal escapable character */
|
||||||
*d++ = '\\';
|
*d++ = '\\';
|
||||||
*d++ = *p++;
|
*d++ = *p++;
|
||||||
s = p;
|
} else { /* we have a zero byte in the string */
|
||||||
|
strncpy(d, "\00", 3); /* escape the zero */
|
||||||
|
d = d + 3;
|
||||||
|
p++; /* skip the zero */
|
||||||
}
|
}
|
||||||
|
s = p; /* move forward */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy the last part (with zero) and return */
|
/* copy the last part (with zero) and return */
|
||||||
memcpy(d, s, &src[strlen(src)] - s + 1);
|
memcpy(d, s, &src[len] - s + 1);
|
||||||
|
|
||||||
return dst;
|
return dst;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
talloc_free(dst);
|
talloc_free(dst);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *unescape_string(void *mem_ctx, const char *src)
|
static struct ldb_val ldb_dn_unescape_value(void *mem_ctx, const char *src)
|
||||||
{
|
{
|
||||||
|
struct ldb_val value;
|
||||||
unsigned x;
|
unsigned x;
|
||||||
char *p, *dst=NULL, *end;
|
char *p, *dst = NULL, *end;
|
||||||
|
|
||||||
|
value.length = 0;
|
||||||
|
|
||||||
LDB_DN_NULL_FAILED(src);
|
LDB_DN_NULL_FAILED(src);
|
||||||
|
|
||||||
dst = p = talloc_strdup(mem_ctx, src);
|
dst = p = talloc_memdup(mem_ctx, src, strlen(src) + 1);
|
||||||
LDB_DN_NULL_FAILED(dst);
|
LDB_DN_NULL_FAILED(dst);
|
||||||
|
|
||||||
end = &dst[strlen(dst)];
|
end = &dst[strlen(dst)];
|
||||||
|
|
||||||
while (*p) {
|
while (*p) {
|
||||||
p += strcspn(p, ",=\n+<>#;\\\"");
|
p += strcspn(p, ",=\n+<>#;\\\"");
|
||||||
if (*p == '\0') /* no escapes or specials found, all ok */
|
|
||||||
return dst;
|
|
||||||
|
|
||||||
if (*p == '\\') {
|
if (*p == '\\') {
|
||||||
if (strchr(",=\n+<>#;\\\"", p[1])) {
|
if (strchr(",=\n+<>#;\\\"", p[1])) {
|
||||||
@@ -112,31 +123,41 @@ static char *unescape_string(void *mem_ctx, const char *src)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* a string with not escaped specials is invalid */
|
/* a string with not escaped specials is invalid (tested) */
|
||||||
|
if (*p != '\0') {
|
||||||
return NULL;
|
goto failed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return dst;
|
value.length = end - dst;
|
||||||
|
value.data = dst;
|
||||||
|
return value;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
talloc_free(dst);
|
talloc_free(dst);
|
||||||
return NULL;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *seek_to_separator(char *string, const char *separator)
|
/* check if the string contains quotes
|
||||||
|
* skips leading and trailing spaces
|
||||||
|
* - returns 0 if no quotes found
|
||||||
|
* - returns 1 if quotes are found and put their position
|
||||||
|
* in *quote_start and *quote_end parameters
|
||||||
|
* - return -1 if there are open quotes
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int get_quotes_position(const char *source, int *quote_start, int *quote_end)
|
||||||
{
|
{
|
||||||
char *p;
|
const char *p;
|
||||||
|
|
||||||
p = strchr(string, '=');
|
p = source;
|
||||||
|
|
||||||
LDB_DN_NULL_FAILED(p);
|
|
||||||
|
|
||||||
p++;
|
|
||||||
|
|
||||||
/* check if there are quotes surrounding the value */
|
/* check if there are quotes surrounding the value */
|
||||||
p += strspn(p, " \n"); /* skip white spaces after '=' */
|
p += strspn(p, " \n"); /* skip white spaces */
|
||||||
|
|
||||||
if (*p == '\"') {
|
if (*p == '\"') {
|
||||||
|
*quote_start = p - source;
|
||||||
|
|
||||||
p++;
|
p++;
|
||||||
while (*p != '\"') {
|
while (*p != '\"') {
|
||||||
p = strchr(p, '\"');
|
p = strchr(p, '\"');
|
||||||
@@ -145,11 +166,50 @@ static char *seek_to_separator(char *string, const char *separator)
|
|||||||
if (*(p - 1) == '\\')
|
if (*(p - 1) == '\\')
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*quote_end = p - source;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
p += strcspn(p, separator);
|
return 0;
|
||||||
|
|
||||||
return p;
|
failed:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *seek_to_separator(char *string, const char *separators)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
int ret, qs, qe;
|
||||||
|
|
||||||
|
p = strchr(string, '=');
|
||||||
|
LDB_DN_NULL_FAILED(p);
|
||||||
|
|
||||||
|
p++;
|
||||||
|
|
||||||
|
/* check if there are quotes surrounding the value */
|
||||||
|
|
||||||
|
ret = get_quotes_position(p, &qs, &qe);
|
||||||
|
if (ret == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (ret == 1) { /* quotes found */
|
||||||
|
|
||||||
|
p += qe; /* positioning after quotes */
|
||||||
|
p += strspn(p, " \n"); /* skip white spaces after the quote */
|
||||||
|
|
||||||
|
if (strcspn(p, separators) != 0) /* if there are characters between quotes */
|
||||||
|
return NULL; /* and separators, the dn is invalid */
|
||||||
|
|
||||||
|
return p; /* return on the separator */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no quotes found seek to separators */
|
||||||
|
ret = strcspn(p, separators);
|
||||||
|
if (ret == 0) /* no separators ?! bail out */
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return p + ret;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -172,132 +232,53 @@ static char *ldb_dn_trim_string(char *string, const char *edge)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ldb_dn_attribute *ldb_dn_explode_attribute(void *mem_ctx, char *raw_attribute)
|
/* we choosed to not support multpile valued components */
|
||||||
|
static struct ldb_dn_component ldb_dn_explode_component(void *mem_ctx, char *raw_component)
|
||||||
{
|
{
|
||||||
struct ldb_dn_attribute *at;
|
struct ldb_dn_component dc;
|
||||||
char *p;
|
char *p;
|
||||||
|
int ret, qs, qe;
|
||||||
|
|
||||||
at = talloc(mem_ctx, struct ldb_dn_attribute);
|
/* find attribute type/value separator */
|
||||||
LDB_DN_NULL_FAILED(at);
|
p = strchr(raw_component, '=');
|
||||||
|
|
||||||
p = strchr(raw_attribute, '=');
|
|
||||||
|
|
||||||
LDB_DN_NULL_FAILED(p);
|
LDB_DN_NULL_FAILED(p);
|
||||||
|
|
||||||
*p = '\0';
|
*p++ = '\0'; /* terminate name and point to value */
|
||||||
|
|
||||||
at->name = talloc_strdup(at, ldb_dn_trim_string(raw_attribute, " \n"));
|
/* copy and trim name in the component */
|
||||||
LDB_DN_NULL_FAILED(at->name);
|
dc.name = talloc_strdup(mem_ctx, ldb_dn_trim_string(raw_component, " \n"));
|
||||||
|
if (!dc.name)
|
||||||
|
return dc;
|
||||||
|
|
||||||
p++;
|
ret = get_quotes_position(p, &qs, &qe);
|
||||||
|
|
||||||
p = ldb_dn_trim_string(p, " \n");
|
switch (ret) {
|
||||||
|
case 0: /* no quotes trim the string */
|
||||||
|
p = ldb_dn_trim_string(p, " \n");
|
||||||
|
dc.value = ldb_dn_unescape_value(mem_ctx, p);
|
||||||
|
break;
|
||||||
|
|
||||||
if (*p == '\"') { /* quotes at start means there must be quotes at the end */
|
case 1: /* quotes found get the unquoted string */
|
||||||
if (p[strlen(p) - 1] != '\"') /* malformed value */
|
p[qe] = '\0';
|
||||||
return NULL;
|
p = p + qs + 1;
|
||||||
|
dc.value.length = strlen(p);
|
||||||
p++;
|
dc.value.data = talloc_memdup(mem_ctx, p, dc.value.length + 1);
|
||||||
p[strlen(p) - 1] = '\0';
|
break;
|
||||||
at->value = talloc_strdup(at, p);
|
|
||||||
|
|
||||||
return at;
|
default: /* mismatched quotes ot other error, bail out */
|
||||||
|
goto failed;
|
||||||
}
|
}
|
||||||
/* no quotes means we must unescape the string */
|
|
||||||
at->value = unescape_string(at, p);
|
|
||||||
LDB_DN_NULL_FAILED(at->value);
|
|
||||||
|
|
||||||
return at;
|
if (dc.value.length == 0) {
|
||||||
|
goto failed;
|
||||||
failed:
|
}
|
||||||
talloc_free(at);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ldb_dn_component *explode_component(void *mem_ctx, char *raw_component)
|
|
||||||
{
|
|
||||||
struct ldb_dn_component *dc;
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
dc = talloc(mem_ctx, struct ldb_dn_component);
|
|
||||||
LDB_DN_NULL_FAILED(dc);
|
|
||||||
|
|
||||||
dc->attr_num = 0;
|
|
||||||
dc->attributes = NULL;
|
|
||||||
|
|
||||||
p = raw_component;
|
|
||||||
|
|
||||||
/* get the components */
|
|
||||||
do {
|
|
||||||
char *t;
|
|
||||||
|
|
||||||
/* terminate the current attribute and return pointer to the next one */
|
|
||||||
t = seek_to_separator(p, "+");
|
|
||||||
LDB_DN_NULL_FAILED(t);
|
|
||||||
|
|
||||||
if (*t) { /* here there is a separator */
|
|
||||||
*t = '\0'; /*terminate */
|
|
||||||
t++; /* a separtor means there's another attribute that follows */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocate attributes pointer */
|
|
||||||
dc->attributes = talloc_realloc(dc, dc->attributes,
|
|
||||||
struct ldb_dn_attribute *,
|
|
||||||
dc->attr_num + 1);
|
|
||||||
LDB_DN_NULL_FAILED(dc->attributes);
|
|
||||||
|
|
||||||
/* store the exploded attirbute in the main structure */
|
|
||||||
dc->attributes[dc->attr_num] = ldb_dn_explode_attribute(dc->attributes, p);
|
|
||||||
LDB_DN_NULL_FAILED(dc->attributes[dc->attr_num]);
|
|
||||||
|
|
||||||
dc->attr_num++;
|
|
||||||
|
|
||||||
/* jump to the next attribute if any */
|
|
||||||
p = t;
|
|
||||||
|
|
||||||
} while(*p);
|
|
||||||
|
|
||||||
return dc;
|
return dc;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
talloc_free(dc);
|
talloc_free(dc.name);
|
||||||
return NULL;
|
dc.name = NULL;
|
||||||
}
|
return dc;
|
||||||
|
|
||||||
/* FIXME: currently consider a dn composed of only case insensitive attributes
|
|
||||||
this is not correct and need to be fixed soon */
|
|
||||||
static void ldb_dn_sort_attributes(struct ldb_dn *edn)
|
|
||||||
{
|
|
||||||
struct ldb_dn_attribute *at0, *at1;
|
|
||||||
int i, j, k, l;
|
|
||||||
|
|
||||||
for (i = 0; i < edn->comp_num; i++) {
|
|
||||||
if (edn->components[i]->attr_num > 1) {
|
|
||||||
|
|
||||||
/* it is very unlikely that there is a multivalued RDN. In that
|
|
||||||
unlikely case it is very unlikely you will find more than 2
|
|
||||||
values. So the use of bubble sort here seem to be acceptable */
|
|
||||||
for (j = 0; (j + 1) < edn->components[i]->attr_num; j++) {
|
|
||||||
for (k = j; k >= 0; k--) {
|
|
||||||
at0 = edn->components[i]->attributes[k];
|
|
||||||
at1 = edn->components[i]->attributes[k + 1];
|
|
||||||
l = ldb_caseless_cmp(at0->name, at1->name);
|
|
||||||
if (l > 0) {
|
|
||||||
/* already sorted, so no bubbles to move exit inner loop */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (l == 0) {
|
|
||||||
if (ldb_caseless_cmp(at0->value, at1->value) >= 0) {
|
|
||||||
/* already sorted, so no bubbles to move exit inner loop */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
edn->components[i]->attributes[k] = at1;
|
|
||||||
edn->components[i]->attributes[k + 1] = at0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn)
|
struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn)
|
||||||
@@ -305,6 +286,8 @@ struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn)
|
|||||||
struct ldb_dn *edn; /* the exploded dn */
|
struct ldb_dn *edn; /* the exploded dn */
|
||||||
char *pdn, *p;
|
char *pdn, *p;
|
||||||
|
|
||||||
|
pdn = NULL;
|
||||||
|
|
||||||
/* Allocate a structure to hold the exploded DN */
|
/* Allocate a structure to hold the exploded DN */
|
||||||
edn = talloc(mem_ctx, struct ldb_dn);
|
edn = talloc(mem_ctx, struct ldb_dn);
|
||||||
LDB_DN_NULL_FAILED(edn);
|
LDB_DN_NULL_FAILED(edn);
|
||||||
@@ -314,8 +297,7 @@ struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn)
|
|||||||
edn->components = NULL;
|
edn->components = NULL;
|
||||||
|
|
||||||
pdn = p = talloc_strdup(edn, dn);
|
pdn = p = talloc_strdup(edn, dn);
|
||||||
if (!pdn)
|
LDB_DN_NULL_FAILED(pdn);
|
||||||
goto failed;
|
|
||||||
|
|
||||||
/* get the components */
|
/* get the components */
|
||||||
do {
|
do {
|
||||||
@@ -323,25 +305,23 @@ struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn)
|
|||||||
|
|
||||||
/* terminate the current component and return pointer to the next one */
|
/* terminate the current component and return pointer to the next one */
|
||||||
t = seek_to_separator(p, ",;");
|
t = seek_to_separator(p, ",;");
|
||||||
if (t == NULL)
|
LDB_DN_NULL_FAILED(t);
|
||||||
goto failed;
|
|
||||||
|
|
||||||
if (*t) { /* here there is a separator */
|
if (*t) { /* here there is a separator */
|
||||||
*t = '\0'; /*terminate */
|
*t = '\0'; /*terminate */
|
||||||
t++; /* a separtor means there's another component that follows */
|
t++; /* a separtor means another component follows */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate space to hold the dn component */
|
/* allocate space to hold the dn component */
|
||||||
edn->components = talloc_realloc(edn, edn->components,
|
edn->components = talloc_realloc(edn, edn->components,
|
||||||
struct ldb_dn_component *,
|
struct ldb_dn_component,
|
||||||
edn->comp_num + 1);
|
edn->comp_num + 1);
|
||||||
if (edn->components == NULL)
|
if (edn->components == NULL)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
/* store the exploded component in the main structure */
|
/* store the exploded component in the main structure */
|
||||||
edn->components[edn->comp_num] = explode_component(edn->components, p);
|
edn->components[edn->comp_num] = ldb_dn_explode_component(edn, p);
|
||||||
if (edn->components[edn->comp_num] == NULL)
|
LDB_DN_NULL_FAILED(edn->components[edn->comp_num].name);
|
||||||
goto failed;
|
|
||||||
|
|
||||||
edn->comp_num++;
|
edn->comp_num++;
|
||||||
|
|
||||||
@@ -350,87 +330,71 @@ struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn)
|
|||||||
|
|
||||||
} while(*p);
|
} while(*p);
|
||||||
|
|
||||||
/* sort attributes if there's any multivalued component */
|
|
||||||
ldb_dn_sort_attributes(edn);
|
|
||||||
|
|
||||||
talloc_free(pdn);
|
talloc_free(pdn);
|
||||||
return edn;
|
return edn;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
|
talloc_free(pdn);
|
||||||
talloc_free(edn);
|
talloc_free(edn);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *ldb_dn_linearize(void *mem_ctx, struct ldb_dn *edn)
|
char *ldb_dn_linearize(void *mem_ctx, const struct ldb_dn *edn)
|
||||||
{
|
{
|
||||||
char *dn, *ename, *evalue;
|
char *dn, *value;
|
||||||
const char *format;
|
const char *format = "%s=%s";
|
||||||
int i, j;
|
int i;
|
||||||
|
|
||||||
dn = talloc_strdup(mem_ctx, "");
|
dn = talloc_strdup(mem_ctx, "");
|
||||||
LDB_DN_NULL_FAILED(dn);
|
LDB_DN_NULL_FAILED(dn);
|
||||||
|
|
||||||
for (i = 0; i < edn->comp_num; i++) {
|
for (i = 0; i < edn->comp_num; i++) {
|
||||||
|
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
dn = talloc_append_string(mem_ctx, dn, ",");
|
format = ",%s=%s";
|
||||||
}
|
}
|
||||||
for (j = 0; j < edn->components[i]->attr_num; j++) {
|
|
||||||
if (j == 0) {
|
|
||||||
format = "%s=%s";
|
|
||||||
} else {
|
|
||||||
format = "+%s=%s";
|
|
||||||
}
|
|
||||||
|
|
||||||
ename = escape_string(dn, edn->components[i]->attributes[j]->name);
|
value = ldb_dn_escape_value(dn, edn->components[i].value);
|
||||||
LDB_DN_NULL_FAILED(ename);
|
LDB_DN_NULL_FAILED(value);
|
||||||
|
|
||||||
evalue = escape_string(dn, edn->components[i]->attributes[j]->value);
|
dn = talloc_asprintf_append(dn, format, edn->components[i].name, value);
|
||||||
LDB_DN_NULL_FAILED(evalue);
|
LDB_DN_NULL_FAILED(dn);
|
||||||
|
|
||||||
dn = talloc_asprintf_append(dn, format, ename, evalue);
|
talloc_free(value);
|
||||||
LDB_DN_NULL_FAILED(dn);
|
|
||||||
|
|
||||||
talloc_free(ename);
|
|
||||||
talloc_free(evalue);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return dn;
|
return dn;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
talloc_free(dn);
|
talloc_free(dn);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: currently consider a dn composed of only case insensitive attributes
|
/* compare DNs using casefolding compare functions */
|
||||||
this is not correct and need to be fixed soon */
|
int ldb_dn_compare(struct ldb_context *ldb, const struct ldb_dn *edn0, const struct ldb_dn *edn1)
|
||||||
int ldb_dn_compare(struct ldb_dn *edn0, struct ldb_dn *edn1)
|
|
||||||
{
|
{
|
||||||
struct ldb_dn_attribute *at0, *at1;
|
int i, ret;
|
||||||
int i, j, k;
|
|
||||||
|
|
||||||
/* if the number of components doesn't match they differ */
|
/* if the number of components doesn't match they differ */
|
||||||
if (edn0->comp_num != edn1->comp_num)
|
if (edn0->comp_num != edn1->comp_num)
|
||||||
return (edn1->comp_num - edn0->comp_num);
|
return (edn1->comp_num - edn0->comp_num);
|
||||||
|
|
||||||
for (i = 0; i < edn0->comp_num; i++) {
|
for (i = 0; i < edn0->comp_num; i++) {
|
||||||
|
const struct ldb_attrib_handler *h;
|
||||||
|
|
||||||
/* if the number of attributes per component doesn't match they differ */
|
/* compare names (attribute names are guaranteed to be ASCII only) */
|
||||||
if (edn0->components[i]->attr_num != edn1->components[i]->attr_num)
|
ret = ldb_caseless_cmp(edn0->components[i].name,
|
||||||
return (edn1->components[i]->attr_num - edn0->components[i]->attr_num);
|
edn1->components[i].name);
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
for (j = 0; j < edn0->components[i]->attr_num; j++) {
|
/* names match, compare values */
|
||||||
at0 = edn0->components[i]->attributes[j];
|
h = ldb_attrib_handler(ldb, edn0->components[i].name);
|
||||||
at1 = edn1->components[i]->attributes[j];
|
ret = h->comparison_fn(ldb, ldb, &(edn0->components[i].value),
|
||||||
|
&(edn1->components[i].value));
|
||||||
/* compare names */
|
if (ret) {
|
||||||
k = ldb_caseless_cmp(at0->name, at1->name);
|
return ret;
|
||||||
if (k)
|
|
||||||
return k;
|
|
||||||
|
|
||||||
/* names match, compare values */
|
|
||||||
k = ldb_caseless_cmp(at0->value, at1->value);
|
|
||||||
if (k)
|
|
||||||
return k;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,55 +402,31 @@ int ldb_dn_compare(struct ldb_dn *edn0, struct ldb_dn *edn1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
casefold a dn. We need to uppercase the attribute names, and the
|
casefold a dn. We need to casefold the attribute names, and canonicalize
|
||||||
attribute values of case insensitive attributes. We also need to remove
|
attribute values of case insensitive attributes.
|
||||||
extraneous spaces between elements
|
|
||||||
*/
|
*/
|
||||||
struct ldb_dn *ldb_dn_casefold(struct ldb_context *ldb, struct ldb_dn *edn)
|
struct ldb_dn *ldb_dn_casefold(struct ldb_context *ldb, const struct ldb_dn *edn)
|
||||||
{
|
{
|
||||||
struct ldb_dn *cedn;
|
struct ldb_dn *cedn;
|
||||||
int i, j;
|
int i;
|
||||||
|
|
||||||
cedn = talloc(ldb, struct ldb_dn);
|
cedn = talloc(ldb, struct ldb_dn);
|
||||||
LDB_DN_NULL_FAILED(cedn);
|
LDB_DN_NULL_FAILED(cedn);
|
||||||
|
|
||||||
cedn->comp_num = edn->comp_num;
|
cedn->comp_num = edn->comp_num;
|
||||||
cedn->components = talloc_array(cedn, struct ldb_dn_component *, edn->comp_num);
|
cedn->components = talloc_array(cedn, struct ldb_dn_component, edn->comp_num);
|
||||||
LDB_DN_NULL_FAILED(cedn->components);
|
LDB_DN_NULL_FAILED(cedn->components);
|
||||||
|
|
||||||
for (i = 0; i < edn->comp_num; i++) {
|
for (i = 0; i < edn->comp_num; i++) {
|
||||||
struct ldb_dn_component *dc;
|
struct ldb_dn_component dc;
|
||||||
|
const struct ldb_attrib_handler *h;
|
||||||
|
|
||||||
dc = talloc(cedn->components, struct ldb_dn_component);
|
dc.name = ldb_casefold(cedn, edn->components[i].name);
|
||||||
LDB_DN_NULL_FAILED(dc);
|
LDB_DN_NULL_FAILED(dc.name);
|
||||||
|
|
||||||
dc->attr_num = edn->components[i]->attr_num;
|
h = ldb_attrib_handler(ldb, dc.name);
|
||||||
dc->attributes = edn->components[i]->attributes;
|
if (h->canonicalise_fn(ldb, cedn, &(edn->components[i].value), &(dc.value)) != 0) {
|
||||||
LDB_DN_NULL_FAILED(dc->attributes);
|
goto failed;
|
||||||
|
|
||||||
for (j = 0; j < edn->components[i]->attr_num; j++) {
|
|
||||||
struct ldb_dn_attribute *at;
|
|
||||||
struct ldb_val v0, v;
|
|
||||||
const struct ldb_attrib_handler *h;
|
|
||||||
|
|
||||||
at = talloc(dc->attributes, struct ldb_dn_attribute);
|
|
||||||
LDB_DN_NULL_FAILED(at);
|
|
||||||
|
|
||||||
at->name = ldb_casefold(at, edn->components[i]->attributes[j]->name);
|
|
||||||
LDB_DN_NULL_FAILED(at->name);
|
|
||||||
|
|
||||||
h = ldb_attrib_handler(ldb, at->name);
|
|
||||||
/* at->value should be a ldb_val, work around
|
|
||||||
this for now .... */
|
|
||||||
v0.data = edn->components[i]->attributes[j]->value;
|
|
||||||
v0.length = strlen(v0.data);
|
|
||||||
if (h->canonicalise_fn(ldb, &v0, &v) != 0) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
talloc_steal(at, v.data);
|
|
||||||
at->value = v.data;
|
|
||||||
dc->attributes[j] = at;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cedn->components[i] = dc;
|
cedn->components[i] = dc;
|
||||||
|
@@ -317,7 +317,7 @@ int ldb_ldif_write(struct ldb_context *ldb,
|
|||||||
|
|
||||||
for (j=0;j<msg->elements[i].num_values;j++) {
|
for (j=0;j<msg->elements[i].num_values;j++) {
|
||||||
struct ldb_val v;
|
struct ldb_val v;
|
||||||
ret = h->ldif_write_fn(ldb, &msg->elements[i].values[j], &v);
|
ret = h->ldif_write_fn(ldb, ldb, &msg->elements[i].values[j], &v);
|
||||||
CHECK_RET;
|
CHECK_RET;
|
||||||
if (ldb_should_b64_encode(&v)) {
|
if (ldb_should_b64_encode(&v)) {
|
||||||
ret = fprintf_fn(private_data, "%s:: ",
|
ret = fprintf_fn(private_data, "%s:: ",
|
||||||
@@ -647,7 +647,7 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
|
|||||||
if (!el->values) {
|
if (!el->values) {
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
ret = h->ldif_read_fn(ldb, &value, &el->values[el->num_values]);
|
ret = h->ldif_read_fn(ldb, ldif, &value, &el->values[el->num_values]);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
@@ -671,7 +671,7 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
el->num_values = 1;
|
el->num_values = 1;
|
||||||
ret = h->ldif_read_fn(ldb, &value, &el->values[0]);
|
ret = h->ldif_read_fn(ldb, ldif, &value, &el->values[0]);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
@@ -120,7 +120,7 @@ static int ldb_match_leaf(struct ldb_context *ldb,
|
|||||||
h = ldb_attrib_handler(ldb, el->name);
|
h = ldb_attrib_handler(ldb, el->name);
|
||||||
|
|
||||||
for (i=0;i<el->num_values;i++) {
|
for (i=0;i<el->num_values;i++) {
|
||||||
if (h->comparison_fn(ldb, &tree->u.simple.value,
|
if (h->comparison_fn(ldb, ldb, &tree->u.simple.value,
|
||||||
&el->values[i]) == 0) {
|
&el->values[i]) == 0) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@@ -188,8 +188,8 @@ char *ldb_binary_encode(void *ctx, struct ldb_val val);
|
|||||||
/*
|
/*
|
||||||
functions for controlling attribute handling
|
functions for controlling attribute handling
|
||||||
*/
|
*/
|
||||||
typedef int (*ldb_attr_handler_t)(struct ldb_context *, const struct ldb_val *, struct ldb_val *);
|
typedef int (*ldb_attr_handler_t)(struct ldb_context *, void *mem_ctx, const struct ldb_val *, struct ldb_val *);
|
||||||
typedef int (*ldb_attr_comparison_t)(struct ldb_context *, const struct ldb_val *, const struct ldb_val *);
|
typedef int (*ldb_attr_comparison_t)(struct ldb_context *, void *mem_ctx, const struct ldb_val *, const struct ldb_val *);
|
||||||
|
|
||||||
struct ldb_attrib_handler {
|
struct ldb_attrib_handler {
|
||||||
const char *attr;
|
const char *attr;
|
||||||
|
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
Unix SMB/CIFS implementation.
|
|
||||||
LDAP server
|
|
||||||
Copyright (C) Simo Sorce 2004
|
|
||||||
Copyright (C) Derrell Lipman 2005
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program 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 General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct ldb_dn_attribute {
|
|
||||||
char *name;
|
|
||||||
char *value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ldb_dn_component {
|
|
||||||
int attr_num;
|
|
||||||
struct ldb_dn_attribute **attributes;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ldb_dn {
|
|
||||||
int comp_num;
|
|
||||||
struct ldb_dn_component **components;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn);
|
|
||||||
char *ldb_dn_linearize(void *mem_ctx, struct ldb_dn *edn);
|
|
||||||
int ldb_dn_compare(struct ldb_dn *edn0, struct ldb_dn *edn1);
|
|
||||||
struct ldb_dn *ldb_dn_casefold(struct ldb_context *ldb, struct ldb_dn *edn);
|
|
@@ -1,8 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
ldb database library
|
ldb database library
|
||||||
|
|
||||||
Copyright (C) Andrew Tridgell 2004
|
Copyright (C) Andrew Tridgell 2004
|
||||||
Copyright (C) Stefan Metzmacher 2004
|
Copyright (C) Stefan Metzmacher 2004
|
||||||
|
Copyright (C) Simo Sorce 2004
|
||||||
|
|
||||||
** NOTE! The following LGPL license applies to the ldb
|
** NOTE! The following LGPL license applies to the ldb
|
||||||
** library. This does NOT imply that all of Samba is released
|
** library. This does NOT imply that all of Samba is released
|
||||||
@@ -105,6 +106,16 @@ struct ldb_context {
|
|||||||
struct ldb_schema schema;
|
struct ldb_schema schema;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* internal ldb exploded dn structures */
|
||||||
|
struct ldb_dn_component {
|
||||||
|
char *name;
|
||||||
|
struct ldb_val value;
|
||||||
|
};
|
||||||
|
struct ldb_dn {
|
||||||
|
int comp_num;
|
||||||
|
struct ldb_dn_component *components;
|
||||||
|
};
|
||||||
|
|
||||||
/* the modules init function */
|
/* the modules init function */
|
||||||
typedef struct ldb_module *(*ldb_module_init_function)(struct ldb_context *ldb, const char *options[]);
|
typedef struct ldb_module *(*ldb_module_init_function)(struct ldb_context *ldb, const char *options[]);
|
||||||
|
|
||||||
@@ -178,17 +189,22 @@ int ldb_set_attrib_handlers(struct ldb_context *ldb,
|
|||||||
unsigned num_handlers);
|
unsigned num_handlers);
|
||||||
int ldb_setup_wellknown_attributes(struct ldb_context *ldb);
|
int ldb_setup_wellknown_attributes(struct ldb_context *ldb);
|
||||||
|
|
||||||
|
|
||||||
|
/* The following definitions come from lib/ldb/common/ldb_dn.c */
|
||||||
struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn);
|
struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn);
|
||||||
char *ldb_dn_linearize(void *mem_ctx, struct ldb_dn *edn);
|
char *ldb_dn_linearize(void *mem_ctx, const struct ldb_dn *edn);
|
||||||
int ldb_dn_compare(struct ldb_dn *edn0, struct ldb_dn *edn1);
|
int ldb_dn_compare(struct ldb_context *ldb, const struct ldb_dn *edn0, const struct ldb_dn *edn1);
|
||||||
struct ldb_dn *ldb_dn_casefold(struct ldb_context *ldb, struct ldb_dn *edn);
|
struct ldb_dn *ldb_dn_casefold(struct ldb_context *ldb, const struct ldb_dn *edn);
|
||||||
|
|
||||||
|
|
||||||
|
/* The following definitions come from lib/ldb/common/ldb_attributes.c */
|
||||||
const char **ldb_subclass_list(struct ldb_context *ldb, const char *class);
|
const char **ldb_subclass_list(struct ldb_context *ldb, const char *class);
|
||||||
void ldb_subclass_remove(struct ldb_context *ldb, const char *class);
|
void ldb_subclass_remove(struct ldb_context *ldb, const char *class);
|
||||||
int ldb_subclass_add(struct ldb_context *ldb, const char *class, const char *subclass);
|
int ldb_subclass_add(struct ldb_context *ldb, const char *class, const char *subclass);
|
||||||
|
|
||||||
int ldb_handler_copy(struct ldb_context *ldb,
|
int ldb_handler_copy(struct ldb_context *ldb, void *mem_ctx,
|
||||||
const struct ldb_val *in, struct ldb_val *out);
|
const struct ldb_val *in, struct ldb_val *out);
|
||||||
int ldb_comparison_binary(struct ldb_context *ldb,
|
int ldb_comparison_binary(struct ldb_context *ldb, void *mem_ctx,
|
||||||
const struct ldb_val *v1, const struct ldb_val *v2);
|
const struct ldb_val *v1, const struct ldb_val *v2);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -111,7 +111,7 @@ static char *ldb_dn_key(struct ldb_context *ldb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
h = ldb_attrib_handler(ldb, attr);
|
h = ldb_attrib_handler(ldb, attr);
|
||||||
if (h->canonicalise_fn(ldb, value, &v) != 0) {
|
if (h->canonicalise_fn(ldb, ldb, value, &v) != 0) {
|
||||||
/* canonicalisation can be refused. For example,
|
/* canonicalisation can be refused. For example,
|
||||||
a attribute that takes wildcards will refuse to canonicalise
|
a attribute that takes wildcards will refuse to canonicalise
|
||||||
if the value contains a wildcard */
|
if the value contains a wildcard */
|
||||||
|
@@ -38,7 +38,6 @@
|
|||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
#include "ldb/include/ldb.h"
|
#include "ldb/include/ldb.h"
|
||||||
#include "ldb/include/ldb_private.h"
|
#include "ldb/include/ldb_private.h"
|
||||||
#include "ldb/include/ldb_dn.h"
|
|
||||||
#include "ldb/ldb_tdb/ldb_tdb.h"
|
#include "ldb/ldb_tdb/ldb_tdb.h"
|
||||||
|
|
||||||
#define LDBLOCK "@INT_LDBLOCK"
|
#define LDBLOCK "@INT_LDBLOCK"
|
||||||
@@ -531,7 +530,7 @@ static int msg_delete_element(struct ldb_module *module,
|
|||||||
h = ldb_attrib_handler(ldb, el->name);
|
h = ldb_attrib_handler(ldb, el->name);
|
||||||
|
|
||||||
for (i=0;i<el->num_values;i++) {
|
for (i=0;i<el->num_values;i++) {
|
||||||
if (h->comparison_fn(ldb, &el->values[i], val) == 0) {
|
if (h->comparison_fn(ldb, ldb, &el->values[i], val) == 0) {
|
||||||
if (i<el->num_values-1) {
|
if (i<el->num_values-1) {
|
||||||
memmove(&el->values[i], &el->values[i+1],
|
memmove(&el->values[i], &el->values[i+1],
|
||||||
sizeof(el->values[i])*(el->num_values-(i+1)));
|
sizeof(el->values[i])*(el->num_values-(i+1)));
|
||||||
|
@@ -30,16 +30,16 @@
|
|||||||
/*
|
/*
|
||||||
convert a ldif formatted objectSid to a NDR formatted blob
|
convert a ldif formatted objectSid to a NDR formatted blob
|
||||||
*/
|
*/
|
||||||
static int ldif_read_objectSid(struct ldb_context *ldb, const struct ldb_val *in,
|
static int ldif_read_objectSid(struct ldb_context *ldb, void *mem_ctx,
|
||||||
struct ldb_val *out)
|
const struct ldb_val *in, struct ldb_val *out)
|
||||||
{
|
{
|
||||||
struct dom_sid *sid;
|
struct dom_sid *sid;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
sid = dom_sid_parse_talloc(ldb, in->data);
|
sid = dom_sid_parse_talloc(mem_ctx, in->data);
|
||||||
if (sid == NULL) {
|
if (sid == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
status = ndr_push_struct_blob(out, ldb, sid,
|
status = ndr_push_struct_blob(out, mem_ctx, sid,
|
||||||
(ndr_push_flags_fn_t)ndr_push_dom_sid);
|
(ndr_push_flags_fn_t)ndr_push_dom_sid);
|
||||||
talloc_free(sid);
|
talloc_free(sid);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
@@ -51,12 +51,12 @@ static int ldif_read_objectSid(struct ldb_context *ldb, const struct ldb_val *in
|
|||||||
/*
|
/*
|
||||||
convert a NDR formatted blob to a ldif formatted objectSid
|
convert a NDR formatted blob to a ldif formatted objectSid
|
||||||
*/
|
*/
|
||||||
static int ldif_write_objectSid(struct ldb_context *ldb, const struct ldb_val *in,
|
static int ldif_write_objectSid(struct ldb_context *ldb, void *mem_ctx,
|
||||||
struct ldb_val *out)
|
const struct ldb_val *in, struct ldb_val *out)
|
||||||
{
|
{
|
||||||
struct dom_sid *sid;
|
struct dom_sid *sid;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
sid = talloc(ldb, struct dom_sid);
|
sid = talloc(mem_ctx, struct dom_sid);
|
||||||
if (sid == NULL) {
|
if (sid == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ static int ldif_write_objectSid(struct ldb_context *ldb, const struct ldb_val *i
|
|||||||
talloc_free(sid);
|
talloc_free(sid);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
out->data = dom_sid_string(ldb, sid);
|
out->data = dom_sid_string(mem_ctx, sid);
|
||||||
talloc_free(sid);
|
talloc_free(sid);
|
||||||
if (out->data == NULL) {
|
if (out->data == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -78,7 +78,7 @@ static int ldif_write_objectSid(struct ldb_context *ldb, const struct ldb_val *i
|
|||||||
/*
|
/*
|
||||||
compare two objectSids
|
compare two objectSids
|
||||||
*/
|
*/
|
||||||
static int ldb_comparison_objectSid(struct ldb_context *ldb,
|
static int ldb_comparison_objectSid(struct ldb_context *ldb, void *mem_ctx,
|
||||||
const struct ldb_val *v1, const struct ldb_val *v2)
|
const struct ldb_val *v1, const struct ldb_val *v2)
|
||||||
{
|
{
|
||||||
if (strncmp(v1->data, "S-", 2) == 0 &&
|
if (strncmp(v1->data, "S-", 2) == 0 &&
|
||||||
@@ -88,26 +88,26 @@ static int ldb_comparison_objectSid(struct ldb_context *ldb,
|
|||||||
if (strncmp(v1->data, "S-", 2) == 0) {
|
if (strncmp(v1->data, "S-", 2) == 0) {
|
||||||
struct ldb_val v;
|
struct ldb_val v;
|
||||||
int ret;
|
int ret;
|
||||||
if (ldif_read_objectSid(ldb, v1, &v) != 0) {
|
if (ldif_read_objectSid(ldb, mem_ctx, v1, &v) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ret = ldb_comparison_binary(ldb, &v, v2);
|
ret = ldb_comparison_binary(ldb, mem_ctx, &v, v2);
|
||||||
talloc_free(v.data);
|
talloc_free(v.data);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return ldb_comparison_binary(ldb, v1, v2);
|
return ldb_comparison_binary(ldb, mem_ctx, v1, v2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
canonicalise a objectSid
|
canonicalise a objectSid
|
||||||
*/
|
*/
|
||||||
static int ldb_canonicalise_objectSid(struct ldb_context *ldb, const struct ldb_val *in,
|
static int ldb_canonicalise_objectSid(struct ldb_context *ldb, void *mem_ctx,
|
||||||
struct ldb_val *out)
|
const struct ldb_val *in, struct ldb_val *out)
|
||||||
{
|
{
|
||||||
if (strncmp(in->data, "S-", 2) == 0) {
|
if (strncmp(in->data, "S-", 2) == 0) {
|
||||||
return ldif_read_objectSid(ldb, in, out);
|
return ldif_read_objectSid(ldb, mem_ctx, in, out);
|
||||||
}
|
}
|
||||||
return ldb_handler_copy(ldb, in, out);
|
return ldb_handler_copy(ldb, mem_ctx, in, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
echo "Running extended search tests"
|
echo "Running extended search tests"
|
||||||
|
|
||||||
rm -f $LDB_URL
|
mv $LDB_URL $LDB_URL.1
|
||||||
|
|
||||||
cat <<EOF | bin/ldbadd || exit 1
|
cat <<EOF | bin/ldbadd || exit 1
|
||||||
dn: cn=testrec1,cn=TEST
|
dn: cn=testrec1,cn=TEST
|
||||||
@@ -67,4 +67,3 @@ checkcount 1 '(i1:1.2.840.113556.1.4.804:=8388608)'
|
|||||||
# this is one that w2k gives
|
# this is one that w2k gives
|
||||||
checkcount 3 '(|(|(&(!(groupType:1.2.840.113556.1.4.803:=1))(groupType:1.2.840.113556.1.4.803:=2147483648)(groupType:1.2.840.113556.1.4.804:=10))(samAccountType=805306368))(samAccountType=805306369))'
|
checkcount 3 '(|(|(&(!(groupType:1.2.840.113556.1.4.803:=1))(groupType:1.2.840.113556.1.4.803:=2147483648)(groupType:1.2.840.113556.1.4.804:=10))(samAccountType=805306368))(samAccountType=805306369))'
|
||||||
|
|
||||||
rm -f $LDB_URL
|
|
||||||
|
@@ -24,9 +24,17 @@ for f in $SCHEMA_NEEDED; do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
tests/init_slapd.sh
|
|
||||||
tests/start_slapd.sh
|
|
||||||
|
|
||||||
export LDB_URL=`tests/ldapi_url.sh`
|
export LDB_URL=`tests/ldapi_url.sh`
|
||||||
|
|
||||||
. tests/test-generic.sh
|
PATH=bin:$PATH
|
||||||
|
export PATH
|
||||||
|
|
||||||
|
if [ -z "$LDBDIR" ]; then
|
||||||
|
LDBDIR="."
|
||||||
|
export LDBDIR
|
||||||
|
fi
|
||||||
|
|
||||||
|
. $LDBDIR/tests/init_slapd.sh
|
||||||
|
. $LDBDIR/tests/start_slapd.sh
|
||||||
|
|
||||||
|
. $LDBDIR/tests/test-generic.sh
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
echo "Running tdb feature tests"
|
echo "Running tdb feature tests"
|
||||||
|
|
||||||
rm -f $LDB_URL
|
mv $LDB_URL $LDB_URL.2
|
||||||
|
|
||||||
checkcount() {
|
checkcount() {
|
||||||
count=$1
|
count=$1
|
||||||
@@ -128,4 +128,3 @@ checkcount 1 '(test=foo)'
|
|||||||
checkcount 0 '(test=FOO)'
|
checkcount 0 '(test=FOO)'
|
||||||
checkcount 0 '(test=fo*)'
|
checkcount 0 '(test=fo*)'
|
||||||
|
|
||||||
rm -f $LDB_URL
|
|
||||||
|
@@ -7,6 +7,8 @@ PATH=bin:$PATH
|
|||||||
export PATH
|
export PATH
|
||||||
|
|
||||||
rm -f tdbtest.ldb
|
rm -f tdbtest.ldb
|
||||||
|
rm -f tdbtest.ldb.1
|
||||||
|
rm -f tdbtest.ldb.2
|
||||||
|
|
||||||
if [ -z "$LDBDIR" ]; then
|
if [ -z "$LDBDIR" ]; then
|
||||||
LDBDIR="."
|
LDBDIR="."
|
||||||
|
Reference in New Issue
Block a user