diff options
-rw-r--r-- | source4/lib/ldb/common/ldb_ldif.c | 79 | ||||
-rw-r--r-- | source4/lib/ldb/include/ldb.h | 13 | ||||
-rw-r--r-- | source4/lib/ldb/include/ldb_private.h | 4 |
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 */ |