LCOV - code coverage report
Current view: top level - source4/dsdb/schema - schema_convert_to_ol.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 0 182 0.0 %
Date: 2024-06-13 04:01:37 Functions: 0 2 0.0 %

          Line data    Source code
       1             : /* 
       2             :    schema conversion routines
       3             : 
       4             :    Copyright (C) Andrew Bartlett 2006-2008
       5             :   
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             :    
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             :    
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             :    
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "ldb.h"
      23             : #include "dsdb/samdb/samdb.h"
      24             : #include "system/locale.h"
      25             : 
      26             : #undef strcasecmp
      27             : 
      28             : #define SEPERATOR "\n  "
      29             : 
      30             : struct attr_map {
      31             :         char *old_attr;
      32             :         char *new_attr;
      33             : };
      34             : 
      35             : struct oid_map {
      36             :         char *old_oid;
      37             :         char *new_oid;
      38             : };
      39             : 
      40           0 : static char *print_schema_recursive(char *append_to_string, struct dsdb_schema *schema, const char *print_class,
      41             :                                     enum dsdb_schema_convert_target target, 
      42             :                                     const char **attrs_skip, const struct attr_map *attr_map, const struct oid_map *oid_map) 
      43             : {
      44           0 :         char *out = append_to_string;
      45             :         const struct dsdb_class *objectclass;
      46           0 :         objectclass = dsdb_class_by_lDAPDisplayName(schema, print_class);
      47           0 :         if (!objectclass) {
      48           0 :                 DEBUG(0, ("Cannot find class %s in schema\n", print_class));
      49           0 :                 return NULL;
      50             :         }
      51             : 
      52             :         do {
      53           0 :                 TALLOC_CTX *mem_ctx = talloc_new(append_to_string);
      54           0 :                 const char *name = objectclass->lDAPDisplayName;
      55           0 :                 const char *oid = objectclass->governsID_oid;
      56           0 :                 const char *subClassOf = objectclass->subClassOf;
      57           0 :                 int objectClassCategory = objectclass->objectClassCategory;
      58             :                 const char **must;
      59             :                 const char **may;
      60           0 :                 char *schema_entry = NULL;
      61           0 :                 struct ldb_val objectclass_name_as_ldb_val = data_blob_string_const(objectclass->lDAPDisplayName);
      62           0 :                 struct ldb_message_element objectclass_name_as_el = {
      63             :                         .name = "objectClass",
      64             :                         .num_values = 1,
      65             :                         .values = &objectclass_name_as_ldb_val
      66             :                 };
      67             :                 unsigned int j;
      68             :                 unsigned int attr_idx;
      69             :                 
      70           0 :                 if (!mem_ctx) {
      71           0 :                         DEBUG(0, ("Failed to create new talloc context\n"));
      72           0 :                         return NULL;
      73             :                 }
      74             : 
      75             :                 /* We have been asked to skip some attributes/objectClasses */
      76           0 :                 if (attrs_skip && str_list_check_ci(attrs_skip, name)) {
      77           0 :                         continue;
      78             :                 }
      79             : 
      80             :                 /* We might have been asked to remap this oid, due to a conflict */
      81           0 :                 for (j=0; oid_map && oid_map[j].old_oid; j++) {
      82           0 :                         if (strcasecmp(oid, oid_map[j].old_oid) == 0) {
      83           0 :                                 oid =  oid_map[j].new_oid;
      84           0 :                                 break;
      85             :                         }
      86             :                 }
      87             :                 
      88             :                 /* We might have been asked to remap this name, due to a conflict */
      89           0 :                 for (j=0; name && attr_map && attr_map[j].old_attr; j++) {
      90           0 :                         if (strcasecmp(name, attr_map[j].old_attr) == 0) {
      91           0 :                                 name =  attr_map[j].new_attr;
      92           0 :                                 break;
      93             :                         }
      94             :                 }
      95             :                 
      96             :                 /* We might have been asked to remap this subClassOf, due to a conflict */
      97           0 :                 for (j=0; subClassOf && attr_map && attr_map[j].old_attr; j++) {
      98           0 :                         if (strcasecmp(subClassOf, attr_map[j].old_attr) == 0) {
      99           0 :                                 subClassOf =  attr_map[j].new_attr;
     100           0 :                                 break;
     101             :                         }
     102             :                 }
     103             :                 
     104           0 :                 may = dsdb_full_attribute_list(mem_ctx, schema, &objectclass_name_as_el, DSDB_SCHEMA_ALL_MAY);
     105             : 
     106           0 :                 for (j=0; may && may[j]; j++) {
     107             :                         /* We might have been asked to remap this name, due to a conflict */ 
     108           0 :                         for (attr_idx=0; attr_map && attr_map[attr_idx].old_attr; attr_idx++) { 
     109           0 :                                 if (strcasecmp(may[j], attr_map[attr_idx].old_attr) == 0) { 
     110           0 :                                         may[j] =  attr_map[attr_idx].new_attr; 
     111           0 :                                         break;                          
     112             :                                 }                                       
     113             :                         }                                               
     114             :                 }
     115             : 
     116           0 :                 must = dsdb_full_attribute_list(mem_ctx, schema, &objectclass_name_as_el, DSDB_SCHEMA_ALL_MUST);
     117             : 
     118           0 :                 for (j=0; must && must[j]; j++) {
     119             :                         /* We might have been asked to remap this name, due to a conflict */ 
     120           0 :                         for (attr_idx=0; attr_map && attr_map[attr_idx].old_attr; attr_idx++) { 
     121           0 :                                 if (strcasecmp(must[j], attr_map[attr_idx].old_attr) == 0) { 
     122           0 :                                         must[j] =  attr_map[attr_idx].new_attr; 
     123           0 :                                         break;                          
     124             :                                 }                                       
     125             :                         }                                               
     126             :                 }
     127             : 
     128           0 :                 schema_entry = schema_class_description(mem_ctx, target, 
     129             :                                                         SEPERATOR,
     130             :                                                         oid, 
     131             :                                                         name,
     132             :                                                         NULL, 
     133             :                                                         subClassOf,
     134             :                                                         objectClassCategory,
     135             :                                                         must,
     136             :                                                         may,
     137             :                                                         NULL);
     138           0 :                 if (schema_entry == NULL) {
     139           0 :                         talloc_free(mem_ctx);
     140           0 :                         DEBUG(0, ("failed to generate schema description for %s\n", name));
     141           0 :                         return NULL;
     142             :                 }
     143             : 
     144           0 :                 switch (target) {
     145           0 :                 case TARGET_OPENLDAP:
     146           0 :                         out = talloc_asprintf_append(out, "objectclass %s\n\n", schema_entry);
     147           0 :                         break;
     148           0 :                 case TARGET_FEDORA_DS:
     149           0 :                         out = talloc_asprintf_append(out, "objectClasses: %s\n", schema_entry);
     150           0 :                         break;
     151           0 :                 default:
     152           0 :                         talloc_free(mem_ctx);
     153           0 :                         DEBUG(0,(__location__ " Wrong type of target %u!", (unsigned)target));
     154           0 :                         return NULL;
     155             :                 }
     156           0 :                 talloc_free(mem_ctx);
     157             :         } while (0);
     158             : 
     159             :         
     160           0 :         for (objectclass=schema->classes; objectclass; objectclass = objectclass->next) {
     161           0 :                 if (ldb_attr_cmp(objectclass->subClassOf, print_class) == 0 
     162           0 :                     && ldb_attr_cmp(objectclass->lDAPDisplayName, print_class) != 0) {
     163           0 :                         out = print_schema_recursive(out, schema, objectclass->lDAPDisplayName, 
     164             :                                                      target, attrs_skip, attr_map, oid_map);
     165             :                 }
     166             :         }
     167           0 :         return out;
     168             : }
     169             : 
     170             : /* Routine to linearise our internal schema into the format that
     171             :    OpenLDAP and Fedora DS use for their backend.  
     172             : 
     173             :    The 'mappings' are of a format like:
     174             : 
     175             : #Standard OpenLDAP attributes
     176             : labeledURI
     177             : #The memberOf plugin provides this attribute
     178             : memberOf
     179             : #These conflict with OpenLDAP builtins
     180             : attributeTypes:samba4AttributeTypes
     181             : 2.5.21.5:1.3.6.1.4.1.7165.4.255.7
     182             : 
     183             : */
     184             : 
     185             : 
     186           0 : char *dsdb_convert_schema_to_openldap(struct ldb_context *ldb, char *target_str, const char *mappings) 
     187             : {
     188             :         /* Read list of attributes to skip, OIDs to map */
     189           0 :         TALLOC_CTX *mem_ctx = talloc_new(ldb);
     190             :         char *line;
     191             :         char *out;
     192           0 :         const char **attrs_skip = NULL;
     193           0 :         unsigned int num_skip = 0;
     194           0 :         struct oid_map *oid_map = NULL;
     195           0 :         unsigned int num_oid_maps = 0;
     196           0 :         struct attr_map *attr_map = NULL;
     197           0 :         unsigned int num_attr_maps = 0;
     198             :         struct dsdb_attribute *attribute;
     199             :         struct dsdb_schema *schema;
     200             :         enum dsdb_schema_convert_target target;
     201             : 
     202           0 :         char *next_line = talloc_strdup(mem_ctx, mappings);
     203             : 
     204           0 :         if (!target_str || strcasecmp(target_str, "openldap") == 0) {
     205           0 :                 target = TARGET_OPENLDAP;
     206           0 :         } else if (strcasecmp(target_str, "fedora-ds") == 0) {
     207           0 :                 target = TARGET_FEDORA_DS;
     208             :         } else {
     209           0 :                 talloc_free(mem_ctx);
     210           0 :                 DEBUG(0, ("Invalid target type for schema conversion %s\n", target_str));
     211           0 :                 return NULL;
     212             :         }
     213             : 
     214             :         /* The mappings are line-separated, and specify details such as OIDs to skip etc */
     215             :         while (1) {
     216           0 :                 line = next_line;
     217           0 :                 next_line = strchr(line, '\n');
     218           0 :                 if (!next_line) {
     219           0 :                         break;
     220             :                 }
     221           0 :                 next_line[0] = '\0';
     222           0 :                 next_line++;
     223             : 
     224             :                 /* Blank Line */
     225           0 :                 if (line[0] == '\0') {
     226           0 :                         continue;
     227             :                 }
     228             :                 /* Comment */
     229           0 :                 if (line[0] == '#') {
     230           0 :                         continue;
     231             :                 }
     232             : 
     233           0 :                 if (isdigit(line[0])) {
     234           0 :                         char *p = strchr(line, ':');
     235           0 :                         if (!p) {
     236           0 :                                 DEBUG(0, ("schema mapping file line has OID but no OID to map to: %s\n", line));
     237           0 :                                 return NULL;
     238             :                         }
     239           0 :                         p[0] = '\0';
     240           0 :                         p++;
     241           0 :                         oid_map = talloc_realloc(mem_ctx, oid_map, struct oid_map, num_oid_maps + 2);
     242           0 :                         trim_string(line, " ", " ");
     243           0 :                         oid_map[num_oid_maps].old_oid = talloc_strdup(oid_map, line);
     244           0 :                         trim_string(p, " ", " ");
     245           0 :                         oid_map[num_oid_maps].new_oid = p;
     246           0 :                         num_oid_maps++;
     247           0 :                         oid_map[num_oid_maps].old_oid = NULL;
     248             :                 } else {
     249           0 :                         char *p = strchr(line, ':');
     250           0 :                         if (p) {
     251             :                                 /* remap attribute/objectClass */
     252           0 :                                 p[0] = '\0';
     253           0 :                                 p++;
     254           0 :                                 attr_map = talloc_realloc(mem_ctx, attr_map, struct attr_map, num_attr_maps + 2);
     255           0 :                                 trim_string(line, " ", " ");
     256           0 :                                 attr_map[num_attr_maps].old_attr = talloc_strdup(attr_map, line);
     257           0 :                                 trim_string(p, " ", " ");
     258           0 :                                 attr_map[num_attr_maps].new_attr = p;
     259           0 :                                 num_attr_maps++;
     260           0 :                                 attr_map[num_attr_maps].old_attr = NULL;
     261             :                         } else {
     262             :                                 /* skip attribute/objectClass */
     263           0 :                                 attrs_skip = talloc_realloc(mem_ctx, attrs_skip, const char *, num_skip + 2);
     264           0 :                                 trim_string(line, " ", " ");
     265           0 :                                 attrs_skip[num_skip] = talloc_strdup(attrs_skip, line);
     266           0 :                                 num_skip++;
     267           0 :                                 attrs_skip[num_skip] = NULL;
     268             :                         }
     269             :                 }
     270             :         }
     271             : 
     272           0 :         schema = dsdb_get_schema(ldb, mem_ctx);
     273           0 :         if (!schema) {
     274           0 :                 talloc_free(mem_ctx);
     275           0 :                 DEBUG(0, ("No schema on ldb to convert!\n"));
     276           0 :                 return NULL;
     277             :         }
     278             : 
     279           0 :         switch (target) {
     280           0 :         case TARGET_OPENLDAP:
     281           0 :                 out = talloc_strdup(mem_ctx, "");
     282           0 :                 break;
     283           0 :         case TARGET_FEDORA_DS:
     284           0 :                 out = talloc_strdup(mem_ctx, "dn: cn=schema\n");
     285           0 :                 break;
     286           0 :         default:
     287           0 :                 talloc_free(mem_ctx);
     288           0 :                 DEBUG(0,(__location__ " Wrong type of target %u!", (unsigned)target));
     289           0 :                 return NULL;
     290             :         }
     291             : 
     292           0 :         for (attribute=schema->attributes; attribute; attribute = attribute->next) {
     293           0 :                 const char *name = attribute->lDAPDisplayName;
     294           0 :                 const char *oid = attribute->attributeID_oid;
     295           0 :                 const char *syntax = attribute->attributeSyntax_oid;
     296           0 :                 const char *equality = NULL, *substring = NULL;
     297           0 :                 bool single_value = attribute->isSingleValued;
     298             : 
     299           0 :                 char *schema_entry = NULL;
     300             :                 unsigned int j;
     301             : 
     302             :                 /* We have been asked to skip some attributes/objectClasses */
     303           0 :                 if (attrs_skip && str_list_check_ci(attrs_skip, name)) {
     304           0 :                         continue;
     305             :                 }
     306             : 
     307             :                 /* We might have been asked to remap this oid, due to a conflict */
     308           0 :                 for (j=0; oid && oid_map && oid_map[j].old_oid; j++) {
     309           0 :                         if (strcasecmp(oid, oid_map[j].old_oid) == 0) {
     310           0 :                                 oid =  oid_map[j].new_oid;
     311           0 :                                 break;
     312             :                         }
     313             :                 }
     314             :                 
     315           0 :                 if (attribute->syntax) {
     316             :                         /* We might have been asked to remap this oid,
     317             :                          * due to a conflict, or lack of
     318             :                          * implementation */
     319           0 :                         syntax = attribute->syntax->ldap_oid;
     320             :                         /* We might have been asked to remap this oid, due to a conflict */
     321           0 :                         for (j=0; syntax && oid_map && oid_map[j].old_oid; j++) {
     322           0 :                                 if (strcasecmp(syntax, oid_map[j].old_oid) == 0) {
     323           0 :                                         syntax =  oid_map[j].new_oid;
     324           0 :                                         break;
     325             :                                 }
     326             :                         }
     327             :                         
     328           0 :                         equality = attribute->syntax->equality;
     329           0 :                         substring = attribute->syntax->substring;
     330             :                 }
     331             : 
     332             :                 /* We might have been asked to remap this name, due to a conflict */
     333           0 :                 for (j=0; name && attr_map && attr_map[j].old_attr; j++) {
     334           0 :                         if (strcasecmp(name, attr_map[j].old_attr) == 0) {
     335           0 :                                 name =  attr_map[j].new_attr;
     336           0 :                                 break;
     337             :                         }
     338             :                 }
     339             :                 
     340           0 :                 schema_entry = schema_attribute_description(mem_ctx, 
     341             :                                                             target, 
     342             :                                                             SEPERATOR, 
     343             :                                                             oid, 
     344             :                                                             name, 
     345             :                                                             equality, 
     346             :                                                             substring, 
     347             :                                                             syntax, 
     348             :                                                             single_value, 
     349             :                                                             false,
     350             :                                                             NULL, NULL,
     351             :                                                             NULL, NULL,
     352             :                                                             false, false);
     353             : 
     354           0 :                 if (schema_entry == NULL) {
     355           0 :                         talloc_free(mem_ctx);
     356           0 :                         DEBUG(0, ("failed to generate attribute description for %s\n", name));
     357           0 :                         return NULL;
     358             :                 }
     359             : 
     360           0 :                 switch (target) {
     361           0 :                 case TARGET_OPENLDAP:
     362           0 :                         out = talloc_asprintf_append(out, "attributetype %s\n\n", schema_entry);
     363           0 :                         break;
     364           0 :                 case TARGET_FEDORA_DS:
     365           0 :                         out = talloc_asprintf_append(out, "attributeTypes: %s\n", schema_entry);
     366           0 :                         break;
     367           0 :                 default:
     368           0 :                         talloc_free(mem_ctx);
     369           0 :                         DEBUG(0,(__location__ " Wrong type of target %u!", (unsigned)target));
     370           0 :                         return NULL;
     371             :                 }
     372             :         }
     373             : 
     374           0 :         out = print_schema_recursive(out, schema, "top", target, attrs_skip, attr_map, oid_map);
     375             : 
     376           0 :         talloc_steal(ldb, out);
     377           0 :         talloc_free(mem_ctx);
     378             : 
     379           0 :         return out;
     380             : }
     381             : 

Generated by: LCOV version 1.13