~ubuntu-branches/ubuntu/vivid/samba/vivid

« back to all changes in this revision

Viewing changes to source3/lib/ldb/tools/oLschema2ldif.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
   ldb database library
3
 
 
4
 
   Copyright (C) Simo Sorce 2005
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 3 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, see <http://www.gnu.org/licenses/>.
22
 
*/
23
 
 
24
 
/*
25
 
 *  Name: ldb
26
 
 *
27
 
 *  Component: oLschema2ldif
28
 
 *
29
 
 *  Description: utility to convert an OpenLDAP schema into AD LDIF
30
 
 *
31
 
 *  Author: Simo Sorce
32
 
 */
33
 
 
34
 
#include "includes.h"
35
 
#include "ldb/include/includes.h"
36
 
#include "ldb/tools/cmdline.h"
37
 
#include "ldb/tools/convert.h"
38
 
 
39
 
#define SCHEMA_UNKNOWN 0
40
 
#define SCHEMA_NAME 1
41
 
#define SCHEMA_SUP 2
42
 
#define SCHEMA_STRUCTURAL 3
43
 
#define SCHEMA_ABSTRACT 4
44
 
#define SCHEMA_AUXILIARY 5
45
 
#define SCHEMA_MUST 6
46
 
#define SCHEMA_MAY 7
47
 
#define SCHEMA_SINGLE_VALUE 8
48
 
#define SCHEMA_EQUALITY 9
49
 
#define SCHEMA_ORDERING 10
50
 
#define SCHEMA_SUBSTR 11
51
 
#define SCHEMA_SYNTAX 12
52
 
#define SCHEMA_DESC 13
53
 
 
54
 
struct schema_conv {
55
 
        int count;
56
 
        int failures;
57
 
};
58
 
 
59
 
struct schema_token {
60
 
        int type;
61
 
        char *value;
62
 
};
63
 
 
64
 
struct ldb_context *ldb_ctx;
65
 
struct ldb_dn *basedn;
66
 
 
67
 
static int check_braces(const char *string)
68
 
{
69
 
        int b;
70
 
        char *c;
71
 
 
72
 
        b = 0;
73
 
        if ((c = strchr(string, '(')) == NULL) {
74
 
                return -1;
75
 
        }
76
 
        b++;
77
 
        c++;
78
 
        while (b) {
79
 
                c = strpbrk(c, "()");
80
 
                if (c == NULL) return 1;
81
 
                if (*c == '(') b++;
82
 
                if (*c == ')') b--;
83
 
                c++;
84
 
        }
85
 
        return 0;
86
 
}
87
 
 
88
 
static char *skip_spaces(char *string) {
89
 
        return (string + strspn(string, " \t\n"));
90
 
}
91
 
 
92
 
static int add_multi_string(struct ldb_message *msg, const char *attr, char *values)
93
 
{
94
 
        char *c;
95
 
        char *s;
96
 
        int n;
97
 
 
98
 
        c = skip_spaces(values);
99
 
        while (*c) {
100
 
                n = strcspn(c, " \t$");
101
 
                s = talloc_strndup(msg, c, n);
102
 
                if (ldb_msg_add_string(msg, attr, s) != 0) {
103
 
                        return -1;
104
 
                }
105
 
                c += n;
106
 
                c += strspn(c, " \t$");
107
 
        }
108
 
 
109
 
        return 0;
110
 
}
111
 
 
112
 
#define MSG_ADD_STRING(a, v) do { if (ldb_msg_add_string(msg, a, v) != 0) goto failed; } while(0)
113
 
#define MSG_ADD_M_STRING(a, v) do { if (add_multi_string(msg, a, v) != 0) goto failed; } while(0)
114
 
 
115
 
static char *get_def_value(TALLOC_CTX *ctx, char **string)
116
 
{
117
 
        char *c = *string;
118
 
        char *value;
119
 
        int n;
120
 
 
121
 
        if (*c == '\'') {
122
 
                c++;
123
 
                n = strcspn(c, "\'");
124
 
                value = talloc_strndup(ctx, c, n);
125
 
                c += n;
126
 
                c++; /* skip closing \' */
127
 
        } else {
128
 
                n = strcspn(c, " \t\n");
129
 
                value = talloc_strndup(ctx, c, n);
130
 
                c += n;
131
 
        }
132
 
        *string = c;
133
 
 
134
 
        return value;
135
 
}
136
 
 
137
 
