Your message dated Fri, 21 Dec 2007 00:52:10 -0800
with message-id <[EMAIL PROTECTED]>
and subject line All fix_ldif code has now been dropped
has caused the attached Bug report to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what I am
talking about this indicates a serious mail system misconfiguration
somewhere.  Please contact me immediately.)

Debian bug tracking system administrator
(administrator, Debian Bugs database)

--- Begin Message ---
Package: slapd
Version: 2.2.23-0.pre5
Severity: wishlist
Tags: patch



-- System Information:
Debian Release: 3.1
  APT prefers unstable
  APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: i386 (i686)
Kernel: Linux 2.6.9-timotheus
Locale: LANG=C, [EMAIL PROTECTED]

Versions of packages slapd depends on:
ii  coreutils [fileutils]      5.2.1-2       The GNU core utilities
ii  debconf                    1.4.38        Debian configuration management sy
ii  fileutils                  5.2.1-2       The GNU file management utilities 
ii  libc6                      2.3.2.ds1-17  GNU C Library: Shared libraries an
ii  libdb4.3                   4.3.27-2      Berkeley v4.3 Database Libraries [
ii  libiodbc2                  3.52.2-3      iODBC Driver Manager
ii  libldap-2.2-7              2.2.23-0.pre5 OpenLDAP libraries
ii  libltdl3                   1.5.6-2       A system independent dlopen wrappe
ii  libperl5.8                 5.8.4-2.3     Shared Perl library
ii  libsasl2                   2.1.19-1.3    Authentication abstraction library
ii  libslp1                    1.0.11-7      OpenSLP libraries
ii  libssl0.9.7                0.9.7d-5      SSL shared libraries
ii  libwrap0                   7.6.dbs-6     Wietse Venema's TCP wrappers libra
ii  perl [libmime-base64-perl] 5.8.4-2.3     Larry Wall's Practical Extraction 
ii  psmisc                     21.5-1        Utilities that use the proc filesy

-- debconf information:
  slapd/fix_directory: true
* shared/organization: schuldei.com
  slapd/upgrade_slapcat_failure:
  slapd/backend: BDB
* slapd/allow_ldap_v2: false
  slapd/no_configuration: false
  slapd/move_old_database: true
  slapd/suffix_change: false
  slapd/slave_databases_require_updateref:
  slapd/autoconf_modules: true
* slapd/domain: schuldei.com
  slapd/password_mismatch:
  slapd/invalid_config: true
* slapd/upgrade_slapadd_failure:
  slapd/purge_database: false
  slapd/admin:




--- /usr/share/slapd/fix_ldif   2004-07-27 08:07:49.000000000 +0200
+++ fix_ldif.orig.pl    2004-08-18 22:43:57.000000000 +0200
@@ -2,6 +2,9 @@
 # Copyright (c) Dave Horsfall.
 # All rights reserved.
 # 
+# extended and rewritten by Andreas Schuldei
+# for debian(-edu)
+# 
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
 # are met:
@@ -113,9 +116,22 @@
 use Data::Dumper;
 use Getopt::Long;
 use MIME::Base64;
+use strict;
+use diagnostics;
 
 my $origDN = '.origDN';        # Attribute stores original DN
 
+# the command line options
+
+my ($opt_dump, $opt_fix, $opt_inheritance, $opt_suffix, $opt_write,
+    $opt_no_auth, $opt_org);
+
+# some big hashes
+my (%entries, %schema, @single);
+
+my $suffix;
+
+
 &parse_options;
 $opt_write = 1 if $opt_fix;
 
@@ -128,6 +144,7 @@
     my $dn = shift @_;
     # Check if base64 encoded
     next if ! $dn =~ /^dn::? /i;
+    my $encoded;
     if($dn =~ /^dn:: /i) {
       $dn =~ s/dn:: (.*)/$1/;
       $dn = decode_base64($dn);
@@ -155,16 +172,15 @@
     # Extract the first component (the RDN)
     # for later tests.
     #
-    ($rdn, undef) = split(/,/, $cdn);
-    ($rdnattr, $rdnval) = split(/=/, $rdn);
+    my ( $rdn, undef ) = split ( /,/, $cdn );
+    my ( $rdnattr, $rdnval ) = split ( /=/, $rdn );
 
     #
     # Get the attributes/values.
     # Attributes are low-cased.
     #
-    for (@_)
-    {
-       ($attr, $val) = split(/\s/, $_, 2);     # In case of "::"
+    for (@_) {
+        my ( $attr, $val ) = split ( /\s/, $_, 2 );    # In case of "::"
        $attr =~ s/://;
        if ($attr =~ /:/)                       # Must be binary (base-64)
        {
@@ -248,46 +264,150 @@
     }
 
     #
-    # Check the objectclass inheritance.
+    # Check the objectclass inheritance and hirarcy.
     #
     if ($opt_inheritance)      # Will soon be mandatory
     {
-       foreach my $i (@{$entries{$cdn}{"objectclass"}})
-       {
+       my $obj_ref = objlist2hash( $entries{$cdn}{'objectclass'} );
+       $obj_ref->{top} = 1 # it might be that top is not there yet. 
+           unless $obj_ref->{alias};
+
+       # remove unknown object classes
+       foreach my $i ( keys %$obj_ref ) {
            next if $i eq "top";        # top is topless :-)
-           if (!defined $sup{$i})
-           {
+            unless ( $schema{objectclass}{$i} ) {
+               # check if objectclass is known in the first place
                print STDERR "dn: $dn\nUnknown objectclass: \"$i\"";
                if ($opt_fix)
                {
                    print STDERR "; ignored";
-                   &remove($i, [EMAIL PROTECTED]"objectclass"}});
+                    delete $obj_ref->{$i};
                }
                print STDERR "\n\n";
            }
-           if (defined $sup{$i} &&
-               !&present($sup{$i}, [EMAIL PROTECTED]"objectclass"}}))
-           {
-               print STDERR "dn: $dn\nNo sup for \"$i\": \"$sup{$i}\"";
-               if ($opt_fix)
-               {
+       }
+       
+       #
+        # check if we have one and only one structural 
+       # object class and remove superfluous object classes.
+       #
+       my %structural_objectclasses;
+       foreach my $i ( keys %$obj_ref ) {      
+           next if $i eq "top";    # top is topless :-)
+           
+           if ( $schema{objectclass}{$i}{structural} ) {
+               $structural_objectclasses{$i}=1;
+           }
+       }
+       if  (1 < scalar keys %structural_objectclasses ) {
+           print STDERR "dn: $dn\nMore then one structural objectclass:";
+           for my $structural_objectclass ( keys %structural_objectclasses ) {
+               print STDERR " \"$structural_objectclass\"";
+           }
+           print STDERR ".";
+           my $removable_objectclasses_ref = 
+               resolve_structural_clash ( \%structural_objectclasses, 
$entries{$cdn} );
+           if ($opt_fix) {
+               print STDERR " Removing ";
+               for my $obj_class ( @$removable_objectclasses_ref ) {
+                   print STDERR " \"$obj_class\"";
+                   delete $obj_ref->{$obj_class};
+               }
+               print STDERR ".\n\n";
+           }
+       }
+       #
+       # Now we find and add missing superior objectclasses
+       #
+       foreach my $i ( keys %$obj_ref ) {      
+           next if $i eq "top";    # top is topless :-)
+           for my $sup ( @{ $schema{objectclass}{$i}{sup} } ) {
+               unless ( $obj_ref->{$sup} ) {
+                   print STDERR "dn: $dn\nNo sup for \"$i\"";
+                   if ($opt_fix) {
                    print STDERR "; inserted";
-                   push @{$entries{$cdn}{"objectclass"}}, $sup{$i};
+                       $obj_ref->{$sup} = 1;
                }
                print STDERR "\n\n";
            }
-       } # each objectclass
-    } # inheritance
+           }    
+       } 
 
     #
-    # Check required attributes.
-    # Can't do in above loop, because the keys
-    # may have changed from inserting new classes.
+       # see if all mandatory attributes are there
     #
-    foreach my $i (@{$entries{$cdn}{"objectclass"}})
-    {
-       &checkattrs($cdn, $i);
+       my %must;
+       for my $i ( keys %$obj_ref ) {  
+           next if $i eq "top";    # top is topless :-)
+           
+           for my $attrib_must ( @{ $schema{objectclass}{$i}{must} } ) {
+               $must{ $attrib_must } = 1;
+           }
+       }
+       my %must_missing;
+      MUST:
+       for my $i ( keys %must ) {
+           next if ($i eq "cn"            or # there is no schema entry for cn!
+                    $i eq "objectclass");    # or for objectclass
+           for my $name ( @{ $schema{attributetype}{$i}{names} } ) {
+               next MUST if $entries{$cdn}{$name};
+           }
+           $must_missing{$i} = 1;
+       }
+       for my $i ( keys %must_missing ) {
+           print STDERR "dn: $dn\nAttribut \"$i\": mandatory but missing";
+           if ($opt_fix) {
+               print STDERR "; inserted";
+               $entries{$cdn}{$i} = [ "" ]; # FIXME: figure out proper syntax
+           }
+           print STDERR "\n\n";
+       }
+
+       # see if any attributes are orphans
+       # everything is allowed with extensibleobject. skip this case
+       unless ( $obj_ref->{extensibleobject} ) { 
+
+           my %attrib_all = %must;
+           foreach my $i ( keys %$obj_ref ) {
+               
+               next if $i eq "top";    # top is topless :-)
+               
+               for my $attrib_may ( @{ $schema{objectclass}{$i}{may} } ) {
+                   $attrib_all{ $attrib_may } = 1;
+               }
+           }
+           my %attrib_orphan;
+           for my $attrib ( keys %{ $entries{$cdn} } ) {
+               next if ".origDN"     eq $attrib or
+                   "encoded"         eq $attrib or
+                   "objectclass"     eq $attrib or
+                   "creatorsname"    eq $attrib or
+                   "createtimestamp" eq $attrib or
+                   "modifiersname"   eq $attrib or
+                   "modifytimestamp" eq $attrib or
+                   "cdn"             eq $attrib or
+                   "dn"              eq $attrib;
+               unless ( $attrib_all{ $attrib } ) {
+                   $attrib_orphan{ $attrib } = 1;
+               }
+           }
+           for my $i ( keys %attrib_orphan ) {
+               print STDERR "dn: $dn\nAttribut \"$i\": is not part of 
objectclasses";
+               for my $objclss ( keys %$obj_ref) {
+                   print STDERR  " \"$objclss\""; 
+               }
+               if ($opt_fix) {
+                   print STDERR "; removed";
+                   delete $entries{$cdn}{$i}; 
     }
+               print STDERR "\n\n";
+           }
+       } # extensibleobject.
+       # at this point we should have an entry with all needed sups, nicely 
cleand up 
+       objhash2list( $entries{$cdn}{objectclass} , $obj_ref ); # back to the 
old format
+    } # inheritance
+
+    
 } # main loop
 
 #
@@ -312,11 +432,16 @@
 
     # Fix up the suffix dn if it's our mess, adding a structural objectclass.
     if ($thisdn eq &canon($suffix)) {
-       if (@{$entries{$thisdn}{'objectclass'}} == 1
-           && lc $entries{$thisdn}{'objectclass'}[0] eq 'dcobject')
-       {
-               if (defined($opt_org))
+       my $obj_ref = objlist2hash( $entries{$thisdn}{'objectclass'} );
+       if ( ( 1 == keys %$obj_ref  
+              and $obj_ref->{dcobject} )
+            or 
+            ( 2 == keys %$obj_ref  
+              and $obj_ref->{dcobject} 
+              and $obj_ref->{top} )
+            )
                {
+            if ( defined($opt_org) ) {
                        push(@{$entries{$thisdn}{'objectclass'}}, 
'organization');
                        push(@{$entries{$thisdn}{'o'}}, $opt_org);
                } else {
@@ -361,34 +486,6 @@
 }
 
 #
-# Check required attributes.
-#
-sub checkattrs
-{
-    (my $dn, $class) = @_;
-    foreach my $attr (@{$reqd{lc $class}})
-    {
-       if (!defined @{$entries{$dn}{lc $attr}})
-       {
-           my $odn = $entries{$dn}{$origDN};
-           print STDERR "dn: $odn\nMissing reqd \"$class\" attr \"$attr\"";
-           if ($opt_fix)
-           {
-               # Quick hack for CI
-               my $fix = "UNKNOWN";
-               if ($attr eq "cn" && $fix ne "")
-               {
-                   $fix = $entries{$dn}{"givenname"}[0];
-               }
-               push @{$entries{$dn}{$attr}}, $fix;
-               print STDERR "; inserted \"$fix\"";
-           }
-           print STDERR "\n\n";
-       }
-    }
-}
-
-#
 # Write an entry to standard output.
 #
 # Ought to wrap at 78 cols as well.
@@ -398,110 +495,35 @@
     my ($dn) = @_;
     my $odn = $entries{$dn}{$origDN};
     if ($entries{$dn}{"encoded"} == 1) {
-      $encoded = encode_base64($odn,"");
+      my $encoded = encode_base64( $odn, "" );
       print "dn:: $encoded\n";
     } else {
       print "dn: $odn\n";
     }
-    foreach my $attr (keys %{$entries{$dn}})
-    {
-       next if $attr eq $origDN;
-       foreach my $value (@{$entries{$dn}{$attr}})
-       {
+    foreach my $attr ( keys %{ $entries{$dn} } ) {
+        next if $attr eq $origDN or $attr eq "encoded" ;
+        foreach my $value ( @{ $entries{$dn}{$attr} } ) {
            print "$attr:";
-           if ($attr =~ /userpassword/i
-               || $value =~ /(^[ :]|[\x00-\x1f\x7f-\xff])/)
+
+            if ( defined $value and ( $attr =~ /userpassword/i
+                || $value =~ /(^[ :]|[\x00-\x1f\x7f-\xff])/ )  )
            {
                print ": ", &enmime($value, "");
            }
-           else
-           {
+            elsif ( defined $value and "" ne $value) { 
                print " $value";
            }
            print "\n";
-       }
-    }
-    print "\n";
-}
 
-#
-# Test for presence of element in list.
-#
-sub present
-{
-    my ($element, $list) = @_;
-    my $found = 0;
-
-    foreach my $i (@$list)
-    {
-        if ($i eq $element)
-        {
-            $found = 1;
-            last;
-        }
-    }
-    return $found;
-}
-
-#
-# Remove specified element from list.
-# It's a unique element, but multiple
-# occurances will be removed.  It will
-# change the order of the list.
-#
-sub remove
-{
-    my ($element, $list) = @_;
-
-    for (my $i = 0; $i < @$list; $i++)
-    {
-        if ($element eq @$list[$i])
-        {
-           @$list[$i] = @$list[$#$list];
-            pop @$list;
         }
     }
+    print "\n";
 }
 
-#
-# Initialise some stuff (automatically called).
-#
-sub INIT
-{
-    #
-    # Initialise the superior objectclasses.
-    # Ought to get this from the schema.
-    #
-    $sup{"dcObject"} = "top";
-    $sup{"inetOrgPerson"} = "organizationalPerson";
-    $sup{"organizationalPerson"} = "person";
-    $sup{"organizationalRole"} = "top";
-    $sup{"organizationalUnit"} = "top";
-    $sup{"person"} = "top";
-    $sup{"posixAccount"} = "top";
-    $sup{"room"} = "top";
-    $sup{"simpleSecurityObject"} = "top";
+sub INIT {
 
-    #
-    # These are incomplete/wrong/WIP.
-    #
-    $sup{"ciAdministrator"} = "top";
-    $sup{"ciApplication"} = "top";
-    $sup{"ciEmployee"} = "inetOrgPerson";
-    $sup{"ciLdapConfig"} = "top";
-    $sup{"ciPrinter"} = "top";
-    $sup{"ciServer"} = "top";
-
-    #
-    # Required attributes.
-    #
-    $reqd{"person"} = [ "sn", "cn" ];  # Special - can be autofixed
-    $reqd{"ciadministrator"} = [ "uid", "userPassword" ];
-    $reqd{"ciapplication"} = [ "ciApp", "ciAppType", "ciHost", "ciStatus", 
"ciPortNum" ];
-    $reqd{"ciemployee"} = [ "employeeNumber", "sn" ];
-    $reqd{"cildapconfig"} = [ "ciHost" ];
-    $reqd{"ciprinter"} = [ "ciPrinterName" ];
-    $reqd{"ciserver"} = [ "name" ];
+    my $schema_ref = parse_schemas();
+    %schema = %$schema_ref;
 
     #
     # Single-value attributes.
@@ -624,3 +646,299 @@
     }
     return $res;
 }
+
+sub read_config {
+    my ($file) = @_;
+    
+    open CONFIG,   "<  $file"  or die "can't open $file: $!";
+
+    my %config;
+    while ( <CONFIG> ) {
+       chomp;
+       s/\#.*//;
+       s/^\s+//;
+       s/\s+$//;
+       next unless length;
+       my ($var, $value) = split(/\s*=\s*/, $_, 2);
+       $config{$var} = $value;
+    }
+    
+    close CONFIG;
+    
+    return \%config;
+}
+
+sub read_slapd_config {
+    my ($file) = @_;
+    
+    open CONFIG,   "<  $file"  or die "can't open $file: $!";
+
+    my $seperator = $/; # save the seperator since it is non-standard
+    undef $/;
+    my $whole_file =  <CONFIG>; # sluuuurp
+    $whole_file =~ s/\n(?!\n)\s+/ /g; # merge logical line as the ldap config 
parser does
+    $/= $seperator; # restore the original line seperator;
+
+    my @whole_file = split (/\n/, $whole_file);
+
+
+    my %config;
+    while ( @whole_file ) {
+       $_ = pop @whole_file;
+       chomp;
+       s/\#.*//;
+       s/^\s+//;
+       s/\s+$//;
+       next unless length;
+       my ($var, $value) = split(/\s+/, $_, 2);
+       push @{ $config{$var} }, $value; 
+
+       # this does not keep the order of the configuration easily
+       # accessable, which is bad for things like databases and
+       # suffixes but does not matter for the include lines of the
+       # schemas. With some efford one could pirce together the order
+       # by getting it from the order in the anonymous arrays.
+
+    }
+    
+    close CONFIG;
+    
+    return \%config;
+}
+
+sub extract_system_schemas {
+    my ($core_schema, $schema_raw_ref) = @_;
+
+    while ( $core_schema ) {
+       $core_schema =~ s/^.*?\n\# system schema\n\#(.*?\))(\n\n.*)$/$2/s;
+       last unless $1;
+       my $core_def = $1;
+       $core_def =~ s/\n(?!\n)\#\s+/ /g;
+       chomp $core_def;
+       $core_def =~s/^\s+//;
+       $core_def =~s/\s+$//;
+       next unless length $core_def;
+       push @$schema_raw_ref, "$core_def\n"; 
+    }
+}
+
+sub read_schema {
+    my ($file) = @_;
+    
+    open SCHEMA,   "<  $file"  or die "can't open $file: $!";
+
+    my $seperator = $/; # save the seperator since it is non-standard
+    undef $/;
+    my $whole_file =  <SCHEMA>; # sluuuurp
+
+    my @schema_raw;    
+    if ($file eq "/etc/ldap/schema/core.schema") {
+       # There are some system schema entries which are hard coded
+       # into openLdap.  They are marked "system schema" in the
+       # core.schema. we try to detect them and remove the comments
+       # in front of those.
+       extract_system_schemas( $whole_file, [EMAIL PROTECTED]);
+       
+    }
+
+    $whole_file =~ s/\n(?!\n)\s+/ /g; 
+    # this is dubious, since we should watch not lines starting with 
+    # whitespaces but balance the parantecies. but this works well.
+    $/= $seperator; # restore the original line seperator;
+
+    
+    my @whole_file = split (/\n/, $whole_file);
+
+    
+    while ( @whole_file ) {
+       $_ = pop @whole_file;
+       chomp;
+       s/\#.*//;
+       s/^\s+//;
+       s/\s+$//;
+       next unless length;
+       push @schema_raw, "$_\n"; 
+    }
+    
+    close SCHEMA;
+    return [EMAIL PROTECTED];
+}
+
+
+sub find_slapd_config {
+
+    my $defaults = "/etc/default/slapd";
+    my $slapd_defaults_ref;
+    
+    if ( -f $defaults ) {
+       $slapd_defaults_ref = read_config( $defaults ); 
+    }
+
+    unless ( $slapd_defaults_ref->{SLAPD_CONF} and 
+        -f $slapd_defaults_ref->{SLAPD_CONF} ) 
+    {
+       $slapd_defaults_ref->{SLAPD_CONF} = "/etc/ldap/slapd.conf";
+    }
+       
+    return $slapd_defaults_ref->{SLAPD_CONF};
+
+}
+
+sub parse_slapd_config {
+    
+    my ($slapd_config_file) = @_;
+    
+    my $slapd_config_href = read_slapd_config( $slapd_config_file );
+    
+    return $slapd_config_href;
+}
+
+sub find_active_schemas {
+    my ($slapd_config_href) = @_;
+
+    return [EMAIL PROTECTED] $slapd_config_href->{include} }; 
+}
+sub preprocess_schemas {
+    my ( $schemas_list_ref ) = @_;
+    
+    my @schemas_raw;
+    
+    for my $file ( @{$schemas_list_ref} ) {
+       push @schemas_raw, @{ read_schema( $file ) }; 
+    }
+    return [EMAIL PROTECTED];
+}
+
+sub get_used_schemas {
+
+    my $slapd_config_path = find_slapd_config();
+    my $slapd_config_href = parse_slapd_config( $slapd_config_path );
+    my $schemas_list_aref = find_active_schemas( $slapd_config_href );
+    my $schemas_raw_aref = preprocess_schemas( $schemas_list_aref );
+    return $schemas_raw_aref;
+}
+
+sub parse_schemas {
+
+    my $schemas_raw_aref = get_used_schemas();
+    
+    my %schema;
+    while ( @$schemas_raw_aref ) {
+       $_= pop @$schemas_raw_aref;
+       chomp;
+
+       #poor man`s parser
+
+       my ( $type ) =
+           /^(\w+)\s/;
+       
+       my ( $structural ) = 
+           /^.*\s(STRUCTURAL)\s.*$/;
+       
+       my ( $auxiliary ) =     
+           /^.*\s(AUXILIARY)\s.*$/;
+       
+       my ( $description ) = 
+           /^.*\s+DESC\s+\'([^\']+)\'.*$/;
+
+       my ( $syntax ) =        
+           /^.*\s+SYNTAX\s+([\d\.\{\}]+).*$/;
+
+
+       my @names;
+       if ( /^.*\s+NAME\s+\(\s*\'([\w\s\']+)\'\s*\).*$/  ) {
+            @names = split(/\'\s+\'/, lc $1);
+       }
+       elsif ( /^.*\s+NAME\s+\'(\w+)\'\s.*$/ ) {
+           push @names, lc $1;
+       }
+       
+       my @sup;
+       if ( /^.*\s+SUP\s+\(\s*([^\)]+?)\s*\).*$/ ) {
+           @sup = split(/\s*\$\s*/, lc $1);
+       }
+       elsif ( /^.*\s+SUP\s+(\w+)\s.*$/ ) {
+           push @sup, lc $1;
+       }
+       
+       my @must;
+       if ( /^.*\s+MUST\s+\(\s*([^\)]+?)\s*\).*$/ ) {
+           @must = split(/\s*\$\s*/, lc $1);
+       }
+       elsif ( /^.*\s+MUST\s+(\w+)\s.*$/ ) {
+           push @must, lc $1 ;
+       }
+       
+       my @may;
+       if ( /^.*\s+MAY\s+\(\s*([^\)]+?)\s*\).*$/ ) {
+           @may = split(/\s*\$\s*/, lc $1);
+       }
+       elsif ( /^.*\s+MAY\s+(\w+)\s.*$/ ) {
+           push @may, lc $1 ;
+       }
+
+       unless ($type eq "attributetype" or 
+               $type eq "objectclass"   or 
+               @names ) 
+       {
+           print STDERR "$_\n"; 
+       }
+       else {
+           for my $name ( @names ) {
+               $name = lc $name;
+
+               $schema{$type}{$name}{names}       = [EMAIL PROTECTED];
+               $schema{$type}{$name}{description}= $description 
+                   if $description;
+               $schema{$type}{$name}{syntax}     = $syntax
+                   if $syntax;
+               $schema{$type}{$name}{structural} = 1
+                   if $structural;
+               $schema{$type}{$name}{auxiliary}  = 1
+                   if $auxiliary;
+               $schema{$type}{$name}{must}       = [EMAIL PROTECTED] 
+                   if @must;
+               $schema{$type}{$name}{may}        = [EMAIL PROTECTED]
+                   if @may;
+               $schema{$type}{$name}{sup}        = [EMAIL PROTECTED] 
+                   if @sup;
+           }
+       }
+    }
+    return \%schema;
+}
+
+sub objlist2hash {
+    my ($list_ref) = @_;
+    
+    my %objectclass;
+    for my $objclass ( @$list_ref ) {
+       $objclass = lc $objclass;
+       $objectclass{$objclass } = 1;
+    }
+    
+    return \%objectclass;
+}
+
+sub objhash2list {
+    my ($array_ref , $obj_hash_ref ) = @_;
+    
+    @$array_ref = keys %$obj_hash_ref;
+}
+
+sub resolve_structural_clash {
+    my ( $structural_objectclasses_ref, $entry_ref ) = @_;
+
+    my @removable_objectclasses;
+
+    # remove automountmap
+    # i dont know good heuristics to decide which one i 
+    # should remove, so this is hard coded.
+    # what other common cases are there?
+    if ($structural_objectclasses_ref->{automountmap}       and
+       $structural_objectclasses_ref->{organizationalunit} and 
+       2 == keys %$structural_objectclasses_ref ) {
+       push @removable_objectclasses, "automountmap";
+    }
+    return [EMAIL PROTECTED];
+}


--- End Message ---
--- Begin Message ---
It's been years since strict schema checking was added and it's always
enforced for the version released with etch.  It's unlikely that anyone
will still be trying to upgrade from an LDAP database that doesn't pass
schema checking and for which fix_ldif would be useful.

We're therefore dropping all fix_ldif code from the slapd package and
closing any remaining bugs open against it.

-- 
Russ Allbery ([EMAIL PROTECTED])               <http://www.eyrie.org/~eagle/>


--- End Message ---

Reply via email to