root/source3/lib/ldb/tools/ad2oLschema.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. usage
  2. fetch_attrs_schema
  3. fetch_oc_recursive
  4. fetch_objectclass_schema
  5. find_schema_dn
  6. process_convert
  7. main

   1 /* 
   2    ldb database library
   3 
   4    Copyright (C) Andrew Bartlett 2006
   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: ad2oLschema
  28  *
  29  *  Description: utility to convert an AD schema into the format required by OpenLDAP
  30  *
  31  *  Author: Andrew Tridgell
  32  */
  33 
  34 #include "includes.h"
  35 #include "ldb/include/includes.h"
  36 #include "system/locale.h"
  37 #include "ldb/tools/cmdline.h"
  38 #include "ldb/tools/convert.h"
  39 
  40 struct schema_conv {
  41         int count;
  42         int skipped;
  43         int failures;
  44 };
  45 
  46 enum convert_target {
  47         TARGET_OPENLDAP,
  48         TARGET_FEDORA_DS
  49 };
  50         
  51 
  52 static void usage(void)
     /* [<][>][^][v][top][bottom][index][help] */
  53 {
  54         printf("Usage: ad2oLschema <options>\n");
  55         printf("\nConvert AD-like LDIF to OpenLDAP schema format\n\n");
  56         printf("Options:\n");
  57         printf("  -I inputfile     inputfile of mapped OIDs and skipped attributes/ObjectClasses");
  58         printf("  -H url           LDB or LDAP server to read schmea from\n");
  59         printf("  -O outputfile    outputfile otherwise STDOUT\n");
  60         printf("  -o options       pass options like modules to activate\n");
  61         printf("              e.g: -o modules:timestamps\n");
  62         printf("\n");
  63         printf("Converts records from an AD-like LDIF schema into an openLdap formatted schema\n\n");
  64         exit(1);
  65 }
  66 
  67 static int fetch_attrs_schema(struct ldb_context *ldb, struct ldb_dn *schemadn,
     /* [<][>][^][v][top][bottom][index][help] */
  68                               TALLOC_CTX *mem_ctx, 
  69                               struct ldb_result **attrs_res)
  70 {
  71         TALLOC_CTX *local_ctx = talloc_new(mem_ctx);
  72         int ret;
  73         const char *attrs[] = {
  74                 "lDAPDisplayName",
  75                 "isSingleValued",
  76                 "attributeID",
  77                 "attributeSyntax",
  78                 "description",          
  79                 NULL
  80         };
  81 
  82         if (!local_ctx) {
  83                 return LDB_ERR_OPERATIONS_ERROR;
  84         }
  85         
  86         /* Downlaod schema */
  87         ret = ldb_search(ldb, ldb, attrs_res, schemadn, LDB_SCOPE_SUBTREE, 
  88                          attrs, "objectClass=attributeSchema");
  89         if (ret != LDB_SUCCESS) {
  90                 printf("Search failed: %s\n", ldb_errstring(ldb));
  91                 return LDB_ERR_OPERATIONS_ERROR;
  92         }
  93         
  94         return ret;
  95 }
  96 
  97 static const char *oc_attrs[] = {
  98         "lDAPDisplayName",
  99         "mayContain",
 100         "mustContain",
 101         "systemMayContain",
 102         "systemMustContain",
 103         "objectClassCategory",
 104         "governsID",
 105         "description",
 106         "subClassOf",
 107         NULL
 108 };
 109 
 110 static int fetch_oc_recursive(struct ldb_context *ldb, struct ldb_dn *schemadn, 
     /* [<][>][^][v][top][bottom][index][help] */
 111                               TALLOC_CTX *mem_ctx, 
 112                               struct ldb_result *search_from,
 113                               struct ldb_result *res_list)
 114 {
 115         int i;
 116         int ret = 0;
 117         for (i=0; i < search_from->count; i++) {
 118                 struct ldb_result *res;
 119                 const char *name = ldb_msg_find_attr_as_string(search_from->msgs[i], 
 120                                                                "lDAPDisplayname", NULL);
 121 
 122                 ret = ldb_search(ldb, ldb, &res, schemadn, LDB_SCOPE_SUBTREE, 
 123                                  oc_attrs, "(&(&(objectClass=classSchema)(subClassOf=%s))(!(lDAPDisplayName=%s)))", 
 124                                                name, name);
 125                 if (ret != LDB_SUCCESS) {
 126                         printf("Search failed: %s\n", ldb_errstring(ldb));
 127                         return ret;
 128                 }
 129                 
 130                 talloc_steal(mem_ctx, res);
 131 
 132                 res_list->msgs = talloc_realloc(res_list, res_list->msgs, 
 133                                                 struct ldb_message *, res_list->count + 2);
 134                 if (!res_list->msgs) {
 135                         return LDB_ERR_OPERATIONS_ERROR;
 136                 }
 137                 res_list->msgs[res_list->count] = talloc_move(res_list, 
 138                                                               &search_from->msgs[i]);
 139                 res_list->count++;
 140                 res_list->msgs[res_list->count] = NULL;
 141 
 142                 if (res->count > 0) {
 143                         ret = fetch_oc_recursive(ldb, schemadn, mem_ctx, res, res_list); 
 144                 }
 145                 if (ret != LDB_SUCCESS) {
 146                         return ret;
 147                 }
 148         }
 149         return ret;
 150 }
 151 
 152 static int fetch_objectclass_schema(struct ldb_context *ldb, struct ldb_dn *schemadn, 
     /* [<][>][^][v][top][bottom][index][help] */
 153                                     TALLOC_CTX *mem_ctx, 
 154                                     struct ldb_result **objectclasses_res)
 155 {
 156         TALLOC_CTX *local_ctx = talloc_new(mem_ctx);
 157         struct ldb_result *top_res, *ret_res;
 158         int ret;
 159         if (!local_ctx) {
 160                 return LDB_ERR_OPERATIONS_ERROR;
 161         }
 162         
 163         /* Downlaod 'top' */
 164         ret = ldb_search(ldb, ldb, &top_res, schemadn, LDB_SCOPE_SUBTREE, 
 165                          oc_attrs, "(&(objectClass=classSchema)(lDAPDisplayName=top))");
 166         if (ret != LDB_SUCCESS) {
 167                 printf("Search failed: %s\n", ldb_errstring(ldb));
 168                 return LDB_ERR_OPERATIONS_ERROR;
 169         }
 170 
 171         talloc_steal(local_ctx, top_res);
 172 
 173         if (top_res->count != 1) {
 174                 return LDB_ERR_OPERATIONS_ERROR;
 175         }
 176 
 177         ret_res = talloc_zero(local_ctx, struct ldb_result);
 178         if (!ret_res) {
 179                 return LDB_ERR_OPERATIONS_ERROR;
 180         }
 181 
 182         ret = fetch_oc_recursive(ldb, schemadn, local_ctx, top_res, ret_res); 
 183 
 184         if (ret != LDB_SUCCESS) {
 185                 printf("Search failed: %s\n", ldb_errstring(ldb));
 186                 return LDB_ERR_OPERATIONS_ERROR;
 187         }
 188 
 189         *objectclasses_res = talloc_move(mem_ctx, &ret_res);
 190         return ret;
 191 }
 192 
 193 static struct ldb_dn *find_schema_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx) 
     /* [<][>][^][v][top][bottom][index][help] */
 194 {
 195         const char *rootdse_attrs[] = {"schemaNamingContext", NULL};
 196         struct ldb_dn *schemadn;
 197         struct ldb_dn *basedn = ldb_dn_explode(mem_ctx, "");
 198         struct ldb_result *rootdse_res;
 199         int ldb_ret;
 200         if (!basedn) {
 201                 return NULL;
 202         }
 203         
 204         /* Search for rootdse */
 205         ldb_ret = ldb_search(ldb, ldb, &rootdse_res, basedn, LDB_SCOPE_BASE, rootdse_attrs, NULL);
 206         if (ldb_ret != LDB_SUCCESS) {
 207                 printf("Search failed: %s\n", ldb_errstring(ldb));
 208                 return NULL;
 209         }
 210         
 211         talloc_steal(mem_ctx, rootdse_res);
 212 
 213         if (rootdse_res->count != 1) {
 214                 printf("Failed to find rootDSE");
 215                 return NULL;
 216         }
 217         
 218         /* Locate schema */
 219         schemadn = ldb_msg_find_attr_as_dn(mem_ctx, rootdse_res->msgs[0], "schemaNamingContext");
 220         if (!schemadn) {
 221                 return NULL;
 222         }
 223 
 224         talloc_free(rootdse_res);
 225         return schemadn;
 226 }
 227 
 228 #define IF_NULL_FAIL_RET(x) do {     \
 229                 if (!x) {               \
 230                         ret.failures++; \
 231                         return ret;     \
 232                 }                       \
 233         } while (0) 
 234 
 235 
 236 static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_target target, FILE *in, FILE *out) 
     /* [<][>][^][v][top][bottom][index][help] */
 237 {
 238         /* Read list of attributes to skip, OIDs to map */
 239         TALLOC_CTX *mem_ctx = talloc_new(ldb);
 240         char *line;
 241         const char **attrs_skip = NULL;
 242         int num_skip = 0;
 243         struct oid_map {
 244                 char *old_oid;
 245                 char *new_oid;
 246         } *oid_map = NULL;
 247         int num_maps = 0;
 248         struct ldb_result *attrs_res, *objectclasses_res;
 249         struct ldb_dn *schemadn;
 250         struct schema_conv ret;
 251 
 252         int ldb_ret, i;
 253 
 254         ret.count = 0;
 255         ret.skipped = 0;
 256         ret.failures = 0;
 257 
 258         while ((line = afdgets(fileno(in), mem_ctx, 0))) {
 259                 /* Blank Line */
 260                 if (line[0] == '\0') {
 261                         continue;
 262                 }
 263                 /* Comment */
 264                 if (line[0] == '#') {
 265                         continue;
 266                 }
 267                 if (isdigit(line[0])) {
 268                         char *p = strchr(line, ':');
 269                         IF_NULL_FAIL_RET(p);
 270                         if (!p) {
 271                                 ret.failures = 1;
 272                                 return ret;
 273                         }
 274                         p[0] = '\0';
 275                         p++;
 276                         oid_map = talloc_realloc(mem_ctx, oid_map, struct oid_map, num_maps + 2);
 277                         trim_string(line, " ", " ");
 278                         oid_map[num_maps].old_oid = talloc_move(oid_map, &line);
 279                         trim_string(p, " ", " ");
 280                         oid_map[num_maps].new_oid = p;
 281                         num_maps++;
 282                         oid_map[num_maps].old_oid = NULL;
 283                 } else {
 284                         attrs_skip = talloc_realloc(mem_ctx, attrs_skip, const char *, num_skip + 2);
 285                         trim_string(line, " ", " ");
 286                         attrs_skip[num_skip] = talloc_move(attrs_skip, &line);
 287                         num_skip++;
 288                         attrs_skip[num_skip] = NULL;
 289                 }
 290         }
 291 
 292         schemadn = find_schema_dn(ldb, mem_ctx);
 293         if (!schemadn) {
 294                 printf("Failed to find schema DN: %s\n", ldb_errstring(ldb));
 295                 ret.failures = 1;
 296                 return ret;
 297         }
 298         
 299         ldb_ret = fetch_attrs_schema(ldb, schemadn, mem_ctx, &attrs_res);
 300         if (ldb_ret != LDB_SUCCESS) {
 301                 printf("Failed to fetch attribute schema: %s\n", ldb_errstring(ldb));
 302                 ret.failures = 1;
 303                 return ret;
 304         }
 305         
 306         switch (target) {
 307         case TARGET_OPENLDAP:
 308                 break;
 309         case TARGET_FEDORA_DS:
 310                 fprintf(out, "dn: cn=schema\n");
 311                 break;
 312         }
 313 
 314         for (i=0; i < attrs_res->count; i++) {
 315                 struct ldb_message *msg = attrs_res->msgs[i];
 316 
 317                 const char *name = ldb_msg_find_attr_as_string(msg, "lDAPDisplayName", NULL);
 318                 const char *description = ldb_msg_find_attr_as_string(msg, "description", NULL);
 319                 const char *oid = ldb_msg_find_attr_as_string(msg, "attributeID", NULL);
 320                 const char *syntax = ldb_msg_find_attr_as_string(msg, "attributeSyntax", NULL);
 321                 BOOL single_value = ldb_msg_find_attr_as_bool(msg, "isSingleValued", False);
 322                 const struct syntax_map *map = find_syntax_map_by_ad_oid(syntax);
 323                 char *schema_entry = NULL;
 324                 int j;
 325 
 326                 /* We have been asked to skip some attributes/objectClasses */
 327                 if (attrs_skip && str_list_check_ci(attrs_skip, name)) {
 328                         ret.skipped++;
 329                         continue;
 330                 }
 331 
 332                 /* We might have been asked to remap this oid, due to a conflict */
 333                 for (j=0; oid && oid_map[j].old_oid; j++) {
 334                         if (strcmp(oid, oid_map[j].old_oid) == 0) {
 335                                 oid =  oid_map[j].new_oid;
 336                                 break;
 337                         }
 338                 }
 339                 
 340                 switch (target) {
 341                 case TARGET_OPENLDAP:
 342                         schema_entry = talloc_asprintf(mem_ctx, 
 343                                                        "attributetype (\n"
 344                                                        "  %s\n", oid);
 345                         break;
 346                 case TARGET_FEDORA_DS:
 347                         schema_entry = talloc_asprintf(mem_ctx, 
 348                                                        "attributeTypes: (\n"
 349                                                        "  %s\n", oid);
 350                         break;
 351                 }
 352                 IF_NULL_FAIL_RET(schema_entry);
 353 
 354                 schema_entry = talloc_asprintf_append(schema_entry, 
 355                                                       "  NAME '%s'\n", name);
 356                 IF_NULL_FAIL_RET(schema_entry);
 357 
 358                 if (description) {
 359                         schema_entry = talloc_asprintf_append(schema_entry, 
 360                                                               "  DESC %s\n", description);
 361                         IF_NULL_FAIL_RET(schema_entry);
 362                 }
 363 
 364                 if (map) {
 365                         const char *syntax_oid;
 366                         if (map->equality) {
 367                                 schema_entry = talloc_asprintf_append(schema_entry, 
 368                                                                       "  EQUALITY %s\n", map->equality);
 369                                 IF_NULL_FAIL_RET(schema_entry);
 370                         }
 371                         if (map->substring) {
 372                                 schema_entry = talloc_asprintf_append(schema_entry, 
 373                                                                       "  SUBSTR %s\n", map->substring);
 374                                 IF_NULL_FAIL_RET(schema_entry);
 375                         }
 376                         syntax_oid = map->Standard_OID;
 377                         /* We might have been asked to remap this oid,
 378                          * due to a conflict, or lack of
 379                          * implementation */
 380                         for (j=0; syntax_oid && oid_map[j].old_oid; j++) {
 381                                 if (strcmp(syntax_oid, oid_map[j].old_oid) == 0) {
 382                                         syntax_oid =  oid_map[j].new_oid;
 383                                         break;
 384                                 }
 385                         }
 386                         schema_entry = talloc_asprintf_append(schema_entry, 
 387                                                               "  SYNTAX %s\n", syntax_oid);
 388                         IF_NULL_FAIL_RET(schema_entry);
 389                 }
 390 
 391                 if (single_value) {
 392                         schema_entry = talloc_asprintf_append(schema_entry, 
 393                                                               "  SINGLE-VALUE\n");
 394                         IF_NULL_FAIL_RET(schema_entry);
 395                 }
 396                 
 397                 schema_entry = talloc_asprintf_append(schema_entry, 
 398                                                       "  )");
 399 
 400                 switch (target) {
 401                 case TARGET_OPENLDAP:
 402                         fprintf(out, "%s\n\n", schema_entry);
 403                         break;
 404                 case TARGET_FEDORA_DS:
 405                         fprintf(out, "%s\n", schema_entry);
 406                         break;
 407                 }
 408                 ret.count++;
 409         }
 410 
 411         ldb_ret = fetch_objectclass_schema(ldb, schemadn, mem_ctx, &objectclasses_res);
 412         if (ldb_ret != LDB_SUCCESS) {
 413                 printf("Failed to fetch objectClass schema elements: %s\n", ldb_errstring(ldb));
 414                 ret.failures = 1;
 415                 return ret;
 416         }
 417         
 418         for (i=0; i < objectclasses_res->count; i++) {
 419                 struct ldb_message *msg = objectclasses_res->msgs[i];
 420                 const char *name = ldb_msg_find_attr_as_string(msg, "lDAPDisplayName", NULL);
 421                 const char *description = ldb_msg_find_attr_as_string(msg, "description", NULL);
 422                 const char *oid = ldb_msg_find_attr_as_string(msg, "governsID", NULL);
 423                 const char *subClassOf = ldb_msg_find_attr_as_string(msg, "subClassOf", NULL);
 424                 int objectClassCategory = ldb_msg_find_attr_as_int(msg, "objectClassCategory", 0);
 425                 struct ldb_message_element *must = ldb_msg_find_element(msg, "mustContain");
 426                 struct ldb_message_element *sys_must = ldb_msg_find_element(msg, "systemMustContain");
 427                 struct ldb_message_element *may = ldb_msg_find_element(msg, "mayContain");
 428                 struct ldb_message_element *sys_may = ldb_msg_find_element(msg, "systemMayContain");
 429                 char *schema_entry = NULL;
 430                 int j;
 431 
 432                 /* We have been asked to skip some attributes/objectClasses */
 433                 if (attrs_skip && str_list_check_ci(attrs_skip, name)) {
 434                         ret.skipped++;
 435                         continue;
 436                 }
 437 
 438                 /* We might have been asked to remap this oid, due to a conflict */
 439                 for (j=0; oid_map[j].old_oid; j++) {
 440                         if (strcmp(oid, oid_map[j].old_oid) == 0) {
 441                                 oid =  oid_map[j].new_oid;
 442                                 break;
 443                         }
 444                 }
 445                 
 446                 switch (target) {
 447                 case TARGET_OPENLDAP:
 448                         schema_entry = talloc_asprintf(mem_ctx, 
 449                                                        "objectclass (\n"
 450                                                        "  %s\n", oid);
 451                         break;
 452                 case TARGET_FEDORA_DS:
 453                         schema_entry = talloc_asprintf(mem_ctx, 
 454                                                        "objectClasses: (\n"
 455                                                        "  %s\n", oid);
 456                         break;
 457                 }
 458                 IF_NULL_FAIL_RET(schema_entry);
 459                 if (!schema_entry) {
 460                         ret.failures++;
 461                         break;
 462                 }
 463 
 464                 schema_entry = talloc_asprintf_append(schema_entry, 
 465                                                       "  NAME '%s'\n", name);
 466                 IF_NULL_FAIL_RET(schema_entry);
 467 
 468                 if (!schema_entry) return ret;
 469 
 470                 if (description) {
 471                         schema_entry = talloc_asprintf_append(schema_entry, 
 472                                                               "  DESC %s\n", description);
 473                         IF_NULL_FAIL_RET(schema_entry);
 474                 }
 475 
 476                 if (subClassOf) {
 477                         schema_entry = talloc_asprintf_append(schema_entry, 
 478                                                               "  SUP %s\n", subClassOf);
 479                         IF_NULL_FAIL_RET(schema_entry);
 480                 }
 481                 
 482                 switch (objectClassCategory) {
 483                 case 1:
 484                         schema_entry = talloc_asprintf_append(schema_entry, 
 485                                                               "  STRUCTURAL\n");
 486                         IF_NULL_FAIL_RET(schema_entry);
 487                         break;
 488                 case 2:
 489                         schema_entry = talloc_asprintf_append(schema_entry, 
 490                                                               "  ABSTRACT\n");
 491                         IF_NULL_FAIL_RET(schema_entry);
 492                         break;
 493                 case 3:
 494                         schema_entry = talloc_asprintf_append(schema_entry, 
 495                                                               "  AUXILIARY\n");
 496                         IF_NULL_FAIL_RET(schema_entry);
 497                         break;
 498                 }
 499 
 500 #define APPEND_ATTRS(attributes) \
 501                 do {                                            \
 502                         int k;                                          \
 503                         for (k=0; attributes && k < attributes->num_values; k++) { \
 504                                 schema_entry = talloc_asprintf_append(schema_entry, \
 505                                                                       " %s", \
 506                                                                       (const char *)attributes->values[k].data); \
 507                                 IF_NULL_FAIL_RET(schema_entry);         \
 508                                 if (k != (attributes->num_values - 1)) { \
 509                                         schema_entry = talloc_asprintf_append(schema_entry, \
 510                                                                               " $"); \
 511                                         IF_NULL_FAIL_RET(schema_entry); \
 512                                         if (target == TARGET_OPENLDAP && ((k+1)%5 == 0)) { \
 513                                                 schema_entry = talloc_asprintf_append(schema_entry, \
 514                                                                                       "\n  "); \
 515                                                 IF_NULL_FAIL_RET(schema_entry); \
 516                                         }                               \
 517                                 }                                       \
 518                         }                                               \
 519                 } while (0)
 520 
 521                 if (must || sys_must) {
 522                         schema_entry = talloc_asprintf_append(schema_entry, 
 523                                                               "  MUST (");
 524                         IF_NULL_FAIL_RET(schema_entry);
 525 
 526                         APPEND_ATTRS(must);
 527                         if (must && sys_must) {
 528                                 schema_entry = talloc_asprintf_append(schema_entry, \
 529                                                                       " $"); \
 530                         }
 531                         APPEND_ATTRS(sys_must);
 532                         
 533                         schema_entry = talloc_asprintf_append(schema_entry, 
 534                                                               " )\n");
 535                         IF_NULL_FAIL_RET(schema_entry);
 536                 }
 537 
 538                 if (may || sys_may) {
 539                         schema_entry = talloc_asprintf_append(schema_entry, 
 540                                                               "  MAY (");
 541                         IF_NULL_FAIL_RET(schema_entry);
 542 
 543                         APPEND_ATTRS(may);
 544                         if (may && sys_may) {
 545                                 schema_entry = talloc_asprintf_append(schema_entry, \
 546                                                                       " $"); \
 547                         }
 548                         APPEND_ATTRS(sys_may);
 549                         
 550                         schema_entry = talloc_asprintf_append(schema_entry, 
 551                                                               " )\n");
 552                         IF_NULL_FAIL_RET(schema_entry);
 553                 }
 554 
 555                 schema_entry = talloc_asprintf_append(schema_entry, 
 556                                                       "  )");
 557 
 558                 switch (target) {
 559                 case TARGET_OPENLDAP:
 560                         fprintf(out, "%s\n\n", schema_entry);
 561                         break;
 562                 case TARGET_FEDORA_DS:
 563                         fprintf(out, "%s\n", schema_entry);
 564                         break;
 565                 }
 566                 ret.count++;
 567         }
 568 
 569         return ret;
 570 }
 571 
 572  int main(int argc, const char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 573 {
 574         TALLOC_CTX *ctx;
 575         struct ldb_cmdline *options;
 576         FILE *in = stdin;
 577         FILE *out = stdout;
 578         struct ldb_context *ldb;
 579         struct schema_conv ret;
 580         const char *target_str;
 581         enum convert_target target;
 582 
 583         ldb_global_init();
 584 
 585         ctx = talloc_new(NULL);
 586         ldb = ldb_init(ctx);
 587 
 588         options = ldb_cmdline_process(ldb, argc, argv, usage);
 589 
 590         if (options->input) {
 591                 in = fopen(options->input, "r");
 592                 if (!in) {
 593                         perror(options->input);
 594                         exit(1);
 595                 }
 596         }
 597         if (options->output) {
 598                 out = fopen(options->output, "w");
 599                 if (!out) {
 600                         perror(options->output);
 601                         exit(1);
 602                 }
 603         }
 604 
 605         target_str = lp_parm_string(-1, "convert", "target");
 606 
 607         if (!target_str || strcasecmp(target_str, "openldap") == 0) {
 608                 target = TARGET_OPENLDAP;
 609         } else if (strcasecmp(target_str, "fedora-ds") == 0) {
 610                 target = TARGET_FEDORA_DS;
 611         } else {
 612                 printf("Unsupported target: %s\n", target_str);
 613                 exit(1);
 614         }
 615 
 616         ret = process_convert(ldb, target, in, out);
 617 
 618         fclose(in);
 619         fclose(out);
 620 
 621         printf("Converted %d records (skipped %d) with %d failures\n", ret.count, ret.skipped, ret.failures);
 622 
 623         return 0;
 624 }

/* [<][>][^][v][top][bottom][index][help] */