static struct schema_token *get_next_schema_token(TALLOC_CTX *ctx, char **string)
138
 
{
139
 
        char *c = skip_spaces(*string);
140
 
        char *type;
141
 
        struct schema_token *token;
142
 
        int n;
143
 
 
144
 
        token = talloc(ctx, struct schema_token);
145
 
 
146
 
        n = strcspn(c, " \t\n");
147
 
        type = talloc_strndup(token, c, n);
148
 
        c += n;
149
 
        c = skip_spaces(c);
150
 
 
151
 
        if (strcasecmp("NAME", type) == 0) {
152
 
                talloc_free(type);
153
 
                token->type = SCHEMA_NAME;
154
 
                /* we do not support aliases so we get only the first name given and skip others */
155
 
                if (*c == '(') {
156
 
                        char *s = strchr(c, ')');
157
 
                        if (s == NULL) return NULL;
158
 
                        s = skip_spaces(s);
159
 
                        *string = s;
160
 
 
161
 
                        c++;
162
 
                        c = skip_spaces(c);
163
 
                }
164
 
 
165
 
                token->value = get_def_value(ctx, &c);
166
 
 
167
 
                if (*string < c) { /* single name */
168
 
                        c = skip_spaces(c);
169
 
                        *string = c;
170
 
                }
171
 
                return token;
172
 
        }
173
 
        if (strcasecmp("SUP", type) == 0) {
174
 
                talloc_free(type);
175
 
                token->type = SCHEMA_SUP;
176
 
 
177
 
                if (*c == '(') {
178
 
                        c++;
179
 
                        n = strcspn(c, ")");
180
 
                        token->value = talloc_strndup(ctx, c, n);
181
 
                        c += n;
182
 
                        c++;
183
 
                } else {
184
 
                        token->value = get_def_value(ctx, &c);
185
 
                }
186
 
 
187
 
                c = skip_spaces(c);
188
 
                *string = c;
189
 
                return token;
190
 
        }
191
 
 
192
 
        if (strcasecmp("STRUCTURAL", type) == 0) {
193
 
                talloc_free(type);
194
 
                token->type = SCHEMA_STRUCTURAL;
195
 
                *string = c;
196
 
                return token;
197
 
        }
198
 
 
199
 
        if (strcasecmp("ABSTRACT", type) == 0) {
200
 
                talloc_free(type);
201
 
                token->type = SCHEMA_ABSTRACT;
202
 
                *string = c;
203
 
                return token;
204
 
        }
205
 
 
206
 
        if (strcasecmp("AUXILIARY", type) == 0) {
207
 
                talloc_free(type);
208
 
                token->type = SCHEMA_AUXILIARY;
209
 
                *string = c;
210
 
                return token;
211
 
        }
212
 
 
213
 
        if (strcasecmp("MUST", type) == 0) {
214
 
                talloc_free(type);
215
 
                token->type = SCHEMA_MUST;
216
 
 
217
 
                if (*c == '(') {
218
 
                        c++;
219
 
                        n = strcspn(c, ")");
220
 
                        token->value = talloc_strndup(ctx, c, n);
221
 
                        c += n;
222
 
                        c++;
223
 
                } else {
224
 
                        token->value = get_def_value(ctx, &c);
225
 
                }
226
 
 
227
 
                c = skip_spaces(c);
228
 
                *string = c;
229
 
                return token;
230
 
        }
231
 
 
232
 
        if (strcasecmp("MAY", type) == 0) {
233
 
                talloc_free(type);
234
 
                token->type = SCHEMA_MAY;
235
 
 
236
 
                if (*c == '(') {
237
 
                        c++;
238
 
                        n = strcspn(c, ")");
239
 
                        token->value = talloc_strndup(ctx, c, n);
240
 
                        c += n;
241
 
                        c++;
242
 
                } else {
243
 
                        token->value = get_def_value(ctx, &c);
244
 
                }
245
 
 
246
 
                c = skip_spaces(c);
247
 
                *string = c;
248
 
                return token;
249
 
        }
250
 
 
251
 
        if (strcasecmp("SINGLE-VALUE", type) == 0) {
252
 
                talloc_free(type);
253
 
                token->type = SCHEMA_SINGLE_VALUE;
254
 
                *string = c;
255
 
                return token;
256
 
        }
257
 
 
258
 
        if (strcasecmp("EQUALITY", type) == 0) {
259
 
                talloc_free(type);
260
 
                token->type = SCHEMA_EQUALITY;
261
 
 
262
 
                token->value = get_def_value(ctx, &c);
263
 
 
264
 
                c = skip_spaces(c);
265
 
                *string = c;
266
 
                return token;
267
 
        }
268
 
 
269
 
        if (strcasecmp("ORDERING", type) == 0) {
270
 
                talloc_free(type);
271
 
                token->type = SCHEMA_ORDERING;
272
 
 
273
 
                token->value = get_def_value(ctx, &c);
274
 
 
275
 
                c = skip_spaces(c);
276
 
                *string = c;
277
 
                return token;
278
 
        }
279
 
 
280
 
        if (strcasecmp("SUBSTR", type) == 0) {
281
 
                talloc_free(type);
282
 
                token->type = SCHEMA_SUBSTR;
283
 
 
284
 
                token->value = get_def_value(ctx, &c);
285
 
 
286
 
                c = skip_spaces(c);
287
 
                *string = c;
288
 
                return token;
289
 
        }
290
 
 
291
 
        if (strcasecmp("SYNTAX", type) == 0) {
292
 
                talloc_free(type);
293
 
                token->type = SCHEMA_SYNTAX;
294
 
 
295
 
                token->value = get_def_value(ctx, &c);
296
 
 
297
 
                c = skip_spaces(c);
298
 
                *string = c;
299
 
                return token;
300
 
        }
301
 
 
302
 
        if (strcasecmp("DESC", type) == 0) {
303
 
                talloc_free(type);
304
 
                token->type = SCHEMA_DESC;
305
 
 
306
 
                token->value = get_def_value(ctx, &c);
307
 
 
308
 
                c = skip_spaces(c);
309
 
                *string = c;
310
 
                return token;
311
 
        }
312
 
 
313
 
        token->type = SCHEMA_UNKNOWN;
314
 
        token->value = type;
315
 
        if (*c == ')') {
316
 
                *string = c;
317
 
                return token;
318
 
        }
319
 
        if (*c == '\'') {
320
 
                c = strchr(++c, '\'');
321
 
                c++;
322
 
        } else {
323
 
                c += strcspn(c, " \t\n");
324
 
        }
325
 
        c = skip_spaces(c);
326
 
        *string = c;
327
 
 
328
 
        return token;
329
 
}
330
 
 
331
 
