r9671: patch from Kai Blin fixing a bug in our base64 encoder
[sfrench/samba-autobuild/.git] / source / lib / ldb / common / ldb_ldif.c
index 70dd2267b5bdb7b7b38975875022f97eceaa5017..38866d703132af4b404dc53694650fcf56926048 100644 (file)
 #include "ldb/include/ldb.h"
 #include "ldb/include/ldb_private.h"
 #include <ctype.h>
-
-
-/*
-  add to the list of ldif handlers for this ldb context
-*/
-int ldb_ldif_add_handlers(struct ldb_context *ldb, 
-                         const struct ldb_ldif_handler *handlers, 
-                         unsigned num_handlers)
-{
-       struct ldb_ldif_handler *h;
-       h = talloc_realloc(ldb, ldb->ldif_handlers,
-                          struct ldb_ldif_handler,
-                          ldb->ldif_num_handlers + num_handlers);
-       if (h == NULL) {
-               ldb_oom(ldb);
-               return -1;
-       }
-       ldb->ldif_handlers = h;
-       memcpy(h + ldb->ldif_num_handlers, 
-              handlers, sizeof(*h) * num_handlers);
-       ldb->ldif_num_handlers += num_handlers;
-       return 0;
-}
-                         
-
-/*
-  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 (ldb_attr_cmp(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 (ldb_attr_cmp(attr, ldb->ldif_handlers[i].attr) == 0) {
-                       return ldb->ldif_handlers[i].write_fn;
-               }
-       }
-       return ldb_ldif_default;
-}
+#ifdef _SAMBA_BUILD_
+#include "system/filesys.h"
+#endif
 
 /*
   
@@ -215,10 +155,10 @@ char *ldb_base64_encode(void *mem_ctx, const char *buf, int len)
        const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        int bit_offset, byte_offset, idx, i;
        const uint8_t *d = (const uint8_t *)buf;
-       int bytes = (len*8 + 5)/6;
+       int bytes = (len*8 + 5)/6, pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0;
        char *out;
 
-       out = talloc_array(mem_ctx, char, bytes+2);
+       out = talloc_array(mem_ctx, char, bytes+pad_bytes+1);
        if (!out) return NULL;
 
        for (i=0;i<bytes;i++) {
@@ -235,7 +175,8 @@ char *ldb_base64_encode(void *mem_ctx, const char *buf, int len)
                out[i] = b64[idx];
        }
 
-       out[i++] = '=';
+       for (;i<bytes+pad_bytes;i++)
+               out[i] = '=';
        out[i] = 0;
 
        return out;
@@ -335,7 +276,7 @@ int ldb_ldif_write(struct ldb_context *ldb,
 
        msg = ldif->msg;
 
-       ret = fprintf_fn(private_data, "dn: %s\n", msg->dn);
+       ret = fprintf_fn(private_data, "dn: %s\n", ldb_dn_linearize(msg->dn, msg->dn));
        CHECK_RET;
 
        if (ldif->changetype != LDB_CHANGETYPE_NONE) {
@@ -354,6 +295,10 @@ int ldb_ldif_write(struct ldb_context *ldb,
        }
 
        for (i=0;i<msg->num_elements;i++) {
+               const struct ldb_attrib_handler *h;
+
+               h = ldb_attrib_handler(ldb, msg->elements[i].name);
+
                if (ldif->changetype == LDB_CHANGETYPE_MODIFY) {
                        switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
                        case LDB_FLAG_MOD_ADD:
@@ -372,10 +317,8 @@ int ldb_ldif_write(struct ldb_context *ldb,
                }
 
                for (j=0;j<msg->elements[i].num_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);
+                       ret = h->ldif_write_fn(ldb, ldb, &msg->elements[i].values[j], &v);
                        CHECK_RET;
                        if (ldb_should_b64_encode(&v)) {
                                ret = fprintf_fn(private_data, "%s:: ", 
@@ -645,10 +588,10 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
                goto failed;
        }
 
-       msg->dn = value.data;
+       msg->dn = ldb_dn_explode(msg, value.data);
 
        while (next_attr(ldif, &s, &attr, &value) == 0) {
-               ldb_ldif_handler_t read_fn;
+               const struct ldb_attrib_handler *h;             
                struct ldb_message_element *el;
                int ret, empty = 0;
 
@@ -694,7 +637,7 @@ 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);
+               h = ldb_attrib_handler(ldb, attr);
 
                if (msg->num_elements > 0 && ldb_attr_cmp(attr, el->name) == 0 &&
                    flags == el->flags) {
@@ -705,7 +648,7 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
                        if (!el->values) {
                                goto failed;
                        }
-                       ret = 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) {
                                goto failed;
                        }
@@ -729,7 +672,7 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
                                goto failed;
                        }
                        el->num_values = 1;
-                       ret = read_fn(ldb, &value, &el->values[0]);
+                       ret = h->ldif_read_fn(ldb, ldif, &value, &el->values[0]);
                        if (ret != 0) {
                                goto failed;
                        }
@@ -786,11 +729,14 @@ static int fgetc_string(void *private_data)
        return EOF;
 }
 
-struct ldb_ldif *ldb_ldif_read_string(struct ldb_context *ldb, const char *s)
+struct ldb_ldif *ldb_ldif_read_string(struct ldb_context *ldb, const char **s)
 {
        struct ldif_read_string_state state;
-       state.s = s;
-       return ldb_ldif_read(ldb, fgetc_string, &state);
+       struct ldb_ldif *ldif;
+       state.s = *s;
+       ldif = ldb_ldif_read(ldb, fgetc_string, &state);
+       *s = state.s;
+       return ldif;
 }