summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/lib/ldb/common/ldb_ldif.c79
-rw-r--r--source4/lib/ldb/include/ldb.h13
-rw-r--r--source4/lib/ldb/include/ldb_private.h4
3 files changed, 86 insertions, 10 deletions
diff --git a/source4/lib/ldb/common/ldb_ldif.c b/source4/lib/ldb/common/ldb_ldif.c
index 9492aa3634..88ef9fae45 100644
--- a/source4/lib/ldb/common/ldb_ldif.c
+++ b/source4/lib/ldb/common/ldb_ldif.c
@@ -41,6 +41,44 @@
#include "ldb/include/ldb_private.h"
#include <ctype.h>
+/*
+ default function for ldif read/write
+*/
+static int ldb_ldif_default(struct ldb_context *ldb, const struct ldb_val *in,
+ struct ldb_val *out)
+{
+ *out = *in;
+ return 0;
+}
+
+
+/*
+ return a function for reading an ldif encoded attributes into a ldb_val
+*/
+static ldb_ldif_handler_t ldb_ldif_read_fn(struct ldb_context *ldb, const char *attr)
+{
+ int i;
+ for (i=0;i<ldb->ldif_num_handlers;i++) {
+ if (strcmp(attr, ldb->ldif_handlers[i].attr) == 0) {
+ return ldb->ldif_handlers[i].read_fn;
+ }
+ }
+ return ldb_ldif_default;
+}
+
+/*
+ return a function for writing an ldif encoded attribute from a ldb_val
+*/
+static ldb_ldif_handler_t ldb_ldif_write_fn(struct ldb_context *ldb, const char *attr)
+{
+ int i;
+ for (i=0;i<ldb->ldif_num_handlers;i++) {
+ if (strcmp(attr, ldb->ldif_handlers[i].attr) == 0) {
+ return ldb->ldif_handlers[i].write_fn;
+ }
+ }
+ return ldb_ldif_default;
+}
/*
this base64 decoder was taken from jitterbug (written by tridge).
@@ -49,9 +87,9 @@
int ldb_base64_decode(char *s)
{
const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- int bit_offset, byte_offset, idx, i, n;
+ int bit_offset=0, byte_offset, idx, i, n;
uint8_t *d = (uint8_t *)s;
- char *p;
+ char *p=NULL;
n=i=0;
@@ -254,13 +292,17 @@ int ldb_ldif_write(struct ldb_context *ldb,
}
for (j=0;j<msg->elements[i].num_values;j++) {
- if (ldb_should_b64_encode(&msg->elements[i].values[j])) {
+ ldb_ldif_handler_t write_fn = ldb_ldif_write_fn(ldb,
+ msg->elements[i].name);
+ struct ldb_val v;
+ ret = write_fn(ldb, &msg->elements[i].values[j], &v);
+ CHECK_RET;
+ if (ldb_should_b64_encode(&v)) {
ret = fprintf_fn(private_data, "%s:: ",
msg->elements[i].name);
CHECK_RET;
ret = base64_encode_f(ldb, fprintf_fn, private_data,
- msg->elements[i].values[j].data,
- msg->elements[i].values[j].length,
+ v.data, v.length,
strlen(msg->elements[i].name)+3);
CHECK_RET;
ret = fprintf_fn(private_data, "\n");
@@ -269,13 +311,15 @@ int ldb_ldif_write(struct ldb_context *ldb,
ret = fprintf_fn(private_data, "%s: ", msg->elements[i].name);
CHECK_RET;
ret = fold_string(fprintf_fn, private_data,
- msg->elements[i].values[j].data,
- msg->elements[i].values[j].length,
+ v.data, v.length,
strlen(msg->elements[i].name)+2);
CHECK_RET;
ret = fprintf_fn(private_data, "\n");
CHECK_RET;
}
+ if (v.data != msg->elements[i].values[j].data) {
+ talloc_free(v.data);
+ }
}
if (ldif->changetype == LDB_CHANGETYPE_MODIFY) {
fprintf_fn(private_data, "-\n");
@@ -510,8 +554,9 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
msg->dn = value.data;
while (next_attr(&s, &attr, &value) == 0) {
+ ldb_ldif_handler_t read_fn;
struct ldb_message_element *el;
- int empty = 0;
+ int ret, empty = 0;
if (ldb_attr_cmp(attr, "changetype") == 0) {
int i;
@@ -555,6 +600,8 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
el = &msg->elements[msg->num_elements-1];
+ read_fn = ldb_ldif_read_fn(ldb, attr);
+
if (msg->num_elements > 0 && ldb_attr_cmp(attr, el->name) == 0 &&
flags == el->flags) {
/* its a continuation */
@@ -564,7 +611,13 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
if (!el->values) {
goto failed;
}
- el->values[el->num_values] = value;
+ ret = read_fn(ldb, &value, &el->values[el->num_values]);
+ if (ret != 0) {
+ goto failed;
+ }
+ if (value.data != el->values[el->num_values].data) {
+ talloc_steal(el->values, el->values[el->num_values].data);
+ }
el->num_values++;
} else {
/* its a new attribute */
@@ -582,7 +635,13 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
goto failed;
}
el->num_values = 1;
- el->values[0] = value;
+ ret = read_fn(ldb, &value, &el->values[0]);
+ if (ret != 0) {
+ goto failed;
+ }
+ if (value.data != el->values[0].data) {
+ talloc_steal(el->values, el->values[0].data);
+ }
msg->num_elements++;
}
}
diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h
index 9a3186b41c..48290beb92 100644
--- a/source4/lib/ldb/include/ldb.h
+++ b/source4/lib/ldb/include/ldb.h
@@ -184,6 +184,19 @@ struct ldb_parse_tree *ldb_parse_tree(void *mem_ctx, const char *s);
char *ldb_filter_from_tree(void *mem_ctx, struct ldb_parse_tree *tree);
char *ldb_binary_encode(void *ctx, struct ldb_val val);
+
+/*
+ functions for controlling ldif encode/decode
+*/
+typedef int (*ldb_ldif_handler_t)(struct ldb_context *, const struct ldb_val *, struct ldb_val *);
+
+struct ldb_ldif_handler {
+ const char *attr;
+ ldb_ldif_handler_t read_fn;
+ ldb_ldif_handler_t write_fn;
+};
+
+
/*
initialise a ldb context
*/
diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h
index 8f91b0d9b1..f6c1c7ff46 100644
--- a/source4/lib/ldb/include/ldb_private.h
+++ b/source4/lib/ldb/include/ldb_private.h
@@ -84,6 +84,10 @@ struct ldb_context {
const char *name;
void *value;
} *opaque;
+
+ /* ldif attribute handling table */
+ unsigned ldif_num_handlers;
+ struct ldb_ldif_handler *ldif_handlers;
};
/* the modules init function */