static struct ldb_message *process_entry(TALLOC_CTX *mem_ctx, const char *entry)
332
 
{
333
 
        TALLOC_CTX *ctx;
334
 
        struct ldb_message *msg;
335
 
        struct schema_token *token;
336
 
        char *c, *s;
337
 
        int n;
338
 
 
339
 
        ctx = talloc_new(mem_ctx);
340
 
        msg = ldb_msg_new(ctx);
341
 
 
342
 
        ldb_msg_add_string(msg, "objectClass", "top");
343
 
 
344
 
        c = talloc_strdup(ctx, entry);
345
 
        if (!c) return NULL;
346
 
 
347
 
        c = skip_spaces(c);
348
 
 
349
 
        switch (*c) {
350
 
        case 'a':
351
 
                if (strncmp(c, "attributetype", 13) == 0) {
352
 
                        c += 13;
353
 
                        MSG_ADD_STRING("objectClass", "attributeSchema");
354
 
                        break;
355
 
                }
356
 
                goto failed;
357
 
        case 'o':
358
 
                if (strncmp(c, "objectclass", 11) == 0) {
359
 
                        c += 11;
360
 
                        MSG_ADD_STRING("objectClass", "classSchema");
361
 
                        break;
362
 
                }
363
 
                goto failed;
364
 
        default:
365
 
                goto failed;
366
 
        }
367
 
 
368
 
        c = strchr(c, '(');
369
 
        if (c == NULL) goto failed;
370
 
        c++;
371
 
 
372
 
        c = skip_spaces(c);
373
 
 
374
 
        /* get attributeID */
375
 
        n = strcspn(c, " \t");
376
 
        s = talloc_strndup(msg, c, n);
377
 
        MSG_ADD_STRING("attributeID", s);
378
 
        c += n;
379
 
        c = skip_spaces(c);     
380
 
 
381
 
        while (*c != ')') {
382
 
                token = get_next_schema_token(msg, &c);
383
 
                if (!token) goto failed;
384
 
 
385
 
                switch (token->type) {
386
 
                case SCHEMA_NAME:
387
 
                        MSG_ADD_STRING("cn", token->value);
388
 
                        MSG_ADD_STRING("name", token->value);
389
 
                        MSG_ADD_STRING("lDAPDisplayName", token->value);
390
 
                        msg->dn = ldb_dn_string_compose(msg, basedn,
391
 
                                                        "CN=%s,CN=Schema,CN=Configuration",
392
 
                                                        token->value);
393
 
                        break;
394
 
 
395
 
                case SCHEMA_SUP:
396
 
                        MSG_ADD_M_STRING("subClassOf", token->value);
397
 
                        break;
398
 
 
399
 
                case SCHEMA_STRUCTURAL:
400
 
                        MSG_ADD_STRING("objectClassCategory", "1");
401
 
                        break;
402
 
 
403
 
                case SCHEMA_ABSTRACT:
404
 
                        MSG_ADD_STRING("objectClassCategory", "2");
405
 
                        break;
406
 
 
407
 
                case SCHEMA_AUXILIARY:
408
 
                        MSG_ADD_STRING("objectClassCategory", "3");
409
 
                        break;
410
 
 
411
 
                case SCHEMA_MUST:
412
 
                        MSG_ADD_M_STRING("mustContain", token->value);
413
 
                        break;
414
 
 
415
 
                case SCHEMA_MAY:
416
 
                        MSG_ADD_M_STRING("mayContain", token->value);
417
 
                        break;
418
 
 
419
 
                case SCHEMA_SINGLE_VALUE:
420
 
                        MSG_ADD_STRING("isSingleValued", "TRUE");
421
 
                        break;
422
 
 
423
 
                case SCHEMA_EQUALITY:
424
 
                        /* TODO */
425
 
                        break;
426
 
 
427
 
                case SCHEMA_ORDERING:
428
 
                        /* TODO */
429
 
                        break;
430
 
 
431
 
                case SCHEMA_SUBSTR:
432
 
                        /* TODO */
433
 
                        break;
434
 
 
435
 
                case SCHEMA_SYNTAX:
436
 
                {
437
 
                        const struct syntax_map *map = 
438
 
                                find_syntax_map_by_standard_oid(token->value);
439
 
                        if (!map) {
440
 
                                break;
441
 
                        }
442
 
                        MSG_ADD_STRING("attributeSyntax", map->AD_OID);
443
 
                        break;
444
 
                }
445
 
                case SCHEMA_DESC:
446
 
                        MSG_ADD_STRING("description", token->value);
447
 
                        break;
448
 
 
449
 
                default:
450
 
                        fprintf(stderr, "Unknown Definition: %s\n", token->value);
451
 
                }
452
 
        }
453
 
 
454
 
        talloc_steal(mem_ctx, msg);
455
 
        talloc_free(ctx);
456
 
        return msg;
457
 
 
458
 
failed:
459
 
        talloc_free(ctx);
460
 
        return NULL;
461
 
}
462
 
 
463
 
