r7803: added support in ldb for callers to setup ldif read/write functions,
authorAndrew Tridgell <tridge@samba.org>
Tue, 21 Jun 2005 06:35:55 +0000 (06:35 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:18:37 +0000 (13:18 -0500)
so that ldbedit, ldbsearch etc can display nice human readable ldif,
while storing the data as binary blobs. This will be used for storing
NDR encoded objectSid and similar attributes, while making the command
line interface sane
(This used to be commit 37e283089a846fc0608fef3981a3447300e33728)

source4/lib/ldb/common/ldb_ldif.c
source4/lib/ldb/include/ldb.h
source4/lib/ldb/include/ldb_private.h

index 9492aa3634040505ffca2439129be1fb66dd66ba..88ef9fae45e305a27532007fc1abbaa006e21575 100644 (file)
 #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++;
                }
        }
index 9a3186b41c920d872ae23424967b48d12201a690..48290beb9284316537005ffe9677e0f900ea09b6 100644 (file)
@@ -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
 */
index 8f91b0d9b17535f1062d101b88c5c1f6344beed5..f6c1c7ff46d1481af874da4e3fa1e49bb8af1e80 100644 (file)
@@ -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 */