53dadcc6fe07a9e77580312af65cd62ab9215598
[samba.git] / source / lib / ldb / common / ldb_ldif.c
1 /* 
2    ldb database library
3
4    Copyright (C) Andrew Tridgell  2004
5
6      ** NOTE! The following LGPL license applies to the ldb
7      ** library. This does NOT imply that all of Samba is released
8      ** under the LGPL
9    
10    This library is free software; you can redistribute it and/or
11    modify it under the terms of the GNU Lesser General Public
12    License as published by the Free Software Foundation; either
13    version 2 of the License, or (at your option) any later version.
14
15    This library is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    Lesser General Public License for more details.
19
20    You should have received a copy of the GNU Lesser General Public
21    License along with this library; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 */
24
25 /*
26  *  Name: ldb
27  *
28  *  Component: ldif routines
29  *
30  *  Description: ldif pack/unpack routines
31  *
32  *  Author: Andrew Tridgell
33  */
34
35 /*
36   see RFC2849 for the LDIF format definition
37 */
38
39 #include "includes.h"
40 #include "ldb/include/includes.h"
41
42 /*
43   
44 */
45 static int ldb_read_data_file(void *mem_ctx, struct ldb_val *value)
46 {
47         struct stat statbuf;
48         char *buf;
49         int count, size, bytes;
50         int ret;
51         int f;
52
53         f = open((const char *)value->data, O_RDONLY);
54         if (f == -1) {
55                 return -1;
56         }
57
58         if (fstat(f, &statbuf) != 0) {
59                 ret = -1;
60                 goto done;
61         }
62
63         if (statbuf.st_size == 0) {
64                 ret = -1;
65                 goto done;
66         }
67
68         value->data = talloc_size(mem_ctx, statbuf.st_size + 1);
69         if (value->data == NULL) {
70                 ret = -1;
71                 goto done;
72         }
73         value->data[statbuf.st_size] = 0;
74
75         count = 0;
76         size = statbuf.st_size;
77         buf = (char *)value->data;
78         while (count < statbuf.st_size) {
79                 bytes = read(f, buf, size);
80                 if (bytes == -1) {
81                         talloc_free(value->data);
82                         ret = -1;
83                         goto done;
84                 }
85                 count += bytes;
86                 buf += bytes;
87                 size -= bytes;
88         }
89
90         value->length = statbuf.st_size;
91         ret = statbuf.st_size;
92
93 done:
94         close(f);
95         return ret;
96 }
97
98 /*
99   this base64 decoder was taken from jitterbug (written by tridge).
100   we might need to replace it with a new version
101 */
102 int ldb_base64_decode(char *s)
103 {
104         const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
105         int bit_offset=0, byte_offset, idx, i, n;
106         uint8_t *d = (uint8_t *)s;
107         char *p=NULL;
108
109         n=i=0;
110
111         while (*s && (p=strchr(b64,*s))) {
112                 idx = (int)(p - b64);
113                 byte_offset = (i*6)/8;
114                 bit_offset = (i*6)%8;
115                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
116                 if (bit_offset < 3) {
117                         d[byte_offset] |= (idx << (2-bit_offset));
118                         n = byte_offset+1;
119                 } else {
120                         d[byte_offset] |= (idx >> (bit_offset-2));
121                         d[byte_offset+1] = 0;
122                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
123                         n = byte_offset+2;
124                 }
125                 s++; i++;
126         }
127         if (bit_offset >= 3) {
128                 n--;
129         }
130
131         if (*s && !p) {
132                 /* the only termination allowed */
133                 if (*s != '=') {
134                         return -1;
135                 }
136         }
137
138         /* null terminate */
139         d[n] = 0;
140         return n;
141 }
142
143
144 /*
145   encode as base64
146   caller frees
147 */
148 char *ldb_base64_encode(void *mem_ctx, const char *buf, int len)
149 {
150         const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
151         int bit_offset, byte_offset, idx, i;
152         const uint8_t *d = (const uint8_t *)buf;
153         int bytes = (len*8 + 5)/6, pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0;
154         char *out;
155
156         out = talloc_array(mem_ctx, char, bytes+pad_bytes+1);
157         if (!out) return NULL;
158
159         for (i=0;i<bytes;i++) {
160                 byte_offset = (i*6)/8;
161                 bit_offset = (i*6)%8;
162                 if (bit_offset < 3) {
163                         idx = (d[byte_offset] >> (2-bit_offset)) & 0x3F;
164                 } else {
165                         idx = (d[byte_offset] << (bit_offset-2)) & 0x3F;
166                         if (byte_offset+1 < len) {
167                                 idx |= (d[byte_offset+1] >> (8-(bit_offset-2)));
168                         }
169                 }
170                 out[i] = b64[idx];
171         }
172
173         for (;i<bytes+pad_bytes;i++)
174                 out[i] = '=';
175         out[i] = 0;
176
177         return out;
178 }
179
180 /*
181   see if a buffer should be base64 encoded
182 */
183 int ldb_should_b64_encode(const struct ldb_val *val)
184 {
185         unsigned int i;
186         uint8_t *p = val->data;
187
188         if (val->length == 0) {
189                 return 0;
190         }
191
192         if (p[0] == ' ' || p[0] == ':') {
193                 return 1;
194         }
195
196         for (i=0; i<val->length; i++) {
197                 if (!isprint(p[i]) || p[i] == '\n') {
198                         return 1;
199                 }
200         }
201         return 0;
202 }
203
204 /* this macro is used to handle the return checking on fprintf_fn() */
205 #define CHECK_RET do { if (ret < 0) return ret; total += ret; } while (0)
206
207 /*
208   write a line folded string onto a file
209 */
210 static int fold_string(int (*fprintf_fn)(void *, const char *, ...), void *private_data,
211                         const char *buf, size_t length, int start_pos)
212 {
213         unsigned int i;
214         int total=0, ret;
215
216         for (i=0;i<length;i++) {
217                 ret = fprintf_fn(private_data, "%c", buf[i]);
218                 CHECK_RET;
219                 if (i != (length-1) && (i + start_pos) % 77 == 0) {
220                         ret = fprintf_fn(private_data, "\n ");
221                         CHECK_RET;
222                 }
223         }
224
225         return total;
226 }
227
228 /*
229   encode as base64 to a file
230 */
231 static int base64_encode_f(struct ldb_context *ldb,
232                            int (*fprintf_fn)(void *, const char *, ...), 
233                            void *private_data,
234                            const char *buf, int len, int start_pos)
235 {
236         char *b = ldb_base64_encode(ldb, buf, len);
237         int ret;
238
239         if (!b) {
240                 return -1;
241         }
242
243         ret = fold_string(fprintf_fn, private_data, b, strlen(b), start_pos);
244
245         talloc_free(b);
246         return ret;
247 }
248
249
250 static const struct {
251         const char *name;
252         enum ldb_changetype changetype;
253 } ldb_changetypes[] = {
254         {"add",    LDB_CHANGETYPE_ADD},
255         {"delete", LDB_CHANGETYPE_DELETE},
256         {"modify", LDB_CHANGETYPE_MODIFY},
257         {NULL, 0}
258 };
259
260 /*
261   write to ldif, using a caller supplied write method
262 */
263 int ldb_ldif_write(struct ldb_context *ldb,
264                    int (*fprintf_fn)(void *, const char *, ...), 
265                    void *private_data,
266                    const struct ldb_ldif *ldif)
267 {
268         unsigned int i, j;
269         int total=0, ret;
270         const struct ldb_message *msg;
271
272         msg = ldif->msg;
273
274         ret = fprintf_fn(private_data, "dn: %s\n", ldb_dn_linearize(msg->dn, msg->dn));
275         CHECK_RET;
276
277         if (ldif->changetype != LDB_CHANGETYPE_NONE) {
278                 for (i=0;ldb_changetypes[i].name;i++) {
279                         if (ldb_changetypes[i].changetype == ldif->changetype) {
280                                 break;
281                         }
282                 }
283                 if (!ldb_changetypes[i].name) {
284                         ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Invalid ldif changetype %d\n",
285                                   ldif->changetype);
286                         return -1;
287                 }
288                 ret = fprintf_fn(private_data, "changetype: %s\n", ldb_changetypes[i].name);
289                 CHECK_RET;
290         }
291
292         for (i=0;i<msg->num_elements;i++) {
293                 const struct ldb_attrib_handler *h;
294
295                 h = ldb_attrib_handler(ldb, msg->elements[i].name);
296
297                 if (ldif->changetype == LDB_CHANGETYPE_MODIFY) {
298                         switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
299                         case LDB_FLAG_MOD_ADD:
300                                 fprintf_fn(private_data, "add: %s\n", 
301                                            msg->elements[i].name);
302                                 break;
303                         case LDB_FLAG_MOD_DELETE:
304                                 fprintf_fn(private_data, "delete: %s\n", 
305                                            msg->elements[i].name);
306                                 break;
307                         case LDB_FLAG_MOD_REPLACE:
308                                 fprintf_fn(private_data, "replace: %s\n", 
309                                            msg->elements[i].name);
310                                 break;
311                         }
312                 }
313
314                 for (j=0;j<msg->elements[i].num_values;j++) {
315                         struct ldb_val v;
316                         ret = h->ldif_write_fn(ldb, ldb, &msg->elements[i].values[j], &v);
317                         CHECK_RET;
318                         if (ldb_should_b64_encode(&v)) {
319                                 ret = fprintf_fn(private_data, "%s:: ", 
320                                                  msg->elements[i].name);
321                                 CHECK_RET;
322                                 ret = base64_encode_f(ldb, fprintf_fn, private_data, 
323                                                       (char *)v.data, v.length,
324                                                       strlen(msg->elements[i].name)+3);
325                                 CHECK_RET;
326                                 ret = fprintf_fn(private_data, "\n");
327                                 CHECK_RET;
328                         } else {
329                                 ret = fprintf_fn(private_data, "%s: ", msg->elements[i].name);
330                                 CHECK_RET;
331                                 ret = fold_string(fprintf_fn, private_data,
332                                                   (char *)v.data, v.length,
333                                                   strlen(msg->elements[i].name)+2);
334                                 CHECK_RET;
335                                 ret = fprintf_fn(private_data, "\n");
336                                 CHECK_RET;
337                         }
338                         if (v.data != msg->elements[i].values[j].data) {
339                                 talloc_free(v.data);
340                         }
341                 }
342                 if (ldif->changetype == LDB_CHANGETYPE_MODIFY) {
343                         fprintf_fn(private_data, "-\n");
344                 }
345         }
346         ret = fprintf_fn(private_data,"\n");
347         CHECK_RET;
348
349         return total;
350 }
351
352 #undef CHECK_RET
353
354
355 /*
356   pull a ldif chunk, which is defined as a piece of data ending in \n\n or EOF
357   this routine removes any RFC2849 continuations and comments
358
359   caller frees
360 */
361 static char *next_chunk(struct ldb_context *ldb, 
362                         int (*fgetc_fn)(void *), void *private_data)
363 {
364         size_t alloc_size=0, chunk_size = 0;
365         char *chunk = NULL;
366         int c;
367         int in_comment = 0;
368
369         while ((c = fgetc_fn(private_data)) != EOF) {
370                 if (chunk_size+1 >= alloc_size) {
371                         char *c2;
372                         alloc_size += 1024;
373                         c2 = talloc_realloc(ldb, chunk, char, alloc_size);
374                         if (!c2) {
375                                 talloc_free(chunk);
376                                 errno = ENOMEM;
377                                 return NULL;
378                         }
379                         chunk = c2;
380                 }
381
382                 if (in_comment) {
383                         if (c == '\n') {
384                                 in_comment = 0;
385                         }
386                         continue;                       
387                 }
388                 
389                 /* handle continuation lines - see RFC2849 */
390                 if (c == ' ' && chunk_size > 1 && chunk[chunk_size-1] == '\n') {
391                         chunk_size--;
392                         continue;
393                 }
394                 
395                 /* chunks are terminated by a double line-feed */
396                 if (c == '\n' && chunk_size > 0 && chunk[chunk_size-1] == '\n') {
397                         chunk[chunk_size-1] = 0;
398                         return chunk;
399                 }
400
401                 if (c == '#' && (chunk_size == 0 || chunk[chunk_size-1] == '\n')) {
402                         in_comment = 1;
403                         continue;
404                 }
405
406                 /* ignore leading blank lines */
407                 if (chunk_size == 0 && c == '\n') {
408                         continue;
409                 }
410
411                 chunk[chunk_size++] = c;
412         }
413
414         if (chunk) {
415                 chunk[chunk_size] = 0;
416         }
417
418         return chunk;
419 }
420
421
422 /* simple ldif attribute parser */
423 static int next_attr(void *mem_ctx, char **s, const char **attr, struct ldb_val *value)
424 {
425         char *p;
426         int base64_encoded = 0;
427         int binary_file = 0;
428
429         if (strncmp(*s, "-\n", 2) == 0) {
430                 value->length = 0;
431                 *attr = "-";
432                 *s += 2;
433                 return 0;
434         }
435
436         p = strchr(*s, ':');
437         if (!p) {
438                 return -1;
439         }
440
441         *p++ = 0;
442
443         if (*p == ':') {
444                 base64_encoded = 1;
445                 p++;
446         }
447
448         if (*p == '<') {
449                 binary_file = 1;
450                 p++;
451         }
452
453         *attr = *s;
454
455         while (*p == ' ' || *p == '\t') {
456                 p++;
457         }
458
459         value->data = (uint8_t *)p;
460
461         p = strchr(p, '\n');
462
463         if (!p) {
464                 value->length = strlen((char *)value->data);
465                 *s = ((char *)value->data) + value->length;
466         } else {
467                 value->length = p - (char *)value->data;
468                 *s = p+1;
469                 *p = 0;
470         }
471
472         if (base64_encoded) {
473                 int len = ldb_base64_decode((char *)value->data);
474                 if (len == -1) {
475                         /* it wasn't valid base64 data */
476                         return -1;
477                 }
478                 value->length = len;
479         }
480
481         if (binary_file) {
482                 int len = ldb_read_data_file(mem_ctx, value);
483                 if (len == -1) {
484                         /* an error occured hile trying to retrieve the file */
485                         return -1;
486                 }
487         }
488
489         return 0;
490 }
491
492
493 /*
494   free a message from a ldif_read
495 */
496 void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *ldif)
497 {
498         talloc_free(ldif);
499 }
500
501 /*
502   add an empty element
503 */
504 static int msg_add_empty(struct ldb_context *ldb,
505                          struct ldb_message *msg, const char *name, unsigned flags)
506 {
507         struct ldb_message_element *el2, *el;
508
509         el2 = talloc_realloc(msg, msg->elements, 
510                                struct ldb_message_element, msg->num_elements+1);
511         if (!el2) {
512                 errno = ENOMEM;
513                 return -1;
514         }
515         
516         msg->elements = el2;
517
518         el = &msg->elements[msg->num_elements];
519         
520         el->name = talloc_strdup(msg->elements, name);
521         el->num_values = 0;
522         el->values = NULL;
523         el->flags = flags;
524
525         if (!el->name) {
526                 errno = ENOMEM;
527                 return -1;
528         }
529
530         msg->num_elements++;
531
532         return 0;
533 }
534
535 /*
536  read from a LDIF source, creating a ldb_message
537 */
538 struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
539                                int (*fgetc_fn)(void *), void *private_data)
540 {
541         struct ldb_ldif *ldif;
542         struct ldb_message *msg;
543         const char *attr=NULL;
544         char *chunk=NULL, *s;
545         struct ldb_val value;
546         unsigned flags = 0;
547
548         value.data = NULL;
549
550         ldif = talloc(ldb, struct ldb_ldif);
551         if (!ldif) return NULL;
552
553         ldif->msg = talloc(ldif, struct ldb_message);
554         if (ldif->msg == NULL) {
555                 talloc_free(ldif);
556                 return NULL;
557         }
558
559         ldif->changetype = LDB_CHANGETYPE_NONE;
560         msg = ldif->msg;
561
562         msg->dn = NULL;
563         msg->elements = NULL;
564         msg->num_elements = 0;
565         msg->private_data = NULL;
566
567         chunk = next_chunk(ldb, fgetc_fn, private_data);
568         if (!chunk) {
569                 goto failed;
570         }
571
572         msg->private_data = chunk;
573         s = chunk;
574
575         if (next_attr(ldif, &s, &attr, &value) != 0) {
576                 goto failed;
577         }
578         
579         /* first line must be a dn */
580         if (ldb_attr_cmp(attr, "dn") != 0) {
581                 ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: First line of ldif must be a dn not '%s'\n", 
582                           attr);
583                 goto failed;
584         }
585
586         msg->dn = ldb_dn_explode(msg, (char *)value.data);
587
588         if (msg->dn == NULL) {
589                 ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'\n", 
590                                   value.data);
591                 goto failed;
592         }
593
594         while (next_attr(ldif, &s, &attr, &value) == 0) {
595                 const struct ldb_attrib_handler *h;             
596                 struct ldb_message_element *el;
597                 int ret, empty = 0;
598
599                 if (ldb_attr_cmp(attr, "changetype") == 0) {
600                         int i;
601                         for (i=0;ldb_changetypes[i].name;i++) {
602                                 if (ldb_attr_cmp((char *)value.data, ldb_changetypes[i].name) == 0) {
603                                         ldif->changetype = ldb_changetypes[i].changetype;
604                                         break;
605                                 }
606                         }
607                         if (!ldb_changetypes[i].name) {
608                                 ldb_debug(ldb, LDB_DEBUG_ERROR, 
609                                           "Error: Bad ldif changetype '%s'\n",(char *)value.data);
610                         }
611                         flags = 0;
612                         continue;
613                 }
614
615                 if (ldb_attr_cmp(attr, "add") == 0) {
616                         flags = LDB_FLAG_MOD_ADD;
617                         empty = 1;
618                 }
619                 if (ldb_attr_cmp(attr, "delete") == 0) {
620                         flags = LDB_FLAG_MOD_DELETE;
621                         empty = 1;
622                 }
623                 if (ldb_attr_cmp(attr, "replace") == 0) {
624                         flags = LDB_FLAG_MOD_REPLACE;
625                         empty = 1;
626                 }
627                 if (ldb_attr_cmp(attr, "-") == 0) {
628                         flags = 0;
629                         continue;
630                 }
631
632                 if (empty) {
633                         if (msg_add_empty(ldb, msg, (char *)value.data, flags) != 0) {
634                                 goto failed;
635                         }
636                         continue;
637                 }
638                 
639                 el = &msg->elements[msg->num_elements-1];
640
641                 h = ldb_attrib_handler(ldb, attr);
642
643                 if (msg->num_elements > 0 && ldb_attr_cmp(attr, el->name) == 0 &&
644                     flags == el->flags) {
645                         /* its a continuation */
646                         el->values = 
647                                 talloc_realloc(msg->elements, el->values, 
648                                                  struct ldb_val, el->num_values+1);
649                         if (!el->values) {
650                                 goto failed;
651                         }
652                         ret = h->ldif_read_fn(ldb, ldif, &value, &el->values[el->num_values]);
653                         if (ret != 0) {
654                                 goto failed;
655                         }
656                         if (value.length == 0) {
657                                 ldb_debug(ldb, LDB_DEBUG_ERROR,
658                                           "Error: Attribute value cannot be empty for attribute '%s'\n", el->name);
659                                 goto failed;
660                         }
661                         if (value.data != el->values[el->num_values].data) {
662                                 talloc_steal(el->values, el->values[el->num_values].data);
663                         }
664                         el->num_values++;
665                 } else {
666                         /* its a new attribute */
667                         msg->elements = talloc_realloc(ldif, msg->elements, 
668                                                          struct ldb_message_element, 
669                                                          msg->num_elements+1);
670                         if (!msg->elements) {
671                                 goto failed;
672                         }
673                         el = &msg->elements[msg->num_elements];
674                         el->flags = flags;
675                         el->name = talloc_strdup(msg->elements, attr);
676                         el->values = talloc(msg->elements, struct ldb_val);
677                         if (!el->values || !el->name) {
678                                 goto failed;
679                         }
680                         el->num_values = 1;
681                         ret = h->ldif_read_fn(ldb, ldif, &value, &el->values[0]);
682                         if (ret != 0) {
683                                 goto failed;
684                         }
685                         if (value.data != el->values[0].data) {
686                                 talloc_steal(el->values, el->values[0].data);
687                         }
688                         msg->num_elements++;
689                 }
690         }
691
692         return ldif;
693
694 failed:
695         talloc_free(ldif);
696         return NULL;
697 }
698
699
700
701 /*
702   a wrapper around ldif_read() for reading from FILE*
703 */
704 struct ldif_read_file_state {
705         FILE *f;
706 };
707
708 static int fgetc_file(void *private_data)
709 {
710         struct ldif_read_file_state *state = private_data;
711         return fgetc(state->f);
712 }
713
714 struct ldb_ldif *ldb_ldif_read_file(struct ldb_context *ldb, FILE *f)
715 {
716         struct ldif_read_file_state state;
717         state.f = f;
718         return ldb_ldif_read(ldb, fgetc_file, &state);
719 }
720
721
722 /*
723   a wrapper around ldif_read() for reading from const char*
724 */
725 struct ldif_read_string_state {
726         const char *s;
727 };
728
729 static int fgetc_string(void *private_data)
730 {
731         struct ldif_read_string_state *state = private_data;
732         if (state->s[0] != 0) {
733                 return *state->s++;
734         }
735         return EOF;
736 }
737
738 struct ldb_ldif *ldb_ldif_read_string(struct ldb_context *ldb, const char **s)
739 {
740         struct ldif_read_string_state state;
741         struct ldb_ldif *ldif;
742         state.s = *s;
743         ldif = ldb_ldif_read(ldb, fgetc_string, &state);
744         *s = state.s;
745         return ldif;
746 }
747
748
749 /*
750   wrapper around ldif_write() for a file
751 */
752 struct ldif_write_file_state {
753         FILE *f;
754 };
755
756 static int fprintf_file(void *private_data, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
757
758 static int fprintf_file(void *private_data, const char *fmt, ...)
759 {
760         struct ldif_write_file_state *state = private_data;
761         int ret;
762         va_list ap;
763
764         va_start(ap, fmt);
765         ret = vfprintf(state->f, fmt, ap);
766         va_end(ap);
767         return ret;
768 }
769
770 int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *ldif)
771 {
772         struct ldif_write_file_state state;
773         state.f = f;
774         return ldb_ldif_write(ldb, fprintf_file, &state, ldif);
775 }