static struct schema_conv process_file(FILE *in, FILE *out)
464
 
{
465
 
        TALLOC_CTX *ctx;
466
 
        struct schema_conv ret;
467
 
        char *entry;
468
 
        int c, t, line;
469
 
        struct ldb_ldif ldif;
470
 
 
471
 
        ldif.changetype = LDB_CHANGETYPE_NONE;
472
 
 
473
 
        ctx = talloc_new(NULL);
474
 
 
475
 
        ret.count = 0;
476
 
        ret.failures = 0;
477
 
        line = 0;
478
 
 
479
 
        while ((c = fgetc(in)) != EOF) {
480
 
                line++;
481
 
                /* fprintf(stderr, "Parsing line %d\n", line); */
482
 
                if (c == '#') {
483
 
                        do {
484
 
                                c = fgetc(in);
485
 
                        } while (c != EOF && c != '\n');
486
 
                        continue;
487
 
                }
488
 
                if (c == '\n') {
489
 
                        continue;
490
 
                }
491
 
 
492
 
                t = 0;
493
 
                entry = talloc_array(ctx, char, 1024);
494
 
                if (entry == NULL) exit(-1);
495
 
 
496
 
                do { 
497
 
                        if (c == '\n') {
498
 
                                entry[t] = '\0';        
499
 
                                if (check_braces(entry) == 0) {
500
 
                                        ret.count++;
501
 
                                        ldif.msg = process_entry(ctx, entry);
502
 
                                        if (ldif.msg == NULL) {
503
 
                                                ret.failures++;
504
 
                                                fprintf(stderr, "No valid msg from entry \n[%s]\n at line %d\n", entry, line);
505
 
                                                break;
506
 
                                        }
507
 
                                        ldb_ldif_write_file(ldb_ctx, out, &ldif);
508
 
                                        break;
509
 
                                }
510
 
                                line++;
511
 
                        } else {
512
 
                                entry[t] = c;
513
 
                                t++;
514
 
                        }
515
 
                        if ((t % 1023) == 0) {
516
 
                                entry = talloc_realloc(ctx, entry, char, t + 1024);
517
 
                                if (entry == NULL) exit(-1);
518
 
                        }
519
 
                } while ((c = fgetc(in)) != EOF); 
520
 
 
521
 
                if (c != '\n') {
522
 
                        entry[t] = '\0';
523
 
                        if (check_braces(entry) == 0) {
524
 
                                ret.count++;
525
 
                                ldif.msg = process_entry(ctx, entry);
526
 
                                if (ldif.msg == NULL) {
527
 
                                        ret.failures++;
528
 
                                        fprintf(stderr, "No valid msg from entry \n[%s]\n at line %d\n", entry, line);
529
 
                                        break;
530
 
                                }
531
 
                                ldb_ldif_write_file(ldb_ctx, out, &ldif);
532
 
                        } else {
533
 
                                fprintf(stderr, "malformed entry on line %d\n", line);
534
 
                                ret.failures++;
535
 
                        }
536
 
                }
537
 
        
538
 
                if (c == EOF) break;
539
 
        }
540
 
 
541
 
        return ret;
542
 
}
543
 
 
544
 
static void usage(void)
545
 
{
546
 
        printf("Usage: oLschema2ldif -H NONE <options>\n");
547
 
        printf("\nConvert OpenLDAP schema to AD-like LDIF format\n\n");
548
 
        printf("Options:\n");
549
 
        printf("  -I inputfile     inputfile of OpenLDAP style schema otherwise STDIN\n");
550
 
        printf("  -O outputfile    outputfile otherwise STDOUT\n");
551
 
        printf("  -o options       pass options like modules to activate\n");
552
 
        printf("              e.g: -o modules:timestamps\n");
553
 
        printf("\n");
554
 
        printf("Converts records from an openLdap formatted schema to an ldif schema\n\n");
555
 
        exit(1);
556
 
}
557
 
 
558
 
 int main(int argc, const char **argv)
559
 
{
560
 
        TALLOC_CTX *ctx;
561
 
        struct schema_conv ret;
562
 
        struct ldb_cmdline *options;
563
 
        FILE *in = stdin;
564
 
        FILE *out = stdout;
565
 
        ldb_global_init();
566
 
 
567
 
        ctx = talloc_new(NULL);
568
 
        ldb_ctx = ldb_init(ctx);
569
 
 
570
 
        setenv("LDB_URL", "NONE", 1);
571
 
        options = ldb_cmdline_process(ldb_ctx, argc, argv, usage);
572
 
 
573
 
        if (options->basedn == NULL) {
574
 
                perror("Base DN not specified");
575
 
                exit(1);
576
 
        } else {
577
 
                basedn = ldb_dn_explode(ctx, options->basedn);
578
 
                if (basedn == NULL) {
579
 
                        perror("Malformed Base DN");
580
 
                        exit(1);
581
 
                }
582
 
        }
583
 
 
584
 
        if (options->input) {
585
 
                in = fopen(options->input, "r");
586
 
                if (!in) {
587
 
                        perror(options->input);
588
 
                        exit(1);
589
 
                }
590
 
        }
591
 
        if (options->output) {
592
 
                out = fopen(options->output, "w");
593
 
                if (!out) {
594
 
                        perror(options->output);
595
 
                        exit(1);
596
 
                }
597
 
        }
598
 
 
599
 
        ret = process_file(in, out);
600
 
 
601
 
        fclose(in);
602
 
        fclose(out);
603
 
 
604
 
        printf("Converted %d records with %d failures\n", ret.count, ret.failures);
605
 
 
606
 
        return 0;
607
 
}